/* ═══════════════════════════════════════════════════════════════════════
   KECKEX — das Blatt der oeffentlichen Seite.

   Es loest vier Dateien ab: public.css (225), landing.css (1789 abzueglich
   der 342 Zeilen des Spiels, die in spiel.css stehen), premium.css (315)
   und cookie_consent.css (175). Dazu Bootstrap, das die Kundenseite
   bisher komplett geladen hat.

   ── Was sich aendert und was nicht ───────────────────────────────────
   Marco am 27.08.2026: "wir fahren frisch auf und nehmen das Beste und
   bauen die Seiten dann neu - mit selbem Content, selben Funktionen und
   Farben, aber halt frischer und ultramodern."

   * **Die Farben sind dieselben.** --kx-green ist Zeichen fuer Zeichen
     das Gruen aus public.css, ebenso --kx-dark, --kx-text-muted und der
     Verlauf des Hero. Wer hier eine Farbe aendert, aendert die Marke.
   * **Die Klassennamen sind dieselben.** Das ist keine Bequemlichkeit,
     sondern eine Entscheidung: landing.js und landing_game.js zeigen mit
     rund fuenfzig Selektoren in dieses Blatt (.lp-grid__item,
     .lp-detail__price, .lp-anim, .kg-*). Eine zweite Namenswelt haette
     jede dieser Stellen zu einer Aenderung gemacht - und "selbe
     Funktionen" zu einer Behauptung.
   * **Neu ist alles dazwischen**: ein Token-System statt gewachsener
     Werte, Grid statt Bootstrap-Raster, fluide Typografie mit clamp()
     statt fester Stufen, ein Abstandsraster statt 31 fester Pixelwerte,
     weichere Radien, ruhigere Schatten.

   ── Die zwoelf Namen, die aus der DATENBANK kommen ───────────────────
   Ein Abschnitt weiter unten heisst "Die Bruecke zur Datenbank" und sieht
   aus wie ein Rest Bootstrap. Er ist keiner. cms_pages.content speichert
   fuer jeden Block die Werte pt-5, pb-3, bg-light, text-center - das sind
   Bootstrap-Klassennamen, die als INHALT in der Datenbank stehen
   (cms_blocks_registry.py, GLOBAL_FIELDS). Phase 6 macht keine
   Migration; also muss dieses Blatt diese Namen weiter verstehen.
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══ 1. Token ═══════════════════════════════════════════════════════ */

:root {
    /* ── Marke. Werte unveraendert aus public.css. ── */
    --kx-green: #97D700;
    --kx-green-light: #97D700;
    /* Die Schriftfarbe „Markenverlauf" aus dem Editor (14.09.2026). Allein
       ist sie das Markengruen; den Verlauf legt die Regel
       `[style*="--kx-verlauf"]` in Abschnitt 4 darueber. */
    --kx-verlauf: var(--kx-green);
    --kx-green-rgb: 151, 215, 0;
    --kx-green-glow: rgba(var(--kx-green-rgb), 0.4);
    --kx-green-dark: #7BA428;
    /* **Die Schriftfarbe AUF dem Gruen** (01.09.2026). Weiss darauf ergibt
       einen Kontrast von 1,74 - noetig sind 4,5, und keiner der Knoepfe
       ist gross genug fuer die Ausnahme fuer grosse Schrift (gemessen:
       13,6 bis 16,8 px). Diese Tinte auf demselben Lime ergibt 7,74.
       Das Gruen bleibt also, was es ist; nur die Beschriftung wird
       lesbar. Wer es zurueckdrehen will, setzt hier `#fff` - eine Zeile. */
    --kx-auf-gruen: #2F2E31;
    /* **Das Gruen als SCHRIFT auf hellem Grund** — dasselbe Problem in
       die andere Richtung: `--kx-green` als Text auf Weiss ergibt
       ebenfalls 1,74. Dieser Ton ist derselbe Farbton, nur dunkel genug
       (4,93 auf Weiss, 4,72 auf `--kx-bg-soft`). Fuer Flaechen bleibt
       `--kx-green` — der ist die Marke; dieser hier ist nur fuer Buchstaben. */
    --kx-gruen-text: #5C7A1D;

    /* ── Dieselben sechs Toene unter kundenneutralem Namen (Paket 9.1).
         **Das ist die Schnittstelle zur Einstellung `Web → Marke`.** Wer
         dort eine Farbe eintraegt, bekommt einen `<style>`-Block im Kopf
         der Seite, der genau diese sechs ueberschreibt (und die alten
         Namen darueber gleich mit — `marke_service.BRUECKE`). Ohne
         Eintrag gelten die Werte hier, und die sind Zeichen fuer Zeichen
         die von Hand gewaehlten oben: an einer Seite ohne Eintrag
         aendert sich nichts.

         **Neue Regeln nehmen den neutralen Namen.** `--kx-green` heisst
         gruen und die Farbe des naechsten Kunden ist es vielleicht
         nicht; umbenannt wird das Blatt aber nicht — 93 KB fuer keinen
         sichtbaren Gewinn.

         **Diese sechs Zeilen sind ABGESCHRIEBEN, nicht gewaehlt**: sie
         sind Zeichen fuer Zeichen die Ausgabe von
         `marke_service.toene("#97D700")`, und
         `test_marke.test_die_vorgabe_im_blatt_ist_die_rechnung` prueft
         das nach. Damit sieht eine Seite ohne Eintrag genauso aus wie
         eine, in der jemand das Kundengruen eintraegt — sonst waere der
         erste Eintrag ein unerklaerlicher Sprung. ── */
    --kx-marke: #97D700;
    --kx-marke-rgb: 151, 215, 0;
    --kx-marke-dunkel: #7CB000;
    /* 4,90 auf Weiss und 4,56 auf `--kx-marke-hauch`. Der von Hand
       gewaehlte `--kx-gruen-text` (#5C7A1D) erfuellt nur den ersten Fall:
       im getoenten Kasten des Impressums landet er bei 4,28. Deshalb
       rechnet `_schriftton()` gegen den Hauch und nicht gegen Weiss. */
    --kx-marke-text: #577C00;
    --kx-auf-marke: #3E3D40;
    /* Der hellste Grund der Marke — der Kasten im Impressum, eine
       Hervorhebung im Fliesstext. Bis zum 02.09.2026 stand er in den vier
       Rechtsseiten als `rgba(107, 142, 35, 0.06)`: ein OLIVGRUEN, das mit
       dem Lime des Kunden nichts zu tun hat und ihm auch bei keiner
       Farbaenderung folgt. Neunmal, in vier Dateien. */
    --kx-marke-hauch: #F3FAE0;

    --kx-dark: #3e3d40;
    --kx-text: #3e3d40;
    /* 01.09.2026: von #6b7280 abgedunkelt. Auf dem hellsten Grund
       (#f1f5f9, die Chips) ergab der alte Ton 4,41 - knapp unter 4,5,
       gemessen an `.lp-detail__category` auf der Landingpage. */
    --kx-text-muted: #5b6472;

    /* ── Flaechen ── */
    --kx-bg: #ffffff;
    --kx-bg-soft: #f8fafc;
    --kx-bg-muted: #f1f5f9;
    --kx-card-bg: #ffffff;
    --kx-card-border: rgba(0, 0, 0, 0.05);
    --kx-line: #e2e8f0;
    --kx-line-strong: #cbd5e1;
    --kx-ink-soft: #475569;
    /* 01.09.2026: von #94a3b8 abgedunkelt. Der alte Ton ergab auf
       Weiss 2,56 - er stand unter anderem an den Eckdaten der
       Geraete (`.lp-detail__specs dt`) und an jedem Platzhalter in
       einem Eingabefeld. Bleibt heller als `--kx-text-muted`, die
       Abstufung stimmt also weiter. */
    --kx-ink-faint: #64748b;

    /* Der Verlauf des Hero. Vier Stopps, unveraendert - er ist das
       Erste, was ein Besucher von der Marke sieht. */
    --kx-hero-verlauf: linear-gradient(170deg, #f0f7e4 0%, #e8f5d6 30%, #f8fdf3 60%, #f0f9ff 100%);
    /* Die dunkle Flaeche von Kontaktkarte, Spielbanner und Fussbereich. */
    --kx-nacht: linear-gradient(135deg, #1e293b, #0f172a);

    /* ── Radien. Das 4-px-Raster aus public.css, --kx-radius bleibt
       der Radius der Karte (18px). ── */
    --kx-radius-xs: 4px;
    --kx-radius-sm: 8px;
    --kx-radius-md: 12px;
    --kx-radius-lg: 16px;
    --kx-radius-xl: 24px;
    --kx-radius: 18px;
    --kx-radius-pill: 50rem;

    /* ── Schrift. Acht Stufen, gemessen an der Verwendung und nicht
       erfunden - eine eigene Skala, absichtlich NICHT die der App. ── */
    --kx-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --kx-fs-xs:   0.75rem;
    --kx-fs-sm:   0.85rem;
    --kx-fs-base: 0.95rem;
    --kx-fs-md:   1.05rem;
    --kx-fs-lg:   1.2rem;
    --kx-fs-xl:   1.5rem;
    --kx-fs-2xl:  2rem;
    --kx-fs-3xl:  3rem;

    /* Schaugroessen, fluide. Sie ersetzen die clamp()-Ausdruecke, die in
       landing.css sechsmal ausgeschrieben standen. */
    --kx-fs-schau: clamp(2.25rem, 5vw, 3.5rem);
    --kx-fs-titel: clamp(1.6rem, 3.5vw, 2.35rem);

    /* ── Abstaende. Ein Raster statt 31 fester Pixelwerte. ── */
    --kx-1: 0.25rem;
    --kx-2: 0.5rem;
    --kx-3: 0.75rem;
    --kx-4: 1rem;
    --kx-5: 1.5rem;
    --kx-6: 2rem;
    --kx-7: 3rem;
    --kx-8: 4rem;
    --kx-abschnitt: clamp(3rem, 7vw, 5.5rem);

    /* ── Schatten. Drei Stufen, ruhiger als die alten. ── */
    --kx-schatten-sm: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.03);
    --kx-schatten: 0 4px 12px rgba(15, 23, 42, 0.06), 0 2px 4px rgba(15, 23, 42, 0.03);
    --kx-schatten-lg: 0 18px 45px rgba(15, 23, 42, 0.10), 0 6px 14px rgba(15, 23, 42, 0.04);
    --kx-schatten-gruen: 0 8px 24px rgba(var(--kx-green-rgb), 0.32);

    /* ── Bewegung ── */
    --kx-schnell: 140ms;
    --kx-normal: 240ms;
    --kx-ruhig: 700ms;
    --kx-kurve: cubic-bezier(0.16, 1, 0.3, 1);

    /* ── Breite ── */
    --kx-wrap: 1200px;
    --kx-wrap-schmal: 800px;
}

/* Das dunkle Ende der Verlaeufe auf den Primaerknoepfen wird aus
   --kx-green abgeleitet, damit eine Farbaenderung des Kunden mitzieht.
   Der feste Wert oben ist der Rueckfall fuer Browser ohne color-mix. */
@supports (color: color-mix(in srgb, red 50%, black)) {
    :root {
        --kx-green-dark: color-mix(in srgb, var(--kx-green) 78%, black);
    }
}

/* ═══ 2. Grundlage ═══════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Die Leiste klebt oben; ein Sprungziel darf nicht darunter landen. */
    scroll-padding-top: 5.5rem;
}

body {
    margin: 0;
    font-family: var(--kx-font);
    font-size: var(--kx-fs-base);
    line-height: 1.65;
    color: var(--kx-text);
    background: var(--kx-bg);
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { font: inherit; color: inherit; }
h1, h2, h3, h4, h5, h6 { margin: 0 0 var(--kx-3); line-height: 1.2; font-weight: 800; }
/* Ein Titelfeld, das selbst eine Ueberschrift traegt (`titel_ueberschrift`
   in web/jinja.py, 14.09.2026): die Ueberschrift der Vorlage waere leer und
   wird ein <div> mit ihren Klassen. `.kx-ueberschrift-platz` gibt ihm, was
   die Regel darueber ihr gab - der Abstand bleibt, wie er war. Die Klassen
   der Vorlage stehen weiter unten und setzen sich wie vorher durch. */
.kx-ueberschrift-platz { margin: 0 0 var(--kx-3); line-height: 1.2; font-weight: 800; }
/* ... und die Ueberschrift aus dem Titelfeld behaelt als <h1> der Seite
   (`eine_h1`) die Groesse der <h2>, die im Editor gewaehlt war: 1.5em ist
   die Vorgabe des Browsers fuer <h2>, fuer <h1> waeren es 2em. */
h1.kx-aus-titelfeld { font-size: 1.5em; }
p { margin: 0 0 var(--kx-3); }
ul, ol { margin: 0 0 var(--kx-3); padding-left: 1.25rem; }
hr { border: 0; border-top: 1px solid var(--kx-line); margin: var(--kx-4) 0; }

:focus-visible {
    outline: 3px solid var(--kx-marke-text);
    outline-offset: 2px;
    border-radius: var(--kx-radius-xs);
}

/* ═══ 3. Layout ══════════════════════════════════════════════════════ */

.kx-wrap,
.container {
    width: 100%;
    max-width: var(--kx-wrap);
    margin-inline: auto;
    padding-inline: var(--kx-5);
}

.lp-section { position: relative; }
.lp-section > .container,
.lp-section > .container-fluid { position: relative; z-index: 1; }

/* Ein Raster, das ohne zwoelf Spaltenklassen auskommt: die Karten sagen,
   wie breit sie mindestens sein wollen, das Raster rechnet den Rest. */
.kx-raster {
    display: grid;
    gap: var(--kx-5);
    grid-template-columns: repeat(auto-fit, minmax(min(var(--kx-min, 260px), 100%), 1fr));
}

.kx-zweispalt {
    display: grid;
    gap: clamp(var(--kx-5), 4vw, var(--kx-7));
    align-items: center;
    grid-template-columns: 1fr;
}
@media (min-width: 62rem) {
    .kx-zweispalt { grid-template-columns: var(--kx-spalten, 5fr 7fr); }
}

/* ═══ 4. Ueberschriften der Abschnitte ═══════════════════════════════ */

.lp-section__title {
    font-size: var(--kx-fs-titel);
    font-weight: 900;
    letter-spacing: -0.025em;
    color: var(--kx-dark);
    margin-bottom: var(--kx-4);
    text-wrap: balance;
}
/* **`:not([style])` seit dem 14.09.2026.** Vorher faerbte diese Regel
   JEDES <span> in einer Abschnittsueberschrift gruen - und ein <span> ist
   genau das, was der Editor fuer eine gewaehlte Farbe schreibt. Marco:
   „wenn ich hier schwarz drücke, kommt die Schrift in grün". Eine
   gewaehlte Farbe gilt jetzt; ein <span> ohne Farbe (so aus der alten
   Seite und aus den verlorenen Farben vor dem 14.09.) bleibt gruen, wie es
   auf der Seite zu sehen war. Gezielt waehlen laesst sich der Verlauf mit
   der Farbe „Markenverlauf" im Editor - die dritte Zeile. */
.lp-section__title span:not([style]),
.kx-gradient-text,
[style*="--kx-verlauf"] {
    background: linear-gradient(135deg, var(--kx-green), var(--kx-green-light));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.lp-section__subtitle {
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-md);
    margin-bottom: var(--kx-6);
    max-width: 60ch;
}
.text-center .lp-section__subtitle { margin-inline: auto; }

.kx-kopf { margin-bottom: var(--kx-6); }

/* Der Freitext eines Blocks. Er kommt aus einem Rich-Text-Editor und
   bringt eigene <p>, <ul> und <strong> mit. */
.kx-fliesstext { font-size: var(--kx-fs-md); color: var(--kx-ink-soft); }
.kx-fliesstext :last-child { margin-bottom: 0; }
.text-center .kx-fliesstext { margin-inline: auto; max-width: 70ch; }

/* ═══ 5. Die Bruecke zur Datenbank ═══════════════════════════════════

   Diese zwoelf Namen stehen als WERTE in cms_pages.content und in
   cms_blocks_registry.py. Sie sind Inhalt, nicht Gestaltung - deshalb
   bleiben sie, obwohl Bootstrap geht. Wer sie umbenennen will, braucht
   eine Migration, und die verbietet der Warnblock vor Phase 6.        */

.text-center { text-align: center; }
.text-start  { text-align: left; }
.text-end    { text-align: right; }

.bg-white   { background-color: #ffffff; }
.bg-light   { background-color: var(--kx-bg-soft); }
.bg-dark    { background-color: var(--kx-dark); }
.bg-primary { background-color: var(--kx-green); }
.text-white { color: #ffffff; }
.text-white .lp-section__title,
.bg-dark .lp-section__title,
.bg-primary .lp-section__title { color: #ffffff; }
.text-white .lp-section__subtitle,
.bg-dark .lp-section__subtitle { color: rgba(255, 255, 255, 0.72); }

.pt-0 { padding-top: 0; }
.pt-3 { padding-top: var(--kx-4); }
.pt-4 { padding-top: var(--kx-5); }
.pt-5 { padding-top: var(--kx-abschnitt); }
.pb-0 { padding-bottom: 0; }
.pb-3 { padding-bottom: var(--kx-4); }
.pb-4 { padding-bottom: var(--kx-5); }
.pb-5 { padding-bottom: var(--kx-abschnitt); }
/* Die beiden "Gross"-Werte der Registry sind zwei Klassen in einem
   Feld ("pt-lg-5 pt-xl-6"); beide muessen greifen. */
@media (min-width: 62rem) {
    .pt-lg-5 { padding-top: var(--kx-abschnitt); }
    .pb-lg-5 { padding-bottom: var(--kx-abschnitt); }
}
@media (min-width: 75rem) {
    .pt-xl-6 { padding-top: calc(var(--kx-abschnitt) * 1.4); }
    .pb-xl-6 { padding-bottom: calc(var(--kx-abschnitt) * 1.4); }
}

/* ═══ 6. Die Handvoll Hilfsklassen, die wirklich benutzt wird ════════ */

.text-muted { color: var(--kx-text-muted); }
.cursor-pointer { cursor: pointer; }
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}

/* ═══ 7. Bewegung beim Scrollen ══════════════════════════════════════

   landing.js schaltet .visible ueber einen IntersectionObserver.       */

.lp-anim {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity var(--kx-ruhig) var(--kx-kurve),
                transform var(--kx-ruhig) var(--kx-kurve);
}
.lp-anim[data-anim="fadeDown"] { transform: translateY(-20px); }
.lp-anim[data-anim="fadeIn"]   { transform: none; }
.lp-anim[data-anim="zoomIn"]   { transform: scale(0.94); }
.lp-anim.visible { opacity: 1; transform: none !important; }

/* Das erste Stück der Seite blendet sich mit CSS ein, nicht erst, wenn
   `einblenden.js` gelaufen ist (Ausbau KS, 10.10.2026). Die Überschrift und das
   Bild ganz oben sind das LCP-Element; solange sie auf `opacity: 0` standen,
   wartete der Lauf auf sechs Skripte - Lighthouse mobil: Überschrift sichtbar
   nach 1,4 s, LCP 4,1 s. Die Bewegung ist dieselbe (28 px nach oben, 700 ms,
   Verzögerung 100/200 ms wie `data-delay`); `einblenden.js` lässt diese
   Elemente aus, weil `.visible` mit `!important` die Bewegung mittendrin
   abbräche. Nur die DIREKTEN Kinder des Abschnitts-Rahmens (`> div > .lp-anim`):
   Überschrift, Bild und Unterzeile des Kopfs. Karten, die tiefer im ersten
   Abschnitt stehen und unter dem Falz liegen können, blenden sich weiter beim
   Scrollen ein. */
#inhalt > section:first-of-type > div > .lp-anim {
    opacity: 1;
    transform: none;
    animation: kxEinsatz var(--kx-ruhig) var(--kx-kurve) both;
}
@keyframes kxEinsatz { from { opacity: 0; transform: translateY(28px); } }
#inhalt > section:first-of-type > div > .lp-anim[data-delay="100"] { animation-delay: .1s; }
#inhalt > section:first-of-type > div > .lp-anim[data-delay="200"] { animation-delay: .2s; }

@keyframes fadeSlideUp {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

/* Suchmaschinen und KI-Crawler fuehren kein JavaScript aus. Ohne diese
   Regel saehen sie opacity:0 auf jedem animierten Abschnitt. */
@media (scripting: none) {
    .lp-anim { opacity: 1 !important; transform: none !important; }
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .lp-anim { opacity: 1 !important; transform: none !important; transition: none; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ═══ 8. Knoepfe ═════════════════════════════════════════════════════ */

.kx-btn,
.kx-premium-btn,
.lp-hero__cta,
.lp-spotlight__cta,
.lp-detail__cta-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    padding: 0.85rem 2.25rem;
    border: 0;
    border-radius: var(--kx-radius-pill);
    background: linear-gradient(135deg, var(--kx-green), var(--kx-green-dark));
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-md);
    font-weight: 700;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    box-shadow: var(--kx-schatten-gruen);
    transition: transform var(--kx-schnell) var(--kx-kurve),
                box-shadow var(--kx-normal) var(--kx-kurve),
                background var(--kx-normal) var(--kx-kurve);
}
.kx-btn:hover,
.kx-premium-btn:hover,
.lp-hero__cta:hover,
.lp-spotlight__cta:hover,
.lp-detail__cta-btn:hover {
    color: var(--kx-auf-gruen);
    background: linear-gradient(135deg, var(--kx-green-light), var(--kx-green));
    transform: translateY(-2px);
    box-shadow: 0 12px 30px rgba(var(--kx-green-rgb), 0.4);
}
.kx-btn:disabled, .kx-premium-btn:disabled { opacity: 0.6; cursor: default; transform: none; }

.kx-btn--geist {
    background: transparent;
    /* Nicht `--kx-green`: als Schrift auf Weiss ergibt der Lime 1,74.
       Der Rahmen darf der Lime bleiben - Rahmen sind kein Text. */
    color: var(--kx-gruen-text);
    border: 1.5px solid var(--kx-green);
    box-shadow: none;
    padding: 0.55rem 1.5rem;
    font-size: var(--kx-fs-base);
}
.kx-btn--geist:hover { background: var(--kx-green); color: var(--kx-auf-gruen); box-shadow: none; }

.kx-btn--klein { padding: 0.5rem 1.25rem; font-size: var(--kx-fs-base); }

.kx-btn--still {
    background: var(--kx-bg-soft);
    color: var(--kx-ink-soft);
    border: 1px solid var(--kx-line-strong);
    box-shadow: none;
}
.kx-btn--still:hover { background: var(--kx-bg-muted); color: var(--kx-ink-soft); box-shadow: none; }

/* ═══ 9. Navigationsleiste ═══════════════════════════════════════════ */

.lp-header { position: relative; z-index: 1060; }
/* ST3: im Shop bleibt die Leiste beim Scrollen oben stehen - Warenkorb, Konto und Menue sind dort immer
   erreichbar (der schwebende Warenkorb ist weg). Die Seiten der Website lassen sie wie bisher mitscrollen.
   `scroll-padding-top`: ein Sprung zu einer Marke (`#anfrage`, `#spKorbMeldung`) landet nicht unter der Leiste. */
.lp-header--klebt { position: sticky; top: 0; }
html:has(.lp-header--klebt) { scroll-padding-top: 4.5rem; }

.kx-navbar {
    position: sticky;
    top: 0;
    z-index: 1060;
    background: rgba(255, 255, 255, 0.86);
    backdrop-filter: blur(24px) saturate(1.6);
    -webkit-backdrop-filter: blur(24px) saturate(1.6);
    border-bottom: 1px solid var(--kx-card-border);
}
.kx-navbar__inner {
    display: flex;
    align-items: center;
    gap: var(--kx-3);
    width: 100%;
    max-width: 1560px;
    margin-inline: auto;
    padding: 6px var(--kx-4);
}
.kx-navbar__marke { flex-shrink: 1; max-width: 118px; display: flex; align-items: center; min-height: 44px; }
.kx-navbar__marke img { filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.05)); }

.kx-navbar__mitte { flex: 1; display: none; justify-content: center; }
@media (min-width: 77rem) { .kx-navbar__mitte { display: flex; } }

.kx-navbar__liste {
    display: flex;
    gap: var(--kx-1);
    list-style: none;
    margin: 0;
    padding: 0;
    flex-wrap: nowrap;
}
/* **`border: 0` und `background: none` sind hier Pflicht, nicht Kosmetik.**
   Die vier Menuepunkte sind `<button>`-Elemente (sie klappen ein Menue
   auf, sie fuehren nicht auf eine Adresse). Der Reset in Zeile 156 setzt
   nur `font` und `color` — ohne diese zwei Zeilen zeichnet der Browser
   seinen Standardrahmen samt grauer Flaeche, und um "Einsatzbereiche",
   "Produkte", "Unternehmen" und "Info" stehen Kaestchen.

   Marco am 31.08.2026 im Vergleich mit www.keckex.com: "warum sieht das
   original schoener aus". Das war der Unterschied. */
.kx-nav-link {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    min-height: 44px;
    padding: 0.5rem 0.9rem;
    border: 0;
    background: none;
    border-radius: var(--kx-radius-sm);
    color: var(--kx-ink-soft);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--kx-schnell), background var(--kx-schnell);
}
.kx-nav-link:hover,
.kx-dropdown[data-offen] > .kx-nav-link {
    color: var(--kx-marke-text);
    background: rgba(var(--kx-green-rgb), 0.10);
}
.kx-nav-link i { font-size: 0.7em; }

.kx-navbar__aktionen {
    display: flex;
    align-items: center;
    gap: var(--kx-2);
    margin-left: auto;
    flex-shrink: 0;
}
/* ST5 (19.10.2026), Marco: die Leiste war ueberladen und auf crm bei 1280 bis 1500 px 1.463 px breit (Sprachwahl
   abgeschnitten). Jetzt von links nach rechts: Logo | Menues und Shop | Haendler finden (schlichter Verweis) |
   Warenkorb, Konto (zwei Symbole) | Kontakt (der EINZIGE gefuellte Knopf) | Sprache. Die Netze stehen im Fuss.
   Was nicht passt, geht schrittweise weg - alle Stufen hier an EINER Stelle (Gegenstueck im Menue:
   `.kx-mobilnav__nurkompakt`):
     ab 80rem   „Haendler finden" mit Namen, darunter nur die Nadel (Name im aria-label, Tooltip im title),
     ab 77rem   die Leiste mit Menues, Haendler und Kontakt; darunter die Leiste der Telefone: Logo | Warenkorb,
                Konto, Sprache, Menue-Knopf - alles andere (Menues, Shop, Haendler, Kontakt) im Menue.
   Die Grenzen sind gemessen, mit Luft darin (`kundenseite_kopf.spec.ts`: jede Breite von 320 bis 1920 px, ohne
   Ueberlauf und ohne dass Menues und Aktionen sich beruehren). Ein Menuepunkt mehr oder ein laengerer Name
   braucht eine Stufe frueher: dann die Grenzen hier und im Test gemeinsam anheben. */
.kx-navbar__haendler-gross, .kx-navbar__kontakt { display: none; }
@media (min-width: 77rem) {
    .kx-navbar__haendler-gross {
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
        min-height: 44px;
        padding: 0.5rem 0.6rem;
        border-radius: var(--kx-radius-sm);
        color: var(--kx-ink-soft);
        font-weight: 500;
        text-decoration: none;
        white-space: nowrap;
        transition: color var(--kx-schnell), background var(--kx-schnell);
    }
    .kx-navbar__haendler-gross:hover { color: var(--kx-marke-text); background: rgba(var(--kx-green-rgb), 0.10); }
    .kx-navbar__kontakt { display: inline-flex; min-height: 44px; }
}
@media (max-width: 79.9375rem) {
    .kx-navbar__haendler-gross .kx-navbar__text { display: none; }
}

/* Die zwei Symbole rechts: Warenkorb und Konto - ohne Rahmen, 40 Pixel gross. */
.kx-navbar__symbol {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: var(--kx-radius-sm);
    background: transparent;
    color: var(--kx-ink-soft);
    font-size: 1.25rem;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: color var(--kx-schnell), background var(--kx-schnell);
}
.kx-navbar__symbol:hover { color: var(--kx-marke-text); background: rgba(var(--kx-green-rgb), 0.10); }
/* ST7a: das Herz der Merkliste (nur mit Inhalt) hat auf den schmalsten Telefonen keinen Platz - bei 320 px war die Leiste 332 px
   breit (`kundenseite_kopf.spec.ts`). Dort steht die Merkliste im Menue (`_public_navbar.html`). */
@media (max-width: 22.4375rem) { .kx-navbar__merk { display: none; } }
/* Angemeldet: ein kleiner Punkt am Personen-Symbol (Nicht-Text-Kontrast 3 : 1 gegen Weiss). */
.kx-navbar__punkt {
    position: absolute;
    top: 7px; right: 6px;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--kx-gruen-text);
    border: 2px solid #fff;
    box-sizing: border-box;
}
/* ST3: der Warenkorb im Kopf (Symbol mit Zahl) - im Shop immer, sonst nur mit Inhalt; die Zahl sitzt an der
   Ecke. Dunkel mit weisser Schrift: das fruehere Rot (#ef4444) erreichte 3,8 : 1 und damit keine 4,5 : 1. */
.kx-navbar__korb-zahl {
    position: absolute;
    top: 0; right: -2px;
    min-width: 18px;
    padding: 0 4px;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-dark);
    color: #fff;
    font-size: var(--kx-fs-xs);
    font-weight: 800;
    line-height: 18px;
    text-align: center;
}
.kx-nav-link--aktiv { color: var(--kx-marke-text); background: rgba(var(--kx-green-rgb), 0.10); }

/* **Auf 375 Pixeln passten Marke, Symbole, Sprache und Menue nicht nebeneinander** (Leiste 26 Pixel zu breit,
   die ganze Seite schob waagrecht). Hier wird nicht umgebrochen, sondern verkleinert: eine Leiste, die auf dem
   Telefon in zwei Zeilen faellt, frisst den halben ersten Bildschirm. */
@media (max-width: 76.9375rem) {
    .kx-navbar__aktionen { gap: var(--kx-1); }
    .kx-navbar__globus { display: none; }
    /* Das Konto-Menue haengt an der Leiste, nicht am Symbol: sonst ragt es links aus dem Fenster. */
    .kx-navbar .kx-navbar__konto { position: static; }
    .kx-navbar .kx-navbar__konto .kx-glass-menu { left: auto; right: var(--kx-3); }
}
@media (max-width: 30rem) {
    .kx-navbar__inner { gap: var(--kx-2); padding: 3px var(--kx-3); }
    .kx-navbar__marke { max-width: 90px; }
    .kx-navbar__symbol { width: 44px; height: 44px; }
}

/* ── Aufklappmenues ──
   Sie oeffnen auf Hover (Maus) und auf Klick (Tastatur, Touch);
   bausteine.js setzt dafuer data-offen. */
.kx-dropdown { position: relative; }
.kx-glass-menu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 1070;
    min-width: 13rem;
    margin: 0;
    padding: var(--kx-2);
    list-style: none;
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-md);
    box-shadow: var(--kx-schatten-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity var(--kx-schnell) var(--kx-kurve),
                transform var(--kx-schnell) var(--kx-kurve),
                visibility var(--kx-schnell);
}
.kx-glass-menu--rechts { left: auto; right: 0; }
/* **`[data-offen]` ohne Klasse davor, und das ist kein Schlendrian.**
   Das Teilen-Menue der Detailtafel haengt an `.lp-detail__share`, die
   Sprachauswahl an `.kx-lang-switch`, die Navigation an `.kx-dropdown` —
   drei Behaelter, eine Mechanik. `bausteine.js` setzt die Marke auf dem
   Elternelement des Knopfes, was auch immer das ist. Ein Selektor, der
   die Klasse verlangt, laesst zwei der drei Menues stumm zugehen: sie
   stehen offen im Markup und sind unsichtbar. Genau das war beim ersten
   Durchgang der Fall. */
.kx-dropdown:hover > .kx-glass-menu,
.kx-dropdown:focus-within > .kx-glass-menu,
[data-offen] > .kx-glass-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.kx-glass-menu a,
.kx-glass-menu span {
    display: block;
    padding: 0.55rem 1rem;
    border-radius: var(--kx-radius-sm);
    color: var(--kx-ink-soft);
    font-weight: 500;
    text-decoration: none;
    transition: background var(--kx-schnell), color var(--kx-schnell), padding-left var(--kx-schnell);
}
.kx-glass-menu a:hover {
    background: rgba(var(--kx-green-rgb), 0.10);
    color: var(--kx-marke-text);
    padding-left: 1.25rem;
}
.kx-glass-menu a[aria-current="true"] { color: var(--kx-marke-text); font-weight: 700; }
.kx-glass-menu__leer { color: var(--kx-ink-faint); font-style: italic; }
/* ST3: „Abmelden" im Konto-Menue ist ein Knopf in einem Formular (POST) und sieht aus wie die Verweise. */
.kx-glass-menu form { margin: 0; }
.kx-glass-menu__knopf {
    display: block;
    width: 100%;
    padding: 0.55rem 1rem;
    border: 0;
    border-radius: var(--kx-radius-sm);
    background: none;
    color: var(--kx-ink-soft);
    font: inherit;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    transition: background var(--kx-schnell), color var(--kx-schnell), padding-left var(--kx-schnell);
}
.kx-glass-menu__knopf:hover {
    background: rgba(var(--kx-green-rgb), 0.10);
    color: var(--kx-marke-text);
    padding-left: 1.25rem;
}

/* ── Soziale Netze. Die Originalfarben bleiben; sie sind die Marken
   der Netze und nicht unsere. ── */
.kx-social { display: flex; flex-wrap: wrap; gap: var(--kx-2); }
.kx-social-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--kx-bg-soft);
    font-size: var(--kx-fs-md);
    text-decoration: none;
    transition: transform var(--kx-schnell) var(--kx-kurve), background var(--kx-schnell);
}
.kx-social-icon:hover { transform: scale(1.12); background: var(--kx-bg-muted); }
.kx-social-facebook  { color: #1877F2; }
.kx-social-instagram { color: #E4405F; }
.kx-social-linkedin  { color: #0A66C2; }
.kx-social-youtube   { color: #FF0000; }
.kx-social-whatsapp  { color: #25D366; }

/* ── Sprachauswahl ── */
.kx-lang-switch { position: relative; font-size: var(--kx-fs-base); font-weight: 600; }
.kx-lang-switch__knopf {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0.4rem 0.6rem;
    border: 0;
    border-radius: var(--kx-radius-sm);
    background: transparent;
    color: var(--kx-ink-soft);
    cursor: pointer;
    transition: color var(--kx-schnell);
}
.kx-lang-switch__knopf:hover { color: var(--kx-marke-text); }
@media (max-width: 30rem) { .kx-lang-switch__knopf { padding: 0.35rem; } }

/* ── Menue fuer kleine Bildschirme ── */
.kx-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;
    border: 0;
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
    font-size: 1.4rem;
    cursor: pointer;
}
@media (min-width: 77rem) { .kx-burger { display: none; } }

.kx-mobilnav {
    position: absolute;
    top: 100%; left: 0; right: 0;
    z-index: 1050;
    max-height: 80vh;
    overflow-y: auto;
    background: #fff;
    border-top: 1px solid var(--kx-line);
    border-radius: 0 0 var(--kx-radius-lg) var(--kx-radius-lg);
    box-shadow: var(--kx-schatten-lg);
    display: none;
}
.kx-mobilnav.kx-offen { display: block; }
.kx-mobilnav__inner { display: flex; flex-direction: column; gap: var(--kx-4); padding: var(--kx-5); }
.kx-mobilnav__rubrik {
    font-size: var(--kx-fs-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--kx-text-muted);
}
.kx-mobilnav__gruppe { display: flex; flex-direction: column; gap: var(--kx-2); padding-left: var(--kx-4); }
.kx-mobilnav__gruppe a { color: var(--kx-text); text-decoration: none; }
.kx-mobilnav__gruppe a:hover { color: var(--kx-marke-text); }
.kx-mobilnav form { margin: 0; }
.kx-mobilnav__knopf { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
/* ST5: ab 77rem stehen Menues, Shop, Haendler, Kontakt und Konto in der Leiste - im Menue ist dann nichts mehr. */
@media (min-width: 77rem) {
    .kx-mobilnav__nurkompakt { display: none; }
}

#mobileNavBackdrop {
    position: fixed;
    inset: 0;
    z-index: 1045;
    background: rgba(15, 23, 42, 0.32);
    backdrop-filter: blur(2px);
}

/* ═══ 10. Fussbereich ════════════════════════════════════════════════ */

.kx-footer {
    position: relative;
    overflow: hidden;
    padding: var(--kx-8) var(--kx-5) var(--kx-6);
    background-color: var(--kx-dark);
    color: rgba(255, 255, 255, 0.72);
}
.kx-footer::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url('/static/img/spotlight_texture.webp') repeat;
    opacity: 0.65;
    pointer-events: none;
    z-index: 0;
}
.kx-footer__inner { position: relative; z-index: 1; }
.kx-footer__spalten {
    display: grid;
    gap: var(--kx-7);
    grid-template-columns: 1fr;
}
@media (min-width: 48rem) { .kx-footer__spalten { grid-template-columns: 1fr 1fr; } }

.kx-footer__col h2,
.kx-footer__col h3,
.kx-footer__col h4 {
    font-size: var(--kx-fs-md);
    font-weight: 700;
    letter-spacing: 0.05em;
    color: #fff;
    margin-bottom: var(--kx-4);
}
.kx-footer__motto {
    font-size: var(--kx-fs-xl);
    font-weight: 300;
    line-height: 1.4;
    color: #fff;
    letter-spacing: 0.02em;
    margin-bottom: var(--kx-5);
}
.kx-footer__col p, .kx-footer__col li { font-size: var(--kx-fs-base); margin-bottom: var(--kx-2); }
/* Das Motto steht NACH der Fliesstext-Regel und mit ihrer Spezifitaet: vorher
   schlug `.kx-footer__col p` (0,1,1) die Regel `.kx-footer__motto` (0,1,0), und
   das Motto stand mit 15 px, Gewicht 300 und Zeilenhoehe 1,4 eng und duenn da
   (WEB1). Wie der Fliesstext des Fusses: gleiche Groesse und Zeilenhoehe, dazu
   Gewicht 500 (weiss auf Dunkel, Kontrast ueber 15:1). */
.kx-footer__col .kx-footer__motto {
    font-size: var(--kx-fs-base);
    font-weight: 500;
    line-height: 1.65;
    letter-spacing: 0.02em;
    margin-bottom: var(--kx-4);
}
.kx-footer__col ul { list-style: none; padding-left: 0; }
.kx-footer__col a {
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
    transition: color var(--kx-schnell);
}
.kx-footer__col a:hover { color: var(--kx-green); }
.kx-footer__col strong, .kx-footer__col b { color: #fff; }
.kx-footer__gruen { color: var(--kx-green); }
/* ST5: die Netze stehen im Fuss (vorher in der Leiste); weisse Kreise, die Marken behalten ihre Farbe
   (`.kx-footer__col a` wuerde sie sonst auf Hellgrau ziehen). */
.kx-footer__netze { margin-top: var(--kx-4); }
.kx-footer__col .kx-footer__netze a.kx-social-icon { background: #fff; }
.kx-footer__col a.kx-social-facebook  { color: #1877F2; }
.kx-footer__col a.kx-social-instagram { color: #E4405F; }
.kx-footer__col a.kx-social-linkedin  { color: #0A66C2; }
.kx-footer__col a.kx-social-youtube   { color: #FF0000; }
.kx-footer__col a.kx-social-whatsapp  { color: #25D366; }

.kx-footer-bottom {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--kx-4);
    margin-top: var(--kx-7);
    padding-top: var(--kx-5);
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.kx-footer-bottom p { margin: 0; font-size: var(--kx-fs-sm); color: rgba(255, 255, 255, 0.55); }
.kx-nach-oben {
    position: absolute;
    right: 0;
    display: none;
    align-items: center;
    justify-content: center;
    width: 36px; height: 36px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    color: rgba(255, 255, 255, 0.8);
    text-decoration: none;
    transition: background var(--kx-schnell), border-color var(--kx-schnell);
}
/* „Nach oben" lag unter dem Chat-Knopf (fest, rechts unten, 60 px, 30 px Abstand): auf Breiten, in denen der
   Inhalt bis an den Rand reicht, verdeckte der Knopf den Verweis - fuer die Maus wie fuer die Tastatur
   (gemessen mit `elementFromPoint` auf 1280 px, Ausbau HH). Er sitzt links neben dem Knopf. */
@media (min-width: 48rem) { .kx-nach-oben { display: flex; right: 7rem; } }
.kx-nach-oben:hover { background: var(--kx-green); border-color: var(--kx-green); color: var(--kx-auf-gruen); }

/* ═══ 11. Hero (Portfolio-Teaser) ════════════════════════════════════ */

.lp-hero,
.kx-hero-gradient {
    position: relative;
    overflow: hidden;
    background: var(--kx-hero-verlauf);
}
/* Live-Check 08.09.2026: der Editor bietet dem Hero-Block eine
   "Hintergrundfarbe" (`bg_color` - `.bg-white`/`.bg-light`/`.bg-dark`/
   `.bg-primary`) an, aber `.kx-hero-gradient` stand im Stylesheet nach
   diesen Klassen und hatte dieselbe Spezifitaet - der Verlauf hat
   jede Wahl ergebnislos ueberschrieben. Die Seite trug deshalb
   unbemerkt schon "Hellgrau" als gespeicherten Wert. Diese vier
   Regeln sind je zwei Klassen (`.kx-hero-gradient.bg-white` etc.) und
   damit spezifischer als beide Einzelregeln - erst damit setzt die
   Wahl im Editor tatsaechlich etwas durch. `.lp-hero` (Shop-Header)
   bekommt nie eine `bg-*`-Klasse und bleibt unberuehrt. */
.kx-hero-gradient.bg-white   { background: var(--kx-bg); }
.kx-hero-gradient.bg-light   { background: var(--kx-bg-soft); }
.kx-hero-gradient.bg-dark    { background: var(--kx-dark); }
.kx-hero-gradient.bg-primary { background: var(--kx-green); }
.lp-hero::before,
.kx-hero-gradient::before {
    content: '';
    position: absolute;
    top: -50%; right: -30%;
    width: 80%; height: 200%;
    background: radial-gradient(circle, rgba(var(--kx-green-rgb), 0.12) 0%, transparent 60%);
    pointer-events: none;
}
.lp-hero::after,
.kx-hero-gradient::after {
    content: '';
    position: absolute;
    bottom: -40%; left: -20%;
    width: 60%; height: 180%;
    background: radial-gradient(circle, rgba(var(--kx-green-rgb), 0.07) 0%, transparent 60%);
    pointer-events: none;
}
/* Live-Check 09.09.2026, fuenfter Fund: "jetzt hat doch der Hintergrund
   einen Farbverlauf" - Marco, nachdem er den Regler oben selbst auf
   "Weiss" gestellt hatte. Gemessen: die Basis war bereits flaches
   rgb(255,255,255), kein `background-image` mehr. Der sichtbare
   Verlauf waren die beiden Leuchtkreise oben (unabhaengig vom
   `bg_color`-Regler) - fuer den gruenen Standard-Hero gedacht, auf
   "Weiss" oder "Hellgrau" blieben sie einfach bestehen und erzeugten
   selbst einen weich einlaufenden Gruenton. Fuer diese beiden hellen
   Voreinstellungen deshalb abgeschaltet; "Dunkel" und "Primärfarbe"
   behalten sie, dort ist der Effekt gewollt und deutlich subtiler
   sichtbar. */
.kx-hero-gradient.bg-white::before, .kx-hero-gradient.bg-white::after,
.kx-hero-gradient.bg-light::before, .kx-hero-gradient.bg-light::after {
    background: none;
}

.lp-hero-title {
    font-size: var(--kx-fs-schau);
    font-weight: 900;
    letter-spacing: -0.03em;
    line-height: 1.08;
    color: var(--kx-dark);
    margin: 0;
    text-wrap: balance;
}
.lp-hero-title p, .lp-hero-subtitle p { margin: 0; padding: 0; line-height: inherit; }

.lp-hero-subtitle {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--kx-5);
    position: relative;
    z-index: 2;
    max-width: 620px;
    margin-inline: auto;
}
.lp-hero-subtitle > div:first-child {
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-md);
    font-weight: 600;
    line-height: 1.5;
}

/* Paket Ö1: zwei Knoepfe unter der Unterzeile — der editierbare und,
   nur wenn eine Telefonnummer eingetragen ist, „Anrufen". */
.lp-hero-ctas { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--kx-3); }

/* Das Skizzenbild: PNG/WEBP mit echtem Alpha-Kanal, der Leerraum
   durch einen festen Behaelter abgeschnitten.
   Live-Check 08.09.2026, zweiter Fund: `mix-blend-mode: multiply` war
   der erste, kleinere Teil des Fehlers (siehe Commit 426798f6) - der
   groessere Teil ist, dass in der Skizze selbst gut die Haelfte der
   Flaeche (die "Karosserien") gar nicht weiss gefuellt, sondern ECHT
   TRANSPARENT ist (per Stichprobe mit Pillow: ~57 % der Pixel mit
   Alpha 0). Auf dem gruenen `--kx-hero-verlauf` zeigte dieser
   transparente Bereich also den Verlauf selbst - keine Blend-Funktion
   kann das aendern, Alpha 0 ist Alpha 0.
   Live-Check 08.09.2026, dritter Fund: der Container bekam deshalb kurz
   eine eigene weisse Karte (Radius, Schatten) - noetig, solange der Hero
   selbst gruen war. Mit dem Fix am `bg_color`-Regler (Commit 22758253)
   ist der Hero jetzt selbst "Hellgrau", fast weiss. Die eigene Karte
   stand seitdem sichtbar ALS Karte auf einer schon fast weissen Flaeche
   ("das Bild setzt sich ab" - Marco) - Radius und Schatten sind deshalb
   wieder raus (Commit 3e582285).
   Live-Check 09.09.2026, vierter Fund: "sehe ich noch einen leichten
   Gruenstich?" - ja, gemessen. `.kx-hero-gradient::before`/`::after`
   malen JEDEM Hero-Block zwei dekorative gruene Leuchtkreise (12 % bzw.
   7 % Deckkraft), unabhaengig vom `bg_color`-Regler. Ihr Zentrum liegt
   rechts der Bildmitte - eine Simulation der exakten Verlaufswerte in
   einem Canvas zeigt dort bis zu 16,5 Punkte Gruenueberschuss (z. B.
   RGB(239,246,229) statt neutral). Genau in diesem transparenten Rand
   der Skizze (siehe oben, ~57 % Alpha 0) wird das sichtbar. Deshalb
   wieder eine FLAeCHE (kein Radius, kein Schatten - das war der Teil,
   der als Karte auffiel) hinter dem Bild: sie blockt die Leuchtkreise,
   ohne eine erkennbare Kante zu ziehen (der Farbunterschied zur
   Hero-Flaeche betraegt in normaler Ansicht nur wenige RGB-Punkte). */
.lp-teaser-container {
    position: relative;
    max-width: 1100px;
    height: 180px;
    margin: var(--kx-6) auto;
    overflow: hidden;
    background: var(--kx-bg);
}
.lp-teaser-img {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    min-width: 800px;
    height: auto;
    object-fit: contain;
}
@media (max-width: 48rem) {
    .lp-teaser-container { height: auto; margin: var(--kx-5) auto; text-align: center; }
    .lp-teaser-img {
        position: relative;
        left: auto; top: auto; transform: none;
        min-width: 0; width: 100%; max-width: 100%;
        margin-inline: auto;
    }
}

/* ═══ 12. Geraeteraster und Detailtafel ══════════════════════════════ */

.lp-section--devices { background: var(--kx-bg-soft); }

.lp-devices {
    display: grid;
    gap: var(--kx-5);
    grid-template-columns: 1fr;
    align-items: start;
}
@media (min-width: 62rem) {
    .lp-devices { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
}

.lp-grid {
    display: grid;
    gap: var(--kx-3);
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
/* Marco am 07.09.2026: vier Spalten auf dem Schreibtisch wirkten
   gedrängt, er wollte drei — grössere Kacheln statt mehr davon. Erst ab
   62rem, wo `.lp-devices` überhaupt in den Zwei-Spalten-Modus geht
   (Raster links, Detailtafel rechts, ~658px breit bei voller
   Containerbreite): 190px statt 150px Mindestbreite passen dort genau
   drei Kacheln hinein (4 × 190px + 3 × 12px Abstand wären 796px, mehr
   als die Spalte hat). Auf Tablet und Telefon bleibt `.lp-grid` in
   seiner vollen Breite — dort war die Dichte nicht das Thema. */
@media (min-width: 62rem) {
    .lp-grid { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
}
.lp-grid__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--kx-1);
    padding: var(--kx-4) var(--kx-3);
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius);
    box-shadow: var(--kx-schatten-sm);
    color: inherit;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: transform var(--kx-schnell) var(--kx-kurve),
                box-shadow var(--kx-normal) var(--kx-kurve),
                border-color var(--kx-normal);
}
.lp-grid__item:hover { transform: translateY(-4px); box-shadow: var(--kx-schatten); }
.lp-grid__item.active {
    border-color: var(--kx-green);
    box-shadow: 0 0 0 3px rgba(var(--kx-green-rgb), 0.18), var(--kx-schatten);
}
.lp-grid__thumb { width: 100%; aspect-ratio: 4 / 3; object-fit: contain; }
/* Ausbau Q: ein Bild, das `einblenden.js` erst in der Naehe laedt, steht bis
   dahin als durchsichtiges Pixel da. Ohne JavaScript kommt es nie - dort zeigt
   das <noscript>-Bild daneben, und das Pixel darf nicht noch einen Kasten
   davorsetzen. */
@media (scripting: none) {
    img[data-spaeter-src] { display: none; }
}
.lp-grid__icon { font-size: 2rem; color: var(--kx-ink-faint); }
.lp-grid__name { font-weight: 700; font-size: var(--kx-fs-base); color: var(--kx-dark); }
/* **Preis und Leasingrate im lesbaren Markenton (23.09.2026).** Im Browser
   gemessen: `--kx-green-dark` ergab beim Preis 2,60 auf Weiss (noetig 4,5)
   und bei der Rate 1,49 auf dem getoenten Grund. Der Grund der Rate ist
   jetzt `--kx-marke-hauch` - genau der Ton, gegen den
   `marke_service._schriftton()` den Schriftton ausrechnet; damit stimmt
   das Paar auch bei einer anderen Kundenfarbe. */
.lp-grid__price { font-weight: 800; font-size: var(--kx-fs-base); color: var(--kx-marke-text); }
.lp-grid__leasing {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.6rem;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-marke-hauch);
    color: var(--kx-marke-text);
    font-size: var(--kx-fs-xs);
    font-weight: 700;
    cursor: pointer;
}

.lp-detail {
    position: sticky;
    top: 6rem;
    padding: var(--kx-5);
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten);
}
@media (max-width: 62rem) { .lp-detail { position: static; } }

.lp-detail__empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--kx-2);
    padding: var(--kx-7) var(--kx-4);
    color: var(--kx-ink-faint);
    text-align: center;
}
.lp-detail__empty i { font-size: 2rem; }

.lp-detail__image {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: contain;
    border-radius: var(--kx-radius-lg);
    background: var(--kx-bg-soft);
    cursor: zoom-in;
}
.lp-detail__gallery { display: flex; flex-wrap: wrap; gap: var(--kx-2); }
.lp-detail__name { margin: var(--kx-3) 0 0; font-size: var(--kx-fs-xl); font-weight: 900; color: var(--kx-dark); }
.lp-detail__category {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-bg-muted);
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-xs);
    font-weight: 600;
}
.lp-detail__price-row { align-items: center; }
.lp-detail__desc { color: var(--kx-ink-soft); font-size: var(--kx-fs-base); }
.lp-detail__list { margin: 0 0 var(--kx-3); padding-left: 1.1rem; }
.lp-detail__list li { margin-bottom: 0.2rem; }
/* Grund: `--kx-bg-soft` (#f8fafc). Voller Ton 1,67 — Schriftton 4,72. */
.lp-detail__list li::marker { color: var(--kx-gruen-text); }
.lp-detail__list li.lp-bullet { list-style: none; }
.lp-detail__list li.lp-bullet::before { content: attr(data-bullet) ' '; color: var(--kx-gruen-text); }

/* Die vier Eckdaten (31.08.2026). Zwei Spalten: Bezeichnung links,
   Wert rechts - eine Tabelle waere fuer drei Zeilen zu viel Geruest,
   und `dl` sagt genau das, was hier steht. */
.lp-detail__specs {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.25rem var(--kx-3);
    margin: 0 0 var(--kx-3);
    font-size: var(--kx-fs-sm);
}
.lp-detail__specs dt { color: var(--kx-ink-faint); }
.lp-detail__specs dd { margin: 0; color: var(--kx-text); font-weight: 500; }
.lp-detail__cms {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    margin-bottom: var(--kx-3);
    color: var(--kx-marke-text);
    font-size: var(--kx-fs-sm);
    font-weight: 500;
    text-decoration: none;
}
.lp-detail__cms:hover { text-decoration: underline; }

.lp-detail__actions { display: flex; flex-direction: column; gap: var(--kx-3); margin-top: var(--kx-4); }
.lp-detail__cta-btn { width: 100%; }
.lp-detail__media-btns { display: grid; gap: var(--kx-2); grid-template-columns: 1fr 1fr; }
.lp-detail__link,
.lp-detail__media-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-1);
    padding: 0.55rem 0.9rem;
    border: 1px solid var(--kx-line-strong);
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
    color: var(--kx-ink-soft);
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--kx-schnell), color var(--kx-schnell), border-color var(--kx-schnell);
}
.lp-detail__link { grid-column: 1 / -1; }
.lp-detail__media-btns--eins > .lp-detail__media-btn { grid-column: 1 / -1; }
.lp-detail__link:hover, .lp-detail__media-btn:hover { background: var(--kx-bg-muted); }
.lp-detail__media-btn--yt:hover  { border-color: #ff0000; color: #ff0000; }
.lp-detail__media-btn--pdf:hover { border-color: #dc2626; color: #dc2626; }
.lp-detail__share-btn { width: 100%; }
.lp-detail__share { grid-column: 1 / -1; position: relative; }
.lp-detail__share .kx-glass-menu { width: 100%; }

/* ═══ 13. Spotlight ══════════════════════════════════════════════════ */

.lp-spotlight {
    position: relative;
    overflow: hidden;
    background-color: var(--kx-dark);
    color: #fff;
}
.lp-spotlight::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url('/static/img/spotlight_texture.webp') repeat;
    opacity: 0.65;
    pointer-events: none;
}
.lp-spotlight__inner {
    position: relative;
    z-index: 1;
    display: grid;
    gap: clamp(var(--kx-5), 5vw, var(--kx-7));
    align-items: center;
    width: 100%;
    max-width: var(--kx-wrap);
    margin-inline: auto;
    padding-inline: var(--kx-5);
    grid-template-columns: 1fr;
}
@media (min-width: 62rem) { .lp-spotlight__inner { grid-template-columns: 1fr 1fr; } }

.lp-spotlight__image-wrap { position: relative; }
.lp-spotlight__image {
    width: 100%;
    max-height: 480px;
    /* L2, 04.09.2026: ein festes Seitenverhaeltnis, damit die Flaeche
       schon vor dem Laden feststeht - vorher sprang der Hotspot-Rahmen
       (`.kx-hotspot-container`) mit, sobald das Bild ankam. */
    aspect-ratio: 4 / 3;
    object-fit: contain;
    cursor: zoom-in;
    filter: drop-shadow(0 24px 48px rgba(0, 0, 0, 0.45));
}
.lp-spotlight__badge {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    padding: 0.3rem 0.9rem;
    margin-bottom: var(--kx-3);
    border-radius: var(--kx-radius-pill);
    /* 0,18 ergab den Grund #4e5934, darauf kam der Lime auf 4,29 -
       0,21 unter der Grenze. Weniger Deckung macht den Grund dunkler
       und den Abstand groesser; die Farbe selbst bleibt. */
    background: rgba(var(--kx-green-rgb), 0.10);
    color: var(--kx-green);
    font-size: var(--kx-fs-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.lp-spotlight__name {
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    font-weight: 900;
    letter-spacing: -0.02em;
    color: #fff;
    margin-bottom: var(--kx-3);
}
.lp-spotlight__desc { color: rgba(255, 255, 255, 0.72); font-size: var(--kx-fs-md); }
.lp-spotlight__pricing {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--kx-4);
    margin-top: var(--kx-4);
}
.lp-spotlight__price { font-size: clamp(1.6rem, 3.5vw, 2.1rem); font-weight: 900; color: var(--kx-green); }
.lp-spotlight__price small { font-size: var(--kx-fs-sm); font-weight: 600; color: rgba(255, 255, 255, 0.5); }
.lp-spotlight__rate {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    padding: 0.3rem 0.9rem;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: var(--kx-radius-pill);
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--kx-fs-base);
    cursor: pointer;
    transition: border-color var(--kx-schnell), background var(--kx-schnell);
}
.lp-spotlight__rate:hover { border-color: var(--kx-green); background: rgba(var(--kx-green-rgb), 0.12); }
.lp-spotlight__actions { display: flex; flex-wrap: wrap; gap: var(--kx-3); margin-top: var(--kx-5); }
.lp-spotlight__icon-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    padding: 0.7rem 1.3rem;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: var(--kx-radius-pill);
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--kx-fs-base);
    font-weight: 600;
    text-decoration: none;
    transition: border-color var(--kx-schnell), color var(--kx-schnell);
}
.lp-spotlight__icon-btn--yt:hover  { border-color: #ff0000; color: #ff5252; }
.lp-spotlight__icon-btn--pdf:hover { border-color: #f87171; color: #f87171; }
.lp-spotlight__fussnote { margin-top: var(--kx-1); font-size: var(--kx-fs-xs); color: rgba(255, 255, 255, 0.35); }

/* ── Hotspots auf dem Spotlight-Bild ── */
.kx-hotspot-container { position: relative; display: inline-block; width: 100%; }
.kx-hotspot {
    position: absolute;
    width: 22px; height: 22px;
    margin: -11px 0 0 -11px;
    border-radius: 50%;
    background: var(--kx-green);
    box-shadow: 0 0 0 6px rgba(var(--kx-green-rgb), 0.25);
    cursor: pointer;
    transition: transform var(--kx-normal) var(--kx-kurve);
}
.kx-hotspot::before {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    border: 2px solid var(--kx-green);
    animation: kxPuls 2.2s infinite;
}
.kx-hotspot:hover { transform: scale(1.2); }
@keyframes kxPuls {
    0%   { opacity: 0.9; transform: scale(0.8); }
    70%  { opacity: 0;   transform: scale(1.6); }
    100% { opacity: 0;   transform: scale(1.6); }
}
.kx-mobile-hotspot-card {
    padding: var(--kx-4);
    margin-bottom: var(--kx-3);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--kx-green);
    border-radius: var(--kx-radius-md);
    box-shadow: 0 4px 15px rgba(var(--kx-green-rgb), 0.15);
}
.kx-mobile-hotspot-card h3 { color: var(--kx-green); font-size: var(--kx-fs-md); margin-bottom: var(--kx-2); }
.kx-mobile-hotspot-card p  { color: rgba(255, 255, 255, 0.78); font-size: var(--kx-fs-base); margin: 0; }

/* ═══ 14. Kontakt ════════════════════════════════════════════════════ */

.kx-kontaktkarte {
    height: 100%;
    padding: clamp(var(--kx-5), 4vw, var(--kx-7));
    border-radius: var(--kx-radius-xl);
    background: url('/static/img/spotlight_texture.webp') repeat, var(--kx-nacht);
    color: #fff;
    box-shadow: var(--kx-schatten-lg);
}
.kx-kontaktkarte h3 { color: var(--kx-green); font-size: var(--kx-fs-2xl); margin-bottom: var(--kx-5); }
.kx-kontaktkarte__vorwort { color: #cbd5e1; font-size: var(--kx-fs-md); margin-bottom: var(--kx-6); }
.kx-kontaktzeile { display: flex; align-items: center; gap: var(--kx-4); margin-bottom: var(--kx-5); }
.kx-kontaktzeile__symbol {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 56px; height: 56px;
    border-radius: 50%;
    background: #fff;
    color: var(--kx-gruen-text);
    font-size: 1.4rem;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.kx-kontaktzeile__titel { font-size: var(--kx-fs-md); font-weight: 700; color: #fff; margin-bottom: 0.15rem; }
.kx-kontaktzeile p { margin: 0; color: rgba(255, 255, 255, 0.6); font-size: var(--kx-fs-base); }
.kx-kontaktzeile a { color: rgba(255, 255, 255, 0.6); text-decoration: none; transition: color var(--kx-schnell); }
.kx-kontaktzeile a:hover { color: var(--kx-green); }

.kx-premium-form {
    width: 100%;
    padding: clamp(var(--kx-5), 4vw, var(--kx-7));
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-lg);
}
.kx-feld { margin-bottom: var(--kx-4); }
.kx-feld--paar { display: grid; gap: var(--kx-4); grid-template-columns: 1fr; }
@media (min-width: 36rem) { .kx-feld--paar { grid-template-columns: 1fr 1fr; } }

.form-label,
.kx-label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    color: var(--kx-ink-soft);
}
.form-control {
    display: block;
    width: 100%;
    padding: 0.75rem 1rem;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    background: var(--kx-bg-soft);
    color: var(--kx-text);
    font-family: inherit;
    font-size: var(--kx-fs-base);
    transition: border-color var(--kx-schnell), box-shadow var(--kx-schnell), background var(--kx-schnell);
}
.form-control:focus {
    outline: none;
    background: #fff;
    border-color: var(--kx-green);
    box-shadow: 0 0 0 4px rgba(var(--kx-green-rgb), 0.15);
}
.form-control::placeholder { color: var(--kx-ink-faint); }
select.form-control {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%236b7280' d='M8 11 3 6h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.9rem center;
    background-size: 14px;
    padding-right: 2.4rem;
}
textarea.form-control { min-height: 6rem; resize: vertical; }
.form-control.is-invalid {
    border-color: #ef4444;
    box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.12);
}
.is-invalid + label, label .is-invalid { color: #ef4444; }

/* Die vier Pillen "Ich stelle die Anfrage fuer" */
.lp-radio-group { display: flex; flex-wrap: wrap; gap: var(--kx-2); }
.lp-radio-pill { position: relative; }
.lp-radio-pill input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}
.lp-radio-pill label {
    display: inline-block;
    padding: 0.5rem 1.1rem;
    border: 1px solid var(--kx-line-strong);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-bg-soft);
    font-size: var(--kx-fs-base);
    font-weight: 600;
    color: var(--kx-ink-soft);
    cursor: pointer;
    transition: all var(--kx-schnell);
}
.lp-radio-pill input:checked + label {
    background: var(--kx-green);
    border-color: var(--kx-green);
    color: var(--kx-auf-gruen);
}
.lp-radio-pill input:focus-visible + label {
    outline: 3px solid var(--kx-marke-text);
    outline-offset: 2px;
}
.lp-radio-pill input.is-invalid + label { border-color: #ef4444; }

.lp-dsgvo {
    display: flex;
    align-items: flex-start;
    gap: var(--kx-3);
    padding: var(--kx-4);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    background: var(--kx-bg-soft);
    font-size: var(--kx-fs-sm);
    color: var(--kx-ink-soft);
}
.lp-dsgvo input { margin-top: 0.25rem; width: 1.05rem; height: 1.05rem; accent-color: var(--kx-green); flex-shrink: 0; }
.lp-dsgvo input.is-invalid { outline: 2px solid #ef4444; outline-offset: 2px; }

.lp-success { text-align: center; padding: var(--kx-6) var(--kx-4); }
/* Grund: `.kx-premium-form` = `--kx-card-bg` (weiss). 1,74 → 4,93. */
.lp-success__icon { font-size: 3rem; color: var(--kx-gruen-text); margin-bottom: var(--kx-3); }

.kx-formfuss { text-align: center; margin-top: var(--kx-5); }
.kx-formfuss p { margin-top: var(--kx-4); font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }

.alert { padding: 0.6rem 0.9rem; border-radius: var(--kx-radius-sm); font-size: var(--kx-fs-sm); margin-bottom: var(--kx-4); }
.alert-danger { background: #fee2e2; border: 1px solid #fca5a5; color: #b91c1c; }
/* HS-H6: der Hinweis „Gesucht in Deutschland" - Hauch der Markenfarbe, Text in Fliesstextfarbe (Kontrast). */
.alert-info { background: var(--kx-marke-hauch); border: 1px solid var(--kx-green); color: var(--kx-text); }
.invalid-feedback { display: block; color: #ef4444; font-size: var(--kx-fs-xs); margin-top: 0.2rem; }
/* L4, 04.09.2026: die Fehlerzeile steht jetzt fest im Markup (fuer
   `aria-describedby`) statt erst per JavaScript eingefuegt zu werden —
   leer soll sie aber keinen Platz beanspruchen. */
.invalid-feedback:empty { display: none; margin: 0; }

.lp-success__naechster-schritt { margin-top: var(--kx-3); font-size: var(--kx-fs-sm); }

/* Der Ladekreis, den landing.js in den Sendeknopf schreibt. */
.spinner-border {
    display: inline-block;
    width: 1rem; height: 1rem;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: kxDreh 0.75s linear infinite;
    vertical-align: -0.125em;
}
.spinner-border-sm { width: 0.85rem; height: 0.85rem; }
@keyframes kxDreh { to { transform: rotate(360deg); } }

/* ═══ 15. Kundenstimmen ══════════════════════════════════════════════ */

.kx-stimme {
    position: relative;
    height: 100%;
    display: flex;
    flex-direction: column;
    padding: var(--kx-5);
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-sm);
    transition: transform var(--kx-normal) var(--kx-kurve), box-shadow var(--kx-normal);
}
.kx-stimme:hover { transform: translateY(-5px); box-shadow: var(--kx-schatten); }
/* Grund: `.kx-stimme` = `--kx-card-bg` (weiss). **Das Zeichen steht auf
   `opacity: 0.2` und ist damit Zierrat** — einen Kontrastwert erfuellt es
   so oder so nicht, und WCAG verlangt fuer Zierrat auch keinen. Der
   Schriftton steht hier trotzdem: er ist der richtige Ton fuer diesen
   Grund, und wer die Deckkraft je hochsetzt, hat dann nicht auch noch
   die Farbe zu reparieren. */
.kx-stimme__zitat {
    position: absolute;
    top: 10px; right: 20px;
    font-size: var(--kx-fs-3xl);
    color: var(--kx-gruen-text);
    opacity: 0.2;
}
.kx-stimme__sterne { display: flex; gap: 0.1rem; color: #f59e0b; margin-bottom: var(--kx-3); }
.kx-stimme__text {
    position: relative;
    z-index: 1;
    flex: 1;
    font-size: var(--kx-fs-md);
    font-style: italic;
    color: var(--kx-ink-soft);
    margin-bottom: var(--kx-5);
}
.kx-stimme__person { display: flex; align-items: center; gap: var(--kx-3); padding-top: var(--kx-4); border-top: 1px solid var(--kx-line); }
.kx-stimme__bild {
    width: 50px; height: 50px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--kx-line);
}
.kx-stimme__initial {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px; height: 50px;
    border-radius: 50%;
    background: var(--kx-dark);
    color: #fff;
    font-weight: 700;
    font-size: var(--kx-fs-lg);
}
.kx-stimme__name { font-weight: 700; color: var(--kx-text); }
.kx-stimme__rolle { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }

/* ═══ 16. Der Spielbanner ════════════════════════════════════════════ */

.kx-spielbanner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--kx-5);
    padding: var(--kx-6) clamp(var(--kx-5), 4vw, var(--kx-7));
    border-radius: var(--kx-radius-xl);
    background: url('/static/img/spotlight_texture.webp') repeat, var(--kx-nacht);
    color: #fff;
    box-shadow: var(--kx-schatten-lg);
}
.kx-spielbanner__text { display: flex; align-items: center; gap: var(--kx-5); }
.kx-spielbanner__symbol {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 60px; height: 60px;
    border-radius: 50%;
    background: rgba(var(--kx-green-rgb), 0.2);
    color: var(--kx-green);
    font-size: var(--kx-fs-2xl);
}
.kx-spielbanner h3 { margin: 0 0 0.2rem; font-size: var(--kx-fs-xl); font-weight: 800; color: #fff; }
.kx-spielbanner p  { margin: 0; color: #cbd5e1; font-size: var(--kx-fs-md); }

/* ═══ 17. Modal (die Huelle des Spiels) ══════════════════════════════

   bausteine.js oeffnet und schliesst sie und feuert dabei dieselben
   Ereignisse, die Bootstrap gefeuert hat (show.bs.modal,
   hidden.bs.modal) - landing_game.js haengt an beiden.               */

.kx-modal {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: none;
    overflow-y: auto;
    padding: var(--kx-4);
    background: rgba(15, 23, 42, 0.55);
    backdrop-filter: blur(6px);
}
.kx-modal.kx-offen { display: block; }
.kx-modal__dialog {
    max-width: 800px;
    margin: 3vh auto;
    background: var(--kx-bg-soft);
    border-radius: var(--kx-radius-xl);
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.35);
    animation: kxModalAuf var(--kx-normal) var(--kx-kurve);
}
@keyframes kxModalAuf {
    from { opacity: 0; transform: translateY(18px) scale(0.98); }
    to   { opacity: 1; transform: none; }
}
.kx-modal__kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--kx-4);
    padding: var(--kx-5) var(--kx-5) var(--kx-2);
}
.kx-modal__titel { margin: 0; font-size: var(--kx-fs-xl); font-weight: 700; color: var(--kx-dark); }
.kx-modal__zu {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px; height: 36px;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.05);
    color: var(--kx-ink-soft);
    font-size: 1.1rem;
    cursor: pointer;
}
.kx-modal__zu:hover { background: rgba(0, 0, 0, 0.1); }
.kx-modal__koerper { padding: var(--kx-2) var(--kx-4) var(--kx-5); }
@media (min-width: 36rem) { .kx-modal__koerper { padding-inline: var(--kx-5); } }
body.kx-modal-offen { overflow: hidden; }

/* Die Eintragszeile der Bestenliste: auf dem Telefon untereinander,
   ab 36rem nebeneinander. Sie ersetzt die Bootstrap-Kette
   `d-flex flex-column flex-sm-row gap-2 w-100 px-3 px-sm-0`. */
.kg-eintrag { display: flex; flex-direction: column; gap: var(--kx-2); width: 100%; }
@media (min-width: 36rem) { .kg-eintrag { flex-direction: row; } }
.kg-eintrag input {
    flex: 1;
    min-width: 0;
    padding: 0.45rem 1rem;
    border: 1px solid var(--kx-line-strong);
    border-radius: var(--kx-radius-pill);
    font-weight: 600;
    text-align: center;
    outline: none;
}
.kg-eintrag input:focus { border-color: var(--kx-green); }
.kg-eintrag button { flex-shrink: 0; white-space: nowrap; }

/* ═══ 18. Finanzierungsrechner ═══════════════════════════════════════ */

.lp-leasing-modal {
    position: fixed;
    inset: 0;
    z-index: 1090;
    display: none;
    align-items: center;
    justify-content: center;
    padding: var(--kx-4);
    background: rgba(15, 23, 42, 0.6);
    backdrop-filter: blur(6px);
}
.lp-leasing-modal.active { display: flex; }
.lp-leasing-card {
    position: relative;
    width: 100%;
    max-width: 440px;
    max-height: 92vh;
    overflow-y: auto;
    padding: var(--kx-6);
    background: #fff;
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-lg);
    animation: kxModalAuf var(--kx-normal) var(--kx-kurve);
}
.lp-leasing-card__close {
    position: absolute;
    top: var(--kx-3); right: var(--kx-3);
    width: 34px; height: 34px;
    border: 0;
    border-radius: 50%;
    background: var(--kx-bg-muted);
    color: var(--kx-ink-soft);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}
.lp-leasing-card__title { font-size: var(--kx-fs-xl); font-weight: 800; color: var(--kx-dark); }
.lp-leasing-card__sub { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); margin-bottom: var(--kx-5); }

.lp-leasing-slider { margin-bottom: var(--kx-5); }
.lp-leasing-slider label { display: block; font-size: var(--kx-fs-base); color: var(--kx-ink-soft); margin-bottom: var(--kx-2); }
.lp-leasing-slider input[type="range"] {
    width: 100%;
    height: 6px;
    appearance: none;
    border-radius: var(--kx-radius-pill);
    background: linear-gradient(90deg, var(--kx-green), var(--kx-line));
    outline: none;
}
.lp-leasing-slider input[type="range"]::-webkit-slider-thumb {
    appearance: none;
    width: 22px; height: 22px;
    border: 3px solid #fff;
    border-radius: 50%;
    background: var(--kx-green);
    box-shadow: var(--kx-schatten);
    cursor: grab;
}
.lp-leasing-slider input[type="range"]::-moz-range-thumb {
    width: 22px; height: 22px;
    border: 3px solid #fff;
    border-radius: 50%;
    background: var(--kx-green);
    cursor: grab;
}
.lp-slider-labels {
    display: flex;
    justify-content: space-between;
    margin-top: var(--kx-1);
    font-size: var(--kx-fs-xs);
    color: var(--kx-text-muted);
}

.lp-leasing-table { width: 100%; border-collapse: collapse; margin-bottom: var(--kx-5); }
.lp-leasing-table td { padding: 0.55rem 0; border-bottom: 1px solid var(--kx-line); font-size: var(--kx-fs-base); }
.lp-leasing-table td:first-child { color: var(--kx-text-muted); }
.lp-leasing-table td:last-child { text-align: right; font-weight: 600; color: var(--kx-text); }
.lp-leasing-total td {
    border-bottom: 0;
    padding-top: var(--kx-3);
    font-size: var(--kx-fs-lg);
    font-weight: 900;
}
.lp-leasing-total td:last-child { color: var(--kx-marke-text); }

/* ═══ 19. Bildergalerie (Lightbox) ═══════════════════════════════════ */

.lp-lightbox {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: rgba(0, 0, 0, 0.92);
    backdrop-filter: blur(8px);
    cursor: zoom-out;
}
.lp-lightbox__buehne {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%; height: 100%;
    padding: var(--kx-6);
}
.lp-lightbox img {
    max-width: 90%;
    max-height: 85vh;
    object-fit: contain;
    box-shadow: 0 0 80px rgba(0, 0, 0, 0.6);
    transition: opacity var(--kx-normal);
}
.lp-lightbox__knopf {
    position: absolute;
    z-index: 10001;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px; height: 48px;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.15);
    color: #fff;
    font-size: var(--kx-fs-xl);
    cursor: pointer;
    transition: background var(--kx-schnell);
}
.lp-lightbox__knopf:hover { background: rgba(255, 255, 255, 0.3); }
.lp-lightbox__knopf--zu { top: var(--kx-5); right: var(--kx-5); background: none; opacity: 0.75; }
.lp-lightbox__knopf--zu:hover { background: none; opacity: 1; }
.lp-lightbox__knopf--zurueck { left: var(--kx-4); top: 50%; transform: translateY(-50%); }
.lp-lightbox__knopf--vor { right: var(--kx-4); top: 50%; transform: translateY(-50%); }
.lp-lightbox__zaehler {
    position: absolute;
    right: var(--kx-5); bottom: var(--kx-5);
    color: rgba(255, 255, 255, 0.5);
    font-size: var(--kx-fs-sm);
}

/* ═══ 20. Einwilligung ═══════════════════════════════════════════════ */

.cc-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: none;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(4px);
}
.cc-banner {
    position: fixed;
    left: 50%;
    bottom: var(--kx-5);
    z-index: 2001;
    width: min(560px, calc(100% - 2rem));
    transform: translate(-50%, 140%);
    transition: transform var(--kx-normal) var(--kx-kurve);
    display: none;
}
.cc-overlay.cc-visible, .cc-banner.cc-visible { display: block; }
.cc-banner.cc-visible { transform: translate(-50%, 0); }
/* Solange das Band offen ist, tritt der Chat-Knopf zur Seite. Er steht
   mit `z-index: 999999 !important` ueber allem (`_chatbot.html`) und lag
   bei 375 px auf „Nein, danke" (gemessen am 10.09.2026) — Ablehnen muss
   so leicht sein wie Zustimmen (L5). Die Klasse setzt `cookie_consent.js`. */
body.kx-einwilligung-offen .kx-chatbot-container { display: none !important; }
.cc-card {
    padding: var(--kx-5);
    background: #fff;
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-lg);
}
.cc-header { display: flex; align-items: center; gap: var(--kx-3); margin-bottom: var(--kx-3); }
.cc-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px; height: 42px;
    border-radius: 50%;
    background: rgba(var(--kx-green-rgb), 0.14);
    color: var(--kx-marke-text);
    font-size: var(--kx-fs-lg);
}
.cc-title { margin: 0; font-size: var(--kx-fs-md); font-weight: 800; color: var(--kx-dark); }
.cc-text { font-size: var(--kx-fs-sm); color: var(--kx-ink-soft); margin-bottom: var(--kx-4); }
/* **Der lesbare Markenton, nicht der abgedunkelte (22.09.2026).**
   `--kx-green-dark` ergibt auf Weiss 2,84 statt der noetigen 4,5 -
   Lighthouse hat "Mehr erfahren" hier und "Alle Details zu diesem Geraet"
   in der Geraetetafel gemeldet. `--kx-marke-text` rechnet
   `marke_service._schriftton()` aus der Farbe des Kunden, bis 4,5
   erreicht sind (fuer #97D700: #577C00, 4,90). */
.cc-text a { color: var(--kx-marke-text); font-weight: 600; }
.cc-actions { display: flex; flex-wrap: wrap; gap: var(--kx-2); }
.cc-btn {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-1);
    padding: 0.65rem 1.2rem;
    border: 1px solid transparent;
    border-radius: var(--kx-radius-pill);
    font-size: var(--kx-fs-base);
    font-weight: 700;
    cursor: pointer;
}
.cc-btn--accept { background: var(--kx-green); color: var(--kx-auf-gruen); box-shadow: var(--kx-schatten-gruen); }
.cc-btn--accept:hover { background: var(--kx-green-dark); }
/* L5, 04.09.2026: „Ablehnen" war umrandet und durchsichtig, „Akzeptieren"
   gefuellt und mit Schatten - zwei Gewichte fuer eine Entscheidung, die
   gleich leicht sein muss. Beide jetzt gefuellt, gleiche Groesse, gleiche
   Schriftstaerke; nur die Farbe unterscheidet, nicht das Gewicht. */
.cc-btn--decline { background: var(--kx-dark); color: #fff; }
.cc-btn--decline:hover { background: color-mix(in srgb, var(--kx-dark) 80%, #000); }
.cc-btn:focus-visible { outline: 3px solid var(--kx-marke-text); outline-offset: 2px; }

/* ── Sprachhinweis (L6, 04.09.2026) ──
   Steht in `base_public.html` direkt nach `<body>`, auf JEDER oeffentlichen
   Seite ohne Uebersetzung fuer den Sprachpraefix im Pfad. */
.kx-sprachhinweis {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    padding: var(--kx-2) var(--kx-4);
    background: var(--kx-bg-soft);
    color: var(--kx-ink-soft);
    font-size: var(--kx-fs-sm);
    text-align: center;
}
.kx-sprachhinweis a { color: var(--kx-marke-text); font-weight: 600; }

/* ═══ 21. Die zehn Bloecke der CMS-Seiten ════════════════════════════

   `intro`, `text_image`, `advantages`, `features`, `video`, `banner`,
   `faq`, `products`, `alert_banner`, `downloads`. Die sechs
   `landing_*`-Bloecke stehen weiter oben bei ihren Abschnitten.        */

/* ── Gemeinsames ── */
.kx-schmal { max-width: var(--kx-wrap-schmal); margin-inline: auto; }
.kx-zweispalt--bild-links > :first-child { order: 2; }
.kx-zweispalt--bild-links > :last-child { order: 1; }
@media (max-width: 62rem) {
    .kx-zweispalt--bild-links > :first-child,
    .kx-zweispalt--bild-links > :last-child { order: 0; }
}

.kx-titel--leicht {
    font-size: clamp(1.6rem, 3.2vw, 2.3rem);
    font-weight: 300;
    line-height: 1.2;
    color: var(--kx-dark);
    margin-bottom: var(--kx-5);
    text-wrap: balance;
}
.kx-titel--halbfett {
    font-size: var(--kx-fs-titel);
    font-weight: 800;
    line-height: 1.2;
    color: var(--kx-dark);
    margin-bottom: var(--kx-4);
}
.kx-untertitel {
    font-size: var(--kx-fs-lg);
    font-weight: 400;
    color: var(--kx-ink-soft);
    margin-bottom: var(--kx-5);
}
/* Der Redakteur tippt Zeilenumbrueche — sie sollen stehen bleiben. */
.kx-vorzeile {
    font-size: var(--kx-fs-base);
    line-height: 1.7;
    color: var(--kx-text-muted);
    white-space: pre-line;
    margin-bottom: var(--kx-5);
}
.kx-vorzeile :last-child { margin-bottom: 0; }

.kx-blockbild {
    width: 100%;
    max-height: 450px;
    object-fit: contain;
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-sm);
}
.kx-blockbild--fuellend { object-fit: cover; max-height: 500px; }

.kx-platzhalter {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 350px;
    border-radius: var(--kx-radius-lg);
    background: var(--kx-bg-muted);
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-sm);
}
.kx-platzhalter--dunkel { background: var(--kx-dark); color: #fff; min-height: 400px; }

/* ── Vorteile ── */
.kx-vorteil {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    padding: var(--kx-5);
    text-align: center;
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-sm);
}
.kx-vorteil__symbol {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 70px; height: 70px;
    margin-bottom: var(--kx-5);
    border-radius: 50%;
    background: rgba(var(--kx-green-rgb), 0.12);
    color: var(--kx-marke-text);
    font-size: 1.8rem;
}
.kx-vorteil__titel { font-size: var(--kx-fs-lg); font-weight: 700; color: var(--kx-dark); }
.kx-vorteil__text {
    font-size: var(--kx-fs-sm);
    line-height: 1.6;
    color: var(--kx-text-muted);
    white-space: pre-line;
    margin: 0;
}

/* ── Galerie ── */
.kx-galerie {
    display: grid;
    gap: var(--kx-3);
    grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 48rem) { .kx-galerie { grid-template-columns: repeat(4, 1fr); } }
.kx-galerie__feld { margin: 0; }
.kx-galerie__feld img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    border-radius: var(--kx-radius-md);
    margin-bottom: var(--kx-2);
}
.kx-galerie__feld figcaption { font-size: var(--kx-fs-xs); color: var(--kx-text-muted); }

/* ── Video ── */
.kx-video {
    position: relative;
    max-width: 980px;
    margin-inline: auto;
    aspect-ratio: 16 / 9;
    border-radius: var(--kx-radius-lg);
    overflow: hidden;
    box-shadow: var(--kx-schatten);
    background: #000;
}
.kx-video iframe, .kx-video video {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    border: 0;
}
.kx-video--datei { aspect-ratio: auto; }
.kx-video--datei video { position: static; max-height: 75vh; object-fit: contain; }

.kx-video-teaser { position: relative; display: inline-block; max-width: 100%; }
.kx-video-teaser img {
    max-height: 75vh;
    border-radius: var(--kx-radius-lg);
    box-shadow: var(--kx-schatten);
}
.kx-video-teaser__knopf {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 70px; height: 70px;
    padding-left: 6px;
    border: 3px solid #fff;
    border-radius: 50%;
    background: rgba(var(--kx-green-rgb), 0.9);
    backdrop-filter: blur(4px);
    box-shadow: var(--kx-schatten);
}

/* ── Video mit Einwilligung (L1, 04.09.2026) ──
   `.kx-video--consent` traegt Vorschaubild, Knopf und Hinweistext
   uebereinander in derselben 16:9-Flaeche; `video_consent.js` ersetzt
   den ganzen Inhalt durch das `<iframe>`, sobald geklickt wird oder eine
   Einwilligung schon vorliegt. */
.kx-video__vorschau {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
}
.kx-video__vorschau--leer { background: var(--kx-dark); }
.kx-video__knopf {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 70px; height: 70px;
    padding-left: 6px;
    border: 3px solid #fff;
    border-radius: 50%;
    background: rgba(var(--kx-green-rgb), 0.9);
    backdrop-filter: blur(4px);
    box-shadow: var(--kx-schatten);
    cursor: pointer;
}
.kx-video__hinweis {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    margin: 0;
    padding: var(--kx-2) var(--kx-3);
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.75), transparent);
    color: #fff;
    font-size: var(--kx-fs-xs);
    text-align: center;
}
.kx-video__hinweis a { color: #fff; text-decoration: underline; }

/* ── Banner ── */
.kx-banner {
    display: grid;
    grid-template-columns: 1fr;
    border-radius: var(--kx-radius-xl);
    overflow: hidden;
    box-shadow: var(--kx-schatten);
}
@media (min-width: 48rem) { .kx-banner { grid-template-columns: 5fr 7fr; } }
.kx-banner__feld {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    padding: clamp(var(--kx-5), 4vw, var(--kx-7));
}
.kx-banner__titel { font-size: 1.8rem; font-weight: 300; color: #fff; margin-bottom: var(--kx-5); }
.kx-banner__titel p { margin: 0; }
.kx-banner__knopf {
    display: inline-block;
    padding: 0.6rem 1.5rem;
    border-radius: var(--kx-radius-pill);
    background: #fff;
    font-weight: 500;
    font-size: var(--kx-fs-base);
    text-decoration: none;
}
.kx-banner__bild { position: relative; min-height: 350px; }
.kx-banner__bild > img,
.kx-banner__bild > .kx-platzhalter { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.kx-wechsler { position: absolute; inset: 0; }
.kx-wechsler__bild {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.8s ease;
}
.kx-wechsler__bild.kx-sichtbar { opacity: 1; }
/* Pause-Taste (WCAG 2.2.2): schwarz auf 70 % und weisse Schrift ist auf jedem Bild lesbar. */
.kx-wechsler__pause {
    position: absolute;
    right: var(--kx-3);
    bottom: var(--kx-3);
    z-index: 2;
    padding: 0.4rem 0.9rem;
    border: 0;
    border-radius: var(--kx-radius-pill);
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    font-size: var(--kx-fs-sm);
    cursor: pointer;
}
.kx-wechsler__pause:hover { background: rgba(0, 0, 0, 0.85); }
.kx-wechsler__pause:focus-visible { outline: 3px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 5px #000; }

/* ── FAQ ── */
.kx-akkordeon { max-width: 900px; margin-inline: auto; display: flex; flex-direction: column; gap: var(--kx-3); }
.kx-falte {
    border-radius: var(--kx-radius-md);
    overflow: hidden;
    box-shadow: var(--kx-schatten-sm);
}
.kx-falte__kopf { margin: 0; }
.kx-falte__knopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--kx-3);
    width: 100%;
    padding: 0.9rem 1.5rem;
    border: 0;
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-md);
    font-weight: 700;
    text-align: left;
    cursor: pointer;
}
.kx-falte__knopf i { transition: transform var(--kx-normal) var(--kx-kurve); }
.kx-falte__knopf[aria-expanded="true"] i { transform: rotate(180deg); }
.kx-falte__koerper {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--kx-normal) var(--kx-kurve);
    background: var(--kx-bg-soft);
}
.kx-falte__koerper.kx-offen { grid-template-rows: 1fr; }
.kx-falte__inhalt {
    overflow: hidden;
    font-size: var(--kx-fs-base);
    line-height: 1.7;
    color: var(--kx-text-muted);
    white-space: pre-line;
    padding-inline: 1.5rem;
}
.kx-falte__koerper.kx-offen .kx-falte__inhalt {
    padding-block: var(--kx-5);
    border-top: 1px solid var(--kx-line);
}

/* ── Geräte-Galerie ── */
.kx-kachel {
    display: flex;
    flex-direction: column;
    color: inherit;
    text-decoration: none;
    transition: transform var(--kx-normal) var(--kx-kurve);
    /* Befund 06.09.2026: `.kx-raster` teilt die Breite mit `auto-fit` und
       `1fr` unter den Kacheln auf - bei DREI Geraeten in einer Kategorie
       eine vernuenftige Spaltenbreite, bei nur EINEM Geraet aber die volle
       Containerbreite fuer eine einzige Kachel (`aspect-ratio: 1` am Bild
       macht daraus ein riesiges Quadrat). `max-width` deckelt die Kachel,
       `margin-inline: auto` haelt sie mittig, wenn ihre Spalte breiter ist
       als sie selbst. */
    max-width: 400px;
    margin-inline: auto;
    width: 100%;
}
a.kx-kachel:hover { transform: translateY(-5px); }
.kx-kachel__bild {
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    overflow: hidden;
    margin-bottom: var(--kx-4);
    background: var(--kx-bg-soft);
    border-bottom: 2px solid var(--kx-green);
}
.kx-kachel__bild img { width: 100%; height: 100%; object-fit: cover; }
.kx-kachel__leer {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%; height: 100%;
    font-size: 4rem;
    color: var(--kx-line-strong);
}
.kx-kachel__marke {
    position: absolute;
    right: var(--kx-4); bottom: var(--kx-4);
    z-index: 10;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 1rem;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-sm);
    font-weight: 500;
    animation: kxPochen 2s infinite ease-in-out;
}
a.kx-kachel:hover .kx-kachel__marke {
    background: var(--kx-green-dark);
    animation: none;
    transform: scale(1.05);
}
@keyframes kxPochen {
    0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(var(--kx-green-rgb), 0.4); }
    50%  { transform: scale(1.03); box-shadow: 0 0 0 10px rgba(var(--kx-green-rgb), 0); }
    100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(var(--kx-green-rgb), 0); }
}
.kx-kachel__titel {
    font-size: var(--kx-fs-lg);
    font-weight: 400;
    color: var(--kx-marke-text);
    margin-bottom: var(--kx-2);
}
.kx-kachel__text {
    font-size: var(--kx-fs-base);
    line-height: 1.4;
    color: var(--kx-text-muted);
    margin-bottom: var(--kx-5);
}
.kx-kachel__text :last-child { margin-bottom: 0; }

.kx-eckdaten { margin: 0; font-size: var(--kx-fs-base); }
.kx-eckdaten > div {
    display: flex;
    gap: var(--kx-2);
    padding-bottom: var(--kx-2);
    margin-bottom: var(--kx-2);
    border-bottom: 1px solid var(--kx-line);
}
.kx-eckdaten dt { min-width: 90px; font-weight: 700; color: var(--kx-dark); }
.kx-eckdaten dd { margin: 0; color: var(--kx-text-muted); }

/* ── Downloads ── */
.kx-downloads { display: flex; flex-direction: column; gap: var(--kx-3); margin-top: var(--kx-5); }
.kx-download {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--kx-4);
    padding: var(--kx-4);
    background: #fff;
    border: 2px solid var(--kx-line);
    border-radius: var(--kx-radius-lg);
    color: inherit;
    text-decoration: none;
    overflow: hidden;
    transition: transform var(--kx-normal) var(--kx-kurve),
                border-color var(--kx-normal),
                box-shadow var(--kx-normal);
}
.kx-download:hover {
    transform: translateY(-3px);
    border-color: rgba(var(--kx-green-rgb), 0.4);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.07), 0 0 30px rgba(var(--kx-green-rgb), 0.12);
}
.kx-download__symbol { font-size: 1.6rem; color: #dc2626; }
.kx-download__text { flex: 1; display: flex; flex-direction: column; }
.kx-download__titel { font-weight: 700; color: var(--kx-dark); }
.kx-download__text small { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }

/* ── Ankündigungs-Banner ── */
.ab {
    position: relative;
    overflow: hidden;
    /* Die vier Schemata der Registry, als Namen aus der Datenbank. */
    --ab-bg: var(--kx-green);
    --ab-text: var(--kx-dark);
    --ab-sub: #1a3a0a;
    --ab-btn-bg: var(--kx-dark);
    --ab-btn-text: #fff;
    --ab-badge: rgba(0, 0, 0, 0.08);
    --ab-bg-dunkel: rgba(105, 160, 50, 0.93);
}
.ab--kx-dark {
    --ab-bg: var(--kx-dark); --ab-text: #fff; --ab-sub: rgba(255, 255, 255, 0.8);
    --ab-btn-bg: var(--kx-green); --ab-btn-text: #fff; --ab-badge: rgba(255, 255, 255, 0.12);
    --ab-bg-dunkel: rgba(15, 23, 42, 0.93);
}
.ab--kx-blue {
    --ab-bg: #2563eb; --ab-text: #fff; --ab-sub: rgba(255, 255, 255, 0.85);
    --ab-btn-bg: #fff; --ab-btn-text: #2563eb; --ab-badge: rgba(255, 255, 255, 0.18);
    --ab-bg-dunkel: rgba(30, 64, 175, 0.93);
}
.ab--kx-orange {
    --ab-bg: #ea580c; --ab-text: #fff; --ab-sub: rgba(255, 255, 255, 0.85);
    --ab-btn-bg: #fff; --ab-btn-text: #ea580c; --ab-badge: rgba(255, 255, 255, 0.18);
    --ab-bg-dunkel: rgba(194, 65, 12, 0.93);
}
.ab__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    background-size: cover;
    background-position: center;
    transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.ab__ov { position: absolute; inset: 0; z-index: 1; background: var(--ab-bg); }
.ab--mit-bild .ab__ov { background: var(--ab-bg-dunkel); }

.ab__row {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1.8rem;
}
.ab:has(.ab__detail) .ab__row { cursor: pointer; }
.ab__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px; height: 38px;
    border-radius: 10px;
    background: var(--ab-badge);
    color: var(--ab-text);
    font-size: var(--kx-fs-lg);
}
.ab__body { flex: 1; min-width: 0; }
.ab__title {
    margin: 0;
    font-size: var(--kx-fs-base);
    font-weight: 700;
    line-height: 1.35;
    color: var(--ab-text);
}
.ab__title p { display: inline; margin: 0; }
.ab__sub { margin-top: 0.1rem; font-size: var(--kx-fs-sm); color: var(--ab-sub); }
.ab__sub p { margin: 0; }
.ab__chev {
    display: inline-flex;
    vertical-align: middle;
    margin-left: 0.3rem;
    font-size: 0.6rem;
    opacity: 0.5;
    transition: transform 0.3s ease;
}

.ab__detail {
    position: relative;
    z-index: 2;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    padding: 0 1.8rem;
    font-size: var(--kx-fs-sm);
    line-height: 1.55;
    color: var(--ab-sub);
    transition: max-height 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94),
                opacity 0.3s ease 0.05s,
                padding 0.3s ease;
}
.ab__detail p { margin: 0; }
.ab.ab--open .ab__detail { max-height: 250px; opacity: 1; padding: 0 1.8rem 0.85rem; }
.ab.ab--open .ab__chev { transform: rotate(180deg); opacity: 0.9; }
.ab.ab--open .ab__bg { transform: scale(1.05); }

/* Auf dem Bildschirm oeffnet auch das Ueberfahren; auf dem Telefon
   gibt es kein Hover, dort tippt man. */
@media (hover: hover) and (pointer: fine) {
    .ab:hover .ab__detail { max-height: 250px; opacity: 1; padding: 0 1.8rem 0.85rem; }
    .ab:hover .ab__chev { transform: rotate(180deg); opacity: 0.9; }
    .ab:hover .ab__bg { transform: scale(1.05); }
}

.ab__btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.45rem 1.2rem;
    border: 0;
    border-radius: var(--kx-radius-pill);
    background: var(--ab-btn-bg);
    color: var(--ab-btn-text);
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.ab__btn:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); }

@media (max-width: 48rem) {
    .ab__row { padding: 0.7rem 1rem; gap: 0.65rem; }
    .ab__icon { width: 32px; height: 32px; border-radius: var(--kx-radius-sm); font-size: var(--kx-fs-md); }
    .ab__title { font-size: var(--kx-fs-sm); }
    .ab__btn { padding: 0.35rem 0.9rem; font-size: var(--kx-fs-xs); }
    .ab__detail, .ab.ab--open .ab__detail { padding-inline: 1rem; }
}

/* ── Brotkrumen der CMS-Seiten ── */
.kx-brotkrumen { padding: var(--kx-4) var(--kx-5) 0; }
.kx-brotkrumen ol {
    display: flex;
    flex-wrap: wrap;
    gap: var(--kx-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--kx-fs-sm);
    color: var(--kx-text-muted);
}
.kx-brotkrumen li + li::before { content: '›'; margin-right: var(--kx-2); color: var(--kx-ink-faint); }
.kx-brotkrumen a { color: var(--kx-text-muted); text-decoration: none; }
.kx-brotkrumen a:hover { color: var(--kx-marke-text); }

/* ═══ 22. Der Shop ═══════════════════════════════════════════════════

   Katalog, Produkt, Warenkorb, Kasse, Bestaetigung. Die Klassen heissen
   weiter `sp-*` (shop public) — dieselbe Entscheidung wie bei `lp-*`:
   die Namen stehen in den Vorlagen und in einem Skript, neu ist, was
   dahinter steht. `shop.css` (672 Zeilen) geht dafuer.               */

/* ST6b: das Kopfbild des Shops ist eine schmale Zeile (Titel links, Zahl der Artikel rechts) - vorher 180 px hoch
   mit Symbol, Marke und Satz, bevor der erste Artikel kam. Hoechstens 72 px am PC, 56 px am Telefon. */
.sp-kopf { background: var(--kx-bg-soft); border-bottom: 1px solid var(--kx-line); }
.sp-kopf__inner {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--kx-3);
    max-width: var(--kx-wrap);
    margin-inline: auto;
    padding: 12px var(--kx-5);
}
.sp-kopf__titel {
    min-width: 0;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--kx-fs-xl);
    font-weight: 900;
    letter-spacing: -0.02em;
    color: var(--kx-dark);
}
.sp-kopf__zahl { flex-shrink: 0; margin: 0; font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
@media (max-width: 47.9375rem) {
    .sp-kopf__inner { padding: 8px var(--kx-4); }
    .sp-kopf__titel { font-size: var(--kx-fs-lg); }
}
/* Brotkrume der Artikelseite (Shop > Kategorie > Artikel); der Name des Artikels kuerzt sich mit Auslassung. */
.sp-krume { margin: 0 0 var(--kx-4); }
.sp-krume ol {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--kx-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--kx-fs-sm);
    color: var(--kx-text-muted);
}
.sp-krume li { flex-shrink: 0; }
.sp-krume li + li::before { content: '›'; margin-right: var(--kx-2); color: var(--kx-ink-faint); }
.sp-krume li:last-child { flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-krume a { display: inline-flex; align-items: center; min-height: 44px; color: var(--kx-text-muted); text-decoration: none; }
.sp-krume a:hover { color: var(--kx-marke-text); }

/* ── Artikelsuche (SH1) ──────────────────────────────────────────────
   Ein GET-Formular ueber den Kategorien. Feld und Knopf stehen in einer Zeile (auch auf 375 px),
   die Beschriftung ist nur fuer Vorleser da. */
.sp-suche { max-width: 40rem; margin: var(--kx-3) auto var(--kx-2); padding-inline: var(--kx-5); }
.sp-suche__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.sp-suche__zeile { display: flex; gap: var(--kx-2); }
.sp-suche__feld {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 2.75rem;
    padding: 0.6rem 1.1rem;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-bg-soft);
    color: var(--kx-text);
    font-size: var(--kx-fs-base);
    font-family: inherit;
}
.sp-suche__feld:focus {
    outline: none;
    background: #fff;
    border-color: var(--kx-green);
    box-shadow: 0 0 0 4px rgba(var(--kx-green-rgb), 0.15);
}
.sp-suche__feld:focus-visible { outline: 3px solid var(--kx-marke-text); outline-offset: 2px; }
.sp-suche__knopf {
    flex: 0 0 auto;
    min-height: 2.75rem;
    padding: 0.5rem 1.2rem;
    border: 1px solid var(--kx-green);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-base);
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}
.sp-suche__stand { max-width: var(--kx-wrap); margin: 0 auto var(--kx-4); padding-inline: var(--kx-5); text-align: center; color: var(--kx-text-muted); font-size: var(--kx-fs-base); }
.sp-suche__stand a { color: var(--kx-marke-text); }
.sp-suche__schnell { max-width: 40rem; margin: 0 auto var(--kx-2); padding-inline: var(--kx-5); font-size: var(--kx-fs-sm); }
.sp-suche__schnell a { display: inline-flex; align-items: center; gap: var(--kx-1); min-height: 2.75rem; color: var(--kx-marke-text); font-weight: 600; text-decoration: none; }
.sp-suche__schnell a:hover { text-decoration: underline; }

/* ── Kategoriefilter (Paket Ö2, ST2b: zwei Stufen) ───────────────────
   Oben die Hauptkategorien, darunter - erst nach der Wahl - ihre Unterkategorien. Beide Zeilen BRECHEN UM
   (am Telefon vorher eine scrollende Reihe von 27 Pillen, 4.742 px breit hinter 390 px Sicht; das zweite
   Suchfeld darueber ist weg: die Artikelsuche findet auch ueber Kategorienamen). */
.sp-kategorien-leiste { max-width: var(--kx-wrap); margin: 0 auto var(--kx-4); }
.sp-categories {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--kx-2);
    padding-inline: var(--kx-5);
}
.sp-categories--unter { margin-top: var(--kx-3); }
.sp-cat-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    padding: 0.45rem 1.1rem;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-card-bg);
    color: var(--kx-ink-soft);
    font-size: var(--kx-fs-base);
    font-weight: 600;
    text-decoration: none;
    transition: all var(--kx-schnell);
}
.sp-cat-pill--klein { padding: 0.3rem 0.85rem; font-size: var(--kx-fs-sm); }
/* ST8a: Ziel mindestens 44 px hoch (gemessen 41 am Schreibtisch). */
.sp-cat-pill { min-height: 44px; }
.sp-cat-pill:hover { border-color: var(--kx-green); color: var(--kx-marke-text); }
.sp-cat-pill.active { background: var(--kx-green); border-color: var(--kx-green); color: var(--kx-auf-gruen); }

/* ── Produktraster ──────────────────────────────────────────────────
   Gemessen 03.09.2026: 48 Karten einspaltig auf 390 px ergaben 22.629 px
   Seitenhoehe. Ab 360 px zwei Spalten mit kleineren Karten (Bild, Name,
   Preis, Knopf — Kategorie-Marke und Beschreibung bleiben dem
   Schreibtisch vorbehalten, wo Platz fuer sie ist); ab 48rem wieder das
   bekannte Raster mit drei bis vier Spalten. */
.sp-products { max-width: var(--kx-wrap); margin-inline: auto; padding: 0 var(--kx-5) var(--kx-abschnitt); }
.sp-grid {
    display: grid;
    gap: var(--kx-3);
    grid-template-columns: 1fr;
}
@media (min-width: 22.5rem) { .sp-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 48rem) {
    .sp-grid { grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); gap: var(--kx-5); }
}
.sp-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    overflow: hidden;
    box-shadow: var(--kx-schatten-sm);
    transition: transform var(--kx-normal) var(--kx-kurve), box-shadow var(--kx-normal);
}
.sp-card:hover { transform: translateY(-4px); box-shadow: var(--kx-schatten); }
.sp-card__link { display: flex; flex-direction: column; flex: 1; color: inherit; text-decoration: none; }
.sp-card__img,
.sp-card__placeholder {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: contain;
    background: var(--kx-bg-soft);
}
.sp-card__placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    color: var(--kx-line-strong);
}
.sp-card__body { display: flex; flex-direction: column; gap: var(--kx-1); flex: 1; padding: var(--kx-4) var(--kx-4) var(--kx-2); }
.sp-card__cat {
    align-self: flex-start;
    padding: 0.1rem 0.55rem;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-bg-muted);
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-xs);
    font-weight: 600;
}
.sp-card__name { margin: 0; font-size: var(--kx-fs-md); font-weight: 700; color: var(--kx-dark); }
.sp-card__nr {
    margin: 0;
    overflow: hidden;
    font-size: var(--kx-fs-xs);
    color: var(--kx-text-muted);
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sp-card__nr mark { background: transparent; color: inherit; font-weight: 700; }
.sp-card__desc { flex: 1; margin: 0; font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
/* Derselbe Befund im Shop: 2,86 gemessen, noetig sind 3,0 fuer grosse
   fette Schrift (19,2 px / 900). */
.sp-card__price { font-size: var(--kx-fs-lg); font-weight: 900; color: var(--kx-marke-text); }
.sp-card__price small { font-weight: 400; opacity: 0.7; }
/* HS-P1: die kleine Zeile unter dem Haendlerpreis ("Listenpreis ..., -23 %", "nicht rabattierbar").
   Nur fuer angemeldete Haendler sichtbar, deshalb nicht im CSS-Ausschnitt. */
.sp-preis-liste { display: block; font-size: var(--kx-fs-xs); font-weight: 400; color: var(--kx-text-muted); }
.sp-preis-liste--gross { font-size: var(--kx-fs-sm); margin: 0 0 var(--kx-3); }
.sp-preis-liste a { color: var(--kx-marke-text); }
/* ST6b: Preis und Knopf stehen im Fuss der Karte (am Telefon nebeneinander, siehe unten). */
.sp-card__fuss { display: flex; flex-direction: column; gap: var(--kx-2); padding: 0 var(--kx-4) var(--kx-4); }
.sp-card__action { margin: 0; }
.sp-card__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    width: 100%;
    padding: 0.6rem 1rem;
    border: 0;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-base);
    font-weight: 700;
    cursor: pointer;
    transition: background var(--kx-schnell);
}
.sp-card__btn:hover { background: var(--kx-green-dark); }
/* ST2b: nach „In den Warenkorb" in der Liste - die Meldung ueber dem Raster und der Haken am Knopf. */
.sp-korb-meldung {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--kx-2);
    margin: 0 0 var(--kx-4);
    padding: var(--kx-3) var(--kx-4);
    border: 1px solid var(--kx-green);
    border-radius: var(--kx-radius-md);
    background: var(--kx-bg-soft);
    color: var(--kx-dark);
    font-size: var(--kx-fs-base);
    font-weight: 600;
}
.sp-korb-meldung[hidden] { display: none; }
/* ST8a: der Sprung auf #spKorbMeldung landet unter der klebenden Kopfleiste, wenn der Rand fehlt. */
.sp-korb-meldung { scroll-margin-top: 6rem; }
.sp-korb-meldung i { color: var(--kx-marke-text); }
.sp-korb-meldung a { display: inline-flex; align-items: center; min-height: 44px; margin-left: auto; color: var(--kx-marke-text); }
/* ST8a: der Text nimmt die Breite neben dem Haken; der Verweis rutscht bei Bedarf in die naechste Zeile (am Telefon stand der Haken allein). */
.sp-korb-meldung > span:not(.visually-hidden) { flex: 1 1 12rem; min-width: 0; }
.sp-card__btn--ok { background: var(--kx-green-dark); }
/* Schmale Bildschirme: zwei Spalten, kompakte Karte. LB29: dieser Block stand VOR den
   Grundregeln der Karte und verlor jede Auseinandersetzung (gleiche Spezifität, spätere
   Regel gewinnt) — Titel, Preis und Knopf der Karte hatten auf dem Telefon die Masse
   des Rechners. Er steht jetzt dahinter. Dazu: „Arbeitshandschuhe" wurde abgeschnitten
   (overflow-wrap), und „In den Warenkorb" brach im 130-px-Knopf auf zwei Zeilen um. */
@media (max-width: 47.9375rem) {
    .sp-card { border-radius: var(--kx-radius-md); }
    .sp-card__body { padding: var(--kx-2) var(--kx-3) 0; gap: 0.2rem; }
    .sp-card__cat, .sp-card__desc { display: none; }
    /* ST6b: der Name hoechstens zwei Zeilen; ST8a: drei - bei 0,25 m / 0,52 m Schlauch IG 1/2" 90° steht das, was die Artikel trennt, am Ende. Die Karten einer Reihe bleiben gleich hoch (Raster). */
    .sp-card__name {
        display: -webkit-box;
        min-height: 2.6em;
        overflow: hidden;
        overflow-wrap: anywhere;
        font-size: var(--kx-fs-sm);
        line-height: 1.3;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 3;
        line-clamp: 3;
    }
    /* Preis links, kleiner Warenkorb-Knopf rechts (nur das Symbol; der Name steht im aria-label und unsichtbar im Knopf). */
    .sp-card__fuss {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: var(--kx-2);
        padding: var(--kx-1) var(--kx-2) var(--kx-2) var(--kx-3);
    }
    .sp-card__price { min-width: 0; font-size: var(--kx-fs-base); line-height: 1.3; }
    .sp-card__action { flex: 0 0 auto; }
    .sp-card__btn { position: relative; width: 44px; height: 44px; padding: 0; font-size: 1.15rem; }
    .sp-card__btn-text {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
    /* Die Kategorien: eine waagrecht wischbare Leiste statt umbrechender Pillen (Tab-Taste scrollt von selbst mit). */
    .sp-kategorien-leiste { margin-bottom: var(--kx-3); }
    .sp-categories {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        padding-inline: var(--kx-4);
        scrollbar-width: none;
    }
    .sp-categories::-webkit-scrollbar { display: none; }
    .sp-categories--unter { margin-top: var(--kx-2); }
    .sp-cat-pill { flex: 0 0 auto; min-height: 44px; white-space: nowrap; }
}

/* ── Blätterleiste ──
   Der Katalog hat seit dem Umzug des alten Shops 3.563 Artikel; die
   Seite zeigt 48 davon. Die Leiste trägt dieselben Marken wie die
   Kategorie-Pillen darueber — es ist dieselbe Art Weg durch denselben
   Katalog. */
.sp-blaettern {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--kx-3);
    margin-top: var(--kx-7);
}
.sp-blatt {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    padding: 0.45rem 1.1rem;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-card-bg);
    color: var(--kx-ink-soft);
    font-size: var(--kx-fs-base);
    font-weight: 600;
    text-decoration: none;
    transition: all var(--kx-schnell);
}
.sp-blatt:hover { border-color: var(--kx-green); color: var(--kx-marke-text); }
.sp-blatt { min-height: 44px; }
.sp-blatt--aus { opacity: 0.4; pointer-events: none; }
/* ST8a: Seitenzahlen (erste, letzte, zwei Nachbarn); am Telefon eine eigene Zeile unter Zurück/Weiter. */
.sp-blatt__zahlen { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--kx-2); margin: 0; padding: 0; list-style: none; }
.sp-blatt--zahl { justify-content: center; min-width: 44px; padding-inline: 0.5rem; }
.sp-blatt--jetzt { border-color: var(--kx-green); background: var(--kx-green); color: var(--kx-auf-gruen); }
.sp-blatt__luecke { padding: 0 var(--kx-1); color: var(--kx-text-muted); }
@media (max-width: 47.9375rem) {
    .sp-blaettern { justify-content: space-between; }
    .sp-blaettern > :first-child { order: 1; }
    .sp-blaettern > :last-child { order: 2; }
    .sp-blatt__zahlen { order: 3; flex-basis: 100%; }
}
.sp-blatt__stand { margin: var(--kx-3) 0 0; text-align: center; }
.sp-blatt__stand { color: var(--kx-text-muted); font-size: var(--kx-fs-base); }

.sp-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--kx-3);
    padding: var(--kx-8) var(--kx-4);
    color: var(--kx-text-muted);
    text-align: center;
}
.sp-empty i { font-size: 2.5rem; opacity: 0.4; }
.sp-empty-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-2);
    padding: 0.6rem 1.5rem;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font-weight: 700;
    text-decoration: none;
}

/* ── Produktseite ── */
.sp-detail-page { padding: var(--kx-3) var(--kx-5) var(--kx-abschnitt); }
.sp-detail-inner { max-width: var(--kx-wrap); margin-inline: auto; }
.sp-back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    margin-bottom: var(--kx-5);
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    text-decoration: none;
    transition: color var(--kx-schnell), transform var(--kx-schnell);
}
.sp-back-link:hover { color: var(--kx-marke-text); transform: translateX(-3px); }

.sp-detail-layout {
    display: grid;
    gap: clamp(var(--kx-5), 4vw, var(--kx-7));
    grid-template-columns: 1fr;
    align-items: start;
}
@media (min-width: 62rem) { .sp-detail-layout { grid-template-columns: 5fr 6fr; } }

.sp-detail-img,
.sp-detail-img-placeholder {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    background: var(--kx-bg-soft);
    border-radius: var(--kx-radius-xl);
}
.sp-detail-img-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 4rem;
    color: var(--kx-line-strong);
}
/* ST5: am Telefon ein flaches Bild (16 : 9, `contain` laesst das Foto unverzerrt), damit „In den Warenkorb" im ersten
   Bildschirm steht (vorher y 914 von 844; das Quadrat allein war 327 Pixel hoch). */
@media (max-width: 47.9375rem) {
    .sp-detail-img, .sp-detail-img-placeholder { aspect-ratio: 16 / 9; }
}
.sp-detail-cat {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    margin-bottom: var(--kx-2);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-bg-muted);
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-xs);
    font-weight: 600;
}
.sp-detail-name {
    font-size: clamp(1.6rem, 3.5vw, 2.2rem);
    font-weight: 900;
    letter-spacing: -0.02em;
    color: var(--kx-dark);
    margin-bottom: var(--kx-2);
}
.sp-detail-sku { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-detail-price {
    font-size: clamp(1.6rem, 3vw, 2rem);
    font-weight: 900;
    color: var(--kx-marke-text);
    margin-bottom: var(--kx-3);
}
.sp-detail-price small { font-weight: 400; opacity: 0.7; }
.sp-detail-stock {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    padding: 0.2rem 0.75rem;
    border-radius: var(--kx-radius-pill);
    font-size: var(--kx-fs-sm);
    font-weight: 600;
}
.sp-detail-stock--ok { background: var(--kx-marke-hauch); color: var(--kx-marke-text); }
.sp-detail-stock--out { background: #fee2e2; color: #b91c1c; }
.sp-detail-desc { margin: var(--kx-5) 0; color: var(--kx-ink-soft); line-height: 1.7; }

/* ── Zubehör ── */
.sp-accessories { margin: var(--kx-6) 0; }
.sp-accessories__title {
    display: flex;
    align-items: center;
    gap: var(--kx-2);
    font-size: var(--kx-fs-md);
    font-weight: 700;
    color: var(--kx-dark);
    margin-bottom: var(--kx-3);
}
.sp-accessories__list { display: flex; flex-direction: column; gap: var(--kx-2); }
.sp-acc-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--kx-3);
    padding: var(--kx-3);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    background: var(--kx-card-bg);
    cursor: pointer;
    transition: border-color var(--kx-schnell), background var(--kx-schnell);
}
.sp-acc-card:hover { border-color: var(--kx-line-strong); }
.sp-acc-cb { position: absolute; opacity: 0; pointer-events: none; }
.sp-acc-card__check {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 24px; height: 24px;
    border: 2px solid var(--kx-line-strong);
    border-radius: var(--kx-radius-xs);
    color: transparent;
    transition: all var(--kx-schnell);
}
.sp-acc-cb:checked ~ .sp-acc-card__check {
    background: var(--kx-green);
    border-color: var(--kx-green);
    color: var(--kx-auf-gruen);
}
.sp-acc-cb:checked ~ .sp-acc-card__info .sp-acc-card__name { color: var(--kx-marke-text); }
.sp-acc-cb:focus-visible ~ .sp-acc-card__check {
    outline: 3px solid var(--kx-marke-text);
    outline-offset: 2px;
}
.sp-acc-card__img {
    flex-shrink: 0;
    width: 48px; height: 48px;
    object-fit: contain;
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
}
.sp-acc-card__img--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--kx-line-strong);
}
.sp-acc-card__info { display: flex; flex-direction: column; flex: 1; }
.sp-acc-card__name { font-weight: 600; color: var(--kx-text); }
.sp-acc-card__nr { font-size: var(--kx-fs-xs); color: var(--kx-text-muted); }
.sp-acc-card__price { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }

.sp-detail-cart-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--kx-3); }
/* LB29: ohne Beschreibung folgt das Formular dem Lagerhinweis unmittelbar — „Menge:" klebte am Hinweis. */
.sp-detail-stock + .sp-detail-cart-form { margin-top: var(--kx-5); }
.sp-detail-qty { display: flex; flex-direction: column; gap: 0.2rem; }
.sp-detail-qty label { font-size: var(--kx-fs-sm); font-weight: 600; color: var(--kx-ink-soft); }
.sp-qty-input {
    width: 5rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
    font: inherit;
    text-align: center;
}
.sp-qty-input:focus { outline: none; border-color: var(--kx-green); background: #fff; }
.sp-detail-atc-btn {
    flex: 1;
    min-width: 14rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    padding: 0.85rem 2rem;
    border: 0;
    border-radius: var(--kx-radius-pill);
    background: linear-gradient(135deg, var(--kx-green), var(--kx-green-dark));
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-md);
    font-weight: 700;
    cursor: pointer;
    box-shadow: var(--kx-schatten-gruen);
    transition: transform var(--kx-schnell) var(--kx-kurve);
}
.sp-detail-atc-btn:hover { transform: translateY(-2px); }

/* ── Warenkorb ── */
.sp-cart-page { padding: var(--kx-6) var(--kx-5) var(--kx-abschnitt); }
.sp-cart-inner { max-width: var(--kx-wrap); margin-inline: auto; }
.sp-cart-title {
    display: flex;
    align-items: center;
    gap: var(--kx-2);
    font-size: var(--kx-fs-titel);
    font-weight: 900;
    color: var(--kx-dark);
    margin-bottom: var(--kx-5);
}
.sp-cart-layout { display: grid; gap: var(--kx-5); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 62rem) { .sp-cart-layout { grid-template-columns: 7fr 5fr; } }

.sp-cart-items {
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten-sm);
    overflow: hidden;
}
.sp-cart-item {
    display: grid;
    grid-template-columns: 64px 1fr auto auto auto;
    align-items: center;
    gap: var(--kx-3);
    padding: var(--kx-4);
    border-bottom: 1px solid var(--kx-line);
}
.sp-cart-item__img {
    width: 64px; height: 64px;
    object-fit: contain;
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
}
.sp-cart-item__img--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--kx-line-strong);
}
.sp-cart-item__info h2 { margin: 0; font-size: var(--kx-fs-md); font-weight: 700; color: var(--kx-dark); }
.sp-cart-item__price { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-cart-item__qty-form { margin: 0; }
.sp-cart-item__subtotal { font-weight: 800; color: var(--kx-dark); white-space: nowrap; }
.sp-cart-item__remove {
    min-width: 44px;
    min-height: 44px;
    border: 0;
    background: transparent;
    color: var(--kx-ink-faint);
    font-size: var(--kx-fs-lg);
    cursor: pointer;
    transition: color var(--kx-schnell);
}
.sp-cart-item__remove:hover { color: #ef4444; }
@media (max-width: 48rem) {
    .sp-cart-item { grid-template-columns: 48px 1fr auto; row-gap: var(--kx-2); }
    .sp-cart-item__img { width: 48px; height: 48px; }
    .sp-cart-item__subtotal { grid-column: 2; }
    .sp-cart-item__remove { grid-column: 3; }
}

.sp-cart-acc {
    display: flex;
    align-items: center;
    gap: var(--kx-2);
    padding: 0.35rem var(--kx-4) 0.35rem calc(var(--kx-4) + 64px + var(--kx-3));
    border-bottom: 1px solid var(--kx-line);
    font-size: var(--kx-fs-sm);
    color: var(--kx-text-muted);
    background: var(--kx-bg-soft);
}
.sp-cart-acc__name { flex: 1; }

.sp-cart-total {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--kx-4);
    font-size: var(--kx-fs-lg);
}
.sp-cart-total strong { font-size: var(--kx-fs-xl); font-weight: 900; color: var(--kx-marke-text); }
.sp-cart-items > .sp-preis-liste { margin: 0; padding: 0 var(--kx-4) var(--kx-4); }
/* ST2b: die Zusammenfassung ueber der Liste - nur wo das Formular UNTER der Liste steht (unter 62rem). Sie
   sagt, was im Korb liegt, und fuehrt mit EINEM Tipp zum Formular (`#anfrage`), statt dass der Besucher
   an einer langen Liste vorbeiwischt. Am Schreibtisch steht das Formular neben der Liste. */
.sp-cart-kopf { display: none; }
@media (max-width: 61.9375rem) {
    .sp-cart-kopf {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: var(--kx-3);
        margin-bottom: var(--kx-4);
        padding: var(--kx-3) var(--kx-4);
        background: var(--kx-card-bg);
        border: 1px solid var(--kx-card-border);
        border-radius: var(--kx-radius-xl);
        box-shadow: var(--kx-schatten-sm);
    }
    .sp-cart-kopf__text { display: flex; flex-direction: column; margin: 0; line-height: 1.3; font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
    .sp-cart-kopf__text strong { font-size: var(--kx-fs-md); font-weight: 800; color: var(--kx-dark); }
    .sp-cart-kopf__knopf {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--kx-2);
        min-height: 2.75rem;
        padding: 0.5rem 1.25rem;
        border-radius: var(--kx-radius-pill);
        background: var(--kx-green);
        color: var(--kx-auf-gruen);
        font-weight: 700;
        text-decoration: none;
    }
    .sp-checkout-card { scroll-margin-top: var(--kx-4); }
}

/* ── Kasse ── */
.sp-checkout-card {
    position: sticky;
    top: 6rem;
    padding: var(--kx-5);
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten);
}
@media (max-width: 62rem) { .sp-checkout-card { position: static; } }
.sp-checkout-card h2 {
    display: flex;
    align-items: center;
    gap: var(--kx-2);
    font-size: var(--kx-fs-lg);
    font-weight: 800;
    color: var(--kx-dark);
}
.sp-checkout-note { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); margin-bottom: var(--kx-5); }
.sp-form-group { margin-bottom: var(--kx-4); }
.sp-form-row { display: grid; gap: var(--kx-4); grid-template-columns: 1fr; }
@media (min-width: 36rem) { .sp-form-row { grid-template-columns: 1fr 1fr; } }
.sp-label {
    display: block;
    margin-bottom: 0.3rem;
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    color: var(--kx-ink-soft);
}
.sp-input {
    display: block;
    width: 100%;
    padding: 0.7rem 1rem;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    background: var(--kx-bg-soft);
    font: inherit;
    color: var(--kx-text);
    transition: border-color var(--kx-schnell), box-shadow var(--kx-schnell), background var(--kx-schnell);
}
.sp-input:focus {
    outline: none;
    background: #fff;
    border-color: var(--kx-green);
    box-shadow: 0 0 0 4px rgba(var(--kx-green-rgb), 0.15);
}
.sp-textarea { resize: vertical; min-height: 5rem; }
.sp-dsgvo {
    display: flex;
    align-items: flex-start;
    gap: var(--kx-3);
    padding: var(--kx-3);
    margin-bottom: var(--kx-4);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    background: var(--kx-bg-soft);
    font-size: var(--kx-fs-sm);
    color: var(--kx-ink-soft);
}
.sp-dsgvo input { margin-top: 0.2rem; width: 1.05rem; height: 1.05rem; accent-color: var(--kx-green); flex-shrink: 0; }
.sp-checkout-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    width: 100%;
    padding: 0.85rem 1.5rem;
    border: 0;
    border-radius: var(--kx-radius-pill);
    background: linear-gradient(135deg, var(--kx-green), var(--kx-green-dark));
    color: var(--kx-auf-gruen);
    font-size: var(--kx-fs-md);
    font-weight: 700;
    cursor: pointer;
    box-shadow: var(--kx-schatten-gruen);
    transition: transform var(--kx-schnell) var(--kx-kurve);
}
.sp-checkout-btn:hover { transform: translateY(-2px); }

/* ── Shop-Konto (HS-K1): schmale Karte, Verweise darunter ── */
.sp-konto { max-width: 30rem; margin-inline: auto; }
.sp-konto h1 { margin-bottom: var(--kx-4); }
.sp-konto-links { display: flex; flex-wrap: wrap; gap: var(--kx-3) var(--kx-5); margin-top: var(--kx-5); font-size: var(--kx-fs-sm); }
.sp-konto-links a { color: var(--kx-marke-text); }

/* ── Bestätigung ── */
.sp-success-page { padding: var(--kx-8) var(--kx-5); }
.sp-success-inner {
    max-width: 560px;
    margin-inline: auto;
    padding: var(--kx-7) var(--kx-5);
    text-align: center;
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-xl);
    box-shadow: var(--kx-schatten);
}
/* Grund: `.sp-success-inner` = `--kx-card-bg` (weiss). 1,74 → 4,93. */
.sp-success-icon { font-size: 3.5rem; color: var(--kx-gruen-text); margin-bottom: var(--kx-3); }
.sp-success-inner h1 { font-size: var(--kx-fs-xl); font-weight: 900; color: var(--kx-dark); }
.sp-success-order-nr { font-size: var(--kx-fs-md); color: var(--kx-ink-soft); }
.sp-success-text { color: var(--kx-text-muted); margin-bottom: var(--kx-6); }
.sp-success-summary {
    text-align: left;
    padding: var(--kx-4);
    margin-bottom: var(--kx-5);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-lg);
    background: var(--kx-bg-soft);
}
.sp-success-summary h2 { font-size: var(--kx-fs-base); font-weight: 700; color: var(--kx-ink-soft); }
.sp-success-item {
    display: flex;
    justify-content: space-between;
    gap: var(--kx-3);
    padding: 0.35rem 0;
    font-size: var(--kx-fs-sm);
    border-bottom: 1px solid var(--kx-line);
    white-space: pre-wrap;
}
.sp-success-total {
    display: flex;
    justify-content: space-between;
    padding-top: var(--kx-3);
    font-size: var(--kx-fs-md);
}
.sp-success-total strong { color: var(--kx-marke-text); font-weight: 900; }
.sp-success-back {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-2);
    padding: 0.7rem 1.75rem;
    border-radius: var(--kx-radius-pill);
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font-weight: 700;
    text-decoration: none;
}


/* **Der zweite Teil des Ö2-Befunds: nicht nur Knopf gegen Knopf.** Auf
   einer kurzen Produktseite (kein Zubehoer, kurze Beschreibung) landet
   „In den Warenkorb" im ERSTEN Bildschirm genau dort, wo die schwebenden
   Knoepfe stehen — der Warenkorb-Knopf lag im Bildschirmfoto direkt AUF
   dem Formularknopf. Zusaetzlicher Randabstand am Seitenende haette das
   NICHT behoben: die Knoepfe sind `position: fixed`, ihre Bildschirm-
   position haengt nicht von der Scrollposition ab, und der Formularknopf
   stand schon im ersten Bild. Was hilft: der wachsende `flex: 1`-Knopf
   raeumt rechts eine Spalte frei, breit genug fuer den schwebenden Turm. */
@media (max-width: 47.9375rem) {
    .sp-detail-cart-form { padding-right: 4.75rem; }
}
/* Scrollt der Besucher den Katalog bis zum Ende, darf die letzte Karte
   nicht unter dem schwebenden Turm verschwinden — hier hilft der
   Randabstand am Seitenende sehr wohl, weil das Ende der Seite und die
   Scrollposition am Ende zusammenfallen. */
@media (max-width: 47.9375rem) {
    .sp-products { padding-bottom: calc(var(--kx-abschnitt) + 6rem); }
}

/* ═══ 22b. Feinfuehlige Ziele auf dem Telefon (Paket Ö1) ══════════════
   Ein Finger trifft kleiner als ein Mauszeiger. Gemessen am 03.09.2026
   auf 390 px: der Kontakt-Knopf in der Leiste 81×31, die Sprachwahl
   59×38, Telefon-/Mail-Verweise 19 px hoch, die beiden Hotspot-Punkte
   auf dem Spotlight-Bild 22×22. Die Regel gilt NUR unter
   `(pointer: coarse)` — am Schreibtisch mit Maus bleibt jede Groesse,
   wie sie war. */
@media (pointer: coarse) {
    .kx-btn, .kx-premium-btn, .lp-hero__cta, .lp-spotlight__cta,
    .lp-detail__cta-btn, .ab__btn, .kx-navbar__kontakt {
        min-height: 44px;
    }
    .kx-nav-link, .kx-lang-switch__knopf, .kx-burger, .kx-navbar__marke {
        min-height: 44px;
    }
    .kx-footer__col a, .kx-kontaktzeile a,
    a[href^="tel:"], a[href^="mailto:"] {
        display: inline-flex;
        align-items: center;
        min-width: 44px;
        min-height: 44px;
    }
    .form-control { min-height: 44px; }
    /* Das Haekchen der DSGVO-Zustimmung: sichtbar bleibt es klein, aber
       auch ein Kaestchen ist ein Tippziel — 40 px, damit der Finger es
       trifft, ohne neben dem Fliesstext zu wirken wie ein Formularfeld. */
    .lp-dsgvo input { width: 40px; height: 40px; }

    /* Die Hotspot-Punkte auf dem Spotlight-Bild: die sichtbare Groesse
       bleibt 22 px (`::after`), aber der Knopf selbst — und damit die
       Trefferflaeche — waechst auf 40 px, mittig um denselben Punkt. */
    .kx-hotspot {
        width: 40px; height: 40px;
        margin: -20px 0 0 -20px;
        background: transparent;
        box-shadow: none;
    }
    .kx-hotspot::after {
        content: '';
        position: absolute;
        inset: 9px;
        border-radius: 50%;
        background: var(--kx-green);
        box-shadow: 0 0 0 6px rgba(var(--kx-green-rgb), 0.25);
    }
}

/* Fussbereich: mindestens 14 px, auch auf dem Telefon. Die Copyright-
   Zeile stand auf `--kx-fs-sm` (13,6 px). */
.kx-footer-bottom p { font-size: 0.875rem; }

/* ═══ 22c. Die klebende Anfragen-Leiste (Paket Ö1) ════════════════════
   Unter 62rem und nur auf der Landingpage: sobald der Besucher zwei
   Bildschirmhoehen gescrollt hat, erscheint unten „Anfragen" und
   „Anrufen" — vorher war die naechste Gelegenheit dazu erst nach zwei
   weiteren Bildschirmhoehen (die Kontaktkarte). `landing.js` schaltet
   `.kx-sichtbar` per IntersectionObserver und versteckt die Leiste
   wieder, sobald das Kontaktformular selbst im Bild ist. */
.kx-sticky-cta {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 1055;
    display: flex;
    gap: var(--kx-2);
    padding: var(--kx-3) var(--kx-4);
    padding-bottom: calc(var(--kx-3) + env(safe-area-inset-bottom, 0px));
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-top: 1px solid var(--kx-card-border);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.1);
    transform: translateY(110%);
    transition: transform var(--kx-normal) var(--kx-kurve);
}
.kx-sticky-cta.kx-sichtbar { transform: translateY(0); }
.kx-sticky-cta a { flex: 1; }
@media (min-width: 62rem) { .kx-sticky-cta { display: none; } }
@media (prefers-reduced-motion: reduce) { .kx-sticky-cta { transition: none; } }

/* Solange die Leiste unten steht, weicht der Chat-Knopf nach oben aus —
   sonst liegt er auf „Anrufen". Der Warenkorb steht seit ST3 im Kopf
   (`.kx-navbar__korb`) und schwebt nicht mehr; hier reicht der Chat-Knopf. */
body.kx-cta-leiste-sichtbar .kx-chatbot-container { bottom: 96px; }
@media (max-width: 576px) {
    body.kx-cta-leiste-sichtbar .kx-chatbot-container { bottom: 86px; }
}

/* Der Chat-Knopf weicht einem Formular mit Textfeldern
   (Kontakt, Kasse, Newsletter) und einem fokussierten Textfeld: `schwebend.js`
   setzt `kx-schwebend-aus` am `<body>`. Ein offenes Chat-Fenster bleibt
   bedienbar (sein Knopf traegt `aria-expanded="true"`). `visibility`, damit die
   ausgeblendeten Knoepfe auch aus der Tab-Reihenfolge fallen. */
body.kx-schwebend-aus .kx-chat-btn:not([aria-expanded="true"]) {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

/* ═══ 23. Druck ══════════════════════════════════════════════════════ */

@media print {
    .kx-navbar, .kx-mobilnav, .cc-banner, .cc-overlay,
    .lp-lightbox, .lp-leasing-modal, .kx-modal,
    .kx-chatbot-container, .kx-spielbanner, .kx-sticky-cta { display: none !important; }
    body { color: #000; background: #fff; }
    .lp-anim { opacity: 1 !important; transform: none !important; }
}

/* ═══ Die Bauteile aus Paket 9.6 ═════════════════════════════════════
   Vier Muster, die der Baukasten bis zum 02.09.2026 nicht hatte — und
   die der Redakteur deshalb aus `intro` nachgebaut hat. Gemessen:
   `ansprechpersonen` waren SECHS `intro`-Bloecke, einer je Person.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Person ─────────────────────────────────────────────────────────
   Karte im Raster. Ohne Foto faellt das Bild weg und die Karte rutscht
   zusammen — ein grauer Platzhalter saehe aus wie ein Fehler. */
.kx-person {
    display: flex;
    flex-direction: column;
    gap: var(--kx-2);
    padding: var(--kx-4);
    background: var(--kx-card-bg);
    border: 1px solid var(--kx-card-border);
    border-radius: var(--kx-radius-lg);
    box-shadow: var(--kx-schatten-sm);
}
.kx-person__bild {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: var(--kx-radius-md);
    margin-bottom: var(--kx-2);
}
.kx-person__name {
    font-size: var(--kx-fs-md);
    font-weight: 800;
    color: var(--kx-text);
    margin: 0;
}
.kx-person__rolle {
    font-size: var(--kx-fs-sm);
    color: var(--kx-text-muted);
    margin: 0;
}
.kx-person__zeile {
    margin: 0;
    font-size: var(--kx-fs-sm);
}
/* **Der abgedunkelte Ton, nicht die Marke.** Genau hier standen am
   02.09.2026 dreizehn unlesbare Stellen mit Kontrast 1,74, weil der
   Redakteur die Nummern von Hand gefaerbt hat. */
.kx-person__zeile a {
    color: var(--kx-marke-text);
    font-weight: 600;
    text-decoration: none;
}
.kx-person__zeile a:hover { text-decoration: underline; }

/* ── Kennzahlen ─────────────────────────────────────────────────────
   Eine Reihe, die auf dem Telefon umbricht. `tabular-nums`, damit
   untereinander stehende Ziffern fluchten. */
.kx-zahlen {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--kx-6);
}
.kx-zahl { text-align: center; min-width: 8rem; }
.kx-zahl__wert {
    font-size: var(--kx-fs-3xl);
    font-weight: 900;
    line-height: 1;
    color: var(--kx-marke-text);
    font-variant-numeric: tabular-nums;
}
.kx-zahl__label {
    margin-top: var(--kx-2);
    font-size: var(--kx-fs-sm);
    color: var(--kx-text-muted);
}

/* ── Logo-Leiste ────────────────────────────────────────────────────
   Graustufig und beim Zeigen farbig: zehn fremde Hausfarben
   nebeneinander nehmen der Seite sonst ihre eigene. */
.kx-logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--kx-6);
}
.kx-logos__feld {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 3.5rem;
}
.kx-logos__feld img {
    max-height: 100%;
    max-width: 10rem;
    object-fit: contain;
    filter: grayscale(1);
    opacity: 0.65;
    transition: filter var(--kx-normal), opacity var(--kx-normal);
}
.kx-logos__feld:hover img { filter: grayscale(0); opacity: 1; }
.kx-logos--farbig img { filter: none; opacity: 1; }

/* ── Trenner ────────────────────────────────────────────────────────
   Eine Linie in der Breite des Textes, nicht der Seite. */
.kx-trenner {
    border: 0;
    border-top: 1px solid var(--kx-line);
    margin: 0;
}

/* ── Textgroessen im Fliesstext (Paket 9.6) ─────────────────────────
   Marco am 02.09.2026: „warum kann man eigentlich die Schriftgroesse
   nicht waehlen?" — Nachgemessen war die Lage sauber: im Inhalt stand
   KEINE einzige handgetippte Groesse.

   **Drei benannte Stufen statt eines Pixelfeldes.** Der Editor
   speichert diese Klassen; was „Vorspann" heisst, entscheidet die Zeile
   hier. Ein fester Wert im Inhalt waere genau die Falle, die am selben
   Tag bei den Farben 66-mal ausgegraben wurde: eingefroren, und keine
   spaetere Aenderung erreicht ihn.

   Die Werte kommen aus der Skala (`--kx-fs-*`) und sind keine eigenen
   Zahlen. */
.kx-text--vorspann {
    font-size: var(--kx-fs-md);
    line-height: 1.7;
}
.kx-text--hinweis {
    font-size: var(--kx-fs-sm);
    color: var(--kx-text-muted);
}

/* ── Rechtstexte: Impressum, Datenschutz, AGB, Gewaehrleistung ────────
   **Marco am 03.09.2026, nachdem die vier Seiten CMS-Seiten wurden:**
   „optisch ist das nicht so huebsch". Er hat recht, und die Ursache war
   nicht der Umbau, sondern wo das Aussehen wohnte: in einem
   `<style>`-Block IN JEDER DER VIER VORLAGEN. Nachgezaehlt am
   03.09.2026 — `impressum.html` 105 Zeilen, die drei anderen je 78 und
   untereinander **byteweise identisch**. Zusammen 339 Zeilen, dreifach
   kopiert, und **keine einzige davon im Blatt**.

   Die Vorlage bringt ihr Aussehen also mit; die CMS-Seite rendert
   `cms_page_public.html` und bekommt nichts davon. Bloecke da, Aussehen
   weg — genau das, was Marco gesehen hat.

   Deshalb steht es jetzt hier, einmal, unter zwei Selektoren:
   `.legal-page` fuer die Vorlage (sie bleibt der Rueckfall, solange
   eine Seite nicht veroeffentlicht ist) und `.kx-rechtstext` fuer den
   CMS-Block. Wer eine Regel aendert, aendert beide Wege.
   ────────────────────────────────────────────────────────────────── */

.legal-page {
    max-width: var(--kx-wrap-schmal);
    margin: 0 auto;
    padding: 3rem 1.5rem 4rem;
}
.legal-page h1 {
    font-size: clamp(1.8rem, 4vw, 2.4rem);
    font-weight: 900;
    color: var(--kx-text);
    margin-bottom: 0.5rem;
    letter-spacing: -0.02em;
}

/* Die Abschnittsueberschrift. Im CMS-Block ist das die Ueberschrift des
   Bausteins (`lp-section__title`) — sie kommt sonst als grosse,
   zentrierte Landingpage-Ueberschrift daher, und ein Paragraph der AGB
   ist keine Landingpage. */
.legal-page h2,
.kx-rechtstext .lp-section__title {
    font-size: var(--kx-fs-lg);
    font-weight: 800;
    color: #334155;
    margin-top: 0;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 2px solid rgba(var(--kx-marke-rgb), 0.28);
    /* Kein `text-align` hier: die Ausrichtung ist ein Feld im Editor
       (`text_align` -> `.text-start`/`.text-center` am `.kx-kopf`), und
       eine Regel hier wuerde die Wahl uebergehen. */
}
.legal-page h2 {
    margin-top: 2.25rem;
}

.legal-page h3,
.kx-rechtstext h3 {
    font-size: var(--kx-fs-md);
    font-weight: 700;
    color: #475569;
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
}
/* **Der Absatzabstand ist hier keine Kosmetik.** Das Blatt setzt
   global `p { margin: 0 }`; die AGB bestehen aber aus durchnummerierten
   Klauseln, die im Quelltext je ein eigener Absatz sind. Ohne diese
   Zeile stehen 1.1 bis 1.5 als eine Wand aus Text, in der man die
   Klausel nicht findet, die man sucht — so war es am 03.09.2026 live zu
   sehen. Die alte Vorlage hatte dafuer `margin-bottom: 0.35rem`; das
   ist absichtlich weniger als ein normaler Absatz, denn die Klauseln
   gehoeren zusammen. */
.legal-page p,
.legal-page li,
.kx-rechtstext p,
.kx-rechtstext li {
    font-size: var(--kx-fs-base);
    color: var(--kx-text-muted);
    line-height: 1.75;
    margin-bottom: 0.35rem;
}
/* Der letzte Absatz eines Blocks nicht — die Fuge macht der Abstand des
   Abschnitts, und beides zusammen waere eine Fuge zu viel. */
.kx-rechtstext .kx-fliesstext > :last-child {
    margin-bottom: 0;
}
/* Fuer Listen steht hier absichtlich NICHTS. Die alte Vorlage hatte
   `.legal-page ul { padding-left: 1.5rem }`, aber Zeile 218 dieses
   Blattes gibt jeder Liste schon `padding-left: 1.25rem` und
   `margin-bottom: var(--kx-3)` — die Vorlagenregel war ein Schubs von
   4 px ueber die allgemeine. Sie hier zu wiederholen hiesse, denselben
   Wert an zwei Stellen zu pflegen; genau daran ist das Aussehen der
   Rechtstexte schon einmal auseinandergelaufen. */
.legal-page a,
.kx-rechtstext a {
    color: var(--kx-marke-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.legal-page a:hover,
.kx-rechtstext a:hover {
    color: var(--kx-dark);
}

/* Der Kasten mit dem gruenen Balken — er steht mitten im AGB-Text und
   war ohne diese Regel ein nacktes `div`.

   **Und er steht bewusst allein, nicht unter `.legal-page`.** Der
   Baustein `firmendaten` benutzt dieselbe Klasse, und ihn kann man auf
   jede CMS-Seite setzen. Waere die Regel an die Rechtsseite gebunden,
   stuende die Anschrift des Kunden dort als nacktes `div` — am
   03.09.2026 war genau das im Impressum zu sehen. */
.legal-highlight {
    background: var(--kx-marke-hauch);
    border-left: 3px solid var(--kx-marke);
    padding: 1rem 1.25rem;
    border-radius: 0 12px 12px 0;
    margin: 1rem 0;
}

/* Die kleine Zeile unter der Ueberschrift („Stand: Maerz 2026"). */
.legal-page .legal-page__updated,
.kx-rechtstext .legal-page__updated {
    font-size: var(--kx-fs-sm);
    color: var(--kx-ink-faint);
    margin-bottom: 0;
}

/* **Die Abstaende stehen NICHT hier, und das ist Absicht.** Ein
   Baustein bringt `lp-section` mit, dessen Vorgabe `--kx-abschnitt` ist
   (bis 5,5rem oben UND unten) — zwischen achtzehn AGB-Paragraphen waeren
   das bis zu 176 px je Fuge. Die Verlockung ist, das hier
   zurechtzuruecken; `.kx-rechtstext` haette dieselbe Spezifitaet wie
   `.pt-5` und stuende spaeter im Blatt, wuerde also gewinnen.

   Genau das darf nicht passieren: `padding_top` ist ein Feld im Editor,
   und was dort gewaehlt wird, muss auf der Seite so erscheinen. Die
   engen Abstaende setzt deshalb `tools/rechtstexte_uebernehmen.py` als
   DATEN — `pt-4`/`pb-0` zwischen den Abschnitten (24 px statt 176) und
   `pt-5`/`pb-5` an den beiden Raendern der Seite, wo die alte Vorlage
   ihr `padding: 3rem 1.5rem 4rem` hatte. Marco kann jeden dieser Werte
   im Editor umstellen, und dann gilt seiner. */

/* ── Symbole reservieren ihren Platz (11.09.2026, berichtigt 14.09.) ──
   Das Blatt der Bootstrap-Symbole laedt seit 2c6334d4 asynchron, damit
   es den ersten Aufbau nicht aufhaelt. Bis es da ist, ist ein <i class=
   "bi bi-…"> ein leeres Inline-Element ohne Breite - und wenn es dann
   sein Zeichen bekommt, ruecken die Knoepfe im Hero auseinander und
   alles darunter springt. Live gemessen: CLS 0,056; mit blockierter
   Symbol-Datei 0, mit blockierten Schriften weiter 0,056 - es sind die
   Symbole, nicht die Schrift. Alle Symbole der Vorlagen und die aus
   landing.js tragen die Klasse `bi`.

   **Der Platzhalter gehoert an das `::before`, nicht an das `<i>`.** Die
   erste Fassung (66830ab5) gab dem `.bi` selbst `inline-block`, 1em x
   1em und `vertical-align: -0.125em`. Das Zeichen steckt aber im
   `::before`, und bootstrap-icons senkt DAS schon um 0,125em - mit dem
   Kasten darum sass jedes Symbol tiefer: in der Zeile doppelt gesenkt,
   und in jedem Knopf mit `align-items: center` noch mehr, weil der
   Kasten 1em hoch war, die Zeile darin aber 1,65em. Marco am 14.09.:
   „warum sind die icons so verschoben überall?" Nachgemessen war es jedes
   Symbol auf jeder Seite, 1 bis 26 px (Chat-Knopf 9, Spiel 11, die
   Platzhalter im Shop 13 bis 26).

   Diese Regel gibt dem `::before` den Kasten, den bootstrap-icons ihm
   ohnehin gibt: 1em breit und hoch (die Schrift hat 300 Einheiten je
   Geviert, jedes Zeichen ist 300 breit, Oberlaenge 300, Unterlaenge 0 -
   die Grundlinie liegt also am unteren Rand) und um 0,125em gesenkt. Ein
   leerer `inline-block` hat seine Grundlinie ebenfalls am unteren Rand;
   vor und nach dem Laden liegt der Kasten deshalb an derselben Stelle.

   - `:where()`, weil keckex.css im Kopf NACH dem Symbolblatt steht. Ein
     blosses `.bi::before` mit `content` hat dieselbe Spezifitaet wie die
     Regel jedes einzelnen Symbols im Symbolblatt, stuende spaeter und
     loeschte damit jedes Zeichen. So gewinnt das Symbolblatt in allem,
     was es selbst setzt, sobald es da ist.
   - `min-width`/`min-height` statt `width`/`height`: ein fester Wert
     rundet anders als die Breite des Zeichens, um 1/64 px je Symbol - in
     einer Reihe aus fuenf Sternen stand der vierte dadurch einen Hauch
     anders. Mit `min-` bestimmt nach dem Laden wieder das Zeichen.

   Gemessen am 14.09.2026 mit Playwright auf zehn Seiten (Landing, CMS,
   Rechtstext, Shop) in 1400 und 390 px: jedes Symbol pixelgleich mit dem
   Stand vor 66830ab5, und mit um 2,5 s verzoegertem Symbolblatt bewegt
   sich beim Eintreffen kein einziges Element. */
:where(.bi)::before {
  content: "";
  display: inline-block;
  min-width: 1em;
  min-height: 1em;
  vertical-align: -0.125em;
}

/* ═══ Chat-Fenster ══════════════════════════════════════════════════════
   Bis zum 14.09.2026 ein <style>-Block in `includes/_chatbot.html`, also
   mitten im <body> jeder oeffentlichen Seite. Der W3C-Validator zaehlt
   das als Fehler, und die Regeln gingen mit jeder Seite neu hinaus,
   statt mit diesem Blatt im Zwischenspeicher zu liegen. Sie stehen hier
   AM ENDE des Blatts - in der Kaskade kamen sie vorher auch nach allem,
   was in `keckex.css` steht. (`spiel.css` laedt spaeter und stand davor;
   es kennt keinen dieser Selektoren.) Geaendert ist eine Zeile, bei
   `.kx-chat-header-title`, mit Grund dort. */
/* **Schrift auf dem Gruen: `--kx-auf-gruen`, nicht Weiss** (01.09.2026).
   Weiss auf dem Lime ergibt 1,74 - die vier Stellen hier (Knopf,
   Kopfzeile, eigene Sprechblase, Senden) waren alle betroffen. */
/* Chatbot Widget Styles */
.kx-chatbot-container {
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 999999 !important;
    font-family: 'Inter', sans-serif;
}

.kx-chat-btn {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background-color: var(--kx-green);
    color: var(--kx-auf-gruen);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.8rem;
    cursor: pointer;
    box-shadow: 0 10px 20px rgba(107, 142, 35, 0.3);
    transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    position: relative;
}

.kx-chat-btn:hover {
    transform: scale(1.1);
}

.kx-chat-attention {
    animation: pulse-attention 2s infinite;
}

@keyframes pulse-attention {
    0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(107, 142, 35, 0.7); }
    50% { transform: scale(1.05); box-shadow: 0 0 0 15px rgba(107, 142, 35, 0); }
    100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(107, 142, 35, 0); }
}

.kx-chat-tooltip {
    position: absolute;
    right: 80px;
    top: 50%;
    transform: translateY(-50%);
    background: white;
    color: var(--kx-dark);
    padding: 0.6rem 1rem;
    border-radius: var(--kx-radius-md);
    font-size: var(--kx-fs-base);
    font-weight: 600;
    box-shadow: 0 5px 15px rgba(0,0,0,0.1);
    white-space: nowrap;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s, transform 0.3s;
    border: 1px solid rgba(107, 142, 35, 0.2);
}

.kx-chat-tooltip::after {
    content: '';
    position: absolute;
    right: -6px;
    top: 50%;
    transform: translateY(-50%);
    border-width: 6px 0 6px 6px;
    border-style: solid;
    border-color: transparent transparent transparent white;
}

.kx-chat-tooltip.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(-50%) translateX(-10px);
}

.kx-chat-window {
    position: absolute;
    bottom: 80px;
    right: 0;
    width: 350px;
    height: 500px;
    max-height: calc(100vh - 120px);
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-radius: 20px;
    box-shadow: 0 15px 40px rgba(0,0,0,0.15);
    border: 1px solid rgba(255,255,255,0.8);
    display: none; /* Controlled via JS */
    flex-direction: column;
    overflow: hidden;
    transform-origin: bottom right;
}

.kx-chat-header {
    background: linear-gradient(135deg, var(--kx-green) 0%, var(--kx-green-dark) 100%);
    color: var(--kx-auf-gruen);
    padding: 1rem 1.25rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Seit dem 14.09.2026 ein <div> statt einer <h4>: der Name des Chats ist
   keine Ueberschrift der Seite, und als <h4> nach einer <h2> war er fuer
   den W3C-Validator ein uebersprungener Rang (auf /shop). Die Zeilenhoehe
   kam bis dahin aus der Regel fuer alle Ueberschriften (`h1, h2, … h6`
   oben) und steht deshalb jetzt hier. */
.kx-chat-header-title {
    font-weight: 600;
    margin: 0;
    font-size: var(--kx-fs-md);
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.kx-chat-header-subtitle {
    font-size: var(--kx-fs-xs);
    opacity: 0.8;
    margin-top: 0.1rem;
}

.kx-chat-close {
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s;
    font-size: var(--kx-fs-xl);
    line-height: 1;
}

.kx-chat-close:hover {
    opacity: 1;
}

.kx-chat-messages {
    flex: 1;
    padding: 1.25rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.kx-msg {
    max-width: 85%;
    padding: 0.75rem 1rem;
    border-radius: var(--kx-radius-lg);
    font-size: var(--kx-fs-base);
    line-height: 1.4;
    word-wrap: break-word;
    animation: fadeUpMsg 0.3s ease forwards;
}

@keyframes fadeUpMsg {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.kx-msg-bot {
    background: #f1f5f9;
    color: #334155;
    border-bottom-left-radius: 4px;
    align-self: flex-start;
}

.kx-msg-bot a {
    font-weight: 600;
}

.kx-msg-user {
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    border-bottom-right-radius: 4px;
    align-self: flex-end;
}

.kx-chat-input-area {
    padding: 1rem;
    background: white;
    border-top: 1px solid #e2e8f0;
    display: flex;
    gap: 0.5rem;
}

.kx-chat-input {
    flex: 1;
    border: 1px solid #cbd5e1;
    border-radius: 20px;
    padding: 0.5rem 1rem;
    outline: none;
    font-size: var(--kx-fs-base);
    transition: border-color 0.2s;
}

.kx-chat-input:focus {
    border-color: var(--kx-green);
}

.kx-chat-send {
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.2s, background-color 0.2s;
}

.kx-chat-send:hover {
    transform: scale(1.05);
    background-color: var(--kx-green-dark);
}

.kx-chat-send:disabled {
    background: #cbd5e1;
    cursor: not-allowed;
    transform: none;
}

/* Typing Indicator */
.kx-typing {
    display: flex;
    gap: 0.3rem;
    align-items: center;
    padding: 0.5rem 0.75rem;
}

.kx-dot {
    width: 6px;
    height: 6px;
    background: #94a3b8;
    border-radius: 50%;
    animation: typingBounce 1.4s infinite ease-in-out both;
}

.kx-dot:nth-child(1) { animation-delay: -0.32s; }
.kx-dot:nth-child(2) { animation-delay: -0.16s; }

@keyframes typingBounce {
    0%, 80%, 100% { transform: scale(0); }
    40% { transform: scale(1); }
}

@media (max-width: 576px) {
    .kx-chatbot-container {
        bottom: 20px;
        right: 20px;
    }
    .kx-chat-window {
        width: calc(100vw - 40px);
        bottom: 70px;
    }
}

/* ═══ Geraeteseite (22.09.2026, `templates/geraet.html`) ════════════════
   Eine Seite je Geraet. Sie benutzt die Klassen der Tafel auf der
   Startseite (`lp-detail__*`) und des Rasters (`lp-grid__*`), damit beide
   gleich aussehen; hier steht nur, was die ganze Seite anders braucht:
   zwei Spalten statt einer Tafel, Miniaturen, der Text in Lesebreite. */

.kx-geraet__kopf { padding-block: var(--kx-4) var(--kx-7); }
.kx-geraet__raster { --kx-spalten: 7fr 5fr; align-items: start; }

.kx-geraet__bildlink { display: block; border-radius: var(--kx-radius-lg); }
.kx-geraet__bild { display: block; height: auto; }
.kx-geraet__ohne-bild {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3rem;
    color: var(--kx-ink-faint);
    cursor: default;
}

.kx-geraet__miniaturen { display: flex; flex-wrap: wrap; gap: var(--kx-2); margin-top: var(--kx-3); }
/* Am Telefon eine Reihe zum Wischen statt drei Reihen untereinander:
   beim MOBI-230V-11L (sieben Bilder) rutschten Name und „Jetzt anfragen"
   sonst unter die erste Bildschirmhoehe (gemessen am 22.09.2026, 375 px). */
@media (max-width: 62rem) {
    .kx-geraet__miniaturen {
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding-bottom: var(--kx-1);
        scrollbar-width: thin;
    }
    .kx-geraet__miniatur { flex: 0 0 auto; scroll-snap-align: start; }
}
.kx-geraet__miniatur {
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
    line-height: 0;
    cursor: pointer;
    transition: border-color var(--kx-schnell) var(--kx-kurve);
}
.kx-geraet__miniatur img {
    width: 72px;
    height: 54px;
    object-fit: cover;
    border-radius: calc(var(--kx-radius-sm) - 2px);
}
.kx-geraet__miniatur:hover,
.kx-geraet__miniatur.is-aktiv { border-color: var(--kx-green); }
.kx-geraet__miniatur:focus-visible { outline: 3px solid var(--kx-marke-text); outline-offset: 2px; }

.kx-geraet__info { display: flex; flex-direction: column; align-items: flex-start; gap: var(--kx-3); }
.kx-geraet__name {
    margin: 0;
    font-size: var(--kx-fs-titel);
    font-weight: 900;
    line-height: 1.1;
    letter-spacing: -0.025em;
    color: var(--kx-dark);
    text-wrap: balance;
}
.kx-geraet__untertitel { margin: 0; font-size: var(--kx-fs-lg); color: var(--kx-ink-soft); text-wrap: pretty; }
.kx-geraet__preis { display: flex; flex-wrap: wrap; align-items: center; gap: var(--kx-2); }
.kx-geraet__preis .lp-grid__price { font-size: var(--kx-fs-xl); }
.kx-geraet__preis small { font-size: var(--kx-fs-sm); font-weight: 500; color: var(--kx-text-muted); }
.kx-geraet__info .lp-detail__actions { width: 100%; }
.kx-geraet__allein { grid-column: 1 / -1; }
.kx-geraet__eckdaten { margin: 0; }

.kx-geraet__text { padding-block: var(--kx-6); background: var(--kx-bg-soft); }
.kx-geraet__text p { margin: 0 0 var(--kx-3); color: var(--kx-ink-soft); font-size: var(--kx-fs-md); line-height: 1.7; }
.kx-geraet__zwischentitel {
    margin: var(--kx-5) 0 var(--kx-2);
    font-size: var(--kx-fs-lg);
    font-weight: 800;
    color: var(--kx-dark);
}
.kx-geraet__text .lp-detail__list { margin-bottom: var(--kx-4); font-size: var(--kx-fs-md); line-height: 1.6; }
.kx-geraet__liste--haken { padding-left: 0; list-style: none; }
.kx-geraet__liste--haken li { position: relative; padding-left: 1.7rem; }
/* Das Haekchen im Schriftton der Marke: `--kx-gruen-text` haelt auf dem
   hellen Grund Kontrast 4,5 (siehe `.lp-detail__list li::marker`). */
.kx-geraet__liste--haken li::before {
    content: '✓';
    position: absolute;
    left: 0.2rem;
    color: var(--kx-gruen-text);
    font-weight: 900;
}

.kx-geraet__weitere .lp-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }

/* Der Weg von der Tafel der Startseite auf die Seite des Geraets.
   Farbe: `--kx-marke-text` und nicht `--kx-green-dark` - siehe `.cc-text a`. */
.lp-detail__seite {
    display: inline-flex;
    align-items: center;
    gap: var(--kx-1);
    margin-bottom: var(--kx-3);
    color: var(--kx-marke-text);
    font-size: var(--kx-fs-sm);
    font-weight: 700;
    text-decoration: none;
}
.lp-detail__seite:hover { text-decoration: underline; }

/* ── Tabelle (22.09.2026) ───────────────────────────────────────────
   Fuer Vergleiche und technische Daten (`cms_blocks/tabelle.html`).
   Eine Karte mit eigenem weissem Grund: so bleibt sie auf jedem
   Hintergrund des Abschnitts lesbar, auch auf dem dunklen. Der Kopf im
   Hauch der Markenfarbe mit einer Linie in der Marke — beides kommt aus
   `Web → Marke`, nicht aus diesem Blatt. Auf dem Telefon scrollt die
   Tabelle in ihrem Rahmen, die Seite bleibt so breit wie der Bildschirm. */
.kx-tabelle {
    margin-top: var(--kx-5);
    overflow-x: auto;
    background: var(--kx-bg);
    color: var(--kx-text);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    box-shadow: var(--kx-schatten-sm);
}
.kx-tabelle:focus-visible { outline: 2px solid var(--kx-marke-text); outline-offset: 2px; }
.kx-tabelle__raster {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--kx-fs-base);
    line-height: 1.5;
    text-align: left;
}
.kx-tabelle__raster th,
.kx-tabelle__raster td {
    padding: var(--kx-3) var(--kx-4);
    border-bottom: 1px solid var(--kx-line);
    vertical-align: top;
}
.kx-tabelle__raster thead th {
    background: var(--kx-marke-hauch);
    border-bottom: 2px solid var(--kx-marke);
    color: var(--kx-dark);
    font-weight: 700;
}
.kx-tabelle__raster tbody th { color: var(--kx-dark); font-weight: 600; }
.kx-tabelle__raster tbody tr:nth-child(even) { background: var(--kx-bg-soft); }
.kx-tabelle__raster tbody tr:last-child > * { border-bottom: 0; }
@media (max-width: 36rem) {
    .kx-tabelle__raster { font-size: var(--kx-fs-sm); }
    .kx-tabelle__raster th,
    .kx-tabelle__raster td { padding: var(--kx-2) var(--kx-3); }
}

/* ═══ Tastatur: Fokusring und Sprunglink (Ausbau HH, 09.10.2026) ═════
   **Der Ring war 1,4:1 stark.** `:focus-visible` (Abschnitt 2) zeichnete 55 % Gruen auf Weiss: das sind
   197/233/115 auf 255/255/255, gemessen 1,4:1 (`e2e/tastatur_kundenseite.spec.ts`, 40 Stellen auf 7 Seiten im
   ersten Lauf). Gebraucht werden 3:1 (WCAG 1.4.11). `--kx-marke-text` hat 4,9:1 auf Weiss und ist die Markenfarbe,
   die `test_kontrast_wache` schon haelt; auf dem dunklen Fussbereich und im Spiel ist es das helle Marken-Gruen.
   **Die Regel steht im CSS-Ausschnitt im Kopf (`kritisch_*.inc`) mit demselben Wert** - das Einwilligungsband
   fokussiert seinen ersten Knopf beim Laden, der Ring ist also im ersten Bild; ein Unterschied zwischen
   Ausschnitt und Blatt sieht `e2e/kundenseite_ausschnitt.spec.ts` als 1.280 Bildpunkte. */
.kx-footer :focus-visible,
.kx-modal :focus-visible { outline-color: var(--kx-marke); }
/* Felder zeichnen ihren Fokus selbst (Rand + Schein, 1,7:1) und nehmen den Umriss weg;
   bei der Tastatur kommt der Ring dazu. */
.form-control:focus-visible,
.sp-input:focus-visible,
.sp-qty-input:focus-visible,
.kx-chat-input:focus-visible {
    outline: 3px solid var(--kx-marke-text);
    outline-offset: 2px;
}
/* Das Ziel des Sprunglinks bekommt den Fokus nur aus dem Skript und braucht keinen Ring. */
#inhalt:focus { outline: none; }
/* Die Leiste klebt oben (`.kx-navbar`): was die Tastatur nach oben schiebt, soll nicht darunter liegen. */
html { scroll-padding-top: 5.5rem; }
/* Der Sprunglink: verborgen steht er inline in `base_public.html` (kein Platz im Fluss, kein
   CLS vor dem Eintreffen dieses Blatts), mit dem Fokus kommt er ins Bild. `!important`, weil ein
   Attribut sonst gewinnt. */
.kx-sprunglink:focus {
    position: fixed !important;
    left: var(--kx-3) !important;
    top: var(--kx-3) !important;
    width: auto !important;
    height: auto !important;
    overflow: visible !important;
    z-index: 2000;
    padding: 0.7rem 1.1rem;
    border-radius: var(--kx-radius-sm);
    background: var(--kx-dark);
    color: #fff;
    font-weight: 700;
    text-decoration: none;
    box-shadow: var(--kx-schatten-lg);
}

/* ═══ Haendlersuche (HS-B, Paket H3) ═════════════════════════════════
   Baustein `haendlersuche`: Formular, EIN Treffer, Anfrage. Alles auf der Telefonbreite zuerst:
   Knoepfe stehen untereinander und sind mindestens 48 px hoch (Daumen), ab 36rem nebeneinander.
   Nur Token, kein eigenes Gruen. */
.kx-hs__vorschau {
    margin: 0 0 var(--kx-4);
    padding: var(--kx-3);
    border: 1px dashed var(--kx-line-strong);
    border-radius: var(--kx-radius-sm);
    color: var(--kx-text-muted);
    font-size: var(--kx-fs-sm);
}
.kx-hs__ergebnis:empty { display: none; }
.kx-hs__ergebnis { margin-top: var(--kx-5); }
.kx-hs__karte {
    padding: var(--kx-5);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-lg);
    background: var(--kx-bg-soft);
}
.kx-hs__vorzeile {
    margin: 0 0 var(--kx-1);
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    color: var(--kx-text-muted);
}
.kx-hs__name { margin: 0 0 var(--kx-2); font-size: var(--kx-fs-xl); line-height: 1.25; }
.kx-hs__anschrift { margin: 0 0 var(--kx-3); font-style: normal; color: var(--kx-ink-soft); }
.kx-hs__person { margin: 0 0 var(--kx-3); color: var(--kx-ink-soft); }
.kx-hs__knoepfe { display: flex; flex-direction: column; gap: var(--kx-3); margin-top: var(--kx-4); }
.kx-hs__knoepfe .kx-premium-btn,
.kx-hs__knoepfe .kx-btn { min-height: 3rem; text-align: center; }
@media (min-width: 36rem) { .kx-hs__knoepfe { flex-direction: row; flex-wrap: wrap; } }
.kx-hs__weitere { margin: var(--kx-4) 0 0; font-size: var(--kx-fs-base); }
.kx-hs__anfrage-titel { margin: var(--kx-5) 0 var(--kx-3); font-size: var(--kx-fs-lg); }
.kx-hs__anfrage-offen { margin-top: var(--kx-4); }
.kx-hs__anfrage-offen summary {
    cursor: pointer;
    padding: var(--kx-3) 0;
    font-weight: 600;
    color: var(--kx-gruen-text);
}
.kx-hs__ohne { margin-top: var(--kx-4); }
.kx-hs .alert { margin-bottom: 0; }

/* Karte der Haendlersuche (HS-B, Paket H4): erst nach Klick, Leaflet kommt von /static/vendor. */
.kx-hs__karten-bereich { margin-top: var(--kx-5); }
.kx-hs__kartenhinweis { margin: var(--kx-3) 0 0; font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.kx-hs__karte-box {
    height: 22rem;
    margin-top: var(--kx-3);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    overflow: hidden;
    z-index: 0;
}
.kx-hs__karte-box[hidden] { display: none; }
.kx-hs__quelle { margin: var(--kx-2) 0 0; font-size: var(--kx-fs-xs); color: var(--kx-text-muted); }
.kx-hs__quelle a { color: inherit; }

/* ── ST6a Vorschläge ─────────────────────────────────────────────────
   Die Liste unter dem Suchfeld (shop_vorschlaege.js, Combobox mit Listbox). Sie hängt unter der Zeile aus Feld
   und Knopf und liegt über dem Raster; jeder Eintrag ist mindestens 44 px hoch, damit der Finger trifft.
   `<mark>` ist das hervorgehobene Suchwort in den Namen der Trefferliste. */
.sp-suche { position: relative; }
.sp-vorschlaege {
    position: absolute;
    z-index: 30;
    top: 100%;
    inset-inline: var(--kx-5);
    max-height: min(32rem, 70vh);
    overflow-y: auto;
    margin-top: var(--kx-1);
    padding: var(--kx-1);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-md);
    background: #fff;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.14);
    text-align: left;
}
.sp-vorschlaege[hidden] { display: none; }
.sp-vorschlaege__titel {
    padding: var(--kx-2) var(--kx-3) var(--kx-1);
    font-size: var(--kx-fs-sm);
    font-weight: 600;
    color: var(--kx-text-muted);
}
.sp-vorschlaege__eintrag {
    display: flex;
    align-items: center;
    gap: var(--kx-3);
    min-height: 2.75rem;
    padding: var(--kx-2) var(--kx-3);
    border-radius: var(--kx-radius-sm);
    color: var(--kx-text);
    text-decoration: none;
}
.sp-vorschlaege__eintrag:hover,
.sp-vorschlaege__eintrag--aktiv { background: var(--kx-bg-soft); }
.sp-vorschlaege__eintrag--aktiv { outline: 2px solid var(--kx-marke-text); outline-offset: -2px; }
.sp-vorschlaege__bild {
    flex: 0 0 auto;
    width: 3rem;
    height: 3rem;
    object-fit: contain;
    border-radius: var(--kx-radius-sm);
    background: #fff;
}
.sp-vorschlaege__bild--leer { border: 1px solid var(--kx-line); background: var(--kx-bg-soft); }
.sp-vorschlaege__text { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.sp-vorschlaege__name { overflow-wrap: anywhere; font-weight: 600; }
.sp-vorschlaege__nummer { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-vorschlaege__preis { flex: 0 0 auto; font-weight: 600; white-space: nowrap; }
.sp-vorschlaege__alle {
    justify-content: center;
    margin-top: var(--kx-1);
    border-top: 1px solid var(--kx-line);
    border-radius: 0 0 var(--kx-radius-sm) var(--kx-radius-sm);
    font-weight: 600;
    color: var(--kx-marke-text);
}
.sp-suche__gemeint strong { font-weight: 600; }
.sp-card__name mark {
    padding: 0 0.1em;
    border-radius: 0.2em;
    background: rgba(var(--kx-green-rgb), 0.28);
    color: inherit;
}
@media (max-width: 40rem) {
    .sp-vorschlaege { inset-inline: var(--kx-3); max-height: 60vh; }
    .sp-vorschlaege__eintrag { min-height: 3.25rem; }
}

/* ── ST7a: die Merkliste ─────────────────────────────────────────────
   Das Herz (`includes/_merkliste_knopf.html`) liegt auf der Karte oben rechts ueber dem Bild, auf der Artikelseite
   als Knopf mit Text unter „In den Warenkorb". Immer mindestens 44 x 44 px. Gemerkt = ausgefuellt, ungemerkt = Umriss;
   der Zustand steht in `aria-pressed`, nicht nur in der Farbe. */
.sp-merk { margin: 0; }
.sp-merk--karte { position: absolute; top: var(--kx-2); right: var(--kx-2); z-index: 2; }
.sp-merk--produkt { margin-top: var(--kx-3); }
.sp-merk__knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-card-bg);
    color: var(--kx-ink-soft);
    font: inherit;
    font-size: var(--kx-fs-base);
    font-weight: 600;
    cursor: pointer;
    transition: border-color var(--kx-schnell), color var(--kx-schnell);
}
.sp-merk--karte .sp-merk__knopf { box-shadow: var(--kx-schatten-sm); }
.sp-merk--produkt .sp-merk__knopf { padding: 0 var(--kx-4); }
.sp-merk__knopf:hover { border-color: var(--kx-green); color: var(--kx-marke-text); }
.sp-merk__knopf[aria-pressed="true"] { color: var(--kx-marke-text); border-color: var(--kx-green); }
.sp-merk__herz { fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linejoin: round; }
.sp-merk__knopf[aria-pressed="true"] .sp-merk__herz { fill: currentColor; }

.sp-merkliste-kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--kx-3);
    margin-bottom: var(--kx-4);
}
.sp-merkliste-kopf__zahl { margin: 0; color: var(--kx-text-muted); font-weight: 600; }
.sp-merkliste-kopf__alle { min-height: 44px; border: 0; cursor: pointer; font: inherit; font-weight: 700; }
.sp-merkliste { margin: 0; padding: 0; list-style: none; }
.sp-merk-zeile {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--kx-3) var(--kx-4);
    padding: var(--kx-4);
    border-bottom: 1px solid var(--kx-line);
}
.sp-merk-zeile:last-child { border-bottom: 0; }
.sp-merk-zeile .sp-cart-item__img { width: 72px; height: 72px; }
.sp-merk-zeile__bild { display: block; line-height: 0; }
.sp-merk-zeile__info { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.sp-merk-zeile__info h2 { margin: 0; font-size: var(--kx-fs-md); font-weight: 700; overflow-wrap: anywhere; }
.sp-merk-zeile__info h2 a { color: var(--kx-dark); text-decoration: none; }
.sp-merk-zeile__info h2 a:hover { color: var(--kx-marke-text); }
.sp-merk-zeile__preis { font-weight: 800; color: var(--kx-marke-text); }
.sp-merk-zeile__unten { display: contents; }
.sp-merk-zeile__menge { display: flex; flex-direction: column; gap: 0.2rem; }
.sp-merk-zeile__menge label { font-size: var(--kx-fs-sm); font-weight: 600; color: var(--kx-ink-soft); }
.sp-merk-zeile__menge .sp-qty-input { min-height: 44px; }
.sp-merk-zeile__aktionen { display: flex; align-items: center; gap: var(--kx-2); }
.sp-merk-zeile__aktionen form { margin: 0; }
.sp-merk-zeile__knopf,
.sp-merk-zeile__weg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    min-height: 44px;
    padding: 0 var(--kx-4);
    border-radius: var(--kx-radius-pill);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}
.sp-merk-zeile__knopf { border: 0; background: var(--kx-green); color: var(--kx-auf-gruen); }
.sp-merk-zeile__knopf:hover { background: var(--kx-green-dark); }
.sp-merk-zeile__weg { position: relative; border: 1px solid var(--kx-line); background: transparent; color: var(--kx-ink-soft); }
.sp-merk-zeile__weg:hover { border-color: #ef4444; color: #b91c1c; }
/* ST8b: Notiz je Artikel - eine Zeile unter dem Namen, am PC neben dem Bild eingerückt. */
.sp-merk-zeile__notiz { grid-column: 2 / -1; display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.sp-merk-zeile__notiz label { font-size: var(--kx-fs-sm); font-weight: 600; color: var(--kx-ink-soft); }
.sp-merk-zeile__notiz label span { font-weight: 400; color: var(--kx-text-muted); }
.sp-merk-zeile__notiz .sp-input { min-height: 44px; }
.sp-merkliste-kopf__knoepfe { display: flex; flex-wrap: wrap; gap: var(--kx-2); }
.sp-merkliste-kopf__notizen {
    min-height: 44px; padding: 0 var(--kx-4); border: 1px solid var(--kx-line); border-radius: var(--kx-radius-pill);
    background: transparent; color: var(--kx-dark); font: inherit; font-weight: 700; cursor: pointer;
}
.sp-merkliste-kopf__notizen:hover { border-color: var(--kx-green); color: var(--kx-marke-text); }
.sp-merkliste-hinweis { margin: var(--kx-4) 0 0; color: var(--kx-text-muted); }
.sp-merkliste-hinweis a { color: var(--kx-marke-text); }
@media (max-width: 47.9375rem) {
    .sp-merk-zeile { grid-template-columns: 56px minmax(0, 1fr); padding: var(--kx-3); }
    .sp-merk-zeile .sp-cart-item__img { width: 56px; height: 56px; }
    .sp-merk-zeile__notiz { grid-column: 1 / -1; }
    /* Unten eine Zeile: Menge, „In den Warenkorb" (nimmt den Rest), Entfernen nur als Symbol (der Name steht im aria-label). */
    .sp-merk-zeile__unten { display: flex; grid-column: 1 / -1; align-items: flex-end; gap: var(--kx-2); }
    .sp-merk-zeile__menge .sp-qty-input { width: 4rem; }
    .sp-merk-zeile__aktionen { flex: 1 1 auto; min-width: 0; }
    .sp-merk-zeile__aktionen > .sp-merk-zeile__knopf { flex: 1 1 auto; padding: 0 var(--kx-2); }
    .sp-merk-zeile__weg { width: 44px; padding: 0; }
    .sp-merk-zeile__weg span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* ── ST7b Schnellbestellung ──────────────────────────────────────────
   Seite /shop/schnellbestellung: ein Textfeld für die Liste, eine Zeile „Einzelnen Artikel hinzufügen" (mit den
   Vorschlägen aus ST6a), die Vorschau als Liste. Wieder verwendet: Kopf und Rückverweis des Warenkorbs
   (`.sp-cart-*`), Felder (`.sp-input`, `.sp-label`, `.sp-qty-input`). Alles ist flach und einfarbig, die Zustände
   stehen im Text und im Symbol, nicht nur in der Farbe. Jedes Ziel ist mindestens 44 px hoch. */
.alert-warning { background: #fffbeb; border: 1px solid #fcd34d; color: #92400e; }
.sp-schnell__inner { max-width: 52rem; }
.sp-schnell__einleitung { margin-bottom: var(--kx-5); color: var(--kx-text-muted); }
.sp-schnell__meldungen { margin: 0; padding-left: 1.1rem; }
.sp-schnell__feld {
    min-height: 11rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--kx-fs-base);
    line-height: 1.55;
}
.sp-schnell__hilfe { margin-top: var(--kx-2); font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-schnell__hilfe p { margin-bottom: var(--kx-2); }
.sp-schnell__beispiel-kopf { margin-bottom: var(--kx-1); font-weight: 600; color: var(--kx-ink-soft); }
.sp-schnell__beispiel {
    margin: 0;
    padding: var(--kx-3);
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-sm);
    background: var(--kx-bg-soft);
    color: var(--kx-text);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--kx-fs-sm);
    overflow-x: auto;
}
.sp-schnell__neu {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 6rem auto;
    gap: var(--kx-3);
    align-items: end;
    margin-bottom: var(--kx-4);
}
.sp-schnell__neu .sp-vorschlaege { inset-inline: 0; }
.sp-schnell__neu .sp-input,
.sp-schnell__neu .sp-qty-input { width: 100%; min-height: 2.75rem; }
.sp-schnell__neu .sp-label { margin-bottom: 0.3rem; }
.sp-datei { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: var(--kx-3); }
.sp-datei__feld { position: relative; display: inline-flex; }
.sp-datei__eingabe { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.sp-datei__knopf { margin: 0; }
.sp-datei__eingabe:focus-visible + .sp-datei__knopf { outline: 3px solid var(--kx-marke-text); outline-offset: 2px; }
.sp-datei__name { min-width: 0; color: var(--kx-text-muted); overflow-wrap: anywhere; }
.sp-schnell__knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kx-2);
    min-height: 2.75rem;
    padding: 0.5rem 1.4rem;
    border: 1px solid var(--kx-green);
    border-radius: var(--kx-radius-pill);
    background: var(--kx-green);
    color: var(--kx-auf-gruen);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}
.sp-schnell__knopf:hover { background: var(--kx-marke-dunkel); border-color: var(--kx-marke-dunkel); }
.sp-schnell__knopf--hell { background: #fff; color: var(--kx-gruen-text); }
.sp-schnell__knopf--hell:hover { background: var(--kx-marke-hauch); border-color: var(--kx-green); }
.sp-schnell__knopf--gross { min-height: 3rem; padding: 0.7rem 1.8rem; font-size: var(--kx-fs-md); }
.sp-schnell__ergebnis { margin-top: var(--kx-5); scroll-margin-top: var(--kx-5); outline: none; }
.sp-schnell__ergebnis > .alert { margin-bottom: 0; }
.sp-schnell__ergebnis > .sp-schnell__vorschau:first-child { margin-top: 0; }
.sp-schnell__vorschau { margin-top: var(--kx-6); padding-top: var(--kx-5); border-top: 1px solid var(--kx-line); }
.sp-schnell__vorschau-titel { font-size: var(--kx-fs-lg); color: var(--kx-dark); }
.sp-schnell__stand { margin-bottom: var(--kx-3); }
.sp-schnell__summe { display: block; margin-top: var(--kx-1); font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-schnell__summe a { color: var(--kx-marke-text); }
.sp-schnell__korb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--kx-2) var(--kx-4); margin-bottom: var(--kx-4); }
.sp-schnell__korb-hinweis { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-schnell__liste {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--kx-line);
    border-radius: var(--kx-radius-lg);
    overflow: hidden;
}
.sp-schnell__posten {
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr) auto auto;
    gap: var(--kx-3);
    align-items: center;
    padding: var(--kx-3) var(--kx-4);
    background: #fff;
}
.sp-schnell__posten + .sp-schnell__posten { border-top: 1px solid var(--kx-line); }
.sp-schnell__posten--offen { display: block; background: #fffbeb; }
.sp-schnell__bild { width: 48px; height: 48px; object-fit: contain; border-radius: var(--kx-radius-sm); background: #fff; }
.sp-schnell__bild--leer { border: 1px solid var(--kx-line); background: var(--kx-bg-soft); }
.sp-schnell__posten > .sp-schnell__text { display: flex; flex-direction: column; min-width: 0; }
.sp-schnell__posten--offen .sp-schnell__text { display: flex; flex-direction: column; gap: 0.15rem; }
.sp-schnell__name { overflow-wrap: anywhere; font-weight: 600; color: var(--kx-text); }
a.sp-schnell__name:hover { color: var(--kx-marke-text); }
.sp-schnell__nr { font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
.sp-schnell__warn { font-size: var(--kx-fs-sm); color: #92400e; }
.sp-schnell__menge-anzeige { text-align: right; white-space: nowrap; font-size: var(--kx-fs-sm); color: var(--kx-text-muted); }
/* ST8b: die Menge ist ein Feld der Vorschau (der Server schreibt sie in den Text). */
.sp-schnell__menge-anzeige { display: flex; flex-direction: column; align-items: flex-end; gap: 0.2rem; }
.sp-schnell__menge-label { font-weight: 600; color: var(--kx-ink-soft); }
.sp-schnell__menge-feld { width: 5rem; min-height: 44px; }
.sp-schnell__mengenhinweis { margin: 0 0 var(--kx-3); }
.sp-schnell__preis { display: block; font-weight: 600; color: var(--kx-text); }
.sp-schnell__status { display: inline-flex; align-items: center; gap: var(--kx-1); font-size: var(--kx-fs-sm); font-weight: 600; color: var(--kx-gruen-text); white-space: nowrap; }
.sp-schnell__grund { display: block; margin-top: var(--kx-1); color: #92400e; }
.sp-schnell__meinten { margin-top: var(--kx-2); font-size: var(--kx-fs-sm); font-weight: 600; color: var(--kx-ink-soft); }
.sp-schnell__vorschlaege { margin: var(--kx-1) 0 0; padding: 0; list-style: none; display: grid; gap: var(--kx-2); }
.sp-schnell__vorschlag {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    width: 100%;
    min-height: 2.75rem;
    padding: var(--kx-2) var(--kx-3);
    border: 1px solid var(--kx-line-strong);
    border-radius: var(--kx-radius-md);
    background: #fff;
    color: var(--kx-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.sp-schnell__vorschlag:hover { border-color: var(--kx-green); background: var(--kx-marke-hauch); }
.sp-schnell__vorschlag-name { font-weight: 600; overflow-wrap: anywhere; }
@media (max-width: 40rem) {
    .sp-schnell__neu { grid-template-columns: 1fr 6rem; }
    .sp-schnell__neu .sp-schnell__knopf { grid-column: 1 / -1; }
    .sp-schnell__aktionen .sp-schnell__knopf,
    .sp-schnell__korb .sp-schnell__knopf { width: 100%; }
    .sp-schnell__posten { grid-template-columns: 48px minmax(0, 1fr); row-gap: var(--kx-2); }
    .sp-schnell__menge-anzeige { grid-column: 2; text-align: left; align-items: flex-start; }
    .sp-schnell__status { grid-column: 2; }
}
