/* ============================================================
   MMD Konfigurator (Beta) — /konfigurator
   Eigenständiges helles Tool-Theme (Referenz: Prototyp konfigurator-wl.html):
   DM Sans + IBM Plex Mono, #f0eeec/#111, Akzentblau #1d6bff,
   Beta-Badge Neongrün. Bewusst getrennt von app.css (dunkle Website).
   ============================================================ */

@font-face {
  font-family: "DM Sans"; font-style: normal; font-weight: 300; font-display: swap;
  src: url("../fonts/dm-sans-v17-latin_latin-ext-300.woff2") format("woff2");
}
@font-face {
  font-family: "DM Sans"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/dm-sans-v17-latin_latin-ext-regular.woff2") format("woff2");
}
@font-face {
  font-family: "DM Sans"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/dm-sans-v17-latin_latin-ext-500.woff2") format("woff2");
}
@font-face {
  font-family: "DM Sans"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/dm-sans-v17-latin_latin-ext-600.woff2") format("woff2");
}
@font-face {
  font-family: "DM Sans"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../fonts/dm-sans-v17-latin_latin-ext-700.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/ibm-plex-mono-v20-latin_latin-ext-regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/ibm-plex-mono-v20-latin_latin-ext-500.woff2") format("woff2");
}
/* Design-Schriften (OFL, lokal gehostet — nie CDN) für Text-Elemente */
@font-face { font-family: "Anton"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/anton-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Archivo"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/archivo-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Amatic SC"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/amatic-sc-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Bangers"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/bangers-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Bebas Neue"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/bebas-neue-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Caveat"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/caveat-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Oswald"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/oswald-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Pacifico"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/pacifico-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Permanent Marker"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/permanent-marker-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Playfair Display"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/playfair-display-v1-latin-regular.woff2") format("woff2"); }
/* Vorlagen-Schriften (Julian, 04.09.2026, Figma-Vorlage Social Club): Archivo Black ist
   eine eigene Familie (nicht der fette Archivo-Schnitt); Bodoni Moda ersetzt die Apple-
   Systemschrift Bodoni 72 aus Figma — die dürfen wir nicht ausliefern, Bodoni Moda ist
   die OFL-Schwester auf Google Fonts. Nur der kursive Schnitt, so wie die Vorlage. */
@font-face { font-family: "Archivo Black"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/archivo-black-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Bodoni Moda"; font-style: italic; font-weight: 400; font-display: swap; src: url("../fonts/bodoni-moda-v1-latin-italic.woff2") format("woff2"); }
/* Vorlagen-Schriften (Lieferung 04.09.2026, s. konfigurator.php → vorlagen_schriften); laden erst, wenn ein Text sie nutzt */
@font-face { font-family: "Barriecito"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/barriecito-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Barrio"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/barrio-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Slackey"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/slackey-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Libre Franklin"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/libre-franklin-v1-latin-500.woff2") format("woff2"); }
@font-face { font-family: "Young Serif"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/young-serif-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Badeen Display"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/badeen-display-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Big Shoulders Inline Text"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/big-shoulders-inline-text-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Anton SC"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/anton-sc-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Nixie One"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/nixie-one-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Rammetto One"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/rammetto-one-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Playwrite US Trad"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/playwrite-us-trad-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Finger Paint"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/finger-paint-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Cormorant Garamond"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/cormorant-garamond-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Oooh Baby"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/oooh-baby-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Lilita One"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/lilita-one-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Annie Use Your Telescope"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/annie-use-your-telescope-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Ranchers"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/ranchers-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Londrina Outline"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/londrina-outline-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Anaheim"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/anaheim-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Libre Barcode 39 Text"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/libre-barcode-39-text-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Nunito Sans"; font-style: normal; font-weight: 900; font-display: swap; src: url("../fonts/nunito-sans-v1-latin-900.woff2") format("woff2"); }
@font-face { font-family: "Erica One"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/erica-one-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Dawning of a New Day"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/dawning-of-a-new-day-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "DotGothic16"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/dotgothic16-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Shrikhand"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/shrikhand-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Londrina Solid"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/londrina-solid-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Moo Lah Lah"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/moo-lah-lah-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Phudu"; font-style: normal; font-weight: 300; font-display: swap; src: url("../fonts/phudu-v1-latin-300.woff2") format("woff2"); }
@font-face { font-family: "Monofett"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/monofett-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Yellowtail"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/yellowtail-v1-latin-regular.woff2") format("woff2"); }
/* Nachlieferung 28.09.2026 (Julian): „Ask my Boss" ist in Nanum Pen gesetzt.
   Google führt die Familie als „Nanum Pen Script", die Schriftdatei selbst nennt
   sich im Namensfeld „Nanum Pen" — so steht es auch in Figma und in Julians CSS,
   deshalb dieser Name. Auf den lateinischen Teil verkleinert (die volle Datei
   bringt den koreanischen Zeichensatz mit, 3,2 MB statt 33 kB). */
@font-face { font-family: "Nanum Pen"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/nanum-pen-script-v1-latin-regular.woff2") format("woff2"); }
/* Druckmotive mit bearbeitbarem Text (Julian, 15.10.2026): Google Fonts (OFL), lokal und nur
   lateinisch (42dot Sans 2,6 MB → 10 kB). Bodoni Moda Bold ersetzt Figmas Bodoni 72. */
@font-face { font-family: "Almarai"; font-style: normal; font-weight: 800; font-display: swap; src: url("../fonts/almarai-v1-latin-800.woff2") format("woff2"); }
@font-face { font-family: "Cherry Bomb One"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/cherry-bomb-one-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Freckle Face"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/freckle-face-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Sacramento"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/sacramento-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Bowlby One SC"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/bowlby-one-sc-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "42dot Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/42dot-sans-v1-latin-500.woff2") format("woff2"); }
@font-face { font-family: "Alfa Slab One"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/alfa-slab-one-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Bodoni Moda Bold"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/bodoni-moda-v1-latin-700.woff2") format("woff2"); }
@font-face { font-family: "Amatica SC"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/amatica-sc-v1-latin-700.woff2") format("woff2"); }
/* Lieferung 2 (Julian, 16.10.2026): Google Fonts (OFL), lokal und nur lateinisch; 42dot Sans 700/800
   als eigene Familien, damit Vorschau und Druck denselben Schnitt nehmen statt künstlich zu fetten. */
@font-face { font-family: "Beth Ellen"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/beth-ellen-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Sedgwick Ave Display"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/sedgwick-ave-display-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Chewy"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/chewy-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "Waiting for the Sunrise"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/waiting-for-the-sunrise-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "42dot Sans Regular"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/42dot-sans-v1-latin-regular.woff2") format("woff2"); }
@font-face { font-family: "42dot Sans Bold"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/42dot-sans-v1-latin-700.woff2") format("woff2"); }
@font-face { font-family: "42dot Sans ExtraBold"; font-style: normal; font-weight: 800; font-display: swap; src: url("../fonts/42dot-sans-v1-latin-800.woff2") format("woff2"); }

:root {
  --kf-bg: #f0eeec;
  --kf-panel: rgba(245, 245, 243, 0.98);
  --kf-ink: #111111;
  --kf-mid: #888888;
  /* Grund unter jedem Produktbild in einer Kachel (Farbauswahl, Board-Blanks,
     Formen). Bis 27.08.2026 war das #f1f0ed — auf dem verschwanden Off White
     und Arctic White praktisch vollständig (Julian: „die sieht man auf diesem
     grauen Hintergrund leider nicht"). Getestet wurden vier Abstufungen gegen
     die echten Produktfotos; #e3dfd8 ist der dunkelste Wert, der die weißen
     Teile klar zeigt, ohne dass die Kachel beige und schwer wirkt — und er
     bleibt in der Farbfamilie von --kf-bg. Schwarz, Oliv und Gelb verlieren
     dabei nichts. */
  --kf-kachel: #e3dfd8;
  /* Grund unter einem freigestellten DESIGN (Logo-Kacheln, Bibliothek). Anders
     als bei Produktfotos hilft hier kein einzelner Ton: ein weißes Logo
     braucht dunkel, ein schwarzes hell — und beides kommt vor. Deshalb ein
     Schachbrett in warmen Tönen (Julian, 27.08.2026: „wenn da ein weißes Logo
     ist, müssen wir auch einen anderen Hintergrund, irgendwie so ein beige,
     nehmen … und nicht einfach nur weiß auf weiß"). Es sagt zugleich, dass die
     Datei transparent ist. Der dunklere Ton ist so gewählt, dass Weiß als Form
     erkennbar bleibt, ohne dass die Kachel schmutzig wirkt. */
  --kf-transparenz: repeating-conic-gradient(#cdc4b5 0% 25%, #f4f1ea 0% 50%) 50% / 14px 14px;
  --kf-border: rgba(0, 0, 0, 0.1);
  --kf-border-strong: rgba(0, 0, 0, 0.14);
  --kf-akzent: #1d6bff;
  --kf-akzent-dunkel: #1558d6;
  --kf-neon: #c8ff00;
  --kf-fehler: #d23737;
  --kf-warn: #b57b1f;
  --kf-gruen: #2f9e5f;
  --kf-buehne: #d8d4cd;
  --kf-zoom-chip: #e9e4d9;
  --kf-header-h: 60px;
  --kf-tabs-h: 46px;

  /* ── Meldungs-System (Julian, 03.08.2026) ──────────────────────────────
     EIN Look für alle Hinweise, damit der Konfigurator „aus einem Guss"
     wirkt. Zwei Oberflächen, streng nach Funktion gewählt:

       • TOOLTIP  = dunkle Pille. Flüchtiger Hover-/Fokus-Hinweis, kurz.
                    (Ausverkauft, Veredelungs-Sperre, Design-Icon-Label …)
       • KARTE    = helle Fläche. Erklärung oder Entscheidung, bleibt stehen.
                    (Beta-Hinweis, „Was ist der HSP?", Lösch-Dialog …)

     Gemeinsame Sprache beider: Schrift DM Sans (Fließtext) / IBM Plex Mono
     (Meta-Label), Radien 8px (Pille) · 12px (Karte), weiche Schatten,
     dezente Motion. Farben strikt aus den Tokens — nie ad-hoc #fff/#fdfdfc. */
  --kf-tip-bg: var(--kf-ink);              /* Tooltip-Fläche */
  --kf-tip-fg: #f5f5f3;                    /* gebrochenes Weiß, nie #fff (DNA) */
  --kf-tip-radius: 8px;
  --kf-tip-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
  --kf-tip-pad: 7px 10px;
  --kf-tip-size: 11.5px;
  --kf-tip-max: 220px;

  --kf-karte-bg: #fdfdfc;                  /* helle Karten-/Popover-Fläche */
  --kf-karte-border: 1px solid var(--kf-border);
  --kf-karte-radius: 12px;
  --kf-karte-shadow: 0 14px 34px rgba(0, 0, 0, 0.13);
  --kf-karte-size: 12.5px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; height: 100%; }
/* Seit 04.09.2026 scrollt die SEITE wieder (Julian: unter dem Konfigurator
   liegt ein Inhaltsbereich, siehe partials/konfi-unten). Der Konfigurator
   selbst bleibt ein fester App-Rahmen in Viewport-Höhe — das ist .kf-app:
   Nav + Schritt-Leiste + Bühne/Panel füllen exakt 100svh, nur das rechte
   Panel scrollt intern. Wer weiterscrollt, verlässt den Rahmen nach unten. */
body {
  background: var(--kf-bg); color: var(--kf-ink);
  font-family: "DM Sans", sans-serif; font-weight: 300;
  font-size: 15px; line-height: 1.5;
  min-height: 100vh; min-height: 100svh;
}
.kf-app {
  height: 100vh; height: 100svh;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.mono { font-family: "DM Sans", sans-serif; }
img { max-width: 100%; }
button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; }

/* ── Header ─────────────────────────────────────────────── */
.kf-header {
  position: relative; flex: none; z-index: 50; height: var(--kf-header-h);
  display: flex; align-items: center; gap: 12px; padding: 0 20px;
  background: var(--kf-panel); border-bottom: 1px solid var(--kf-border);
}
/* Logo mittig im Header (Julian, 31.07.2026) — absolut zentriert */
.kf-logo {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; z-index: 2;
}
.kf-logo img { height: 26px; width: auto; filter: invert(1); } /* weißes Logo → dunkel auf hellem Grund */
/* Das Beta-Badge links neben dem Burger (.kf-beta / .kf-beta-wrap) ist zum
   Go-live entfallen (Julian, 27.08.2026) — samt Regeln, damit hier kein
   Stilrest für ein Bauteil steht, das es nicht mehr gibt. */

/* ── Tabs ───────────────────────────────────────────────── */
.kf-tabs {
  flex: none; z-index: 49; height: var(--kf-tabs-h);
  /* relative wegen des Projekt-Eintrags, der links am Rand klebt (s.u.) */
  position: relative;
  display: flex; justify-content: center; gap: 4px; padding: 0 12px;
  background: var(--kf-panel); border-bottom: 1px solid var(--kf-border);
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.kf-tabs::-webkit-scrollbar { display: none; }
/* Seit dem 30.09.2026 trägt die Leiste `hidden` — sie hält nur noch das
   Gerüst für konfi-modi.js. display:flex oben schlüge das Attribut sonst. */
.kf-tabs[hidden] { display: none; }
/* height:auto + align-self:center: der Unterstrich sitzt direkt unter dem
   Text, nicht am Boden der 46-px-Leiste (Julian, 23.09.2026: „überall"). */
.kf-tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: 6px 14px; height: auto; align-self: center; white-space: nowrap;
  font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.45); transition: color 0.2s, border-color 0.2s;
}
.kf-tab.active { color: var(--kf-ink); border-bottom-color: rgba(17, 17, 17, 0.7); }

/* Der Weg mit Linie und Punkten (29.09.2026) hat genau einen Tag gelebt: am
   30.09.2026 sind die Schritte ganz entfallen. Was ihn ersetzt, steht unten
   unter „Eine Spalte". */

/* ── Eine Spalte statt vier Schritte (30.09.2026) ────────────────────────
   Julian: „mach alles untereinander. Links das Bild bleibt gleich und man
   scrollt sich nach unten durch." Die Abschnitte tragen Überschriften statt
   Reitern — sie sind die Gliederung, die vorher die Leiste war. */
.kf-spalte { display: flex; flex-direction: column; }
.kf-abschnitt { padding: 0 0 26px; }
.kf-abschnitt + .kf-abschnitt { border-top: 1px solid var(--kf-border); padding-top: 22px; }
.kf-abschnitt-titel {
  margin: 0 0 14px; font-size: 13px; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.5);
}

/* Der Abschluss klebt am Fuß des Panels: wer oben die Menge ändert, soll
   sehen, was das kostet, ohne zu scrollen. Vorher standen Preis, Lieferzeit
   und Menge an drei Stellen verteilt in drei Schritten. */
/* Seit 12.10.2026 (Julian, Bild 39: „der graue Background darf unten
   rechts/links nicht noch hinter der Pille sein, also nur über der Pille und
   nach oben raus nicht als Verlauf, sondern als cleaner Cut mit Schattierung,
   damit man sieht, dass es davor liegt"): die Leiste selbst hat den Grund der
   Seite (weiß, deckt den durchlaufenden Inhalt), das Grau trägt nur noch der
   Streifen mit den Zahlen über dem Knopf; oben eine klare Kante mit Schatten
   statt des Auslaufs vom 02.10.2026. */
.kf-abschluss {
  /* bottom -2px: deckt den 2-px-Rand des Panels (padding 2px 0), durch den
     sonst Inhalt unter dem Knopf durchblitzte */
  position: sticky; bottom: -2px; z-index: 8;
  margin-top: auto; padding: 0 0 6px;
  background: #fff;
  box-shadow: 0 -10px 18px -12px rgba(17, 17, 17, .22);
}
/* Das Grau läuft bis zur Mitte des Knopfs dahinter (Abnahme 12.10.2026: „dann
   sieht es gut an den Button geknüpft aus") — als Fläche am Knopf selbst, damit
   es bei jeder Knopfhöhe (44/48 px je nach Fenster) genau die Hälfte ist. Sie
   liegt im Stapel der Leiste (sticky, z-index) hinter dem Knopf; Hover und
   gesperrt deshalb über die Farbe statt opacity — opacity hätte den Knopf zum
   eigenen Stapel gemacht und das Grau darübergelegt. */
.kf-abschluss .kf-btn-primary::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 50%;
  background: var(--kf-bg); z-index: -1; pointer-events: none;
}
.kf-abschluss .kf-btn-primary:hover { opacity: 1; background: #2b2b2b; }
.kf-abschluss .kf-btn-primary:disabled { opacity: 1; background: #a8a8a6; }
/* Die Zeile trug fuenf verschiedene Schriftgroessen und -staerken auf einmal:
   Lieferzeit fett, Beschriftungen in Versalien, Werte gross-fett — und keine
   gemeinsame Grundlinie. Julian, 01.10.2026: „das Feld ist noch nicht sauber,
   das kleiner und dadurch sauberer setzen, da musst du glaube ich auch Rules
   fuer einfuehren."

   Die Regeln, nach denen sie jetzt gesetzt ist:
     1. EINE Grundlinie fuer alles (align-items: baseline)
     2. ZWEI Stufen, nicht fuenf: Beschriftung 10 px grau in Versalien,
        Wert 12 px schwarz fett. Auch die Lieferzeit haelt sich daran.
     3. Gruppen werden durch einen Strich getrennt, nicht durch Abstand nach
        Gefuehl — Abstand allein liest sich bei drei Werten als Zufall.
     4. Nichts bricht um; wird es eng, weicht die Lieferzeit (sie steht auch
        im Korb), nicht der Preis. */
/*   5. Die Zeile liegt in einer gefüllten Leiste, also braucht sie Seitenluft
        (Julian, 02.10.2026: „die Schrift ist viel zu weit am Rand, das sieht
        man doch"). In der offenen Spalte darüber steht Text bündig an der
        Kante und das ist richtig; in einem Streifen mit eigenem Grund klebt
        er. Der Knopf darunter bleibt bewusst randlos — er IST die Fläche. */
.kf-abschluss-zahlen {
  display: flex; align-items: baseline; justify-content: center;
  gap: 0; margin-bottom: 0; min-width: 0; padding: 11px 14px;   /* bündig am Knopf (Abnahme 12.10.2026) */
  font-size: 11.5px; color: var(--kf-mid);
  background: var(--kf-bg); border-top: 1px solid var(--kf-border);
}
.kf-abschluss-liefer {
  display: inline-flex; align-items: baseline; gap: 6px; min-width: 0;
  white-space: nowrap;
}
/* Ein Flex-Kasten kann kein text-overflow — die Kuerzung gehoert an den Wert
   darin, sonst wird mitten im Wort abgeschnitten, ohne dass man es sieht. */
.kf-abschluss-liefer strong { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.kf-abschluss-liefer svg { align-self: center; flex: none; width: 13px; height: 13px; opacity: .55; }
.kf-abschluss-liefer strong { color: var(--kf-ink); font-weight: 600; font-size: 11.5px; }
.kf-abschluss-summe { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; flex: none; }
/* Regel 3, konsequent: DERSELBE Strich vor jeder weiteren Gruppe — vorher
   stand er nur zwischen Stueckzahl und Preis, nicht vor der Stueckzahl
   (Julian, 02.10.2026). */
.kf-abschluss-summe::before {
  content: ''; display: inline-block; width: 1px; height: 10px;
  /* rechts 6 + die 6 px Flex-Lücke der Gruppe = 12, wie links */
  margin: 0 6px 0 12px; background: var(--kf-border); vertical-align: -1px;
}
.kf-abschluss-summe .mono { font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--kf-mid); }
.kf-abschluss-summe strong { color: var(--kf-ink); font-size: 12.5px; font-weight: 700; margin-right: 0; }
/* Das Info-„i" ist dasselbe Bauteil wie ueberall (.kf-info-i), in der engen
   Leiste nur kleiner gesetzt. */
.kf-abschluss-i { width: 16px; height: 16px; align-self: center; margin-left: 2px; }
.kf-abschluss-i .i-info { width: 12px; height: 12px; }
/* Regel 3: der Strich zwischen Stueckzahl und Preis — mit genau demselben
   Abstand wie der vor der Stueckzahl (Julian, 08.10.2026: „alle gleich viel
   Abstand"). Vorher verteilte space-between den Rest der Breite vor den Zahlen. */
.kf-abschluss-summe strong + .mono::before {
  content: ''; display: inline-block; width: 1px; height: 10px;
  /* links 6 + die 6 px Flex-Lücke davor = 12, wie rechts */
  margin: 0 12px 0 6px; background: var(--kf-border); vertical-align: -1px;
}
/* Handy: der Platz reicht sonst nicht für „ca. 5–7 Werktage" — Symbol weg,
   beide Striche gleichmäßig 8 | 8 (statt 12 | 12). */
@media (max-width: 480px) {
  .kf-abschluss-liefer svg { display: none; }
  .kf-abschluss-zahlen { padding: 0 8px; }
  .kf-abschluss-summe::before { margin: 0 2px 0 8px; }
  .kf-abschluss-summe strong + .mono::before { margin: 0 8px 0 2px; }
}
/* Mobil-Runde 2 (Julian, 16.10.2026: „ca. 2–3 Werktage, Stückzahl und Preis pro Stück …
   sehr klein"): zwei Zeilen statt einer gequetschten — oben die Lieferzeit, darunter
   Stückzahl und Preis, lesbar groß. */
@media (max-width: 480px) {
  .kf-abschluss-zahlen { flex-wrap: wrap; row-gap: 3px; padding: 10px 12px 11px; }
  .kf-abschluss-liefer { width: 100%; justify-content: center; }
  .kf-abschluss-liefer strong { font-size: 13.5px; }
  .kf-abschluss-summe::before { display: none; }
  .kf-abschluss-summe { gap: 7px; }
  .kf-abschluss-summe .mono { font-size: 11px; }
  .kf-abschluss-summe strong { font-size: 15px; }
  .kf-abschluss-summe strong + .mono::before { height: 12px; margin: 0 10px 0 3px; }   /* 7 px Lücke + 3 = 10 | 10 */
  .kf-abschluss-i { width: 22px; height: 22px; }
  .kf-abschluss-i .i-info { width: 14px; height: 14px; }
}

/* Das Panel ist jetzt eine Spalte mit klebendem Fuß — dafür braucht es die
   volle Höhe, sonst klebt nichts. */
.kf-panel { display: flex; flex-direction: column; }

/* ── Arbeitsweise: der erste Tab selbst ──────────────────────────────────
   Drei Stufen kamen hierher: eigener Streifen unter der Leiste (klar, kostete
   eine Zeile Höhe — Julian, 24.08.2026), dann „Konfiguration" + Modus-Chip
   (doppelte Beschriftung für eine Sache), jetzt heißt der Tab einfach so, wie
   man arbeitet (Julian, 25.08.2026). Der Name trägt die normale Tab-Typografie
   — der Tab reiht sich damit optisch bei „Veredelung & Größen" ein; nur das
   Chevron verrät, dass hier gewählt wird. */
.kf-tab-wrap { position: relative; display: flex; }
.kf-tab-modus { display: inline-flex; align-items: center; gap: 6px; }
.kf-tab-chev { flex: none; opacity: 0.4; transition: transform 0.18s ease, opacity 0.2s ease; }
.kf-tab-modus:hover .kf-tab-chev,
.kf-tab-modus.active .kf-tab-chev { opacity: 0.7; }
.kf-tab-modus[aria-expanded="true"] .kf-tab-chev { transform: rotate(180deg); opacity: 1; }

.kf-tab-trenner {
  flex: none; align-self: center; width: 1px; height: 16px;
  background: var(--kf-border); margin: 0 6px;
}
/* Ab genug Breite klebt „Projekt" am linken Rand und die vier Schritte bleiben
   mittig (Julian, 25.08.2026: „Projekt muss ganz links in der Zeile sein").
   Zentriert mitlaufend saß es irgendwo in der Mitte und las sich wie ein
   fünfter Schritt. Die Trennlinie entfällt dann — zwischen Rand und Mitte liegt
   ohnehin Luft. Darunter läuft alles wieder in einer Reihe (die Leiste scrollt
   dort waagerecht; absolut positioniert würde der Eintrag über die Schritte
   rutschen, sobald man scrollt). */
/* Schwelle gemessen, nicht geschätzt: bei 821 px füllen die vier Schritte die
   Leiste schon komplett aus, die Zentrierung fällt auf den linken Rand zurück —
   und der absolut gesetzte Projekt-Eintrag lag genau über „Gestalten". Ab
   1040 px bleibt links garantiert Luft. */
@media (min-width: 1040px) {

  .kf-tab-trenner { display: none; }
}
/* Der Warenkorb in der Kopfzeile ist IM Konfigurator doppelt: der Tab „Anfrage"
   trägt denselben Zähler und führt an dieselbe Stelle, und seit dem Projekt-Umbau
   ist der Korb ohnehin Teil des Projekts (Julian, 25.08.2026: „man nimmt den
   Warenkorb raus und packt Projekt rein"). Auf der Website bleibt er — dort ist
   er der einzige Weg dorthin. */
/* Eng auf den Warenkorb-Link (…?warenkorb=1): das breitere [href*="warenkorb"]
   traf auch das Anmelden-Symbol, dessen Rücksprung „weiter=/create/warenkorb"
   enthält — Gäste sahen auf der Warenkorbseite kein Anmelden (Prüfrunde 05.10.2026). */
.kf-page .nav-icon-btn[href*="?warenkorb=1"] { display: none; }

.kf-modus-pop {
  /* fixed statt absolute: das Popover liegt außerhalb der waagerecht
     scrollenden Tab-Leiste, konfi-modi.js setzt left/top unter den Chip. */
  position: fixed; z-index: 60; width: min(330px, calc(100vw - 24px));
  display: flex; flex-direction: column; gap: 2px; padding: 6px;
  background: #fff; border: 1.5px solid var(--kf-border); border-radius: 12px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.16);
}
.kf-modus-pop[hidden] { display: none; }
.kf-modus-pop-kopf {
  margin: 3px 4px 5px; font-size: 9px; letter-spacing: 0.16em;
  text-transform: uppercase; color: rgba(17, 17, 17, 0.38);
}
.kf-modus-opt {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 9px 10px; border: none; background: none; border-radius: 9px;
  cursor: pointer; text-align: left; text-transform: none; letter-spacing: 0;
  transition: background 0.15s ease;
}
.kf-modus-opt:hover { background: rgba(17, 17, 17, 0.045); }
.kf-modus-opt.active { background: rgba(29, 107, 255, 0.08); }
.kf-modus-opt > svg { flex: none; margin-top: 1px; opacity: 0.8; }
.kf-modus-opt.active > svg { opacity: 1; }
.kf-modus-opt-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kf-modus-opt-text strong {
  font-family: 'DM Sans', sans-serif; font-size: 13px; font-weight: 600;
  color: var(--kf-ink); letter-spacing: 0;
}
.kf-modus-opt.active .kf-modus-opt-text strong { color: var(--kf-akzent); }
.kf-modus-opt-text em {
  font-family: 'DM Sans', sans-serif; font-size: 11px; font-style: normal;
  line-height: 1.5; color: rgba(17, 17, 17, 0.5); letter-spacing: 0;
}
@media (max-width: 560px) {
  /* 92 px reichten für „Konfiguration" nicht (gemessen 99 px → „KONFI…").
     Die Reiter-Leiste scrollt waagerecht, der aktive Schritt darf also seinen
     Namen ausschreiben; die Kappung bleibt als Notbremse für lange
     Projekt-/Modusnamen (Julian, 10.09.2026). */
  .kf-tab-modus { max-width: 150px; }
  .kf-tab-modus-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .kf-tab-trenner { margin: 0 3px; }
}
/* Artikel-Zähler im Anfrage-Tab (ersetzt den Warenkorb im Header) */
.kf-tab-anzahl {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; padding: 0 4px; margin-left: 5px;
  background: var(--kf-akzent); color: #fff; font-size: 9.5px; font-weight: 600;
  border-radius: 8px; letter-spacing: 0; vertical-align: middle;
}
.kf-tab-anzahl[hidden] { display: none; }
/* Bestätigte Schritte behalten den Strich — auch wenn man den Bereich wechselt */
.kf-tab.fertig { border-bottom-color: rgba(17, 17, 17, 0.7); color: rgba(17, 17, 17, 0.6); }
.kf-tab.fertig.active { color: var(--kf-ink); }
/* Ausverkaufte Familie: Veredelung/Größen & Ausstattung sind gesperrt —
   ausgegraut, nicht klickbar, kein aktiver/fertig-Strich (Julian, 03.08.2026) */
/* Gesperrt heißt nicht stumm: der Tab bleibt hover- und klickbar, damit der
   globale Tooltip den Grund zeigen kann und ein Klick (Touch) ihn als Toast
   nachreicht. Der Wechsel selbst wird in konfigurator.js abgefangen. */
.kf-tab.gesperrt {
  color: rgba(17, 17, 17, 0.22); cursor: not-allowed;
  border-bottom-color: transparent;
}
.kf-tab.gesperrt:hover { color: rgba(17, 17, 17, 0.34); }

/* ── Layout: füllt den restlichen Viewport, kein Seiten-Scroll ── */
.kf-body {
  flex: 1; min-height: 0;
  /* Bühne (links) = 1fr, wächst mit dem Viewport; rechte Spalte gedeckelt, damit
     auf breiten Screens der Editier-Bereich breiter wird statt White Space. */
  display: grid; grid-template-columns: 1fr clamp(360px, 38%, 560px); gap: 0;
  max-width: 1840px; margin: 0 auto; width: 100%;
  padding: 16px 20px 18px;
  align-items: stretch;
  /* Generelle Regel: nichts darf horizontal aus der Fläche ragen und Scrollen erzwingen */
  overflow-x: clip;
  transition: grid-template-columns 0.32s cubic-bezier(0.22, 0.8, 0.3, 1); /* rutscht mit der Werkzeugleiste mit */
}
/* Design-Schritt: das Produkt nimmt sich mehr Platz (Leiste + große Bühne),
   die rechte Spalte (Produktauswahl etc.) rückt komprimiert nach rechts.
   Nur Desktop — mobil gilt das gestapelte Layout. */
@media (min-width: 921px) {
  body.kf-design-aktiv .kf-body { grid-template-columns: 1fr clamp(340px, 32%, 470px); }
}

/* ── Bühne (links): immer die große Produktansicht.
     Desktop: vertikale Thumb-Leiste links + Bühne füllt den Rest ── */
.kf-stage {
  min-height: 0; padding-right: 24px;
  display: flex; flex-direction: row; gap: 10px;
}
.kf-stage-wrap {
  position: relative; flex: 1; min-height: 0; min-width: 0;
  background: var(--kf-buehne); border-radius: 10px;
  overflow: hidden; touch-action: none;
}
.kf-stage-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; padding: 2.5%; user-select: none; -webkit-user-drag: none;
}
.kf-stage-img.cover { object-fit: cover; padding: 0; }
/* Modellfoto: ohne Polster und an der UNTERKANTE verankert (Julian, 29.09.2026).
   Die freigestellten Halbkörperaufnahmen enden genau dort, wo die Figur aus dem
   Bild läuft — sie sollen unten bündig an der Bühnenkante stehen und nicht
   mittig schweben. `object-position` greift auch dann, wenn die Bühne schmaler
   ist als das Bildverhältnis (Hochformat auf dem Handy). */
.kf-stage-img.kf-stage-modell { padding: 0; object-position: bottom; }
/* Nicht-blockierender Hinweis-Toast (z.B. Warnung bei geringer Druckauflösung) */
.kf-toast {
  position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 12px);
  z-index: 60; max-width: min(560px, calc(100vw - 32px));
  display: flex; align-items: flex-start; gap: 10px;
  background: var(--kf-ink); color: #fff; border-radius: 12px; padding: 12px 12px 12px 15px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.28); font-size: 12.5px; line-height: 1.5;
  opacity: 0; pointer-events: none; transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.22, 0.8, 0.3, 1);
}
.kf-toast.an { opacity: 1; pointer-events: auto; transform: translate(-50%, 0); }
.kf-toast-warn { border-left: 3px solid #f0a500; }
/* Gelungen: derselbe Neon-Akzent, den auch Bestätigungen im Konfigurator
   tragen — die Farbe sagt „hat geklappt", ohne ein zweites Grün einzuführen. */
.kf-toast-ok { border-left: 3px solid var(--kf-neon); }
.kf-toast-text { flex: 1 1 auto; }
.kf-toast-zu { flex: none; background: none; border: none; color: rgba(255, 255, 255, 0.8); font-size: 18px; line-height: 1; cursor: pointer; padding: 0 2px; }
.kf-toast-zu:hover { color: #fff; }
/* Handy: über der festen Abschluss-Leiste (Stückzahl, Preis, „Zum Warenkorb"),
   nicht darauf — der Hinweis verdeckte genau den Knopf, den man als Nächstes
   drückt (Prüfrunde 05.10.2026). Das × bekommt 44 px Tippfläche. */
@media (max-width: 820px) {
  .kf-toast { bottom: calc(132px + env(safe-area-inset-bottom, 0px)); }
  .kf-toast-zu { min-width: 44px; min-height: 44px; margin: -12px -8px -12px 0; }
}
/* Datei aufs Vorschaubild ziehen: klares „hier ablegen"-Overlay */
.kf-stage-wrap.kf-stage-drop::after {
  content: "Design hier ablegen"; position: absolute; inset: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center; text-align: center; padding: 16px;
  background: rgba(29, 107, 255, 0.08); border: 3px dashed var(--kf-akzent); border-radius: 10px;
  font-size: 15px; font-weight: 600; color: var(--kf-akzent); pointer-events: none;
}

/* Anfrage-Schritt: Artikel-Karte klickbar → Artikel NUR auswählen (blau
   umrandet) + links read-only anzeigen, ohne Bearbeitung (Julian, 06.08.2026). */
.kf-korb-klickbar { cursor: pointer; }
/* Ausgewählter Artikel (angeklickt) UND Artikel in Bearbeitung tragen denselben
   blauen Kasten (Julian, 10.08.2026: der in Bearbeitung nicht mehr mit Strich,
   sondern mit demselben Rahmen wie ein angeklickter Artikel). */
.kf-korb-item.kf-korb-gewaehlt,
.kf-korb-item.in-bearbeitung {
  /* Ring-Geometrie (Julian, 17./18.08.2026, mehrere Runden): Artikel zieht sich
     per Negativ-Margin nach außen, der 2px-Ring ist INSET auf der Artikelkante
     gezeichnet (Scrollfenster kann ihn so nie anschneiden). Bewusst 6px LUFT
     zur Kartenkante (Pull 14 statt volles 20er-Padding): ganz außen kollidierte
     der Ring mit Kartenrundung und Scrollbar — mit gleichmäßigem Abstand sitzt
     er sauber, egal wo der Artikel im Scrollfenster steht. */
  margin: 0 -14px; padding-left: 14px; padding-right: 14px;
  border-radius: 11px; border-bottom-color: transparent;   /* Listen-Trennstrich weg, wenn ausgewählt */
  box-shadow: inset 0 0 0 2px var(--kf-akzent);
}
/* REGEL (Julian, 18.08.2026): immer nur EIN blauer Ring gleichzeitig. Ist ein
   Artikel per Klick ausgewählt, verliert der „in Bearbeitung"-Artikel seinen
   Ring (nur die Optik — Layout/Margins bleiben, damit nichts springt). */
#kf-korb:has(.kf-korb-gewaehlt) .kf-korb-item.in-bearbeitung:not(.kf-korb-gewaehlt) {
  box-shadow: none;
  border-bottom-color: rgba(0, 0, 0, 0.06); /* Trennstrich wieder zeigen */
}
/* Oberster Artikel: Ring auch nach OBEN mit denselben 6px Luft zur Kartenkante
   hochziehen. Unten NICHT pullen — sonst schöbe sich der Ring in die Summenzeile. */
.kf-korb-item.kf-korb-gewaehlt:first-child,
.kf-korb-item.in-bearbeitung:first-child { margin-top: -14px; padding-top: 14px; }
@media (max-width: 920px) {
  /* Mobile .kf-card hat 12px/13px Padding — gleiche 6px Luft zur Kartenkante */
  .kf-korb-item.kf-korb-gewaehlt,
  .kf-korb-item.in-bearbeitung { margin: 0 -7px; padding-left: 7px; padding-right: 7px; }
  .kf-korb-item.kf-korb-gewaehlt:first-child,
  .kf-korb-item.in-bearbeitung:first-child { margin-top: -6px; padding-top: 6px; }
}

/* Read-only-Vorschau: deckt die Bühne ab und zeigt den ausgewählten Artikel
   groß (Produktfoto + Design-Komposit). Keine Werkzeuge, keine Seitenwahl. */
.kf-vorschau {
  position: absolute; inset: 0; z-index: 30;
  background: var(--kf-buehne); border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
}
.kf-vorschau[hidden] { display: none; }
/* Bild füllt die Bühne EXAKT wie #kf-stage-img (width/height 100% statt Eigengröße). */
.kf-vorschau-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: 2.5%; user-select: none; -webkit-user-drag: none; }
/* Pille + Thumbs 1:1 wie auf der Bühne (.kf-ansicht-pille / .kf-thumbs mit
   .kf-thumb + .kf-thumb-tag) — inkl. VORNE/HINTEN-Labels. */
.kf-vorschau-pille {
  position: absolute; left: 16px; bottom: 16px; z-index: 11;
  background: var(--kf-zoom-chip); border-radius: 999px; padding: 5px 12px;
  font-size: 9px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.7); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
  pointer-events: none; opacity: 1; transition: opacity 0.15s ease;
}
.kf-vorschau-thumbs {
  position: absolute; left: 16px; bottom: 16px; z-index: 12; display: flex; gap: 6px; align-items: flex-end;
  opacity: 0; transform: translateY(6px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.kf-vorschau:hover .kf-vorschau-thumbs { opacity: 1; transform: none; pointer-events: auto; }
.kf-vorschau:hover .kf-vorschau-pille { opacity: 0; }
/* Stift (oben links) + Vollbild (unten rechts) — gleiche .kf-view-btn-Optik wie
   auf der Bühne; erscheinen beim Hover übers Produkt. */
.kf-vorschau-edit { position: absolute; left: 16px; top: 16px; }
.kf-vorschau-full { position: absolute; right: 16px; bottom: 16px; cursor: pointer; }
/* „Artikel bearbeiten" steht dauerhaft (Julian, 09.09.2026) — sie ist der Weg
   zurück ins Design und darf nicht erst beim Hover erscheinen. Der Vollbild-Knopf
   bleibt ein Hover-Werkzeug. */
.kf-vorschau-edit { opacity: 1; }
.kf-vorschau-full { opacity: 0; transition: opacity 0.15s ease; }
.kf-vorschau:hover .kf-vorschau-full { opacity: 1; }
/* Vollbild: exakt wie die Bühne (gleiche Fläche, kein Radius) */
.kf-vorschau:fullscreen, .kf-vorschau:-webkit-full-screen { background: var(--kf-buehne); border-radius: 0; padding: 3vh 3vw; }
.kf-vorschau:fullscreen .kf-vorschau-edit, .kf-vorschau:-webkit-full-screen .kf-vorschau-edit,
.kf-vorschau:fullscreen .kf-vorschau-full, .kf-vorschau:-webkit-full-screen .kf-vorschau-full { opacity: 1; }

/* Zoom-Bühne: Bild + Druckzone + Logos zusammen skaliert/verschoben
   (translate VOR scale in der Transform-Liste heißt: die Verschiebung bleibt
   unskaliert, also 1:1 zur Maus/Touch-Bewegung — siehe wendeZoomAn() im JS) */
.kf-stage-canvas { position: absolute; inset: 0; transform-origin: center center; }
.kf-stage-wrap.kf-gezoomt .kf-stage-canvas { cursor: grab; }
.kf-stage-wrap.kf-gezoomt.kf-schwenkt .kf-stage-canvas { cursor: grabbing; }

.kf-logo-layer { position: absolute; inset: 0; }
.kf-logo-item {
  position: absolute; width: 30%; transform: translate(-50%, -50%);
  cursor: grab; border: 1.5px dashed transparent; border-radius: 2px;
}
.kf-logo-item:active { cursor: grabbing; }
.kf-logo-item img { display: block; width: 100%; height: auto; pointer-events: none; }
.kf-logo-item.ausgewaehlt { border-style: solid; border-color: var(--kf-akzent); }
/* Gestrichelter blauer Rahmen um NICHT ausgewählte Designs nur, wenn die
   Hilfslinien an sind — sind sie aus (und das Design nicht ausgewählt), ist gar
   kein Rahmen zu sehen (Julian, 04.08.2026). Ausgewählt = immer solider Rahmen. */
body.kf-hilfslinien-an .kf-logo-item:not(.ausgewaehlt) {
  border-color: rgba(29, 107, 255, 0.65);
}
/* Text-Elemente: Breite folgt dem Inhalt, Schriftgröße setzt das JS (relativ zum Bild) */
.kf-text-item { width: auto; }
.kf-text-inhalt {
  display: block; padding: 2px 6px; font-weight: 600; line-height: 1.15;
  /* Instagram-Stil: Text bricht an der Zonenbreite (max-width wird per JS in
     positioniereItem gesetzt) NUR an Leerzeichen auf mehrere Zeilen um — ganze
     Wörter bleiben immer zusammen (nie mitten im Wort trennen). \n aus manuellen
     Umbrüchen bleiben erhalten. Zentriert, damit umgebrochene Zeilen ruhig stehen. */
  white-space: pre-wrap; overflow-wrap: normal; word-break: normal; hyphens: none;
  text-align: center;
  user-select: none; -webkit-user-select: none;
}
.kf-text-item.editiert { cursor: text; }
.kf-text-item.editiert .kf-text-inhalt { user-select: text; -webkit-user-select: text; outline: none; min-width: 24px; }
/* Element-Griffe (Editor-Vorbild): weiße Eckpunkte skalieren, roter Kreis
   oben löscht, blaue Kreise drehen (unten links) & verschieben (unten
   rechts) — alle nur am AUSGEWÄHLTEN Element sichtbar */
.kf-eckpunkt {
  position: absolute; width: 11px; height: 11px; padding: 0;
  background: #fff; border: 1.5px solid var(--kf-akzent); border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25); touch-action: none;
  display: none;
}
.kf-eckpunkt[data-ecke="tl"] { left: -6px; top: -6px; cursor: nwse-resize; }
.kf-eckpunkt[data-ecke="tr"] { right: -6px; top: -6px; cursor: nesw-resize; }
.kf-eckpunkt[data-ecke="bl"] { left: -6px; bottom: -6px; cursor: nesw-resize; }
.kf-eckpunkt[data-ecke="br"] { right: -6px; bottom: -6px; cursor: nwse-resize; }
.kf-griff {
  position: absolute; width: 22px; height: 22px; padding: 0;
  border: none; border-radius: 50%; color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  display: none; align-items: center; justify-content: center;
  touch-action: none;
}
.kf-griff-loeschen { left: 50%; top: -30px; transform: translateX(-50%); background: var(--kf-fehler); cursor: pointer; }
.kf-griff-loeschen:hover { filter: brightness(1.12); }
.kf-griff-rotate { left: -12px; bottom: -30px; background: var(--kf-akzent); cursor: grab; }
.kf-griff-rotate:active { cursor: grabbing; }
.kf-griff-move { right: -12px; bottom: -30px; background: var(--kf-akzent); cursor: move; }
/* Trefferfläche auf 44 px, ohne den Kreis zu vergrößern (Mobil-Audit
   15.09.2026: 22×22 gemessen, das ist die Hälfte der Schwelle — und das sind
   die primären Fingerelemente auf dem Shirt). Größere Kreise würden das Design
   verdecken, deshalb ein unsichtbares Feld darum. Nur auf Touch, damit sich die
   Felder am Zeiger nicht gegenseitig überlagern. Muster wie .konto-pw-eye::after. */
@media (hover: none) and (pointer: coarse) {
  .kf-griff::before { content: ''; position: absolute; inset: -11px; border-radius: 50%; }
}
.kf-logo-item.ausgewaehlt .kf-eckpunkt { display: block; }
.kf-logo-item.ausgewaehlt .kf-griff { display: flex; }
.kf-logo-item.editiert .kf-eckpunkt,
.kf-logo-item.editiert .kf-griff { display: none; } /* beim Tippen nicht im Weg */
/* MEHRFACHAUSWAHL (04.09.2026): gewählte Elemente behalten den blauen Rahmen,
   ihre Einzel-Griffe weichen dem gemeinsamen Gruppenrahmen (.kf-gruppe) */
#kf-logo-layer.kf-mehrfach .kf-logo-item.ausgewaehlt .kf-eckpunkt,
#kf-logo-layer.kf-mehrfach .kf-logo-item.ausgewaehlt .kf-griff { display: none; }
.kf-gruppe {
  position: absolute; z-index: 30; box-sizing: border-box;
  border: 1.5px dashed var(--kf-akzent); border-radius: 3px;
  cursor: move; touch-action: none;
}
.kf-gruppe-ecke {
  position: absolute; width: 12px; height: 12px; padding: 0;
  background: #fff; border: 1.5px solid var(--kf-akzent); border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25); touch-action: none;
}
.kf-gruppe-ecke[data-ecke="tl"] { left: -7px; top: -7px; cursor: nwse-resize; }
.kf-gruppe-ecke[data-ecke="tr"] { right: -7px; top: -7px; cursor: nesw-resize; }
.kf-gruppe-ecke[data-ecke="bl"] { left: -7px; bottom: -7px; cursor: nesw-resize; }
.kf-gruppe-ecke[data-ecke="br"] { right: -7px; bottom: -7px; cursor: nwse-resize; }
/* Auswahlrahmen beim Ziehen über die Bühne */
.kf-lasso {
  position: absolute; z-index: 40; pointer-events: none;
  border: 1px solid var(--kf-akzent); background: rgba(29, 107, 255, 0.08); border-radius: 2px;
}
/* Kontextleiste: Anzahl + Ebenen-Menü */
.kf-ctx-anzahl { font-size: 10.5px; letter-spacing: 0.06em; color: var(--kf-mid); padding: 0 6px; white-space: nowrap; }
.kf-ctx-ebenen-wrap { position: relative; display: inline-flex; }
.kf-ctx-pop-ebenen { display: flex; flex-direction: column; min-width: 190px; padding: 6px; }
.kf-ebenen-aktion {
  display: block; width: 100%; text-align: left; background: none; border: none; border-radius: 8px;
  padding: 9px 10px; font-family: "DM Sans", sans-serif; font-size: 12.5px; font-weight: 500; color: var(--kf-ink); cursor: pointer;
}
.kf-ebenen-aktion:hover { background: rgba(0, 0, 0, 0.06); }
/* Spiegeln (06.10.2026): eingeschaltete Achse sichtbar, mit Haken davor */
.kf-ctx-spiegel-wrap { position: relative; display: inline-flex; }
.kf-ebenen-aktion[data-spiegel] { position: relative; padding-left: 28px; }
.kf-ebenen-aktion[data-spiegel].aktiv { font-weight: 700; }
.kf-ebenen-aktion[data-spiegel].aktiv::before {
  content: ""; position: absolute; left: 11px; top: 50%; width: 8px; height: 4px; margin-top: -4px;
  border-left: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg);
}
.kf-ebenen-aktion--liste { margin-top: 4px; border-top: 1px solid var(--kf-border); border-radius: 0 0 8px 8px; padding-top: 11px; color: var(--kf-akzent); }
/* Druckbereich: gestrichelte Orientierung, solange ein Element gewählt ist.
   mix-blend-mode: difference macht den Rahmen auf JEDER Produktfarbe sichtbar
   (auf Schwarz erscheint er weiß, auf Weiß schwarz — ein fester Grauton wäre
   auf dunklen Shirts unsichtbar) */
.kf-druckzone {
  position: absolute; z-index: 1; pointer-events: none;
  border: 1.5px dashed rgba(255, 255, 255, 0.75); border-radius: 4px;
  mix-blend-mode: difference;
}
/* Ab Schritt 2 ist die Bühne reine Vorschau (so sieht das Produkt nach dem
   Druck aus): keine Rahmen/Griffe, kein Ziehen — bearbeitet wird nur in Design.
   !important bewusst: ".kf-logo-item.ausgewaehlt .kf-eckpunkt" (3 Klassen) ist
   sonst SPEZIFISCHER als dieses Schritt-Gate (2 Klassen) und würde gewinnen,
   wenn eine Auswahl aus Schritt 1 stehen bleibt — sichtbarer Bug: Griffe/
   Rahmen blieben nach dem Schrittwechsel sichtbar, bis ein Klick neu rendert
   (Julian, 31.07.2026). Zusätzlich wird die Auswahl beim Verlassen von
   Schritt 1 jetzt auch im JS aktiv geleert (setStep()), das hier ist die
   defensive zweite Absicherung. */
/* Hier standen bis zum 30.09.2026 die Regeln, die ab Schritt 2 die Buehne
   read-only machten: keine Rahmen, keine Eckpunkte, keine Griffe, keine
   Druckzone, keine Kontextleiste, keine Massanzeige. Sie hingen an
   body.kf-ab-schritt-2 - und die Klasse gibt es nicht mehr, seit rechts alles
   untereinander steht. Es gibt keinen Zeitpunkt mehr, ab dem das Gestalten
   vorbei ist; also bleibt die Buehne offen. */

/* Live-Maßanzeige (Breite/Höhe/HSP-Abstand) — JS setzt left/top/height per
   Inline-Style relativ zu bildRect(), genau wie #kf-druckzone. Container hat
   pointer-events:none (nichts soll die Bühne blockieren), nur der HSP-Info-
   Button braucht wieder pointer-events:auto. */
.kf-mass-anzeige { position: absolute; inset: 0; z-index: 13; pointer-events: none; }
/* Größe/Kontrast nach Julians Referenz-Screenshot (31.07.2026) — deutlich
   kräftiger als die anfängliche, kleine Variante. Breite-Label sitzt UNTER
   dem Design (nicht mehr darüber): darüber liegt der Löschen-Griff
   (.kf-griff-loeschen, -30px über dem Element) — das Label verdeckte ihn. */
/* Gleiche Font/Formsprache wie .kf-hsp-label (kein Mono-Font, DM Sans wie der
   Rest der Seite, gleicher font-weight/border-radius) — nur ca. halb so groß
   und schwarz statt Amber (Julian, 31.07.2026: "3.9cm"-Kasten war deutlich
   zu groß, soll aber sonst genauso aussehen wie das HSP-Label) */
.kf-mass-label {
  position: absolute; transform: translate(-50%, 0); margin-top: 8px;
  background: rgba(17, 17, 17, 0.9); color: #fff; white-space: nowrap;
  font-weight: 600; letter-spacing: 0.02em;
  font-size: 8px; padding: 2px 5px; border-radius: 4px;
}
.kf-mass-label[hidden] { display: none; }
/* Druckqualität zu niedrig (effektive dpi in aktueller Druckgröße unter der
   Warnschwelle, s. JS DRUCK_WARN_DPI): dezentes oranges Dreieck oben rechts am
   Design — Details erst per Tooltip (data-tip: Hover, auf Touch per Tap).
   Bewusst KEIN rotes Label/Toast mehr (Julian, 18.08.2026). */
.kf-dpi-warn {
  /* INNEN in der Design-Ecke (nicht auf der Kante): genau dort sitzen die
     Skalier-Eckpunkte — außen platziert verdeckte das Dreieck den tr-Griff. */
  position: absolute; top: 3px; right: 3px; z-index: 6;
  width: 15px; height: 15px; color: #f59e0b;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
  cursor: help; pointer-events: auto;
}
.kf-dpi-warn svg { display: block; width: 100%; height: 100%; }
/* Mitte-Magnet-Hilfslinien (Smart Guides): erscheinen nur, solange der Element-
   Mittelpunkt beim Verschieben auf der Zonen-Mitte eingerastet ist. Liegen im
   Zoom-Canvas (Bühne) bzw. in der Mockup-Box (Ausstattung) — JS setzt
   left/top/width/height inline. */
.kf-snap-linie { position: absolute; display: none; pointer-events: none; z-index: 5; }
.kf-snap-v { width: 0; border-left: 1.5px dashed var(--kf-akzent); }
.kf-snap-h { height: 0; border-top: 1.5px dashed var(--kf-akzent); }
/* Höhen-Label steht links vom Element — GLEICHE Pille wie das Breite-Label
   unten (Julian, 03.08.2026: das gedrehte vertical-rl-Label wirkte durch das
   Schreibrichtungs-Layout deutlich klobiger als das Breite-Label; beide sollen
   identisch aussehen). Also horizontaler Text, nur links statt unten platziert. */
.kf-mass-label-vertikal {
  transform: translate(-100%, -50%); margin-top: 0; margin-left: -8px;
}
/* HSP-"Dogleg": EIN Element, zwei Kanten als gestrichelte Linie (border-left
   = senkrechtes Stück ab dem HSP-Punkt, border-bottom = der Knick nach
   rechts zum Label) — mix-blend-mode:difference wie #kf-druckzone, bleibt
   dadurch auf JEDER Produktfarbe sichtbar. Das Label sitzt IMMER rechts
   neben dem Design (nie darüber/darauf, s. JS aktualisiereMassAnzeige()). */
.kf-hsp-linie {
  position: absolute; pointer-events: none;
  /* Senkrechte Linie an der RECHTEN Kante (= fester HSP-Anker am Kragen),
     Knick am UNTEREN Rand nach links zum Design (s. JS: die Box reicht von
     der Design-Kante bis zum festen Anker). Liegt das Design rechts vom
     Anker, dreht die JS die Box um und setzt .rechts — dann sitzt die
     senkrechte Linie stattdessen an der LINKEN Kante (Knick nach rechts). */
  border-right: 1.5px dashed rgba(255, 255, 255, 0.9);
  border-bottom: 1.5px dashed rgba(255, 255, 255, 0.9);
  mix-blend-mode: difference;
}
.kf-hsp-linie.rechts {
  border-right: none;
  border-left: 1.5px dashed rgba(255, 255, 255, 0.9);
}
/* Jetzt normales Flex-Kind INNERHALB von .kf-hsp-info-wrap (neben dem Icon,
   kein eigenes position:absolute mehr nötig) — s. Kommentar dort */
.kf-hsp-label {
  background: #f0b429; color: #111; font-size: 10.5px; font-weight: 600;
  white-space: nowrap; padding: 3px 8px; border-radius: 5px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}
/* Icon + Maßangabe als EIN Cluster (Julian, 31.07.2026: "HSP xx.x cm direkt
   neben das i"). Positioniert wird das ICON exakt auf den HSP-Punkt (die
   senkrechte Linie fällt genau darunter) — das Label läuft nach rechts weg.
   Deshalb nur um die halbe Icon-Breite (17px/2) nach links, NICHT um die halbe
   Cluster-Breite (das hätte das Icon links neben den Punkt geschoben). */
.kf-hsp-info-wrap {
  position: absolute; transform: translate(-8.5px, -50%);
  display: inline-flex; align-items: center; gap: 8px; pointer-events: auto;
}
.kf-hsp-info-wrap[hidden] { display: none; }
.kf-hsp-info-btn {
  width: 17px; height: 17px; flex: none; border-radius: 50%; border: none;
  background: #f0b429; color: #111; padding: 0; line-height: 0; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  display: inline-flex; align-items: center; justify-content: center;
}
/* Das Zeichen aus partials/i-info, aufrecht (Julian, 14.10.2026) */
.kf-hsp-info-btn .i-info { width: 15px; height: 15px; display: block; }
/* Öffnet nach UNTEN (nicht nach oben): der Info-Button sitzt oben am HSP-
   Punkt, meist nah am oberen Rand der Bühne — #kf-stage-wrap hat
   overflow:hidden, ein nach oben öffnendes Popover würde dort abgeschnitten
   (gleicher Bug wie zuvor beim Sample-Modal-Tooltip). */
.kf-hsp-info-pop {
  position: absolute; left: 8.5px; top: calc(100% + 9px); transform: translateX(-50%);
  z-index: 5; /* explizit über dem HSP-Label (Julian, 31.07.2026: Label lag teils vor dem Popover) */
  /* Karten-System (helle Erklärung am „i") — zentrale --kf-karte-*-Tokens */
  width: 240px; background: var(--kf-karte-bg); color: var(--kf-ink); border: var(--kf-karte-border);
  border-radius: var(--kf-karte-radius); padding: 12px 14px; font-size: var(--kf-karte-size); line-height: 1.5;
  box-shadow: var(--kf-karte-shadow);
  opacity: 0; visibility: hidden; transform: translateX(-50%) translateY(-4px); pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s 0.18s;
}
.kf-hsp-info-pop strong { display: block; margin-bottom: 4px; }
@media (hover: hover) {
  .kf-hsp-info-wrap:hover .kf-hsp-info-pop {
    opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); pointer-events: auto;
    transition-delay: 0s;
  }
}
.kf-hsp-info-wrap.offen .kf-hsp-info-pop {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); pointer-events: auto;
  transition-delay: 0s;
}
/* Ganz oben im Bild (y nah 0) reicht selbst "nach unten" kaum Platz vor der
   Werkzeugleiste — zusätzlich horizontal an den linken Rand klemmen statt
   zentriert, falls die Bühne schmal ist (kleine Fenster/Mobile) */
@media (max-width: 700px) {
  .kf-hsp-info-pop { left: auto; right: -8px; transform: translateY(-4px); width: min(240px, calc(100vw - 40px)); }
  .kf-hsp-info-wrap:hover .kf-hsp-info-pop,
  .kf-hsp-info-wrap.offen .kf-hsp-info-pop { transform: translateY(0); }
}

/* Info-„i" am Upload-Panel („Design hochladen") — GLEICHER Stil wie das
   Größen-i (.kf-info-i: dezenter grauer Kreis, keine Bühnen-Amber-Optik) und
   die Karte im .kf-info-tip-Look (helle --kf-karte-*-Tokens). Wichtig: die
   Karte sitzt IM .kf-tb-label und muss dessen uppercase/letter-spacing
   zurücksetzen, sonst schreit der Text in Großbuchstaben (Julian, 17.08.2026). */
.kf-tb-label-info { display: flex; align-items: center; gap: 7px; }
/* Credits im D.AI-Panel als Pille — „so in dem Stil wie das Projekt" (Julian,
   29.09.2026). Rechts in der Titelzeile; beim Zeigen klappt darunter auf, was
   ein Konto bringt und dass man später welche dazukaufen kann. */
.kf-dai-credits-wrap { position: relative; display: inline-flex; margin-left: auto; }
/* Die Credits tragen die bewegte Markenfarbe (Julian, 02.10.2026: „mach das
   auch in dem bewegten Farbton") — derselbe Verlauf wie der Generieren-Knopf
   und die MMD-Pille in der Navigation. Wird es knapp, gewinnt die Warnung:
   eine Zahl, die gleich alle ist, darf nicht hübsch aussehen. */
.kf-dai-credits {
  border: 0; border-radius: 999px; padding: 4px 11px;
  background: linear-gradient(90deg, #ff5fa2, #7c5cff, #ff5fa2);
  background-size: 220% 100%; color: #fff;
  animation: kf-ki-gen-fluss 14s ease-in-out infinite;
  text-transform: none; letter-spacing: 0;
  font-family: inherit; font-size: 11px; font-weight: 600; white-space: nowrap;
  cursor: help; transition: opacity 0.15s ease;
}
.kf-dai-credits:hover { opacity: .92; }
.kf-dai-credits--wenig { background: #c0392b; color: #fff; animation: none; }
@media (prefers-reduced-motion: reduce) { .kf-dai-credits { animation: none; } }
.kf-dai-credits-pop {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 70;
  width: min(250px, calc(100vw - 40px));
  background: var(--kf-karte-bg); border: var(--kf-karte-border); border-radius: var(--kf-karte-radius);
  box-shadow: var(--kf-karte-shadow); padding: 12px 14px;
  color: rgba(17, 17, 17, 0.75); font-size: var(--kf-karte-size); line-height: 1.55;
  font-weight: 400; letter-spacing: 0; text-transform: none; text-align: left;
  opacity: 0; visibility: hidden; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
}
.kf-dai-credits-pop strong { display: block; margin-bottom: 5px; color: var(--kf-ink); font-weight: 600; }
.kf-dai-credits-kaufen {
  display: block; width: 100%; margin-top: 10px; padding: 8px 12px;
  border: 1px solid var(--kf-border-strong); border-radius: 999px; background: none;
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--kf-ink);
}
.kf-dai-credits-kaufen:disabled { opacity: 0.45; cursor: not-allowed; }
.kf-dai-credits-bald { display: block; margin-top: 5px; text-align: center; font-size: 11px; color: var(--kf-mid); }
@media (hover: hover) {
  .kf-dai-credits-wrap:hover .kf-dai-credits-pop,
  .kf-dai-credits:focus-visible ~ .kf-dai-credits-pop {
    opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
    transition: opacity 0.2s ease, transform 0.2s ease;
  }
}
/* Ohne Zeigegerät (Touch) schaltet der Klick um — s. konfigurator.js */
.kf-dai-credits-wrap.offen .kf-dai-credits-pop {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

/* ── Stil, Farben, Format (Etappe B, Julian 29.09.2026) ──────────────────────
   Drei Reihen Chips zwischen Beschreibung und „Generieren". Sie sind bewusst
   klein und ruhig: die Beschreibung bleibt die Hauptsache, die Chips schärfen
   sie nur. */
.kf-ki-optionen { display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
/* Farben und Format je in eigener Zeile: nebeneinander brachen die Chips um
   („Quer" fiel in die zweite Reihe), und eine umbrechende Auswahl liest sich
   schlechter als eine längere Spalte. */
.kf-ki-opt-zwei { display: flex; flex-direction: column; gap: 12px; }
.kf-ki-opt-label {
  margin: 0 0 6px; font-family: 'DM Sans', sans-serif;
  font-size: 10px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--kf-mid);
}
.kf-ki-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.kf-ki-chip {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--kf-border); border-radius: 999px;
  background: #fff; padding: 5px 10px; cursor: pointer;
  font-family: 'DM Sans', sans-serif; font-size: 11.5px; font-weight: 500; color: var(--kf-ink);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.kf-ki-chip:hover { border-color: var(--kf-border-strong); background: #fbfbfa; }
.kf-ki-chip.aktiv { background: var(--kf-ink); border-color: var(--kf-ink); color: #fff; font-weight: 600; }
/* Das Format zeigt sein Seitenverhältnis als kleines Rechteck — schneller
   erfasst als das Wort daneben. */
.kf-ki-format-zeichen {
  display: block; height: 11px; border: 1.3px solid currentColor; border-radius: 2px; opacity: 0.7;
}

/* Warten mit D.AI: Kachel, Funke, Balken, Uhr — seit dem 05.10.2026 in dai-laden.css. */
.kf-upload-info-wrap { position: relative; display: inline-flex; }
.kf-info-i:hover, .kf-info-i:focus-visible { color: var(--kf-ink); }
.kf-upload-info-pop {
  position: absolute; left: 0; top: calc(100% + 8px); z-index: 70;
  width: min(270px, calc(100vw - 40px));
  background: var(--kf-karte-bg); border: var(--kf-karte-border); border-radius: var(--kf-karte-radius);
  box-shadow: var(--kf-karte-shadow); padding: 12px 14px;
  color: rgba(17, 17, 17, 0.75); font-size: var(--kf-karte-size); line-height: 1.55;
  font-weight: 400; letter-spacing: normal; text-transform: none; text-align: left;
  opacity: 0; visibility: hidden; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
}
.kf-upload-info-pop strong {
  display: block; margin-bottom: 6px; color: var(--kf-ink); font-weight: 600;
}
@media (hover: hover) {
  .kf-upload-info-wrap:hover .kf-upload-info-pop,
  #kf-upload-info-btn:focus-visible ~ .kf-upload-info-pop {
    opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
    transition-delay: 0s;
  }
}
.kf-upload-info-wrap.offen .kf-upload-info-pop {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
  transition-delay: 0s;
}
.kf-upload-info-liste { display: grid; gap: 7px; }
/* Die Rechte als letzter Absatz der Karte, abgesetzt: sie sind keine
   Datei-Empfehlung wie die vier darüber, sondern eine Zusage des Kunden. */
.kf-upload-info-rechte {
  display: block; margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--kf-border);
}
.kf-upload-info-rechte b { display: block; margin-bottom: 2px; font-weight: 600; color: var(--kf-ink); }
.kf-upload-info-liste b { font-weight: 600; color: var(--kf-ink); }
/* Das Upload-Panel scrollt nie (kompakter Inhalt) — overflow freigeben, damit
   das Info-Popover über den Panelrand hinaus aufgehen kann statt abgeschnitten
   im Scrollbereich zu hängen. Andere Panels behalten ihr overflow-y:auto. */
#kf-panel-upload { overflow: visible; }
/* Mobil sitzt das Flyout als Sheet mitten im Screen — am Label verankert würde
   das Popover oben UND rechts aus dem Viewport ragen (Audit 17.08.2026). Darum
   mobil als FIXES Overlay am unteren Bildschirmrand (das offene Flyout hat
   transform:none, fixed wirkt also echt viewportbezogen). */
@media (max-width: 920px) {
  .kf-upload-info-pop {
    /* bottom über dem Ansprechpartner-Widget (Avatar sitzt unten rechts) — 12px verdeckte
       dessen Ecke die letzte Kartenzeile (Audit 17.08.2026) */
    position: fixed; left: 12px; right: 12px; top: auto; bottom: 84px; width: auto;
    transform: translateY(6px);
  }
  .kf-upload-info-wrap:hover .kf-upload-info-pop,
  .kf-upload-info-wrap.offen .kf-upload-info-pop { transform: translateY(0); }
}

/* Kontext-Werkzeuge überm Produkt: weiße Pille, erscheint bei Auswahl */
/* ── STANDARD für schwebende Leisten ──────────────────────────────────────
   Julian, 25.08.2026: „diese Leiste als Standard nehmen, falls auch mal neue
   gebaut werden." Die Kontext-Leiste über einem ausgewählten Element ist die
   Vorlage — alles, was über der Bühne schwebt, trägt dieselben vier Werte:

     Grund   #fff (voll deckend, nicht durchscheinend)
     Kante   1.5px var(--kf-border)
     Radius  999px
     Schatten 0 6px 24px rgba(0,0,0,.13)

   Sie stehen als Token da, damit eine neue Leiste sie erbt statt sie zu
   erraten. NICHT betroffen: die Zoom-Pille und die Vollbild-Knöpfe — die
   tragen bewusst den warmen Beige-Chip (Julian, 24.08.2026: „das mit dem Zoom
   ist ok") und sind Bedienelemente, keine Leisten. */
:root {
  --kf-leiste-grund: #fff;
  --kf-leiste-kante: 1.5px solid var(--kf-border);
  --kf-leiste-schatten: 0 6px 24px rgba(0, 0, 0, 0.13);
}
.kf-leiste {
  background: var(--kf-leiste-grund);
  border: var(--kf-leiste-kante);
  border-radius: 999px;
  box-shadow: var(--kf-leiste-schatten);
}
.kf-ctx {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 14; display: flex; align-items: center; gap: 1px;
  background: var(--kf-leiste-grund); border: var(--kf-leiste-kante); border-radius: 999px;
  padding: 4px 9px; box-shadow: var(--kf-leiste-schatten);
  max-width: calc(100% - 16px); white-space: nowrap;
}
.kf-ctx[hidden] { display: none; }
.kf-ctx [hidden] { display: none !important; }
/* Steht die Leiste über dem Element, klappen ihre Fenster nach oben auf — wie auf
   dem Board (15.10.2026). Mobil bleiben es die Blätter von unten. */
@media (min-width: 821px) {
  .kf-ctx[data-pop-lage="oben"] .kf-ctx-pop { top: auto; bottom: calc(100% + 9px); }
}
/* Griff zum freien Verschieben der Leiste (Julian: "falls sie oben stört") */
.kf-ctx-griff {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 26px; margin-left: -3px; border-radius: 6px;
  color: var(--kf-ink); opacity: 0.4; cursor: grab; touch-action: none;
  transition: opacity 0.15s, background 0.15s;
}
.kf-ctx-griff:hover { opacity: 0.8; background: rgba(29, 107, 255, 0.07); }
.kf-ctx-griff:focus-visible { outline: 2px solid var(--kf-akzent); outline-offset: 1px; opacity: 0.8; }
.kf-ctx--zieht { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22); user-select: none; }
.kf-ctx--zieht .kf-ctx-griff, .kf-ctx-griff:active { cursor: grabbing; opacity: 0.85; }
.kf-ctx-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 28px; padding: 3px 9px;
  background: none; border: none; border-radius: 999px;
  font-size: 11.5px; font-weight: 500; color: var(--kf-ink);
  transition: background 0.15s, color 0.15s; flex: none;
}
.kf-ctx-btn:hover { background: rgba(29, 107, 255, 0.07); color: var(--kf-akzent); }
.kf-ctx-btn.active { background: rgba(29, 107, 255, 0.11); color: var(--kf-akzent); }
.kf-ctx-icon { width: 28px; padding: 3px 0; font-size: 12px; }
.kf-ctx-icon b { font-weight: 800; }
.kf-ctx-rot:hover { background: rgba(214, 64, 64, 0.08); color: var(--kf-fehler); }
/* Ein Knopf in der Kontext-Leiste, der nicht ein Werkzeug unter vielen ist,
   sondern der Weg weiter (Board: „Größen festlegen"). Gefüllt statt flach,
   damit er sich vom Rest der Leiste abhebt, ohne sie zu sprengen. */
.kf-ctx-stark { background: var(--kf-ink); color: var(--kf-bg); padding: 3px 12px; }
.kf-ctx-stark:hover { background: var(--kf-ink); color: var(--kf-bg); opacity: 0.86; }
.kf-ctx-sep { flex: none; width: 1px; height: 18px; background: var(--kf-border); margin: 0 5px; }
.kf-ctx-sep[hidden] { display: none; }
.kf-ctx-slider { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.kf-ctx-slider .mono {
  font-size: 8.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--kf-mid);
}
/* Gleicher schmaler Regler-Look wie der Zoom-Regler (Julian, 31.07.2026:
   "deutlich cleaner") — dünne Schiene, satter Kreis-Griff statt Browser-
   Default; Farbe bleibt das Akzentblau der Kontext-Pille, nicht das
   Beige-Schwarz der Zoom-Pille (andere Umgebung/anderer Kontrast). */
/* ════════════════════════════════════════════════════════════════════════
   EINE REGLER-REGEL (Julian, 02.10.2026: „wir haben eine Regler-Regel und
   das ist, dass alle Regler so aussehen … wir brauchen Konsistenz")

   Vorher gab es zwei Fassungen mit einer Begründung, die nicht trug: der
   Größen-Regler blau („Akzentblau der Kontext-Pille"), der Zoom-Regler
   schwarz („Beige-Schwarz der Zoom-Pille"). Zwei Umgebungen sind kein Grund
   für zwei Bauteile — ein Regler ist ein Regler.

   Gewählt ist Schwarz: das Designsystem ist einfarbig, und Blau markiert
   sonst Links und aktive Zustände. Breite und Länge dürfen sich je Ort
   unterscheiden, Schiene und Griff nicht.
   ════════════════════════════════════════════════════════════════════════ */
input[type="range"] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 16px; margin: 0;
  background: none; cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track { height: 2px; border-radius: 2px; background: rgba(17, 17, 17, 0.22); }
input[type="range"]::-moz-range-track { height: 2px; border-radius: 2px; background: rgba(17, 17, 17, 0.22); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; margin-top: -6px;
  width: 14px; height: 14px; border-radius: 50%; background: var(--kf-ink); border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; background: var(--kf-ink); border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
input[type="range"]:disabled { opacity: .45; cursor: default; }
/* Nur die Länge ist Ortssache. */
#kf-ctx-groesse, .kf-groesse-slider { width: 88px; }
.kf-ctx-schrift-wrap { position: relative; display: inline-flex; flex: none; }
.kf-ctx-farbe-wrap { position: relative; display: inline-flex; flex: none; }
.kf-ctx-farbkreis {
  width: 14px; height: 14px; border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.2); margin-right: 6px; flex: none;
}
/* Farb-Popover: öffnet unter dem Farbe-Button, enthält die Farbreihe */
.kf-ctx-pop {
  position: absolute; top: calc(100% + 9px); left: 50%; transform: translateX(-50%);
  z-index: 15; display: flex;
  background: #fff; border: 1.5px solid var(--kf-border); border-radius: 10px;
  padding: 9px 10px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.16);
  max-width: 210px;
}
.kf-ctx-pop[hidden] { display: none; }
/* Schriftart-Popover: links ausgerichtet (der Button sitzt ganz links in der
   Pille, ein zentriertes Popover würde links abgeschnitten) + eigenes Grid,
   das bei vielen Schriftarten scrollt statt die Bühne zu sprengen */
.kf-ctx-pop-fonts {
  left: 0; transform: none; flex-direction: column;
  width: 268px; max-width: none; max-height: 320px; overflow-y: auto; scrollbar-width: none;
  white-space: normal; /* .kf-ctx erzwingt nowrap — hier bewusst zurücksetzen,
    sonst rutscht z.B. "IBM Plex Mono" einzeilig aus der Kachel */
}
.kf-ctx-pop-fonts::-webkit-scrollbar { display: none; }
/* min-width:0 verhindert, dass Grid/Kacheln als Flex-/Grid-Kinder an ihrer
   Inhaltsbreite (z.B. "Permanent Marker" in einer Zeile) festhalten und über
   den Popover-Rand hinausragen */
.kf-ctx-pop-fonts .kf-fonts-grid { width: 100%; min-width: 0; }
.kf-ctx-pop-fonts .kf-font-kachel { min-width: 0; overflow-wrap: break-word; }

/* Vorne/Hinten unten links (Julian, 31.07.2026): ohne Hover übers Produkt
   nur eine schlichte Pille mit der aktiven Ansicht; sobald man aufs Bild
   geht, blenden BEIDE Karten (Vorne + Hinten) sanft ein. Sauberes Cross-Fade
   über Opacity/Transform (kein Layout-Morph mit width/height → flüssig,
   nicht ruckelig). Pille und Karten liegen an derselben Ecke, sodass es wie
   ein Aufblühen aus der Pille wirkt. */
.kf-thumbs {
  position: absolute; left: 12px; bottom: 12px; z-index: 12;
  display: flex; flex-direction: row; align-items: flex-end; gap: 6px;
  transform-origin: bottom left;
  opacity: 0; transform: translateY(6px) scale(0.96); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.28s cubic-bezier(0.22, 0.8, 0.3, 1);
}
.kf-thumb {
  flex: none; width: 52px; height: 62px; border: 1.5px solid var(--kf-border); border-radius: 8px;
  background: #fff; overflow: hidden; padding: 0; position: relative;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.1);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.kf-thumb:hover { transform: translateY(-2px); }
.kf-thumb.active { border-color: var(--kf-ink); }
/* Trennstrich zwischen Freisteller-Ansichten (Vorne/Hinten) und Modellbildern */
.kf-thumb-trenner { flex: none; align-self: center; width: 1px; height: 46px; margin: 0 3px; background: var(--kf-border-strong); }
/* Modell-Thumbs auf den Oberkörper/das Produkt fokussieren (nicht die Beine zeigen) */
.kf-thumb-modell img { object-position: center 20%; }
/* „Mit KI"-Button in der Kontextleiste (Icon + kurzer Text) */
.kf-ctx-ki { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; white-space: nowrap; }
.kf-ctx-ki svg { flex: none; }
/* Modell-Daten-Zeile im SizeGuide (statt Bilder) */
.kf-sizeguide-modelltext { margin: 12px 0 0; font-size: 12px; color: var(--kf-mid); line-height: 1.5; }
.kf-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.kf-thumb.contain img { object-fit: contain; padding: 5px; }
.kf-thumb-tag {
  position: absolute; left: 0; right: 0; bottom: 0; font-size: 8px; letter-spacing: 0.08em;
  text-transform: uppercase; text-align: center; background: rgba(240, 238, 236, 0.92); padding: 2px 0;
  font-family: "DM Sans", sans-serif; color: rgba(17, 17, 17, 0.7);
}
/* Pille (aktive Ansicht) — Gegenstück, sichtbar SOLANGE nicht gehovert */
.kf-ansicht-pille {
  position: absolute; left: 12px; bottom: 12px; z-index: 11;
  background: var(--kf-zoom-chip); border-radius: 999px; padding: 5px 12px;
  font-size: 9px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.7); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
  transform-origin: bottom left;
  transition: opacity 0.18s ease, transform 0.2s cubic-bezier(0.22, 0.8, 0.3, 1);
}
@media (hover: hover) {
  .kf-stage-wrap:hover .kf-thumbs,
  .kf-stage-wrap:fullscreen .kf-thumbs,
  .kf-stage-wrap:-webkit-full-screen .kf-thumbs {
    opacity: 1; transform: none; pointer-events: auto;
  }
  .kf-stage-wrap:hover .kf-ansicht-pille,
  .kf-stage-wrap:fullscreen .kf-ansicht-pille,
  .kf-stage-wrap:-webkit-full-screen .kf-ansicht-pille {
    opacity: 0; transform: translateY(4px) scale(0.9); pointer-events: none;
  }
}
@media (hover: none) {
  /* Touch: keine Pille, beide Karten dauerhaft */
  .kf-thumbs { opacity: 1; transform: none; pointer-events: auto; }
  .kf-ansicht-pille { display: none; }
}

/* Design-Kacheln oben links im Bild (nur Design-Schritt): platzierte Designs
   klein + „Logo ablegen"-Kachel. Hover-gated wie Zoom/Hilfslinien; Hover auf
   eine Kachel vergrößert sie, Klick öffnet das Ebenen-Panel (JS). */
.kf-stage-designs {
  position: absolute; left: 12px; top: 12px; z-index: 12;
  display: flex; flex-direction: row; align-items: flex-start; gap: 7px;
  opacity: 0; transform: translateY(-6px) scale(0.96); pointer-events: none;
  transform-origin: top left;
  transition: opacity 0.2s ease, transform 0.28s cubic-bezier(0.22, 0.8, 0.3, 1);
}
@media (hover: hover) {
  .kf-stage-wrap:hover .kf-stage-designs,
  .kf-stage-wrap:fullscreen .kf-stage-designs,
  .kf-stage-wrap:-webkit-full-screen .kf-stage-designs {
    opacity: 1; transform: none; pointer-events: auto;
  }
}
@media (hover: none) { .kf-stage-designs { opacity: 1; transform: none; pointer-events: auto; } }
.kf-sd-tile {
  flex: none; width: 48px; height: 48px; border-radius: 10px; padding: 0;
  border: 1.5px solid var(--kf-border); background: var(--kf-transparenz); overflow: hidden; position: relative;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.1); cursor: pointer;
  transform-origin: top left;
  transition: transform 0.18s cubic-bezier(0.22, 0.8, 0.3, 1), box-shadow 0.18s ease, border-color 0.15s;
}
.kf-sd-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: 5px; }
.kf-sd-tile:hover { transform: scale(1.7); z-index: 5; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.26); border-color: var(--kf-border-strong); }
/* Nachbarn zur Seite schieben statt verdecken: die Kachel wächst (origin top
   left) nach rechts, also rücken alle nachfolgenden Kacheln um die Mehrbreite
   (48→~82px = ~34px) nach rechts weg (Julian, 03.08.2026). Linke Nachbarn
   bleiben stehen, da nichts über sie wächst. */
.kf-sd-tile:hover ~ .kf-sd-tile { transform: translateX(34px); }
/* Beim Umsortieren (Ziehen) nichts vergrößern oder beiseiteschieben — sonst
   wandern die Trefferflächen unter dem Zeiger weg (06.10.2026) */
.kf-stage-designs.sortiert .kf-sd-tile { transform: none !important; transition: none; }
.kf-sd-tile.zieht { opacity: 0.35; }
.kf-sd-tile { touch-action: none; }
/* Die Objektleiste bleibt oben links stehen (Julian, 15.10.2026: „die müssen
   ja oben links fest bleiben"). Bis dahin rückte sie bei offener Kontextleiste
   48 px nach unten, weil die Leiste fest oben auf der Bühne stand — seit dem
   15.10. sitzt die Leiste am Element (MMDLeiste.lage). */
/* Text-Kachel: neutraler Look, zeigt den Text-Inhalt (Design-Farbe ignoriert) */
.kf-sd-text { display: flex; align-items: center; justify-content: center; }
.kf-sd-text span {
  font-size: 8px; font-weight: 700; line-height: 1.1; text-align: center; padding: 3px;
  color: var(--kf-ink); overflow: hidden; overflow-wrap: anywhere;
}

/* Hilfslinien-Schalter (oben rechts im Bild): blendet Druckzone + HSP-Linie
   ein/aus, nur im Design-Schritt relevant. Gleiches Hover-Gate wie Zoom/
   Vollbild (Julian, 31.07.2026, widerruft die anfängliche "immer sichtbar"-
   Entscheidung): nur bei Hover übers Produkt, auf Touch immer da. */
.kf-hilfslinien-btn {
  position: absolute; top: 12px; right: 12px; z-index: 12;
  display: flex; align-items: center; gap: 9px;
  background: var(--kf-zoom-chip); border: none; border-radius: 999px;
  /* Höhe an die Kontext-Leiste (#kf-ctx, 38px) angeglichen — Julian: „gleich groß" */
  padding: 9px 8px 9px 14px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
  color: rgba(17, 17, 17, 0.7); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
@media (hover: hover) {
  .kf-stage-wrap:hover .kf-hilfslinien-btn,
  .kf-stage-wrap:fullscreen .kf-hilfslinien-btn,
  .kf-stage-wrap:-webkit-full-screen .kf-hilfslinien-btn {
    opacity: 1; transform: none; pointer-events: auto;
  }
}
@media (hover: none) {
  .kf-hilfslinien-btn { opacity: 1; transform: none; pointer-events: auto; }
}
.kf-hilfslinien-schalter {
  position: relative; flex: none; width: 34px; height: 20px; border-radius: 999px;
  background: rgba(17, 17, 17, 0.18); transition: background 0.18s ease;
}
.kf-hilfslinien-schalter::after {
  content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform 0.18s ease;
}
.kf-hilfslinien-btn[aria-pressed="true"] .kf-hilfslinien-schalter { background: var(--kf-akzent); }
.kf-hilfslinien-btn[aria-pressed="true"] .kf-hilfslinien-schalter::after { transform: translateX(14px); }
/* Zoom nur im Design-Schritt: in allen anderen Tabs bleibt beim Hover nur
   Vorne/Hinten + Vollbild — so ist klar, dass bearbeitet (zoomen/messen) nur
   in Design wird (Julian, 03.08.2026). Vollbild-Button bleibt sichtbar. */

/* Vollbild + Zoom (unten rechts im Bild): nur bei Hover übers Produkt oder
   im Vollbild selbst sichtbar — Touch-Geräte haben kein Hover, dort immer da */
.kf-view-controls {
  position: absolute; right: 12px; bottom: 12px; z-index: 12;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  opacity: 0; transform: translateY(4px); pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
@media (hover: hover) {
  .kf-stage-wrap:hover .kf-view-controls,
  .kf-stage-wrap:fullscreen .kf-view-controls,
  .kf-stage-wrap:-webkit-full-screen .kf-view-controls {
    opacity: 1; transform: none; pointer-events: auto;
  }
}
@media (hover: none) {
  .kf-view-controls { opacity: 1; transform: none; pointer-events: auto; }
}
/* Vorlage (Julian, 31.07.2026): warmer Beige-Chip statt weißem Panel, kein
   Rahmen, schwarzer Kreis-Regler auf dünner Schiene — s. Referenz-Screenshot */
.kf-view-btn {
  flex: none; width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
  background: var(--kf-zoom-chip); border: none; border-radius: 11px;
  color: rgba(17, 17, 17, 0.8); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}
.kf-view-btn:hover { color: var(--kf-ink); }
.kf-view-btn svg { display: block; }
/* „Design bearbeiten"-Stift oben links — nur außerhalb des Design-Schritts, sonst
   wie der Vollbild-Button (Größe/Chip); erscheint mit dem Hover übers Produkt. */
/* Seit 04.09.2026 AUSGESCHRIEBEN und immer sichtbar (Julian: Leute klickten den
   Artikel an und wollten links am Produkt ziehen — der Stift allein sagte nicht,
   dass man hierueber zurueck ins Design kommt). */
/* Dieselbe ausgeschriebene Pille auch in der Read-only-Vorschau des
   Warenkorbs (Julian, 09.09.2026): dort stand nur der Stift, und der sagt
   nicht, dass man darüber zurück ins Design kommt. */
.kf-edit-btn, .kf-vorschau-edit {
  width: auto; padding: 0 14px 0 11px; gap: 8px;
  font-family: "DM Sans", sans-serif; font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  cursor: pointer;
}
.kf-edit-btn { position: absolute; left: 12px; top: 12px; z-index: 12; }
/* Der Stift fuehrte zurueck ins Gestalten - in einer Spalte ist man nie
   draussen. Er ist damit immer aus. */
.kf-edit-btn { display: none; }

/* Das Sample steht seit dem 30.09.2026 als Textlink neben „Produktinfo"
   (Julian) — es braucht keine eigene Bauform mehr, .kf-textlink genügt. */

/* Der Size Guide in der Produktinfo: eine Zwischenüberschrift, weil das
   Fenster jetzt zwei Themen trägt. */
.kf-info-h3 {
  margin: 22px 0 10px; padding-top: 18px;
  border-top: 1px solid var(--kf-border);
  font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.55);
}
.kf-zoom {
  display: flex; align-items: center; gap: 9px;
  background: var(--kf-zoom-chip); border: none; border-radius: 999px;
  padding: 0 14px; height: 38px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}
.kf-zoom-btn {
  flex: none; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
  background: none; border: none; border-radius: 50%; color: rgba(17, 17, 17, 0.55);
}
.kf-zoom-btn:hover:not(:disabled) { color: var(--kf-ink); }
.kf-zoom-btn:disabled { opacity: 0.35; cursor: default; }
.kf-zoom-btn svg { display: block; }
/* Regler: eigens gestylt (kein Browser-Default) — dünne Schiene, satter
   schwarzer Kreis-Griff, wie in der Vorlage. step="1" im Markup macht die
   Bewegung beim Ziehen fühlbar stufenlos statt in 25%-Sprüngen zu rasten.
   Gilt für JEDEN Regler in einer .kf-zoom-Pille: Designfeld, Eigenes Produkt
   und Board. Vorher hingen die Regeln an zwei IDs — das Board bekam deshalb
   den grauen Browser-Regler (Julian, 25.08.2026). */
/* Zoom: nur Breite und flex — das Aussehen kommt aus der Regler-Regel oben. */
.kf-zoom input[type="range"] { width: 92px; flex: none; }
.kf-zoom-pct { font-size: 11px; color: rgba(17, 17, 17, 0.6); min-width: 32px; text-align: right; }

/* Vollbild: Bühne füllt den Screen, Steuerelemente bleiben erreichbar */
.kf-stage-wrap:fullscreen,
.kf-stage-wrap:-webkit-full-screen { background: var(--kf-buehne); border-radius: 0; }

/* ── Design-Werkzeuge (links, nur im Design-Schritt): schmale Icon-Rail,
      Klick öffnet das Flyout-Panel daneben — beides fährt animiert rein ── */
.kf-toolbar {
  flex: none; width: 0; margin-right: -10px; /* kompensiert das Flex-Gap im eingeklappten Zustand */
  opacity: 0; transform: translateX(-14px);
  overflow: visible; min-height: 0; /* visible: das Flyout schwebt außerhalb dieser Box */
  transition: width 0.32s cubic-bezier(0.22, 0.8, 0.3, 1), margin-right 0.32s cubic-bezier(0.22, 0.8, 0.3, 1), opacity 0.26s ease, transform 0.32s cubic-bezier(0.22, 0.8, 0.3, 1);
}
body.kf-design-aktiv .kf-toolbar { width: 64px; margin-right: 0; opacity: 1; transform: none; }
/* WICHTIG: die Breite bleibt IMMER 64px, auch bei offenem Panel — das Flyout
   schwebt als Overlay über der Bühne (position:absolute weiter unten), damit
   Produktbild + platzierte Elemente beim Öffnen/Schließen nie verrutschen */
.kf-toolbar-inner {
  position: relative; /* Anker für das absolut positionierte Flyout */
  width: 100%; height: 100%; min-height: 0;
  display: flex; flex-direction: row; gap: 6px; align-items: stretch;
}
.kf-rail {
  flex: none; width: 64px; min-height: 0; overflow-y: auto; scrollbar-width: none;
  background: #fff; border: 1.5px solid var(--kf-border); border-radius: 10px;
  padding: 8px 5px; display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.kf-rail::-webkit-scrollbar { display: none; }
.kf-rail-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  width: 100%; min-height: 52px; padding: 6px 2px;
  background: none; border: none; border-radius: 8px; color: var(--kf-ink);
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.02em;
  transition: background 0.15s, color 0.15s;
}
/* Am Schreibtisch steht die Spalte senkrecht und zeigt nur Zeichen — der Name
   erscheint beim Zeigen RECHTS daneben (data-tip-seite, konfigurator.js).
   Julian, 30.09.2026: „links in der Zeile beim Hovern zeig die Schrift rechts
   daneben an und nicht darunter." Unter dem Zeichen brauchte jeder Knopf zehn
   Pixel Höhe für ein Wort, das man nach dem zweiten Mal nicht mehr liest.
   Auf dem Handy liegt die Spalte quer (Block unten) — dort bleiben die Wörter:
   waagerecht ist Platz, und ein Kurzhinweis beim Tippen hilft niemandem.
   Ausnahme .mm-wz-icon: der Werkzeug-Wähler des Boards trägt sein ZEICHEN in
   einem span (konfi-board.js setzt es), nicht nur seinen Namen. */
@media (min-width: 921px) {
  .kf-rail-btn { min-height: 44px; gap: 0; }
  .kf-rail-btn > span:not(.mm-wz-icon) { display: none; }
}
.kf-rail-btn:hover { background: rgba(29, 107, 255, 0.06); color: var(--kf-akzent); }
.kf-rail-btn.active { background: rgba(29, 107, 255, 0.1); color: var(--kf-akzent); }
.kf-rail-btn:disabled { opacity: 0.35; cursor: default; }
.kf-rail-btn:disabled:hover { background: none; color: var(--kf-ink); }
.kf-rail-spacer { flex: 1; }
.kf-undo-btn {
  flex: none; display: flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  background: none; border: 1.5px solid var(--kf-border); border-radius: 7px; color: var(--kf-ink);
  transition: border-color 0.2s, color 0.2s, opacity 0.2s;
}
.kf-undo-btn:hover:not(:disabled) { border-color: var(--kf-akzent); color: var(--kf-akzent); }
.kf-undo-btn:disabled { opacity: 0.35; cursor: default; }
/* Flyout: schwebt als Overlay NEBEN der Rail (position:absolute) — nimmt am
   Flex-Layout nicht teil, damit die Bühne beim Öffnen/Schließen niemals ihre
   Größe ändert (Produktbild + platzierte Elemente bleiben fix verankert) */
.kf-flyout {
  position: absolute; top: 0; left: calc(100% + 8px); z-index: 20;
  /* 300px → 340px (Julian, 17.08.2026): die ausfahrenden Panels im Design-Tab
     dürfen mehr Platz einnehmen — man soll die Inhalte besser erkennen */
  width: 340px; height: auto; max-height: 440px; min-height: 0;
  display: flex; flex-direction: column; /* Panel füllt die Höhe und scrollt sauber */
  background: #fff; border: 1.5px solid var(--kf-border); border-radius: 10px;
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.16);
  opacity: 0; transform: translateX(-8px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.24s cubic-bezier(0.22, 0.8, 0.3, 1);
}
/* KI-Design hat viel Inhalt (Prompt + Vorschau + Buttons) → mehr Höhe, scrollt intern */
/* KI & Bibliothek brauchen mehr Platz (Bild-Vorschauen/Referenzen erkennbar) */
.kf-toolbar[data-panel="ki"] .kf-flyout { width: 430px; max-height: 88%; }
.kf-toolbar[data-panel="bib"] .kf-flyout { width: 400px; max-height: 84%; }
.kf-toolbar.panel-offen .kf-flyout { opacity: 1; transform: none; pointer-events: auto; }
/* Das offene Panel gehört ÜBER die Bearbeitungsleiste (Julian, 28.09.2026:
   „das darf nicht dahinter liegen, das ist ja aktiv"). Die z-index: 20 des
   Flyouts allein reichen nicht: .kf-toolbar ist absolut positioniert und macht
   damit einen eigenen Stapelkontext auf — nach außen zählt nur ihre eigene 6,
   und die verliert gegen .kf-ctx mit 14. Angehoben wird nur, solange ein Panel
   offen ist; die eingeklappte Werkzeugleiste bleibt, wo sie war. */
.kf-toolbar.panel-offen { z-index: 24; }
/* Hochladen/Text zeigen nur so viel Fläche wie ihr Inhalt braucht (kein
   Leerraum) — Ebenen darf mehr Platz einnehmen, da dort beliebig viele
   Elemente auflaufen können */
.kf-toolbar[data-panel="ebenen"] .kf-flyout { max-height: 68%; }
.kf-flyout-panel {
  width: 100%; flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-width: none;
  padding: 12px 12px 12px 12px; display: flex; flex-direction: column; gap: 9px;
}
.kf-flyout-panel::-webkit-scrollbar { display: none; }
.kf-flyout-panel[hidden] { display: none; }
/* ‹-Schließer: schlichte Kreis-Fläche (keine kastige Umrandung mehr) —
   der Pfeil bleibt, nur ohne Rand/eckige Ecken */
.kf-flyout-zu {
  position: absolute; right: -13px; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; padding: 0 0 1px;
  display: flex; align-items: center; justify-content: center;
  background: #fff; border: none; border-radius: 50%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18); color: rgba(17, 17, 17, 0.55);
  font-size: 13px; line-height: 1; cursor: pointer;
  transition: color 0.15s;
}
.kf-flyout-zu:hover { color: var(--kf-akzent); }
/* Dropzone (Upload-Panel): Datei ablegen oder klassisch hochladen */
.kf-dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  width: 100%; border: 1.5px dashed var(--kf-border-strong); border-radius: 10px;
  padding: 18px 12px; text-align: center; color: var(--kf-mid); cursor: pointer;
  background: none; font-family: inherit;
  transition: border-color 0.2s, background 0.2s;
}
.kf-dropzone:hover { border-color: var(--kf-ink); }
.kf-dropzone.aktiv { border-color: var(--kf-akzent); background: rgba(29, 107, 255, 0.05); }
.kf-dropzone svg { color: rgba(17, 17, 17, 0.55); }
.kf-dropzone p, .kf-dropzone span { font-size: 12px; font-weight: 500; color: var(--kf-mid); line-height: 1.35; }
/* Ein Hinweis in der Dropzone ist ein Hinweis, kein Aufruf. Ohne diese Zeile
   zieht ihn die Regel darüber auf 12px hoch und er steht so groß da wie „Lege
   dein Design hier ab" (Julian, 27.08.2026: „diese Infotexte können oft
   einfach ein bisschen kleiner sein"). */
.kf-dropzone .kf-tb-hint { font-size: 9.5px; font-weight: 400; line-height: 1.5; }
.kf-dropzone-klein { padding: 11px 12px; gap: 6px; }
.kf-dropzone-klein span { font-size: 11.5px; font-weight: 600; }
/* Mit .kf-dropzone davor, sonst gewinnt „.kf-dropzone span" darüber und das
   Trennwort steht mit 12px so groß da wie die Aufforderung selbst. */
.kf-dropzone .kf-dropzone-oder {
  font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--kf-mid);
}
/* Schriftarten-Grid: jede Kachel in ihrer eigenen Schrift */
.kf-fonts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.kf-font-kachel {
  min-height: 44px; padding: 6px 8px;
  background: none; border: 1.5px solid var(--kf-border); border-radius: 8px;
  font-size: 14px; line-height: 1.15; color: var(--kf-ink);
  display: flex; align-items: center; justify-content: center; text-align: center;
  overflow: hidden; transition: border-color 0.15s, background 0.15s;
}
.kf-font-kachel:hover { border-color: var(--kf-akzent); }
.kf-font-kachel.active { border-color: var(--kf-akzent); background: rgba(29, 107, 255, 0.07); }
.kf-tb-btn {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 38px;
  background: none; border: 1.5px dashed var(--kf-border-strong); border-radius: 8px;
  padding: 8px 10px; font-size: 12px; font-weight: 500; color: var(--kf-ink);
  text-align: left; transition: border-color 0.2s, background 0.2s;
}
.kf-tb-btn svg { flex: none; }
.kf-tb-btn:hover { border-color: var(--kf-akzent); background: rgba(29, 107, 255, 0.04); }
.kf-tb-hint { font-size: 9.5px; line-height: 1.5; color: var(--kf-mid); }
/* Die Kurzfassung der Werkzeug-Labels ist normalerweise unsichtbar; nur unter
   560 px tauscht sie mit der Langfassung (Block weiter unten). Diese Regel MUSS
   global stehen — im Handy-Block versteckt zeigte der Desktop beide Wörter
   hintereinander („HochladenUpload", belegt 10.09.2026 im Screenshot). */
.kf-rail-kurz { display: none; }

.kf-tb-label {
  font-size: 10px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(17, 17, 17, 0.55); font-family: "DM Sans", sans-serif;
}
/* KI-Design-Panel (Rail „KI-Design") */
.kf-ki { display: flex; flex-direction: column; gap: 10px; }
/* Kein Großzieher (Julian, 02.10.2026: „das Fenster soll sich einfach
   automatisch anpassen, wenn man mehr Text reinpackt"). Die Höhe setzt
   konfigurator.js nach dem Inhalt; field-sizing:content könnte das allein,
   kann Safari aber noch nicht. Ab der Deckelung scrollt das Feld. */
.kf-ki-prompt {
  width: 100%; resize: none; overflow-y: auto; min-height: 66px; max-height: 240px;
  padding: 9px 11px; font-size: 16px;
  border: 1px solid var(--kf-border); border-radius: 9px; background: #fff; color: var(--kf-ink);
  font-family: inherit; line-height: 1.4;
}
.kf-ki-prompt:focus { outline: none; border-color: var(--kf-ink); }
/* Desktop-Feldgröße: EIN konsolidierter Block am Dateiende (13px für alle
   Text-Eingaben) — hier stand vorher ein Override, der .kf-ki-refine-input nie
   erreichte, weil dessen Basisregel weiter unten im Stylesheet steht. */
.kf-ki #kf-ki-gen { display: inline-flex; align-items: center; justify-content: center; gap: 7px; }
/* Generieren läuft: kein Standard-Spinner, stattdessen pulsiert die Sparkle (größer/kleiner + heller/dunkler) */
#kf-ki-gen.btn-laedt { opacity: 1; }
#kf-ki-gen.btn-laedt::after { display: none; }
#kf-ki-gen svg { transform-origin: center; }
#kf-ki-gen.btn-laedt svg { animation: kf-sparkle-puls 1.1s ease-in-out infinite; }
@keyframes kf-sparkle-puls {
  0%, 100% { transform: scale(0.7); opacity: 0.5; }
  50%      { transform: scale(1.18); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { #kf-ki-gen.btn-laedt svg { animation-duration: 2.4s; } }
/* Ergebnis, Verlauf, Anpassen, „Neues Design" und „Bisher erzeugt": seit dem
   06.10.2026 in dai-laden.css — Explore baut sein Fenster aus denselben Teilen. */
/* Start-Zustand (Prompt + Referenzen + Generieren) — wird ausgeblendet, sobald
   ein Ergebnis da ist: immer nur EIN Eingabefeld sichtbar (Julian, 18.08.2026) */
.kf-ki-start { display: flex; flex-direction: column; gap: 10px; }
.kf-ki-start[hidden] { display: none; }
.kf-ki-ref-label { margin: 0; font-size: 11px; font-weight: 600; color: var(--kf-ink); }
.kf-ki-ref-label span { font-weight: 400; color: var(--kf-mid); }
/* Referenzbilder */
.kf-ki-ref { display: flex; flex-direction: column; gap: 7px; }
.kf-ki-ref-strip { display: flex; flex-wrap: wrap; gap: 6px; padding: 7px 7px 0 0; }
/* Das „+" neben den Referenz-Vorschauen: dieselbe Kachelgröße wie ein Bild,
   nur leer. Erscheint erst, wenn schon ein Bild hängt (Julian, 28.09.2026). */
.kf-ki-ref-plus {
  flex: none; width: 46px; height: 46px; border-radius: 8px;
  border: 1.5px dashed var(--kf-border); background: transparent;
  color: var(--kf-mid); font-size: 20px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color 0.15s, color 0.15s;
}
.kf-ki-ref-plus:hover { border-color: var(--kf-akzent); color: var(--kf-akzent); }

/* Ladezustand: steht seit dem 05.10.2026 in dai-laden.css (eine Kachel für Konfigurator und Explore). */

.kf-ki-ref-strip[hidden] { display: none; }
.kf-ki-ref-thumb {
  position: relative; width: 46px; height: 46px; border-radius: 8px;
  border: 1px solid var(--kf-border);
  background: repeating-conic-gradient(#f0f0ee 0% 25%, #fff 0% 50%) 50% / 10px 10px;
}
.kf-ki-ref-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; border-radius: 7px; }
.kf-ki-ref-thumb button {
  position: absolute; top: -7px; right: -7px; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid #fff; background: var(--kf-ink); color: #fff; font-size: 11px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0; box-sizing: border-box;
}
.kf-ki-ref-thumb button:hover { opacity: 0.85; }
.kf-ki-ref-add {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px dashed var(--kf-border-strong); background: none; border-radius: 8px;
  padding: 6px 11px; font-family: inherit; font-size: 11.5px; font-weight: 600; color: var(--kf-ink);
}
.kf-ki-ref-add:hover { background: var(--kf-flaeche); }
/* „Aus Bibliothek wählen" + Picker */
.kf-ki-bib-link {
  align-self: flex-start; background: none; border: none; padding: 2px 0; cursor: pointer;
  font-family: inherit; font-size: 11.5px; font-weight: 600; color: var(--kf-ink);
  text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--kf-border-strong);
}
.kf-ki-bib-link[hidden] { display: none; }
.kf-ki-bib-picker { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 8px; border: 1px solid var(--kf-border); border-radius: 9px; background: var(--kf-flaeche); }
.kf-ki-bib-picker[hidden] { display: none; }
.kf-ki-bib-pick {
  position: relative;
  aspect-ratio: 1 / 1; border: 1px solid var(--kf-border); border-radius: 7px; cursor: pointer; padding: 3px; overflow: hidden;
  background: repeating-conic-gradient(#f0f0ee 0% 25%, #fff 0% 50%) 50% / 8px 8px;
}
.kf-ki-bib-pick:hover { border-color: var(--kf-ink); }
.kf-ki-bib-pick img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Lösch-× im KI-Referenz-Picker: dieselbe Bibliothek, also auch hier löschbar (auf Hover) */
.kf-ki-bib-pick:hover .kf-bib-x { display: flex; }
@media (hover: none) { .kf-ki-bib-pick .kf-bib-x { display: flex; } }

/* Bibliothek-Panel */
#kf-panel-bib { position: relative; }
#kf-panel-bib.kf-bib-drop-aktiv { outline: 2px dashed var(--kf-border-strong); outline-offset: 4px; border-radius: 10px; }
.kf-bib-drop-hinweis {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.92); border-radius: 10px; z-index: 5;
  font-size: 12.5px; font-weight: 600; color: var(--kf-ink); pointer-events: none; text-align: center; padding: 12px;
}
.kf-bib-drop-hinweis[hidden] { display: none; } /* Autor-display darf [hidden] nicht überstimmen */
.kf-bib { display: flex; flex-direction: column; gap: 10px; }
.kf-bib-leer { text-align: center; padding: 8px 2px 4px; display: flex; flex-direction: column; gap: 8px; }
.kf-bib-leer-titel { font-size: 13px; font-weight: 600; color: var(--kf-ink); margin: 0; }
.kf-bib-add-klein {
  align-self: flex-start; border: 1px dashed var(--kf-border-strong); background: none; cursor: pointer;
  border-radius: 8px; padding: 6px 11px; font-family: inherit; font-size: 11.5px; font-weight: 600; color: var(--kf-akzent);
}
.kf-bib-add-klein:hover { background: rgba(29, 107, 255, 0.06); }
.kf-bib-gruppe { display: flex; flex-direction: column; gap: 6px; }
.kf-bib-titel { font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--kf-mid); }
.kf-bib-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.kf-bib-item {
  position: relative; aspect-ratio: 1; border: 1px solid var(--kf-border); border-radius: 8px; cursor: pointer;
  background: var(--kf-transparenz);
  overflow: hidden; padding: 4px; display: flex; align-items: center; justify-content: center; transition: border-color 0.13s, transform 0.13s;
}
.kf-bib-item:hover { border-color: var(--kf-akzent); transform: translateY(-1px); }
.kf-bib-item img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.kf-bib-text { background: #f4f1ea; }
.kf-bib-text span { font-size: 12px; line-height: 1.15; color: var(--kf-ink); overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; word-break: break-word; }
.kf-bib-x {
  position: absolute; top: 3px; right: 3px; width: 17px; height: 17px; border-radius: 50%;
  border: none; background: rgba(17, 17, 17, 0.62); color: #fff; font-size: 13px; line-height: 1;
  display: none; align-items: center; justify-content: center; cursor: pointer; padding: 0 0 1px;
}
.kf-bib-item:hover .kf-bib-x { display: flex; }
.kf-bib-x:hover { background: var(--kf-fehler); }
@media (hover: none) { .kf-bib-x { display: flex; } }
/* × grau, wenn das Design gerade in einem Produkt verwendet wird (nicht löschbar) */
.kf-bib-x--gesperrt, .kf-bib-x--gesperrt:hover { background: rgba(17, 17, 17, 0.3); cursor: default; }
.kf-bib-hinweis { font-size: 11px; color: var(--kf-fehler); margin: 2px 0 0; line-height: 1.4; }
/* Inline-Lösch-Bestätigung der Bibliothek: hängt am BODY und sitzt fixed direkt
   am angeklickten × (JS setzt left/top, in den Viewport geklemmt) — kann damit
   nirgends von scrollenden Panels abgeschnitten werden (Julian, 18.08.2026). */
.kf-bib-popover { position: fixed; right: auto; width: 230px; z-index: 320; }
/* Solange das Popover offen ist: × bleibt sichtbar (auch ohne Hover) und rot … */
.kf-bib-x.kf-bib-x--offen { display: flex; background: var(--kf-fehler); }
/* … und die Kachel ist markiert — man sieht immer, WAS entfernt würde. */
.kf-bib-loeschen-aktiv { box-shadow: 0 0 0 2px var(--kf-fehler); }
.kf-farbreihe { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.kf-farbe-swatch {
  width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid rgba(0, 0, 0, 0.15);
  padding: 0; cursor: pointer; transition: transform 0.13s, box-shadow 0.13s; flex: none;
}
.kf-farbe-swatch:hover { transform: scale(1.18); }
.kf-farbe-swatch.active { box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px var(--kf-akzent); }
/* Eigene Farbe: cleaner Farbkreis (weicher Verlauf) mit weißem Plus */
.kf-farbe-eigene {
  background: conic-gradient(from 210deg, #ff4d4d, #ff9f45, #ffe14d, #52d16a, #38a1ff, #9a5cff, #ff4dd2, #ff4d4d);
  display: inline-flex; align-items: center; justify-content: center;
  overflow: hidden; position: relative; border: none;
}
.kf-farbe-plus {
  position: relative; z-index: 1; color: #fff; font-size: 13px; font-weight: 700;
  line-height: 1; pointer-events: none; text-shadow: 0 1px 2.5px rgba(0, 0, 0, 0.4);
}
.kf-farbe-eigene input { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }

/* Ebenen-Kopf: Label links, Vorne/Hinten-Umschalter rechts */
.kf-tb-kopf { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.kf-seiten-mini { display: inline-flex; border: 1.5px solid var(--kf-border); border-radius: 14px; overflow: hidden; }
.kf-seite-mini {
  background: none; border: none; padding: 3px 9px; min-height: 24px;
  font-size: 9px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.55); cursor: pointer; transition: background 0.15s, color 0.15s;
}
.kf-seite-mini.active { background: var(--kf-ink); color: var(--kf-bg); }

/* Ebenen-Liste: oben = vorderste Ebene; Ziehen sortiert */
.kf-ebenen-liste { display: flex; flex-direction: column; gap: 4px; }
.kf-ebenen-leer { font-size: 10.5px; line-height: 1.5; color: var(--kf-mid); }
.kf-ebene-x {
  flex: none; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
  border-radius: 5px; font-size: 13px; line-height: 1; color: rgba(17, 17, 17, 0.4); cursor: pointer;
}
.kf-ebene-x:hover { background: rgba(0, 0, 0, 0.06); color: var(--kf-fehler); }
/* Auge (Sichtbarkeit) — SVG, kein Emoji; sitzt links vom × */
.kf-ebene-auge {
  flex: none; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 5px; color: rgba(17, 17, 17, 0.45); cursor: pointer;
}
.kf-ebene-auge:hover { background: rgba(0, 0, 0, 0.06); color: var(--kf-ink); }
/* Ausgeblendete Ebene: Vorschau + Name ausgegraut (bleibt in der Liste) */
.kf-ebene.ausgeblendet .kf-ebene-thumb,
.kf-ebene.ausgeblendet .kf-ebene-name { opacity: 0.4; }
.kf-ebene.ausgeblendet .kf-ebene-auge { color: var(--kf-akzent); }
.kf-ebene {
  display: flex; align-items: center; gap: 7px; width: 100%;
  background: none; border: 1.5px solid var(--kf-border); border-radius: 8px;
  padding: 5px 7px; min-height: 36px; cursor: grab; user-select: none; -webkit-user-select: none;
  touch-action: none; text-align: left; transition: border-color 0.15s, background 0.15s;
}
.kf-ebene:active { cursor: grabbing; }
.kf-ebene.active { border-color: var(--kf-akzent); background: rgba(29, 107, 255, 0.05); }
.kf-ebene.zieht { opacity: 0.45; border-style: dashed; }
.kf-ebene-thumb {
  flex: none; width: 24px; height: 24px; border-radius: 5px; border: 1px solid var(--kf-border);
  background-color: var(--kf-buehne); background-size: contain; background-position: center;
  background-repeat: no-repeat; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; line-height: 1; overflow: hidden;
}
.kf-ebene-name {
  flex: 1; min-width: 0; font-size: 11px; font-weight: 500; color: var(--kf-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; pointer-events: none;
}
/* Text-Ebenen: Name ist klickbar und direkt in der Leiste editierbar */
.kf-ebene-name.editierbar { cursor: text; }
.kf-ebene-name.editierbar:hover { color: var(--kf-akzent); }
.kf-ebene-edit {
  flex: 1; min-width: 0; font: inherit; font-size: 11px; font-weight: 500;
  color: var(--kf-ink); background: none; border: none;
  border-bottom: 1px dashed var(--kf-akzent); padding: 0;
}
.kf-ebene-edit:focus { outline: none; }
/* Zieh-Griff: links, fährt beim Hover der Zeile weich aus */
.kf-ebene-griff {
  flex: none; order: -1; display: flex; align-items: center;
  width: 0; opacity: 0; margin-right: -7px; overflow: hidden;
  color: rgba(17, 17, 17, 0.35); pointer-events: none;
  transition: width 0.25s cubic-bezier(0.22, 0.8, 0.3, 1), opacity 0.2s ease,
    margin-right 0.25s cubic-bezier(0.22, 0.8, 0.3, 1);
}
.kf-ebene:hover .kf-ebene-griff { width: 12px; opacity: 1; margin-right: 0; }
/* Beim Ziehen hängt die Zeile als Geist an der Maus */
.kf-ebene-ghost {
  position: fixed; z-index: 120; pointer-events: none;
  display: flex; align-items: center; gap: 7px;
  background: #fff; border: 1.5px solid var(--kf-akzent); border-radius: 8px;
  padding: 5px 7px; min-height: 36px; opacity: 0.93;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22);
  /* verkleinert an der Maus — stört beim Zielen nicht */
  transform: scale(0.75) rotate(1.5deg); transform-origin: top left;
}
.kf-ebene-ghost .kf-ebene-griff { display: none; }
.kf-seite-mini.drop-ziel { background: var(--kf-akzent); color: #fff; }
.kf-tb-btn:disabled { opacity: 0.45; cursor: default; }
.kf-tb-btn:disabled:hover { border-color: var(--kf-border-strong); background: none; }

/* ── Panel (rechts): einziger Scroll-Container (Fallback) ── */
.kf-panel {
  /* overscroll: Seit die Seite unter dem Konfigurator weitergeht (04.09.2026)
     darf der Scroll aus dem Panel auf die Seite durchreichen — sonst kommt man
     über Produktauswahl/Veredelung nie nach unten (Julian). Im Warenkorb-Schritt
     bleibt er gefangen (Regel unten), die Zusammenfassung soll nicht wegrutschen. */
  /* Waagerecht ist nichts zu holen: overflow-y allein macht die X-Achse
     automatisch scrollbar, und ein Trackpad-Wisch schob dann die ganze Spalte
     zur Seite — Beschriftungen standen links ausserhalb (Julian, 02.10.2026:
     „guck mal das man das gesamte Fenster nicht nach links oder rechts
     schieben kann, weil sonst kann sich das verziehen"). */
  min-width: 0; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: auto;
  /* Keine Seitenpolster: die Karte liegt direkt an der runden Maske — sonst
     scheint links/rechts ein schmaler Hintergrund-Streifen durch */
  padding: 2px 0;
  /* Runde Scroll-Maske im Karten-Radius: beim Scrollen wirken die Ecken
     exakt wie Karte/Bühne */
  border-radius: 10px;
  /* Scrollbalken ausblenden (Julians Wunsch) — gescrollt wird weiter normal */
  scrollbar-width: none;
}
.kf-panel::-webkit-scrollbar { display: none; }
.kf-step { animation: kf-ein 0.25s ease; }
@keyframes kf-ein { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .kf-step { animation: none; } }

.kf-label {
  font-size: 11px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.55); margin-bottom: 8px; font-family: "DM Sans", sans-serif;
}
.kf-pflicht { color: var(--kf-akzent); }
.kf-feld-optional { color: var(--kf-mid); font-weight: 400; font-size: 0.85em; }
.kf-block { margin-top: 18px; }
/* Größen-Block bekommt MEHR Luft nach oben als die 18px-Norm: der
   Automatisch/Manuell-Umschalter saß sonst gleich weit weg von „Stückzahl"
   wie vom Größen-Raster — unklar, wozu er gehört (Feedback 17.08.2026) */
#kf-groessen-block { margin-top: 30px; }

/* Schritt 1 */
/* Produktleiste bricht um, statt seitlich zu scrollen (Julian, 02.10.2026:
   „kannst du die alle etwas kleiner machen und nicht scrollbar sondern wenn
   dann untereinander"). Sie scrollte seit dem 20.08.2026 — in der einspaltigen
   Fassung ist aber Platz, und was man nicht sieht, wählt man nicht. Kleiner
   gesetzt passen die Einträge meist ohnehin in eine Zeile. */
.kf-familien {
  display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px;
}
/* Weicher Auslauf am rechten Rand: zeigt, dass die Leiste weitergeht
   (sonst übersieht man „Eigenes Produkt"). Verschwindet am Ende der Leiste. */
.kf-familien-wrap { position: relative; }
/* Der weiße Auslauf am rechten Rand ist raus (Julian, 25.08.2026: „hier macht
   der rechts so einen weißen Streifen, das passt nicht"). Er sollte andeuten,
   dass die Leiste weitergeht — legte sich dafür aber quer über die letzte
   Kachel und schnitt ihre Schrift an. Dass es weitergeht, sagt die halb
   sichtbare Kachel dahinter von sich aus. */
.kf-familien .kf-familie { flex: none; }
.kf-familie {
  border: 1.5px solid var(--kf-border); background: none; border-radius: 20px;
  padding: 6px 14px; min-height: 32px; font-size: 11px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--kf-ink); transition: all 0.2s;
}
.kf-familie.active { background: var(--kf-ink); border-color: var(--kf-ink); color: var(--kf-bg); }
/* Ausverkaufte Familien bleiben blass (verfügbare stehen in normalem Schwarz) —
   der Hinweis erscheint erst beim Auswählen */
.kf-familie.ausverkauft { color: rgba(17, 17, 17, 0.4); }
.kf-familie.ausverkauft.active { color: rgba(240, 238, 236, 0.75); }

/* Hinweis unter der Produktauswahl, wenn eine ausverkaufte Familie gewählt ist */
.kf-ausverkauft-hinweis {
  margin: 10px 0 2px; font-size: 12.5px; line-height: 1.55; color: rgba(17, 17, 17, 0.65);
}
/* „Gerade ausverkauft" fällt bewusst auf (Julian, 10.08.2026: „gerade" ging sonst
   unter) — Signalfarbe + größer/fetter, damit der ausverkauft-Status sofort greift. */
.kf-ausverkauft-hinweis strong { font-weight: 700; color: var(--kf-fehler); font-size: 14px; }
/* Ohne Bestellrecht im Firmenkonto (05.10.2026): steht VOR dem gesperrten Knopf */
.kf-bestellen-gesperrt { margin: 0 0 4px; font-size: 13px; line-height: 1.5; color: var(--kf-fehler); }

/* Der Warenkorb-Schritt endet bündig mit der Bühne links — die Karte streckt
   sich über die volle Panelhöhe, statt mitten im Grau aufzuhören (Julian,
   28.08.2026: „bündig mit dem Bild links"). :not([hidden]) ist Pflicht:
   display:flex würde sonst das [hidden] der anderen Schritte aushebeln. */
.kf-step[data-step-panel="4"]:not([hidden]) { display: flex; flex-direction: column; gap: 14px; min-height: 100%; padding-bottom: 0; box-sizing: border-box; }
.kf-step[data-step-panel="4"]:not([hidden]) > .kf-card { margin-bottom: 0; } /* Abstand macht das gap oben */
.kf-step[data-step-panel="4"]:not([hidden]) > .kf-card:first-child { flex: 1 0 auto; }

/* Sample anfragen / Aufs Board: Outline-Pillen wie die Startseiten-CTAs
   (.btn-outline in plattform.blade.php) — Julian, 28.08.2026: „eher so wie
   die hier" statt der eckigen Mono-Ghost-Buttons. */
.kf-sample-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: 42px; margin-top: 12px;
  background: #fff; border: 1px solid rgba(17, 17, 17, 0.18); border-radius: 999px;
  font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--kf-ink); transition: background 0.15s, border-color 0.15s;
}
.kf-sample-btn:hover { background: rgba(0, 0, 0, 0.04); border-color: rgba(17, 17, 17, 0.34); }
/* display:flex überschreibt sonst das [hidden]-Attribut — dann bliebe der
   Sample-Button bei ausverkaufter Familie sichtbar (kein Bestellweg erlaubt) */
.kf-sample-btn[hidden] { display: none; }
/* Ausstattungs-Sofort-Vorschau: Mockup + fest eingesetztes Logo in seiner Zone.
   Das Logo wird immer auf volle Zonenbreite gezogen (object-fit: contain hält
   das Seitenverhältnis und verhindert Überlauf). Der gestrichelte Rahmen liegt
   als ::after mit mix-blend-mode:difference darüber — dadurch auf hellem (Neck-
   Label/Hangtag klassisch) UND dunklem Mockup (Hangtag schmal, Webetikett)
   gleich gut sichtbar. */
/* Die Zonen liegen weit genug innen, dass die Griffe (max. 30px außerhalb des
   Logos) trotz overflow:hidden nie am Box-Rand abgeschnitten werden — die
   Zonen-Klemme im JS hält das Logo ohnehin komplett in der Zone. */
/* overflow SICHTBAR lassen: die blaue Auswahl-Umrandung + Griffe eines Logos/
   Texts am Rand des Druckfelds dürfen nicht am Mockup-Rand abgeschnitten werden
   (Julian, 14.08.2026). Die Rundung sitzt daher am Mockup-Bild selbst, nicht an
   der Box. Elemente bleiben ohnehin per klemmeAusstTransform im Druckbereich. */
.kf-ausst-vorschau { position: relative; width: min(300px, 100%); margin: 4px 0 12px; display: block; }
.kf-ausst-mockup { display: block; width: 100%; height: auto; border-radius: 6px; }
/* Zone = gestrichelte Druckfeld-Grenze (mix-blend-mode: auf hellem wie dunklem
   Mockup sichtbar). Das Logo liegt jetzt als frei editierbares .kf-ausst-item
   darüber, nicht mehr fix in der Zone. */
.kf-ausst-zone { position: absolute; box-sizing: border-box; pointer-events: none; }
.kf-ausst-zone::after { content: ""; position: absolute; inset: 0; box-sizing: border-box; border: 1.5px dashed #fff; mix-blend-mode: difference; pointer-events: none; }
/* Editierbares Ausstattungs-Logo — dieselbe Formsprache wie das ausgewählte
   Design-Element (blauer Rahmen + Griffe), nur ohne cm-/Maßanzeige und ohne
   90°-Button (Julian, 06.08.2026). Rahmen + Griffe erscheinen NUR, wenn das
   Logo ausgewählt ist (.aktiv) — Klick aufs Logo wählt es, Klick daneben hebt
   die Auswahl auf, damit man das Ergebnis sauber ansehen kann. Neu eingefügte
   Logos sind standardmäßig ausgewählt. */
.kf-ausst-item {
  position: absolute; width: 30%; transform: translate(-50%, -50%);
  cursor: grab; border: 1.5px solid transparent; border-radius: 2px;
  z-index: 2; touch-action: none;
}
.kf-ausst-item.aktiv { border-color: var(--kf-akzent); }
.kf-ausst-item:active { cursor: grabbing; }
.kf-ausst-item img { display: block; width: 100%; height: auto; pointer-events: none; }
/* Ausstattungs-TEXT: Breite folgt dem Inhalt (Umbruch an der Zonenbreite per
   max-width in positioniereAusstText), nicht die feste 30 %-Logo-Breite. */
.kf-ausst-item.kf-text-item { width: auto; }
.kf-ausst-item.aktiv .kf-eckpunkt { display: block; }
.kf-ausst-item.aktiv .kf-griff { display: flex; }

/* ---- Zweispalten-Editor der Ausstattung (Julian, 10.08.2026): Mockup links,
        RECHTS Add-Buttons + Werkzeugleiste + Element-Hierarchie. Toolbar/Liste
        nutzen bewusst die GLEICHEN Klassen wie der Design-Schritt (.kf-ctx,
        .kf-ebene, Font-/Farb-Popover), damit es 1:1 gleich aussieht. ---- */
.kf-ausst-editor { display: flex; gap: 16px; align-items: flex-start; margin: 4px 0 10px; }
.kf-ausst-buehne { flex: 0 0 auto; width: min(240px, 46%); margin: 0; }
.kf-ausst-buehne .kf-ausst-vorschau { width: 100%; margin: 0; }
.kf-ausst-panel { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 12px; }
/* Add-Buttons oben rechts, kompakt nebeneinander */
/* Logo/Text nebeneinander, Bibliothek volle Breite darunter — kompakt */
.kf-ausst-add-reihe { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.kf-ausst-add-reihe > * { min-width: 0; }
.kf-ausst-add-reihe > .kf-ausst-add-btn { width: 100%; }
.kf-ausst-add-wrap { position: relative; display: flex; width: 100%; }
.kf-ausst-add-wrap .kf-ausst-add-btn { flex: 1; width: 100%; }
.kf-ausst-bibwrap { grid-column: 1 / -1; }
/* flacher + KEIN 14px-Top-Margin (kommt von .kf-btn-klein; höhere Spezifität nötig,
   da .kf-btn-klein weiter unten in der Datei steht) */
.kf-ausst-add-reihe .kf-ausst-add-btn { margin-top: 0; min-height: 40px; padding: 8px 12px; }
@media (hover: hover) and (pointer: fine) { .kf-ausst-add-reihe .kf-ausst-add-btn { min-height: 34px; padding: 7px 12px; } }
.kf-ausst-add-wrap .kf-ausst-add-btn { flex: 1; }
.kf-ausst-add-btn { flex: 1; min-height: 40px; }
.kf-ausst-add-btn.offen { border-color: var(--kf-akzent); color: var(--kf-akzent); background: rgba(29, 107, 255, 0.06); }
/* Logo-Popup: schwebt über dem Inhalt (schiebt nichts auseinander), schließbar */
.kf-ausst-logopicker { display: flex; flex-direction: column; gap: 8px; }
.kf-ausst-logopop {
  /* rechtsbündig ankern → öffnet nach LINKS in den Panel-Bereich, nie über den
     rechten Rand hinaus (kein horizontaler Scroll). */
  position: absolute; top: calc(100% + 6px); right: 0; left: auto; z-index: 30;
  width: min(300px, 82vw); max-width: calc(100vw - 24px);
  background: #fff; border: 1.5px solid var(--kf-border);
  border-radius: 12px; padding: 12px; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.16);
}
/* Runder, deckender Knopf exakt in der Popup-Ecke — wie der Schließen-Knopf
   der Werkzeug-Panels. Vorher lag ein nacktes × halb AUF der gestrichelten
   Dropzone-Linie („nicht sauber gesetzt", Julian, 01.09.2026). */
.kf-ausst-logopop-zu {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--kf-border); border-radius: 50%;
  background: #fff; cursor: pointer; color: var(--kf-mid); font-size: 17px; line-height: 1;
  z-index: 2;
}
.kf-ausst-logopop-zu:hover { background: rgba(0, 0, 0, 0.06); color: var(--kf-ink); }
/* Ausstattung-Bibliothek-Picker (geordnet, scrollbar).
   KEIN position:relative hier — dieses Element trägt auch .kf-ausst-logopop
   (position:absolute); ein relative würde das Popup in den Fluss holen und den
   „Bibliothek"-Button riesig aufblähen (Julian, 14.08.2026). Das absolute
   Popup ist bereits der Positionsanker fürs Lösch-Popover. */
.kf-ausst-bibpicker { display: flex; flex-direction: column; gap: 11px; max-height: min(58vh, 440px); overflow-y: auto; padding-top: 6px; }
.kf-ausst-bibpicker .kf-bib-item { cursor: pointer; }
/* Bibliothek-Popup: mehr Platz als das schmale Logo-Popup (mehr Einträge sichtbar) */
.kf-ausst-bibpop { width: min(420px, 88vw); }
/* Kontext-Werkzeugleiste als STATISCHE Pille im Panel (statt schwebend überm
   Produkt) — sonst identisch zur Design-Toolbar. Bleibt bewusst in EINER Reihe
   (Julian, 10.08.2026: nicht umbrechen) — bei extremer Enge scrollt sie sanft. */
.kf-ctx-inline {
  position: static; transform: none; left: auto; top: auto; z-index: auto;
  max-width: 100%; white-space: nowrap; flex-wrap: nowrap; overflow-x: auto;
  align-self: stretch; scrollbar-width: none;
}
.kf-ctx-inline::-webkit-scrollbar { display: none; }
.kf-ctx-inline .kf-ctx-slider { flex: 1 1 auto; min-width: 56px; }
.kf-ctx-inline .kf-groesse-slider { width: 100%; min-width: 56px; }
.kf-ctx-inline .kf-ctx-farbe-btn { width: 28px; }
.kf-ctx-inline .kf-ctx-farbe-btn .kf-ctx-farbkreis { width: 16px; height: 16px; }
.kf-ctx-inline .kf-ctx-pop-fonts { width: min(260px, 78vw); }
/* Dropzone im Logo-Picker etwas kompakter als im Design-Upload-Panel */
.kf-ausst-dropzone { padding: 14px 12px; }
.kf-ausst-dropzone p { margin: 6px 0 2px; }
/* Drag&Drop direkt aufs Mockup: Akzent-Rahmen als Ablege-Hinweis */
.kf-ausst-vorschau.kf-drop-aktiv { outline: 2px dashed var(--kf-akzent); outline-offset: -2px; }
@media (max-width: 560px) {
  /* Gestapelt: Mockup mittig, darunter die Add-Buttons über die VOLLE Breite.
     align-items:stretch ist hier entscheidend — das flex-start des Desktop-
     Zweispalters ließ die Logo/Text-Reihe sonst links auf Minimalbreite
     zusammenschnurren (Julian, 18.08.2026: „mittig machen"). */
  .kf-ausst-editor { flex-direction: column; align-items: stretch; }
  .kf-ausst-buehne { width: 100%; max-width: 300px; align-self: center; }
  .kf-ausst-panel { width: 100%; }
}
.kf-sample-produkt { font-size: 14px; font-weight: 600; margin: 4px 0 2px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.kf-sample-preis {
  font-size: 12px; font-weight: 600; color: var(--kf-ink);
  background: rgba(0, 0, 0, 0.06); border-radius: 14px; padding: 3px 10px;
  font-family: "DM Sans", sans-serif;
}
.kf-sample-text { font-size: 12.5px; color: var(--kf-mid); margin: 6px 0 12px; line-height: 1.5; }
.kf-sample-groessen { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 26px; }
.kf-sample-groesse {
  min-width: 44px; min-height: 36px; padding: 7px 14px;
  background: none; border: 1.5px solid var(--kf-border); border-radius: 8px;
  font-size: 13px; font-weight: 500; color: var(--kf-ink); transition: all 0.15s;
}
.kf-sample-groesse:hover { border-color: var(--kf-border-strong); }
.kf-sample-groesse.active { background: var(--kf-ink); border-color: var(--kf-ink); color: var(--kf-bg); }
.kf-sample-groesse.ausverkauft { opacity: 0.35; cursor: not-allowed; }
.kf-sample-groesse.ausverkauft:hover { border-color: var(--kf-border); }
/* ── EIN Tooltip für ALLE Hover-Hinweise ────────────────────────────────
   Singleton am <body>, per JS befüllt + positioniert (aus [data-tip]).
   Bewusst NICHT als ::after im jeweiligen Feld: dadurch (a) erbt er nie die
   Transparenz eines gedimmten Feldes (Bug: ausverkaufte Sample-Größe war
   halbtransparent) und (b) kann ihn kein Panel-/Modal-Rand oder Nachbarfeld
   abschneiden — er liegt fix über dem Viewport und wird in den sichtbaren
   Bereich geklemmt bzw. klappt nach oben (Julian, 03.08.2026: „immer
   vollständig lesbar & überall gleich"). Optik = zentrale --kf-tip-*-Tokens. */
.kf-tip {
  position: fixed; left: 0; top: 0; z-index: 500;
  max-width: min(280px, calc(100vw - 24px));
  background: var(--kf-tip-bg); color: var(--kf-tip-fg);
  font-family: "DM Sans", sans-serif; font-size: var(--kf-tip-size);
  font-weight: 500; line-height: 1.4; letter-spacing: 0; text-align: left;
  border-radius: var(--kf-tip-radius); box-shadow: var(--kf-tip-shadow);
  padding: var(--kf-tip-pad);
  opacity: 0; visibility: hidden; transform: translateY(2px); pointer-events: none;
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0s 0.14s;
}
.kf-tip.sichtbar { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
/* Tooltip mit Detailfoto: bei Konstruktionsbegriffen (Raw Cut, breit gerippt,
   Kängurutasche …) hängt über dem Text ein kleines Produktfoto. Die Box wird
   dafür breiter und der Text bekommt etwas Luft (Julian, 24.08.2026). */
.kf-tip.mit-bild { max-width: min(300px, calc(100vw - 24px)); padding: 6px 6px 10px; }
.kf-tip.mit-bild img {
  display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: calc(var(--kf-tip-radius) - 3px); margin-bottom: 8px; background: rgba(255, 255, 255, 0.06);
}
.kf-tip.mit-bild > span { display: block; padding: 0 6px; }
/* Sample-Modal darf den Tooltip nicht abschneiden (die Box ist kurz, braucht
   keinen Scroll) — sonst klippt overflow-y:auto den unten austretenden Tooltip
   (Julian, screenshot #106: linke Seite abgeschnitten) */
#kf-sample-modal .kf-modal-box { overflow: visible; }
/* Produktinfo-Modal ebenso — damit das gezoomte Modelbild nicht abgeschnitten
   wird (Inhalt ist kurz: Specs + kleine Bildreihe) */
#kf-info-modal .kf-modal-box { overflow: visible; }
/* Neck-Label-Hinweis in der Produktinfo: dezent wie eine normale Spec-Zeile
   (kein Fett, keine Farbe), nur ein kleines „i" dahinter mit Hover-Erklärung
   (Julian, 10.08.2026). */
#kf-info-liste .kf-info-note { display: flex; align-items: center; gap: 6px; }
.kf-note-i {
  position: relative; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border: 1px solid var(--kf-mid); border-radius: 50%;
  font-size: 9.5px; font-weight: 700; font-style: italic; color: var(--kf-mid);
  cursor: help; line-height: 1;
}
.kf-note-i:hover, .kf-note-i:focus-visible { border-color: var(--kf-ink); color: var(--kf-ink); outline: none; }
.kf-note-tip {
  position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: 240px; z-index: 30; pointer-events: none;
  background: var(--kf-ink); color: #fff; font-size: 11.5px; font-weight: 400; font-style: normal;
  line-height: 1.45; text-align: left; padding: 7px 9px; border-radius: 7px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); opacity: 0; visibility: hidden; transition: opacity 0.12s;
}
.kf-note-i:hover .kf-note-tip, .kf-note-i:focus-visible .kf-note-tip { opacity: 1; visibility: visible; }

/* Modelbilder (getragen) im Produktinfo-Popup: kleine Reihe, Klick öffnet die
   Lightbox groß (Julian, 03.08.2026 — statt Hover-Zoom im engen Popup) */
.kf-info-modell[hidden] { display: none; }
.kf-info-modell-label {
  font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.5); margin-top: 18px; margin-bottom: 9px;
}
.kf-info-modell-reihe { display: flex; gap: 9px; }
.kf-info-modell-bild {
  flex: none; width: 66px; height: 94px; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--kf-border); background: var(--kf-bg); cursor: zoom-in;
  position: relative; padding: 0;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.kf-info-modell-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kf-info-modell-bild:hover {
  transform: translateY(-2px); border-color: var(--kf-border-strong);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.16);
}
/* Gruppen (Mann/Frau bzw. Getragen) untereinander, jede mit eigenem Label */
.kf-info-modell-hint {
  font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.4); margin-top: 18px;
}
.kf-info-modell-gruppe .kf-info-modell-label { margin-top: 12px; }
.kf-info-modell-gruppe:first-of-type .kf-info-modell-label { margin-top: 8px; }
/* Im Size Guide sitzt die Referenz unter der Tabelle */
.kf-sizeguide-modell { margin-top: 4px; }

/* Lightbox: Modelbild groß über allem — Top-Layer über der Produktinfo */
.kf-lightbox {
  position: fixed; inset: 0; z-index: 400;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  background: rgba(12, 12, 12, 0.88); padding: 4vmin;
  animation: kf-lightbox-auf 0.2s ease;
}
.kf-lightbox[hidden] { display: none; }
@keyframes kf-lightbox-auf { from { opacity: 0; } to { opacity: 1; } }
.kf-lightbox-bild {
  /* Höhe lässt Platz für den Zähler darunter (Julian, 03.08.2026: Zähler wurde
     vorher vom Bild überdeckt) */
  max-width: 100%; max-height: calc(100% - 30px); width: auto; height: auto;
  object-fit: contain; border-radius: 10px; box-shadow: 0 24px 70px rgba(0, 0, 0, 0.5);
}
.kf-lightbox-close {
  position: absolute; top: 18px; right: 20px; z-index: 2;
  width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255, 255, 255, 0.14); color: #fff; font-size: 24px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s ease;
}
.kf-lightbox-close:hover { background: rgba(255, 255, 255, 0.26); }
.kf-lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 46px; height: 46px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255, 255, 255, 0.14); color: #fff; font-size: 30px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s ease;
}
.kf-lightbox-nav:hover { background: rgba(255, 255, 255, 0.26); }
.kf-lightbox-prev { left: 16px; }
.kf-lightbox-next { right: 16px; }
.kf-lightbox-nav[hidden] { display: none; }
.kf-lightbox-zaehler {
  /* Fließt UNTER dem Bild (flex-column) — nie mehr vom Bild überdeckt */
  flex: none; color: rgba(255, 255, 255, 0.8); font-size: 12px;
  letter-spacing: 0.08em; font-weight: 500;
}
@media (max-width: 640px) {
  .kf-lightbox-prev { left: 8px; }
  .kf-lightbox-next { right: 8px; }
  .kf-lightbox-nav { width: 40px; height: 40px; font-size: 26px; }
}
.kf-sample-mail {
  display: block; text-align: center; margin-top: 10px;
  font-size: 12px; font-weight: 500; color: var(--kf-mid); text-decoration: underline;
  text-underline-offset: 3px;
}
.kf-sample-mail:hover { color: var(--kf-ink); }
#kf-sample-hinzufuegen:disabled { opacity: 0.4; cursor: default; }

/* "Per E-Mail anfragen" (ausverkaufte Familie). Die Hover-Erklärung läuft über
   den globalen .kf-tip-Singleton (data-tip am Wrapper), ebenso der Sample-
   „liegt schon in der Anfrage"-Hinweis. */
.kf-mail-wrap { position: relative; display: inline-flex; }
.kf-mail-wrap[hidden] { display: none; }
.kf-mail-btn { text-decoration: none; display: inline-flex; align-items: center; }

/* Marken-Logo (everplain) überm Produkttitel — Katalog-Optik, nicht klickbar.
   Beim Hover (Touch: Fokus/Tap) fährt „Offizieller Merch-Partner" rechts aus
   dem Logo heraus (gleiche Mechanik wie das Größen-i neben „Automatisch"). */
.kf-marke { display: inline-flex; align-items: center; margin-bottom: 7px; cursor: default; outline: none; }
.kf-marken-logo { display: block; height: 26px; width: auto; opacity: 0.85; }
.kf-marke-hint {
  max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap; margin-left: 0;
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.04em; color: rgba(17, 17, 17, 0.55);
  transform: translateX(-6px);
  transition: max-width 0.3s ease, opacity 0.25s ease, margin-left 0.3s ease, transform 0.3s ease;
}
.kf-marke:hover .kf-marke-hint, .kf-marke:focus-visible .kf-marke-hint {
  max-width: 200px; opacity: 1; margin-left: 9px; transform: none;
}
/* Touch: :focus-visible greift bei Tap nicht (nur Tastatur) — dort reicht der
   normale Tap-Fokus, sonst wäre der Hint auf dem Handy NIE zu sehen. Tap
   daneben nimmt den Fokus und fährt ihn wieder ein. */
@media (hover: none) {
  .kf-marke:focus .kf-marke-hint { max-width: 200px; opacity: 1; margin-left: 9px; transform: none; }
}
.kf-produkt-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.kf-produkt-name { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; }
.kf-produkt-links { display: flex; gap: 16px; }
.kf-textlink {
  background: none; border: none; padding: 6px 0; font-size: 12.5px; font-weight: 500;
  color: rgba(17, 17, 17, 0.6); text-decoration: underline; text-underline-offset: 3px;
}
.kf-textlink:hover { color: var(--kf-ink); }

/* Produktfarben: bewusst dezent; 3px Seitenluft, damit der vergrößerte
   Active-Zustand nicht an der Panel-Maske abgeschnitten wird */
.kf-farbe-titel { margin: 16px 0 8px; font-size: 12px; color: var(--kf-mid); display: flex; align-items: baseline; gap: 6px; }
.kf-farbe-titel-k { text-transform: uppercase; letter-spacing: 0.08em; font-size: 10.5px; }
.kf-farbe-titel-v { color: var(--kf-ink); font-weight: 700; }
/* Kacheln groß halten UND volle Breite (bündig mit den Buttons): so viele ~72px-
   Kacheln wie passen, per 1fr auf die volle Breite gestreckt. */
/* Kacheln in fester, angemessener Größe (nicht streckend) und via space-between bis an beide Ränder */
.kf-farben { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 72px)); justify-content: space-between; gap: 9px 6px; margin-top: 0; padding: 0; align-items: start; }
.kf-farbe {
  width: 26px; height: 26px; border-radius: 50%; border: 1.5px solid rgba(0, 0, 0, 0.12);
  padding: 0; position: relative; transition: transform 0.15s;
}
.kf-farbe.active { border-color: var(--kf-ink); transform: scale(1.1); box-shadow: inset 0 0 0 2px var(--kf-bg); }
/* Mockup-Kacheln zur Farbauswahl (Produktbild je Farbe) */
.kf-farbe-mock {
  /* Hochkant, damit das Shirt-Mockup (Hochformat) die Kachel gut ausfüllt.
     height:auto nötig, sonst greift die 26px-Höhe der Basis .kf-farbe und aspect-ratio wird ignoriert. */
  width: 100%; height: auto; aspect-ratio: 4 / 5; border-radius: 9px; border: 1.5px solid var(--kf-border);
  /* Kachelgrund aus dem Token — s. --kf-kachel: der alte Wert war zu hell und
     ließ Off White und Arctic White verschwinden. */
  background: var(--kf-kachel); padding: 2px; display: flex; align-items: center; justify-content: center;
  transition: border-color 0.15s, background 0.15s;
}
.kf-farbe-mock img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.kf-farbe-mock:hover { border-color: var(--kf-border-strong); background: #dcd7ce; }
.kf-farbe-mock.active { border-color: var(--kf-ink); border-width: 2px; transform: none; box-shadow: none; background: #dcd7ce; }

/* Vorder-/Rückseite als kompakte Umschalt-Chips (Ansicht links wechselt mit) */
.kf-seiten-chips { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.kf-chip {
  background: #fff; border: 1.5px solid var(--kf-border); border-radius: 8px;
  padding: 10px 14px; min-height: 48px; text-align: left; cursor: pointer;
  user-select: none; -webkit-user-select: none;
  display: flex; flex-direction: column; gap: 2px; transition: border-color 0.15s;
}
.kf-chip.active { border-color: var(--kf-ink); }
.kf-chip-titel { font-size: 13px; font-weight: 600; }
.kf-chip-status { font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(17, 17, 17, 0.45); max-width: 100%; }
/* Logo-Liste im Chip: Name + × je Zeile, bewusst schlicht (kein Haken) */
.kf-chip-logo { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-width: 0; }
.kf-chip-logo-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: rgba(17, 17, 17, 0.6); }
.kf-chip-logo-x {
  flex: none; width: 18px; height: 18px; background: none; border: none; border-radius: 4px;
  color: rgba(17, 17, 17, 0.4); font-size: 13px; line-height: 1; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.kf-chip-logo-x:hover { background: rgba(0, 0, 0, 0.06); color: var(--kf-fehler); }

/* Schritt 2 */
.kf-lieferzeit {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1.5px solid var(--kf-border); border-radius: 8px; padding: 13px 16px;
  background: #fff; margin-bottom: 18px; font-size: 13px;
}
.kf-lieferzeit span { display: flex; align-items: center; gap: 8px; color: rgba(17, 17, 17, 0.6); font-weight: 500; }
.kf-lieferzeit strong { font-weight: 600; }

.kf-zwei { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: end; }
/* display:grid überschreibt sonst das [hidden]-Default — Zeilen wie die
   USt-ID-Zeile (Privatperson) blieben dadurch sichtbar */
.kf-zwei[hidden] { display: none; }
.kf-stepper {
  display: flex; border: 1.5px solid var(--kf-border-strong); border-radius: 8px;
  overflow: hidden; background: #fff; height: 58px;
}
.kf-stepper button {
  width: 46px; background: none; border: none; font-size: 20px; color: rgba(17, 17, 17, 0.6);
}
.kf-stepper button:hover { background: rgba(0, 0, 0, 0.04); }
.kf-stepper input {
  flex: 1; min-width: 0; border: none; text-align: center; font-size: 19px; font-weight: 600;
  background: none; -moz-appearance: textfield; appearance: textfield; color: var(--kf-ink);
}
.kf-stepper input::-webkit-outer-spin-button, .kf-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; }
.kf-stepper input:focus { outline: none; }

.kf-preisbox {
  border: 1.5px solid var(--kf-border); border-radius: 8px; background: #fff;
  height: 58px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
}
.kf-preisbox strong { font-size: 19px; font-weight: 600; }
.kf-preisbox .mono { font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--kf-mid); }

.kf-stufen-hint { margin-top: 10px; font-size: 12.5px; color: rgba(17, 17, 17, 0.6); }
.kf-stufen-hint strong { color: var(--kf-akzent); font-weight: 600; }

.kf-groessen-kopf { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.kf-groessen-kopf .kf-label { margin-bottom: 8px; }
.kf-modus { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.kf-modus-btn {
  background: none; border: 1.5px solid var(--kf-border); border-radius: 20px;
  padding: 4px 12px; min-height: 28px; font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.05em; text-transform: uppercase; color: rgba(17, 17, 17, 0.5);
  transition: all 0.15s;
}
.kf-modus-btn.active { background: var(--kf-ink); border-color: var(--kf-ink); color: var(--kf-bg); }
.kf-auto-wrap { display: flex; align-items: center; }
.kf-info-wrap { position: relative; display: flex; }
/* Hover-Geräte: i ist versteckt und fährt beim Hover über „Automatisch"
   rechts daneben heraus (schiebt die Pille optisch nach links) */
@media (hover: hover) {
  .kf-info-wrap { max-width: 0; opacity: 0; overflow: hidden; margin-left: 0; transition: max-width 0.25s ease, opacity 0.25s ease, margin-left 0.25s ease; }
  .kf-auto-wrap:hover .kf-info-wrap, .kf-info-wrap:focus-within {
    max-width: 26px; opacity: 1; overflow: visible; margin-left: 6px;
  }
}
/* Das „i" (Julian, 29.09.2026: „schöner machen … kleiner und schlichter"). Bis
   dahin ein gesetzter Buchstabe in einem 20-px-Kreis mit 1,5-px-Rand — in einer
   Zeile aus 11-px-Versalien war er das Schwerste weit und breit. Jetzt ein
   dünnes Zeichen (partials/i-info) ohne eigenen Rahmen; die Trefffläche bleibt
   20 px, sichtbar sind 14. */
.kf-info-i {
  width: 20px; height: 20px; border: 0; border-radius: 50%;
  background: none; color: rgba(17, 17, 17, 0.4);
  display: flex; align-items: center; justify-content: center; cursor: help;
  padding: 0; transition: color 0.15s ease;
}
.kf-info-i .i-info { width: 14px; height: 14px; display: block; }
.kf-info-tip {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 70;
  width: 270px; max-width: calc(100vw - 40px);
  /* Karten-System (helle Erklärung an einem „i") — zentrale --kf-karte-*-Tokens */
  background: var(--kf-karte-bg); border: var(--kf-karte-border); border-radius: var(--kf-karte-radius);
  box-shadow: var(--kf-karte-shadow);
  color: rgba(17, 17, 17, 0.75); font-size: var(--kf-karte-size); line-height: 1.5; padding: 12px 14px;
  opacity: 0; visibility: hidden; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
}
@media (hover: hover) {
  .kf-info-wrap:hover .kf-info-tip, .kf-info-i:focus-visible + .kf-info-tip {
    opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
  }
}
.kf-info-wrap.offen .kf-info-tip { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }

.kf-groessen { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px 10px; }
.kf-groesse { text-align: center; }
.kf-groesse label {
  display: block; font-size: 10px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(17, 17, 17, 0.6); margin-bottom: 4px;
  font-family: "DM Sans", sans-serif; text-align: center;
}
.kf-groesse input {
  width: 100%; border: 1.5px solid var(--kf-border-strong); border-radius: 8px;
  background: #fff; padding: 11px 12px; font-size: 16px; font-weight: 500; text-align: center;
  -moz-appearance: textfield; appearance: textfield; color: var(--kf-ink); min-height: 44px;
}
.kf-groesse input::-webkit-outer-spin-button, .kf-groesse input::-webkit-inner-spin-button { -webkit-appearance: none; }
.kf-groesse input:focus { outline: none; border-color: var(--kf-akzent); }
/* Größen-Toggle: Label blau = aktiv, Klick wählt die Größe ab (grau, Feld gesperrt) */
.kf-groesse-toggle {
  display: inline-block; background: none; border: none; padding: 2px 6px; margin-bottom: 2px;
  font-size: 10px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  font-family: "DM Sans", sans-serif; color: var(--kf-akzent); cursor: pointer;
  border-radius: 4px; transition: color 0.15s, background 0.15s;
}
.kf-groesse-toggle:hover { background: rgba(29, 107, 255, 0.08); }
.kf-groesse.aus .kf-groesse-toggle { color: rgba(17, 17, 17, 0.3); }
.kf-groesse.aus .kf-groesse-toggle:hover { background: rgba(0, 0, 0, 0.05); }
.kf-groesse.aus input { opacity: 0.35; background: rgba(0, 0, 0, 0.03); }
/* Ausverkauft (Bestand <= 0): wie abgewählt, aber nicht wieder aktivierbar */
.kf-groesse.ausverkauft .kf-groesse-toggle { cursor: not-allowed; }
.kf-groesse.ausverkauft .kf-groesse-toggle:hover { background: none; }
.kf-groesse input[readonly] { color: rgba(17, 17, 17, 0.65); background: rgba(255, 255, 255, 0.6); cursor: default; }
.kf-zuordnung { margin-top: 8px; font-size: 12.5px; font-weight: 500; color: var(--kf-warn); }
.kf-zuordnung.ok { color: var(--kf-gruen); }

/* Alle Technik-Kacheln gleich groß (Julian, 02.10.2026: „die sollten alle die
   selbe Größe haben"). Die Spalten waren schon gleich breit; ungleich waren die
   HÖHEN — Stickerei und Puff tragen zusätzlich das Vektor-Abzeichen. grid-auto-rows
   zieht jede Reihe auf dieselbe Höhe, und die Mengen-Pille bricht nicht mehr um
   („ab 25 / Stk." stand zweizeilig in der Kachel). */
.kf-vered-grid { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; gap: 10px; }
.kf-vered {
  border: 1.5px solid var(--kf-border); border-radius: 8px; background: #fff;
  padding: 15px 16px; text-align: left; transition: all 0.2s; min-height: 44px;
}
.kf-vered:hover { border-color: var(--kf-border-strong); }
.kf-vered.active { border-color: var(--kf-ink); background: #fff; }
/* Gesperrte Karten: NICHT die Karte selbst dimmen (die Hover-Nachricht würde
   die Transparenz erben und unlesbar) — nur Inhalte dimmen, Karte bleibt deckend */
.kf-vered.gesperrt, .kf-vered.gesperrt-info, .kf-vered.gesperrt-moq {
  background: #f4f3f1; border-color: rgba(0, 0, 0, 0.05);
}
.kf-vered.gesperrt .kf-vered-name, .kf-vered.gesperrt-info .kf-vered-name, .kf-vered.gesperrt-moq .kf-vered-name { color: rgba(17, 17, 17, 0.32); }
.kf-vered.gesperrt .kf-vered-moq, .kf-vered.gesperrt-info .kf-vered-moq, .kf-vered.gesperrt-moq .kf-vered-moq { background: rgba(17, 17, 17, 0.22); color: rgba(255, 255, 255, 0.92); }
.kf-vered.gesperrt { pointer-events: none; }
/* Gesperrt MIT Hover-Erklärung: Druckverfahren ohne Design (Klick → Schritt 1)
   bzw. Blank bei Designs (aria-disabled, kein Klick) */
.kf-vered.gesperrt-info { cursor: pointer; }
.kf-vered.gesperrt-info[aria-disabled="true"] { cursor: not-allowed; }
/* Unter Mindestmenge: gedimmt, aber klickbar — Klick springt auf die MOQ */
.kf-vered.gesperrt-moq:hover { border-color: var(--kf-border-strong); }
.kf-vered.gesperrt-moq:hover .kf-vered-name { color: rgba(17, 17, 17, 0.6); }
/* Veredelungs-Hinweise laufen über den globalen .kf-tip-Singleton (s.o.) —
   kein eigener ::after mehr (wurde vom Panel-Rand abgeschnitten). */
.kf-design-hint {
  margin-top: 6px; background: none; border: none; padding: 2px 0;
  font-size: 12.5px; color: rgba(17, 17, 17, 0.6); cursor: pointer; text-align: left;
}
.kf-design-hint span { color: var(--kf-akzent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.kf-design-hint:hover span { color: var(--kf-akzent-dunkel); }
.kf-vered-name { display: block; font-size: 14.5px; font-weight: 600; margin-bottom: 6px; }
.kf-vered-moq {
  display: inline-block; background: var(--kf-ink); color: var(--kf-bg);
  font-size: 9px; font-weight: 500; letter-spacing: 0.1em; padding: 3px 9px; border-radius: 20px;
  font-family: "DM Sans", sans-serif; white-space: nowrap;
}
.kf-moq-hint { margin-top: 10px; font-size: 12.5px; color: var(--kf-akzent); }

/* Vektor-Pflicht-Badge (Stickerei/Puff): immer sichtbar, wie „Requires vector file" */
.kf-vered-badge {
  display: inline-block; margin: 6px 6px 0 0; padding: 3px 9px; border-radius: 20px;
  background: rgba(17, 17, 17, 0.06); border: 1px solid rgba(17, 17, 17, 0.1);
  font-size: 9px; font-weight: 500; letter-spacing: 0.08em; color: rgba(17, 17, 17, 0.62);
  font-family: "DM Sans", sans-serif; white-space: nowrap;
}
.kf-vered { position: relative; }
.kf-vered-moq { margin-top: 6px; }
/* Info-„i" oben rechts an der Kachel — öffnet den Technik-Vergleich */
.kf-vered-i {
  position: absolute; top: 8px; right: 8px; width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  /* Das Zeichen ist das SVG aus partials/i-info (Kreis + aufrechtes „i") —
     kein gesetzter, kursiver Buchstabe mehr (Julian, 14.10.2026: „die müssen
     überall einheitlich sein"). Hover dunkelt nur ab, statt zu füllen. */
  border: 0; border-radius: 50%;
  color: rgba(17, 17, 17, 0.5);
  cursor: help; transition: color 0.15s; z-index: 2;
}
.kf-vered-i .i-info { width: 17px; height: 17px; display: block; }
.kf-vered-i:hover, .kf-vered-i:focus-visible { color: var(--kf-ink); outline: none; }
/* Sobald die KACHEL unter dem Zeiger liegt, schaltet das „i" die Farben um
   (Julian, 25.08.2026: „das ‚i‘ muss auch beim Hovern erkennbar sein, dann
   einfach Farben-Switch?"). Vorher invertierte es erst, wenn man genau den
   kleinen Kreis traf — auf der gedimmten Kachel war es bis dahin Grau auf Grau.
   Im gesperrten Zustand bleibt es voll sichtbar: es ist genau dort der einzige
   Weg zur Erklärung, warum die Kachel gesperrt ist. */
.kf-vered:hover .kf-vered-i { color: var(--kf-ink); }
/* Dasselbe „i" an der Überschrift — dort läuft es mit im Text, statt in einer
   Kachelecke zu kleben. Gleiche Optik, damit man es als dieselbe Funktion liest. */
.kf-vered-i.kf-label-i {
  /* relative statt static: das „i" bleibt im Textfluss, ist aber Bezugsrahmen
     für sein eigenes ::before. Mit static suchte der Kreis auf dem Handy den
     nächsten positionierten Vorfahren — das war #kf-panel, und aus dem 18-px-
     Kreis wurde eine 402 × 904 px große weiße Ellipse hinter dem Formular
     (Julian, 10.09.2026: „die Mobil-Version spinnt bisschen"). */
  position: relative; display: inline-flex; width: 17px; height: 17px; margin-left: 7px;
  vertical-align: middle; font-size: 10px; cursor: pointer;
  /* top/right der absoluten Grundform zurücknehmen: als relatives Element
     verschoben sie das „i" um 8 px nach oben rechts aus der Zeile (Julian,
     25.09.2026: „das ‚i' ist hier verrutscht"). */
  top: auto; right: auto;
}
.kf-vered.gesperrt-info .kf-vered-i, .kf-vered.gesperrt-moq .kf-vered-i,
.kf-vered.gesperrt .kf-vered-i {
  color: rgba(17, 17, 17, 0.75); opacity: 1;   /* ohne Hintergrund (Julian, 14.10.2026) */
}
.kf-vered.gesperrt-info:hover .kf-vered-i, .kf-vered.gesperrt-moq:hover .kf-vered-i,
.kf-vered.gesperrt:hover .kf-vered-i { color: var(--kf-ink); }

/* Technik-Vergleich (Overlay über das „i") */
.kf-tech-overlay {
  position: fixed; inset: 0; z-index: 400; background: rgba(10, 10, 10, 0.55);
  display: flex; align-items: center; justify-content: center; padding: 18px;
}
.kf-tech-card {
  position: relative; background: #fff; border-radius: 14px; padding: 26px 26px 20px;
  max-width: 860px; width: 100%; max-height: min(86vh, 86svh); overflow-y: auto;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.3);
}
.kf-tech-card h2 { margin: 0 0 16px; font-size: 19px; font-weight: 700; color: var(--kf-ink); }
.kf-tech-x {
  position: absolute; top: 12px; right: 12px; width: 32px; height: 32px;
  border: none; border-radius: 50%; background: rgba(17, 17, 17, 0.06);
  font-size: 18px; line-height: 1; color: var(--kf-ink); cursor: pointer;
}
.kf-tech-x:hover { background: rgba(17, 17, 17, 0.12); }
.kf-tech-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.kf-tech-karte {
  border: 1.5px solid var(--kf-border); border-radius: 10px; padding: 14px 15px;
  display: flex; flex-direction: column; gap: 8px;
}
.kf-tech-karte.aktiv { border-color: var(--kf-ink); }
.kf-tech-karte h3 { margin: 0; font-size: 15px; font-weight: 700; color: var(--kf-ink); }
.kf-tech-karte h3 .kf-vered-badge { margin: 4px 0 0; display: inline-block; }
.kf-tech-text { margin: 0; font-size: 12.5px; line-height: 1.55; color: rgba(17, 17, 17, 0.78); }
.kf-tech-punkt { margin: 0; font-size: 12px; line-height: 1.5; color: rgba(17, 17, 17, 0.66); }
.kf-tech-punkt b {
  display: block; font-size: 10px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(17, 17, 17, 0.45); margin-bottom: 2px;
}
.kf-tech-ab { margin: auto 0 0; padding-top: 6px; font-size: 11px; color: var(--kf-mid); }
/* Optionale Technik-Fotos (config: veredelung_infos.*.bilder) */
.kf-tech-bilder { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.kf-tech-bild { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 7px; }
@media (max-width: 820px) {
  .kf-tech-grid { grid-template-columns: 1fr; }
  .kf-tech-card { padding: 22px 16px 16px; }
  .kf-vered-i { width: 26px; height: 26px; font-size: 12px; }
}
/* Schmale Screens: Kacheln einspaltig — Regel liegt im bestehenden
   480px-Block weiter unten (dort überschrieb die alte 2-Spalten-Regel). */

.kf-fehler { margin-top: 10px; font-size: 13px; font-weight: 500; color: var(--kf-fehler); }

/* Schritt 3 */
.kf-summary-bar { margin-bottom: 18px; }
.kf-summary-bar .kf-preisbox { flex-direction: column-reverse; }

.kf-sonder-label { margin-top: 18px; display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
/* „Auftragsproduktion" neben der Überschrift: die Schrift von „Sample", nicht die Versalien des Labels */
.kf-sonder-label .kf-sonder-link { padding: 0; letter-spacing: 0; text-transform: none; white-space: nowrap; }
.kf-option {
  border: 1.5px solid var(--kf-border); border-radius: 10px; background: #fff;
  padding: 16px 18px; margin-bottom: 12px; transition: opacity 0.2s;
}
/* Gesperrte Option: Kopf + Beschreibung ausgrauen; die ganze Karte ist klickbar
   (→ Mengen-Tab) und zeigt den Grund als Hover-Tooltip. Radios deaktiviert. */
.kf-option.gesperrt { cursor: pointer; }
.kf-option.gesperrt .kf-option-kopf, .kf-option.gesperrt > .kf-option-text { opacity: 0.42; }
.kf-option.gesperrt .kf-radios { pointer-events: none; }
.kf-option-kopf { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.kf-option-name { font-size: 14.5px; font-weight: 600; }
.kf-option-badge {
  background: rgba(29, 107, 255, 0.1); color: var(--kf-akzent); font-size: 11px; font-weight: 600;
  padding: 3px 9px; border-radius: 20px;
}
.kf-option-badge.moq {
  background: var(--kf-ink); color: var(--kf-bg); font-size: 9px; letter-spacing: 0.1em;
  font-family: "DM Sans", sans-serif; font-weight: 500;
}
.kf-radios { margin-left: auto; display: flex; gap: 14px; }
.kf-radios label { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; cursor: pointer; min-height: 44px; }
.kf-radios input { accent-color: var(--kf-akzent); width: 17px; height: 17px; }
.kf-option-text { font-size: 12.5px; color: rgba(17, 17, 17, 0.6); margin-top: 8px; }
.kf-option-koerper { margin-top: 14px; border-top: 1px solid var(--kf-border); padding-top: 14px; }
.kf-option-koerper[hidden] { display: none; }
/* Eigene Verpackung: „Eigenes Logo? Ja/Nein" (gleiche Optik wie der Optionskopf) */
.kf-logowahl { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.kf-logowahl-frage { font-size: 13px; font-weight: 600; color: var(--kf-text); }
.kf-logowahl .kf-radios { margin-left: auto; }

.kf-styles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
/* Kompakte Auswahl (Printed/Woven, Klassisch/Schmal): kleines Vorschau-Bild
   neben dem Namen — die große Vorschau mit dem eingesetzten Logo ist das, worauf
   es ankommt (Julian, 04.08.2026). */
.kf-style {
  position: relative;
  display: flex; align-items: center; gap: 10px; text-align: left;
  border: 1.5px solid var(--kf-border); border-radius: 8px; background: none;
  padding: 8px 10px; min-height: 44px;
}
.kf-style.active { border-color: var(--kf-ink); background: #fff; }
.kf-style-bild {
  width: 42px; height: 42px; flex: none; object-fit: contain; border-radius: 5px;
  background: var(--kf-buehne); cursor: zoom-in;
}
/* Großansicht beim Hovern NUR über das kleine Bild — schwebt darüber auf, ohne
   das Layout zu verschieben (Julian, 04.08.2026) */
.kf-style-zoom {
  position: absolute; left: 8px; bottom: calc(100% + 8px);
  width: 180px; height: 180px; object-fit: contain; padding: 10px;
  background: #fff; border: 1px solid var(--kf-border); border-radius: 10px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.18);
  opacity: 0; visibility: hidden; transform: scale(0.92); transform-origin: bottom left;
  transition: opacity 0.14s ease, transform 0.14s ease; pointer-events: none; z-index: 60;
}
.kf-style-bild:hover ~ .kf-style-zoom { opacity: 1; visibility: visible; transform: scale(1); }
.kf-style-text { display: flex; flex-direction: column; min-width: 0; }
.kf-style-name { display: block; font-size: 13px; font-weight: 600; }
.kf-style-moq { font-size: 10.5px; color: var(--kf-mid); font-family: "DM Sans", sans-serif; }

/* Logo-Bibliothek in den Ausstattungs-Optionen: vorhandene Logos wählen (Bild+
   Name) oder mit × wieder entfernen. Der Chip ist ein Wrapper mit zwei Buttons. */
.kf-logo-wahl-reihe { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.kf-logo-wahl {
  position: relative; display: flex; align-items: center; max-width: 100%;
  background: #fff; border: 1.5px solid var(--kf-border); border-radius: 8px;
  min-height: 40px; transition: border-color 0.15s;
}
.kf-logo-wahl:hover { border-color: var(--kf-border-strong); }
.kf-logo-wahl.active { border-color: var(--kf-ink); }
.kf-logo-wahl-btn {
  display: flex; align-items: center; gap: 8px; background: none; border: none;
  padding: 6px 4px 6px 10px; cursor: pointer; max-width: 100%;
}
.kf-logo-wahl-btn img {
  width: 30px; height: 30px; object-fit: contain; flex: none;
  background: var(--kf-buehne); border-radius: 5px; padding: 2px;
}
.kf-logo-wahl-btn span {
  font-size: 11px; color: rgba(17, 17, 17, 0.7); max-width: 150px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kf-logo-wahl-x {
  flex: none; min-width: 40px; align-self: stretch; padding: 0 12px 0 6px;
  background: none; border: none; cursor: pointer; font-size: 18px; line-height: 1;
  color: rgba(17, 17, 17, 0.4); transition: color 0.15s;
}
.kf-logo-wahl-x:hover { color: var(--kf-warn); }
.kf-ausst-add { margin-top: 4px; }

/* Schritt 4 + 5 */
.kf-card {
  border: 1.5px solid var(--kf-border); border-radius: 10px; background: #fff;
  padding: 20px; margin-bottom: 16px;
}
/* Anfrage: die Karte schließt unten bündig mit der Bühne ab (kein Rest-
   Abstand beim Scrollen ans Ende); Abstand zum Formular trägt das Formular */
[data-step-panel="4"] .kf-card { margin-bottom: 0; }
[data-step-panel="4"] .kf-form { margin-top: 16px; }
.kf-summary { font-size: 14px; }
.kf-summary-zeile {
  display: flex; justify-content: space-between; gap: 16px; padding: 9px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.kf-summary-zeile:last-child { border-bottom: none; }
.kf-summary-zeile span { color: rgba(17, 17, 17, 0.55); }
.kf-summary-zeile strong { font-weight: 500; text-align: right; }
/* Ausstattungs-Zeile: Options-Name + kleines Logo-Thumbnail (wie oben bei den
   Design-Icons), rechtsbündig */
.kf-korb-ausst-wert { display: inline-flex; align-items: center; justify-content: flex-end; gap: 7px; }
.kf-korb-ausst-wert > span { color: var(--kf-ink); }
.kf-korb-ausst-logo { display: inline-flex; flex: none; }
.kf-korb-ausst-logo .kf-datei-thumb { width: 24px; height: 24px; border-radius: 5px; }

.kf-preis-kopf { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.kf-mwst { display: flex; align-items: center; gap: 8px; cursor: pointer; min-height: 44px; }
.kf-mwst .mono { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--kf-mid); }
.kf-mwst input { position: absolute; opacity: 0; }
.kf-mwst-switch {
  width: 36px; height: 20px; border-radius: 10px; background: rgba(0, 0, 0, 0.15);
  position: relative; transition: background 0.2s;
}
.kf-mwst-switch::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; transition: transform 0.2s;
}
.kf-mwst input:checked + .kf-mwst-switch { background: var(--kf-akzent); }
.kf-mwst input:checked + .kf-mwst-switch::after { transform: translateX(16px); }

.kf-stufen-tabelle { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 12.5px; }
.kf-stufen-tabelle td {
  padding: 7px 10px; border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  font-family: "DM Sans", sans-serif;
}
.kf-stufen-tabelle td:last-child { text-align: right; }
.kf-stufen-tabelle tr.aktiv td { background: rgba(29, 107, 255, 0.08); color: var(--kf-akzent); font-weight: 500; }
.kf-liefer-final { margin-top: 12px; font-size: 13px; color: rgba(17, 17, 17, 0.65); }
.kf-preis-fussnote { margin-top: 10px; font-size: 11.5px; color: var(--kf-mid); }

.kf-korb-item {
  padding: 14px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.kf-korb-item:first-child { padding-top: 0; }
/* Kopfzeile: Swatch + Name links, Preis rechts — das × sitzt oben rechts in der Ecke */
/* Kopfzeile ohne rechten Puffer — das × ist in die Titelzeile gewandert (04.09.2026) */
.kf-korb-kopf { display: flex; gap: 12px; align-items: flex-start; position: relative; }
.kf-korb-kopf .kf-korb-preis { margin-left: auto; }
/* Immer sichtbar rechts: Gesamt-Richtwert groß, Stückpreis + Stückzahl klein */
.kf-korb-preisblock { margin-left: auto; text-align: right; flex: none; }
.kf-korb-gesamt { display: block; font-weight: 600; font-size: 15px; white-space: nowrap; }
.kf-korb-preis-meta { display: block; font-size: 11px; color: rgba(17, 17, 17, 0.6); margin-top: 2px; white-space: nowrap; }
.kf-korb-zeilen { margin-top: 8px; max-width: 520px; }
/* Artikel-Editor unter „Details" (Julian, 01.09.2026): Stückzahl, Größen und
   Veredelung direkt am Artikel ändern. Optik lehnt sich an Schritt 2 an,
   nur kompakter — es ist eine Karte, kein eigener Schritt. */
.kf-korb-stueck-wrap { display: flex; align-items: center; gap: 8px; }
.kf-korb-stueck {
  width: 74px; padding: 5px 8px; font-size: 13px; font-weight: 500; text-align: right;
  border: 1px solid var(--kf-border-strong); border-radius: 7px; background: #fff;
  font-family: "DM Sans", sans-serif; color: var(--kf-ink);
}
.kf-korb-stueck:focus { outline: none; border-color: var(--kf-ink); }
.kf-korb-groessen-auto {
  padding: 5px 10px; font-size: 10px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; border: 1px solid var(--kf-border-strong); border-radius: 999px;
  background: none; color: rgba(17, 17, 17, 0.55); font-family: "DM Sans", sans-serif;
  cursor: pointer; transition: all 0.15s;
}
.kf-korb-groessen-auto:hover { color: var(--kf-ink); border-color: var(--kf-ink); }
.kf-korb-groessen-auto.aktiv { background: var(--kf-ink); border-color: var(--kf-ink); color: var(--kf-bg); }
.kf-korb-groessen-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(44px, 1fr)); gap: 6px 8px;
  padding: 9px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.kf-korb-groesse { display: grid; gap: 3px; text-align: center; }
.kf-korb-groesse > span {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.07em; text-transform: uppercase;
  color: rgba(17, 17, 17, 0.55);
}
.kf-korb-groesse input {
  width: 100%; box-sizing: border-box; padding: 5px 4px; font-size: 12.5px; text-align: center;
  border: 1px solid var(--kf-border); border-radius: 7px; background: #fff;
  font-family: "DM Sans", sans-serif; color: var(--kf-ink);
}
.kf-korb-groesse input:focus { outline: none; border-color: var(--kf-ink); }
.kf-korb-groesse.aus { opacity: 0.4; }
/* Ausverkaufte Größe, in der noch eine Menge steht: DAS ist der Grund für die rote
   Warnung über der Zeile. Sie wird deshalb rot markiert und bleibt lesbar (kein
   opacity 0.4), sonst sieht der Kunde die Warnung, aber nicht die Ursache
   (Julian, 09.09.2026). */
.kf-korb-groesse.aus.schuld { opacity: 1; }
.kf-korb-groesse.aus.schuld > span { color: var(--kf-fehler); }
.kf-korb-groesse.aus.schuld input {
  border-color: var(--kf-fehler); color: var(--kf-fehler);
  box-shadow: inset 0 0 0 1px var(--kf-fehler);
}
.kf-korb-vered-zeile { align-items: center; }
.kf-korb-vered-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.kf-korb-vered-chip {
  padding: 5px 10px; font-size: 10px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; border: 1px solid var(--kf-border-strong); border-radius: 999px;
  background: none; color: rgba(17, 17, 17, 0.55); font-family: "DM Sans", sans-serif;
  cursor: pointer; transition: all 0.15s;
}
.kf-korb-vered-chip:hover { color: var(--kf-ink); border-color: var(--kf-ink); }
.kf-korb-vered-chip.aktiv { background: var(--kf-ink); border-color: var(--kf-ink); color: var(--kf-bg); }
.kf-korb-vered-chip.gesperrt { opacity: 0.4; cursor: default; }
.kf-korb-vered-chip.gesperrt:hover { color: rgba(17, 17, 17, 0.55); border-color: var(--kf-border-strong); }
.kf-korb-ausst-plus {
  border: none; background: none; padding: 0; font-family: "DM Sans", sans-serif;
  font-size: inherit; font-weight: 500; color: var(--kf-ink); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(17, 17, 17, 0.3);
}
.kf-korb-ausst-plus:hover { text-decoration-color: var(--kf-ink); }
.kf-korb-item-fehler { padding: 8px 0; }
.kf-korb-zeilen[hidden] { display: none; }
.kf-korb-design-anzahl { margin-left: 8px; font-size: 11px; font-weight: 500; color: rgba(17, 17, 17, 0.55); }

/* Design-Icons unter Name + Farbe: nur Mini-Bilder/Schriftproben —
   Hover (bzw. Tap) zeigt Kontext, Dateiname bzw. Text */
.kf-design-icons { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.kf-design-icon { position: relative; display: inline-flex; cursor: default; }
.kf-design-icon .kf-datei-thumb { width: 26px; height: 26px; border-radius: 5px; }
.kf-design-icon .kf-datei-thumb.leer::after { line-height: 24px; font-size: 7px; }
.kf-design-icon .kf-datei-thumb-text { font-size: 12px; }
/* Design-Icon-Labels laufen über den globalen .kf-tip-Singleton (s.o.). */

/* Produkt-Mini-Bild = Freisteller mit Designs (transparent, wie die normalen
   Produktbilder) — Hover zeigt Vorne + Hinten groß */
.kf-korb-swatch { position: relative; }
/* Unsichtbar = display:none — ein nur transparentes Zoom-Panel würde sonst
   den Scrollbereich des Panels vergrößern (Karte schloss unten nicht bündig) */
.kf-korb-swatch-zoom {
  position: absolute; left: calc(100% + 10px); top: -4px; z-index: 25;
  display: none; gap: 10px; padding: 10px;
  background: #fdfdfc; border: 1px solid var(--kf-border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
  pointer-events: none;
}
.kf-zoom-seite { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.kf-zoom-bild {
  width: 138px; height: 170px; border-radius: 8px; background-color: var(--kf-buehne);
  background-size: contain; background-position: center; background-repeat: no-repeat;
}
.kf-zoom-label { font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--kf-mid); }
@media (hover: hover) {
  .kf-korb-swatch:hover .kf-korb-swatch-zoom:not([hidden]) { display: flex; }
}

/* Lösch-Popover am × — eigener Bestätigungsdialog statt des Browser-Fensters */
.kf-korb-item { position: relative; }
.kf-loeschen-popover {
  position: absolute; top: 26px; right: 4px; z-index: 35;
  width: min(250px, calc(100% - 16px));
  /* Karten-System (Entscheidungs-Dialog) — zentrale --kf-karte-*-Tokens */
  background: var(--kf-karte-bg); border: var(--kf-karte-border); border-radius: var(--kf-karte-radius);
  box-shadow: var(--kf-karte-shadow); padding: 14px;
}
.kf-loeschen-popover p { margin: 0 0 10px; font-size: 12.5px; line-height: 1.5; color: var(--kf-ink); }
.kf-loeschen-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.kf-loeschen-ja, .kf-loeschen-nein {
  border-radius: 20px; padding: 6px 12px; min-height: 32px;
  font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.kf-loeschen-ja { background: none; border: 1.5px solid var(--kf-fehler); color: var(--kf-fehler); }
.kf-loeschen-ja:hover { background: var(--kf-fehler); color: #fff; }
.kf-loeschen-nein { background: var(--kf-ink); border: 1.5px solid var(--kf-ink); color: #f0eeec; }
.kf-korb-fuss { display: flex; gap: 14px; align-items: center; }
/* Artikel bearbeiten abgesetzt rechts (Julian, 04.09.2026) — Details/Staffelpreise bleiben links */
.kf-korb-fuss .kf-korb-bearbeiten { margin-left: auto; }
/* "Artikel bearbeiten": reiner Textlink — Hover rot (führt zurück in die Schritte) */
.kf-korb-bearbeiten {
  display: inline-block; margin-top: 6px; background: none; border: none; padding: 2px 0;
  font-size: 11px; font-weight: 600; color: var(--kf-mid); cursor: pointer;
  transition: color 0.15s;
}
.kf-korb-bearbeiten:hover { color: var(--kf-fehler); }
/* Statuszeile über dem Artikel (nur in Bearbeitung): Hinweis + Speichern */
.kf-korb-status {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 10px;
}
.kf-korb-hinweis { margin: 0; font-size: 12px; font-weight: 600; color: var(--kf-akzent); }
/* Board-Übernahme: neutraler Prüf-Hinweis (blau wie „in Bearbeitung", kein
   Fehler-Amber — es fehlt nichts, es ist nur vorbelegt) */
.kf-korb-hinweis-pruefen { color: #2f6fd6; font-weight: 500; }
.kf-korb-speichern {
  flex: none; padding: 7px 16px; border: none; border-radius: 999px;
  background: var(--kf-ink); color: #fff; font-size: 11px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer;
}
.kf-korb-speichern:disabled { opacity: 0.35; cursor: not-allowed; }
/* Artikel in Bearbeitung: trägt jetzt denselben blauen Kasten wie ein
   angeklickter Artikel (Regel oben bei .kf-korb-gewaehlt) — kein Strich mehr. */

/* Editierbarer Artikelname ("Artikel 1" o. eigener Projektname) — der Stift
   daneben signalisiert die Editierbarkeit */
/* Titelzeile traegt rechts das × (Julian, 04.09.2026: ganz oben rechts, damit der
   Name nicht bis ganz rechts geht) — deshalb der Puffer rechts */
.kf-korb-titel-zeile { display: flex; align-items: center; gap: 4px; margin: 0 0 8px; min-width: 0; position: relative; padding-right: 34px; }
.kf-korb-titel {
  display: block; max-width: 100%; min-width: 0; margin: 0; padding: 2px 0;
  border: none; border-bottom: 1px dashed transparent; background: none;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: rgba(17, 17, 17, 0.55);
}
.kf-korb-titel:hover { border-bottom-color: rgba(17, 17, 17, 0.25); }
/* Beim Schreiben volle Zeilenbreite — kurze Namen werden sonst am Feldrand
   abgeschnitten; nach dem Verlassen schrumpft das Feld wieder an den Text */
.kf-korb-titel:focus { outline: none; border-bottom-color: var(--kf-akzent); color: var(--kf-ink); flex: 1; }
.kf-korb-titel::placeholder { color: rgba(17, 17, 17, 0.55); opacity: 1; }
.kf-korb-titel-stift {
  display: flex; align-items: center; justify-content: center; flex: none;
  width: 26px; height: 26px; background: none; border: none; border-radius: 6px;
  color: rgba(17, 17, 17, 0.45); cursor: pointer; padding: 0;
}
/* Unsichtbares Mess-Element: identischer Stil wie das Namensfeld */
.kf-korb-titel-mess {
  position: absolute; left: -9999px; top: 0; visibility: hidden;
  white-space: pre; width: auto !important;
}
.kf-korb-titel-stift:hover { color: var(--kf-akzent); background: rgba(29, 107, 255, 0.07); }

/* Datei-Aufklapper an der Veredelungs-Zeile */
.kf-dateien-btn {
  margin-left: 8px; background: none; border: none; padding: 0;
  font-size: 11px; font-weight: 600; color: var(--kf-akzent); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.kf-dateien-btn.offen { color: var(--kf-akzent-dunkel); }
.kf-korb-dateien { display: flex; flex-wrap: wrap; gap: 8px 16px; padding: 8px 0 2px; }
.kf-korb-dateien[hidden] { display: none; }
.kf-datei { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: rgba(17, 17, 17, 0.75); }
.kf-datei-thumb {
  width: 34px; height: 34px; border-radius: 6px; border: 1px solid var(--kf-border); flex: none;
  background-color: var(--kf-buehne); background-size: contain; background-position: center; background-repeat: no-repeat;
}
.kf-datei-thumb.leer::after { content: "PDF"; display: block; text-align: center; line-height: 32px; font-size: 9px; font-weight: 700; letter-spacing: 0.06em; color: var(--kf-mid); }
/* Text-Elemente im Aufklapper: Schriftprobe in Original-Schrift/-Farbe */
.kf-datei-thumb-text {
  display: flex; align-items: center; justify-content: center;
  background-color: #d8d4cd; font-size: 15px; font-weight: 600; line-height: 1;
}
.kf-datei-text strong { font-weight: 600; color: var(--kf-ink); }
.kf-korb-swatch { width: 40px; height: 40px; border-radius: 8px; border: 1px solid var(--kf-border); flex: none; background-size: contain; background-position: center; background-repeat: no-repeat; background-color: var(--kf-buehne); }
.kf-korb-info { flex: 1; min-width: 0; font-size: 13px; }
.kf-korb-name { display: block; font-weight: 600; font-size: 14px; }
.kf-korb-meta { display: block; color: rgba(17, 17, 17, 0.6); margin-top: 2px; }
/* Details/Staffelpreise als schlichte Textlinks — blau bei Hover und
   solange der Bereich offen ist */
.kf-korb-details-btn {
  display: inline-block; margin-top: 6px; background: none; border: none; padding: 2px 0;
  font-size: 11px; font-weight: 600; color: rgba(17, 17, 17, 0.55); cursor: pointer;
  transition: color 0.15s;
}
.kf-korb-details-btn:hover, .kf-korb-details-btn.offen { color: var(--kf-akzent); }
.kf-korb-details { display: block; margin-top: 6px; }
.kf-korb-details[hidden] { display: none; }
.kf-korb-details .kf-stufen-tabelle { margin-top: 6px; max-width: 340px; }
/* Fußnote unter der Staffeltabelle: bewusst dezent */
.kf-korb-details .kf-korb-meta { font-size: 11px; color: var(--kf-mid); margin-top: 5px; }
.kf-mwst-klein { margin: 2px 0 6px; min-height: 32px; }
.kf-korb-preis { font-weight: 600; white-space: nowrap; }
.kf-korb-entfernen {
  position: absolute; top: 50%; right: -8px; transform: translateY(-50%);
  background: none; border: none; color: var(--kf-mid); font-size: 17px; line-height: 1;
  padding: 6px; min-width: 32px; min-height: 32px;
}
.kf-korb-entfernen:hover { color: var(--kf-fehler); }
.kf-korb-leer { font-size: 13.5px; color: var(--kf-mid); padding: 8px 0 4px; }
/* Gesamtblock: Summen-Tabelle in voller Breite; darunter eine Steuerungszeile
   mit Rabattcode-Aufklapper (links) und MwSt-Schalter (rechts). */
.kf-korb-summe-zeile {
  display: flex; flex-direction: column; align-items: stretch; margin-top: 16px;
  padding-top: 16px; border-top: 2px solid rgba(17, 17, 17, 0.14); /* Trennung Artikel | Zusammenfassung */
}
/* Aufschlüsselung: Meta-Zeile + Artikel/Versand/Gesamt */
.kf-korb-summe { margin: 0; width: 100%; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.kf-summe-meta { font-size: 11px; font-weight: 500; color: var(--kf-mid); }
.kf-summe-zeile { display: flex; justify-content: space-between; gap: 16px; font-size: 13px; font-weight: 500; }
.kf-summe-zeile > span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
.kf-summe-gesamt { font-size: 15px; font-weight: 700; border-top: 1px solid var(--kf-border); margin-top: 3px; padding-top: 5px; }
.kf-summe-rabatt { color: var(--kf-akzent); }
/* Steuerungszeile direkt unter Gesamt: Rabattcode-Trigger links, MwSt rechts */
.kf-summe-controls {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-top: 8px;
}
.kf-summe-controls .kf-mwst-klein { margin: 0; flex: none; }
/* Trigger wächst mit, damit das offene Feld die freie Breite füllt (MwSt bleibt rechts) */
.kf-rabatt-trigger { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1 1 auto; }
/* Dezenter grauer „+ Rabattcode"-Knopf (kein Unterstrich, kein Kreis) */
.kf-rabatt-auf {
  border: none; background: none; cursor: pointer; padding: 5px 2px; min-height: 30px; margin-right: auto;
  font-family: inherit; font-size: 12px; font-weight: 500; color: var(--kf-mid);
}
.kf-rabatt-auf:hover { color: var(--kf-ink); }
/* Inline-Feld: Eingabe (breit, füllt die Zeile) + kleiner OK-Pfeil + Schließen-× */
.kf-rabatt-panel { margin-top: 4px; }
.kf-rabatt-eingabe { display: flex; gap: 5px; align-items: center; flex: 1 1 auto; min-width: 0; }
#kf-rabatt-input {
  flex: 1 1 auto; min-width: 0; height: 30px; padding: 4px 10px; font-size: 16px;
  border: 1px solid var(--kf-border); border-radius: 8px; background: #fff; color: var(--kf-ink);
  font-family: inherit; text-transform: uppercase;
}
#kf-rabatt-input::placeholder { text-transform: none; }
#kf-rabatt-input:focus { outline: none; border-color: var(--kf-ink); } /* schwarz statt blau */
/* Desktop-Feldgröße: siehe konsolidierten Block am Dateiende. */
.kf-rabatt-ok {
  flex: none; width: 30px; height: 30px; border-radius: 8px; cursor: pointer; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px;
  border: none; background: var(--kf-ink); color: #fff; /* schwarz statt blau */
}
.kf-rabatt-ok:hover { opacity: 0.85; }
.kf-rabatt-meldung { margin: 6px 0 0; font-size: 12px; color: var(--kf-fehler); }
/* Aktiver Code: Chip + Entfernen-× (liegt jetzt direkt im .kf-rabatt-trigger) */
.kf-rabatt-chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--kf-akzent);
  background: rgba(29, 107, 255, 0.08); border: 1px solid rgba(29, 107, 255, 0.2); border-radius: 999px; padding: 5px 11px;
  min-width: 0;
}
.kf-rabatt-chip strong { font-weight: 700; white-space: nowrap; }
.kf-rabatt-chip .i-haken { width: 13px; height: 13px; }
.kf-rabatt-weg {
  flex: none; width: 30px; height: 30px; border: none; background: none; cursor: pointer;
  color: var(--kf-mid); font-size: 20px; line-height: 1; border-radius: 7px;
}
.kf-rabatt-weg:hover { background: rgba(0, 0, 0, 0.06); color: var(--kf-fehler); }
/* Beide Aktionen NEBENEINANDER (spart Höhe, mehr Platz für die scrollende Liste):
   „+ Artikel konfigurieren" | „Anfrage fertigstellen" — gleich breit (Julian, 14.08.2026) */
.kf-korb-buttons { display: flex; gap: 10px; margin-top: 14px; flex-wrap: nowrap; }
.kf-korb-buttons > * { flex: 1 1 0; min-width: 0; }
.kf-korb-buttons .kf-form-toggle-wrap { display: flex; }
.kf-korb-buttons #kf-form-toggle { width: 100%; }
/* Aktuelle-Konfiguration-Wrapper: Karten fließen im 2-Spalten-Grid von Schritt 4 mit */
#kf-korb-card, #kf-form, .kf-erfolg { grid-column: 1 / -1; }
/* Anfrage-Liste scrollt in ihrem EIGENEN Fenster, damit Zusammenfassung (Summe,
   Rabattcode, MwSt) und die Buttons immer sichtbar bleiben — man muss nicht mehr
   an vielen Artikeln vorbeiscrollen, um „Anfrage fertigstellen" zu erreichen
   (Julian, 14.08.2026). Höhe = Viewport minus Nav + Summen-Footer; Untergrenze,
   damit sie auf kurzen Screens nicht kollabiert. Nur wenn Überlauf → Scrollbar. */
#kf-korb {
  /* 424px statt 380px (Julian, 01.09.2026): die „Sichere Zahlung"-Fußnote kam
     unter den Buttons dazu — die Liste gibt ihre Höhe ab, damit die Buttons in
     der Standard-Ansicht bündig sichtbar enden; die Fußnote liegt knapp
     darunter und ist per Panel-Scroll erreichbar. */
  max-height: max(220px, calc(100dvh - 424px));
  overflow-y: auto; overflow-x: hidden; /* NUR vertikal scrollen — kein Links/Rechts-Swipe */
  overscroll-behavior: contain; touch-action: pan-y;
  /* Scrollfenster bis an die Kartenkante ausdehnen (Items ziehen sich mit
     −20px-Margin dorthin, s. .kf-korb-gewaehlt) — der Auswahl-Ring ist INSET
     auf der Artikelkante gezeichnet und braucht daher keinen Extra-Rand im
     Clip-Bereich (Julian, 17./18.08.2026). */
  margin: -20px -20px 0; padding: 20px 20px 0;
  /* Scrollbar unsichtbar (wie .kf-flyout-panel): die sichtbare 8px-Leiste nahm
     rechts Platz weg — der Auswahl-Ring hatte dadurch rechts mehr Abstand als
     links (Julian, 18.08.2026). Ohne Leiste sind beide Seiten identisch. */
  scrollbar-width: none;
}
#kf-korb::-webkit-scrollbar { display: none; }
/* KOMPAKTER ABSCHLUSS (Julian, 04.09.2026: „am Anfang kleiner halten, erst bei
   Bestellung fertigstellen ausklappen — sonst nimmt es den Artikeln den Platz").
   Eingeklappt: nur Meta + Gesamt in einer Zeile und die zwei Knöpfe; die Liste
   bekommt die gesparte Höhe (max-height oben: 424px Footer → 236px). */
.kf-korb-kompakt-zeile { display: none; }
#kf-korb-card.kf-korb-kompakt .kf-korb-kompakt-zeile {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  /* Deutliche Trennung zwischen Artikeln und Zusammenfassung (Julian, 04.09.2026) */
  margin-top: 16px; padding-top: 16px; border-top: 2px solid rgba(17, 17, 17, 0.14);
}
.kf-korb-kompakt-meta { font-size: 12.5px; color: var(--kf-mid); }
.kf-korb-kompakt-gesamt { font-size: 15px; font-weight: 600; white-space: nowrap; }
.kf-korb-kompakt-gesamt strong { font-size: 19px; font-weight: 700; margin-left: 6px; }
#kf-korb-aufklappen { display: none; width: 100%; }
#kf-korb-card.kf-korb-kompakt #kf-korb-aufklappen { display: block; }
#kf-korb-card.kf-korb-kompakt .kf-korb-summe-zeile,
#kf-korb-card.kf-korb-kompakt .kf-summe-controls,
#kf-korb-card.kf-korb-kompakt #kf-rabatt-panel,
#kf-korb-card.kf-korb-kompakt .kf-versandland,
#kf-korb-card.kf-korb-kompakt .kf-kauf-email-feld,
#kf-korb-card.kf-korb-kompakt .kf-agb-check--kauf,
#kf-korb-card.kf-korb-kompakt .kf-datencheck,
#kf-korb-card.kf-korb-kompakt #kf-kauf-fehler,
#kf-korb-card.kf-korb-kompakt .kf-kauf-fussnote,
#kf-korb-card.kf-korb-kompakt .kf-vertrauen,
#kf-korb-card.kf-korb-kompakt #kf-form-toggle-wrap { display: none; }
/* 304px statt 236px (Julian, 04.09.2026: Knöpfe waren unten angeschnitten):
   Nav 72 + Schritt-Leiste 44 + Body-Polster 34 + Karten-Polster 40 + Trennlinie/
   Gesamt-Zeile ~60 + Knöpfe ~62 — gemessen bei 900 und 720 px Höhe. */
#kf-korb-card.kf-korb-kompakt #kf-korb { max-height: max(220px, calc(100dvh - 304px)); }
@media (max-width: 920px) {
  #kf-korb { margin: -12px -13px 0; padding: 12px 13px 0; }
}

.kf-form .kf-zwei { align-items: start; }
.kf-feld { margin-bottom: 12px; }
.kf-feld label { display: block; font-size: 12px; font-weight: 500; margin-bottom: 5px; color: rgba(17, 17, 17, 0.7); }
.kf-feld input, .kf-feld textarea {
  width: 100%; border: 1.5px solid var(--kf-border-strong); border-radius: 8px; background: #fff;
  padding: 11px 13px; font-size: 16px; color: var(--kf-ink); min-height: 44px; resize: vertical;
}
.kf-feld input:focus, .kf-feld textarea:focus { outline: none; border-color: var(--kf-akzent); }
/* Format-Feedback direkt im Feld: nach der Eingabe rot, wenn Pflicht/Muster
   (USt-ID, PLZ, E-Mail …) nicht passen — geprüft wird über die pattern-Attribute */
.kf-feld input:user-invalid { border-color: var(--kf-fehler); }
.kf-hp { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.kf-form-hinweis { font-size: 11.5px; color: var(--kf-mid); margin: 4px 0 14px; }
.kf-form-hinweis strong { font-weight: 600; color: var(--kf-ink); }
/* Abschnitts-Label (Rechnungs-/Lieferadresse) + Identisch-Checkbox */
.kf-form-abschnitt { margin-top: 16px; }
.kf-check {
  display: flex; align-items: center; gap: 9px; margin: 4px 0 14px;
  font-size: 13px; color: var(--kf-ink); cursor: pointer; min-height: 24px;
}
.kf-check input { width: 16px; height: 16px; accent-color: var(--kf-ink); flex: none; cursor: pointer; }
/* AGB-/Widerrufs-Bestätigung vor dem Absenden (Checkout-Vorbereitung 28.08.2026) */
.kf-agb-check { margin: 14px 0 12px; align-items: flex-start; font-size: 12.5px; line-height: 1.5; }
.kf-agb-check input { margin-top: 1px; }
.kf-agb-check a { color: var(--kf-ink); text-decoration: underline; text-underline-offset: 2px; }

/* Kundentyp-Umschaltung (Unternehmen / Privatperson): Segment-Steuerung,
   ausgewähltes Segment in Ink-Fläche — gleiche Tokens wie .kf-familie.active */
.kf-kundentyp {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  background: #fff; border: 1.5px solid var(--kf-border-strong); border-radius: 10px;
  padding: 4px; margin-bottom: 14px;
}
.kf-kundentyp-opt {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; border-radius: 7px; cursor: pointer;
  font-size: 13px; font-weight: 600; letter-spacing: 0.02em; color: var(--kf-ink);
  transition: background 0.18s, color 0.18s;
}
.kf-kundentyp-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.kf-kundentyp-opt:has(input:checked) { background: var(--kf-ink); color: var(--kf-bg); }
.kf-kundentyp-opt:has(input:focus-visible) { box-shadow: 0 0 0 2px var(--kf-akzent); }

/* Erfolg */
.kf-erfolg { text-align: center; padding: 40px 20px; }
.kf-erfolg-check {
  width: 58px; height: 58px; margin: 0 auto 18px; border-radius: 50%;
  background: rgba(47, 158, 95, 0.12); color: var(--kf-gruen);
  display: flex; align-items: center; justify-content: center;
  animation: kf-puls 1.2s ease-out 1;
}
@keyframes kf-puls {
  0% { box-shadow: 0 0 0 0 rgba(47, 158, 95, 0.35); }
  100% { box-shadow: 0 0 0 22px rgba(47, 158, 95, 0); }
}
@media (prefers-reduced-motion: reduce) { .kf-erfolg-check { animation: none; } }
.kf-erfolg h2 { font-size: 21px; font-weight: 600; margin-bottom: 8px; }
.kf-erfolg p { font-size: 14px; color: rgba(17, 17, 17, 0.6); max-width: 380px; margin: 0 auto; }

/* Buttons */
.kf-nav-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 18px; }
/* Variante: „Design bestätigen" voll-breit (genauso lang wie „Sample anfragen") */
.kf-nav-row--voll { display: block; margin-top: 10px; }
.kf-nav-row--voll > .kf-btn-primary { width: 100%; }
/* … und seit dem 29.09.2026 auch rund wie die beiden Knöpfe darüber (Julian:
   „mach das Design bestätigen auch als Pille"). Gilt für denselben Platz, wenn
   dort statt des Weiter-Knopfs der Mail-Weg steht (ausverkaufte Familie). */
.kf-nav-row--voll .kf-btn-primary { border-radius: 999px; }
.kf-nav-row--voll .kf-mail-wrap:not([hidden]) { display: block; }
/* CTA „Nicht das Richtige gefunden?" — dezent unter Schritt 1 & Anfrage.
   Standardmäßig nur die Frage; beim Hovern schiebt sich „Jetzt anfragen →"
   heraus. Klick öffnet das Anfrage-Popup direkt im Konfigurator. */
/* Voller Trennstrich + rechtsbündig; der Button selbst ist nur so breit wie sein
   Text, damit „Jetzt anfragen" NUR beim Hover über den Text ausfährt (nicht über
   die ganze Leiste), Julian 06.08.2026. */
.kf-cta-anfrage-wrap {
  /* „Nicht das Richtige gefunden?" links in der Spalte — rechts sitzt (fix) das
     Ansprechpartner-Widget. Kein Trennstrich (Julian, 11.08.2026). */
  margin-top: 14px; display: flex; justify-content: flex-start; align-items: center;
  min-height: 46px;
}
/* Design-Schritt: hier ist links das große Produktbild — die CTA sitzt deshalb
   rechts unter „Design bestätigen" (Julian, 11.08.2026). */
[data-step-panel="1"] .kf-cta-anfrage-wrap { justify-content: flex-end; }
.kf-cta-anfrage {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0;
  border: none; background: none; font-family: "DM Sans", sans-serif;
  font-size: 12.5px; cursor: pointer; color: rgba(17, 17, 17, 0.55);
}
.kf-cta-frage { transition: color 0.15s ease; }
.kf-cta-reveal {
  color: var(--kf-akzent); font-weight: 600; white-space: nowrap;
  max-width: 0; overflow: hidden; opacity: 0; transform: translateX(-4px);
  transition: max-width 0.28s ease, opacity 0.2s ease, transform 0.2s ease;
}
.kf-cta-anfrage:hover .kf-cta-frage,
.kf-cta-anfrage:focus-visible .kf-cta-frage { color: var(--kf-text); }
.kf-cta-anfrage:hover .kf-cta-reveal,
.kf-cta-anfrage:focus-visible .kf-cta-reveal { max-width: 170px; opacity: 1; transform: translateX(0); }
/* Touch (kein Hover): den Hinweis dauerhaft zeigen, damit er tippbar erkennbar ist */
@media (hover: none) {
  .kf-cta-reveal { max-width: 170px; opacity: 1; transform: none; }
}

/* Inline-Icons (→ ← ✓) als SVG — DM Sans enthält diese Zeichen NICHT, sie fielen
   sonst live auf eine System-Schrift zurück. Größe folgt em, Farbe currentColor. */
.i-icon { display: inline-block; width: 1em; height: 1em; vertical-align: -0.125em; flex-shrink: 0; }
/* Deaktivierte Haupt-/Ghost-Buttons klar ausgrauen; pointer-events aus, damit der
   Hover-Hinweis am umschließenden Wrapper (z. B. „Anfrage fertigstellen") greift. */
.kf-btn-primary:disabled, .kf-btn-ghost:disabled { opacity: 0.4; pointer-events: none; }
.kf-form-toggle-wrap { display: inline-flex; }
.kf-form-toggle-wrap.kf-nicht-bereit { cursor: not-allowed; }
.kf-btn-primary {
  background: var(--kf-ink); color: var(--kf-bg); border: none; border-radius: 4px;
  padding: 15px 26px; min-height: 48px; font-size: 11px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; transition: opacity 0.2s; position: relative;
}
.kf-btn-primary:hover { opacity: 0.82; }
.kf-btn-ghost {
  background: none; color: rgba(17, 17, 17, 0.65); border: 1px solid rgba(17, 17, 17, 0.18);
  border-radius: 4px; padding: 14px 22px; min-height: 48px; font-size: 11px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; transition: all 0.2s;
}
.kf-btn-ghost:hover { border-color: rgba(17, 17, 17, 0.45); color: var(--kf-ink); }
.kf-btn-klein { padding: 10px 16px; min-height: 44px; margin-top: 14px; }
.kf-btn-breit { width: 100%; }

/* Lade-Zustand (analog .btn-laedt in app.css) */
.kf-btn-laedt { pointer-events: none; opacity: 0.75; }
.kf-btn-laedt span { visibility: hidden; }
.kf-btn-laedt::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 16px; height: 16px;
  margin: -8px 0 0 -8px; border: 2px solid rgba(240, 238, 236, 0.35);
  border-top-color: var(--kf-bg); border-radius: 50%;
  animation: kf-spin 0.7s linear infinite;
}
@keyframes kf-spin { to { transform: rotate(360deg); } }

/* Modals */
/* ── Einstiegs-Tutorial (partials/kf-tutorial, js/konfi-tutorial.js) ──────
   Ein Spotlight-Fenster, das einmal durch die Bereiche führt. Der dunkle
   Grund entsteht NICHT als Fläche, sondern als riesiger Schatten um das
   Loch — so bleibt das hervorgehobene Element in seiner echten Farbe stehen
   (Julian, 10.09.2026: „Text mit Hervorhebung"). */
.kf-tut { position: fixed; inset: 0; z-index: 150; }
.kf-tut[hidden] { display: none; }
.kf-tut-loch {
  position: fixed; border-radius: 12px; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(17, 17, 17, 0.55), 0 0 0 2px rgba(255, 255, 255, 0.85);
  transition: top 0.25s ease, left 0.25s ease, width 0.25s ease, height 0.25s ease;
}
.kf-tut-loch[hidden] { display: none; }
/* Ist kein Loch gesetzt (Ziel gerade nicht sichtbar), braucht das Fenster
   selbst einen Grund — sonst stünde die Karte auf dem hellen Konfigurator. */
.kf-tut:has(.kf-tut-loch[hidden]) { background: rgba(17, 17, 17, 0.55); }
.kf-tut-karte {
  position: fixed; width: min(340px, calc(100vw - 24px));
  background: var(--kf-karte-bg); border-radius: var(--kf-karte-radius); padding: 18px 20px 16px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.3);
}
.kf-tut-karte-mitte { top: 50%; left: 50%; transform: translate(-50%, -50%); }
.kf-tut-zaehler {
  font-family: "IBM Plex Mono", monospace; font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--kf-mid); margin: 0 0 6px;
}
.kf-tut-titel { font-size: 17px; font-weight: 600; margin: 0 0 6px; }
.kf-tut-text { font-size: 13.5px; line-height: 1.6; color: rgba(17, 17, 17, 0.72); margin: 0; }
.kf-tut-text strong { font-weight: 600; color: var(--kf-ink); }
.kf-tut-punkte { display: flex; gap: 5px; margin: 14px 0 0; }
.kf-tut-punkte span {
  width: 6px; height: 6px; border-radius: 50%; background: rgba(17, 17, 17, 0.16);
}
.kf-tut-punkte span.aktiv { background: var(--kf-akzent); }
.kf-tut-knoepfe { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.kf-tut-spacer { flex: 1; }
.kf-tut-skip, .kf-tut-zurueck {
  background: none; border: none; padding: 8px 6px; cursor: pointer;
  font-family: "DM Sans", sans-serif; font-size: 12.5px; color: var(--kf-mid);
}
.kf-tut-skip:hover, .kf-tut-zurueck:hover { color: var(--kf-ink); }
.kf-tut-weiter { padding: 9px 18px; font-size: 12.5px; }
/* Solange das Fenster offen ist, wird hinter ihm nicht gescrollt. */
body.kf-tut-offen { overflow: hidden; }
@media (prefers-reduced-motion: reduce) {
  .kf-tut-loch { transition: none; }
}
@media (max-width: 560px) {
  /* Auf dem Handy sitzt die Karte fest am unteren Rand: sie muss sich nicht
     um ein Ziel drängeln, das fast die halbe Höhe einnimmt. */
  .kf-tut-karte, .kf-tut-karte-mitte {
    top: auto !important; left: 12px !important; right: 12px;
    bottom: 12px; width: auto; transform: none;
  }
  /* Ziel in der unteren Hälfte → Karte nach oben, sonst verdeckt sie das
     Element, das sie erklärt (js/konfi-tutorial.js setzt die Klasse). */
  .kf-tut-karte.kf-tut-oben {
    top: var(--kf-tut-oben, calc(var(--nav-h, 60px) + 12px)) !important; bottom: auto;
  }
}
/* Beim Öffnen liegt der Fokus auf „Weiter" (Tastatur) — auf dem Handy stand
   dort ein doppelter schwarzer Ring um den schwarzen Knopf. Leiser Ring statt
   keinem (Mobil-Runde 2, 16.10.2026: „nicht so ganz so clean"). */
.kf-tut-karte .kf-tut-weiter:focus-visible { outline: 2px solid rgba(13, 13, 13, 0.22); outline-offset: 2px; box-shadow: none; }

.kf-modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 20px; }
.kf-modal[hidden] { display: none; }
/* Das Zuschneiden öffnet seit dem 15.10.2026 auch vom Board — über dessen Leiste (z 150/160) */
.kf-crop-modal { z-index: 400; }
.kf-modal-backdrop { position: absolute; inset: 0; background: rgba(17, 17, 17, 0.4); }
.kf-modal-box {
  /* Karten-System, große Variante: gleiche Fläche/Radius wie Popover/Dialog,
     nur stärkere Elevation (größere Oberfläche) */
  position: relative; background: var(--kf-karte-bg); border-radius: var(--kf-karte-radius); padding: 28px;
  max-width: 460px; width: 100%; max-height: 84vh; max-height: 84svh; overflow-y: auto;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.25);
}
.kf-modal-box h2 { font-size: 17px; font-weight: 600; margin-bottom: 14px; }
.kf-modal-close {
  position: absolute; top: 12px; right: 12px; width: 36px; height: 36px;
  background: none; border: none; font-size: 20px; color: var(--kf-mid); border-radius: 8px;
}
.kf-modal-close:hover { background: rgba(0, 0, 0, 0.05); color: var(--kf-ink); }
.kf-modal-box ul { list-style: none; }
.kf-modal-box li { font-size: 13.5px; padding: 8px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.06); }
.kf-modal-box li:last-child { border-bottom: none; }
.kf-sizeguide { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.kf-sizeguide th, .kf-sizeguide td {
  padding: 7px 6px; text-align: center; border-bottom: 1px solid rgba(0, 0, 0, 0.07);
  font-family: "DM Sans", sans-serif;
}
.kf-sizeguide td:first-child { text-align: left; font-family: "DM Sans", sans-serif; font-weight: 500; }
.kf-modal-hinweis { font-size: 12px; color: var(--kf-mid); margin-top: 12px; }

/* ── Newsletter-Popup (Double-Opt-In) ── */
.kf-nl-box { max-width: 420px; text-align: center; }
.kf-nl-box h2 { margin-bottom: 8px; }
.kf-nl-icon {
  width: 50px; height: 50px; margin: 4px auto 14px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.05); color: var(--kf-ink);
}
.kf-nl-text { font-size: 13.5px; line-height: 1.5; color: var(--kf-mid); margin-bottom: 14px; }
.kf-nl-kontext {
  display: inline-block; font-size: 11px; letter-spacing: 0.03em; color: var(--kf-ink);
  background: rgba(0, 0, 0, 0.05); border-radius: 999px; padding: 5px 12px; margin-bottom: 14px;
}
/* [hidden] muss Author-CSS schlagen (sonst bleiben Form/Kontext beim Erfolg sichtbar) */
.kf-nl-form[hidden], .kf-nl-kontext[hidden], .kf-nl-erfolg[hidden], .kf-nl-fehler[hidden] { display: none; }
.kf-nl-reihe { display: flex; gap: 8px; align-items: stretch; }
#kf-nl-email {
  flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 10px 13px; font-size: 16px;
  border: 1px solid var(--kf-border); border-radius: 10px; background: #fff; color: var(--kf-ink);
  font-family: inherit;
}
#kf-nl-email:focus { outline: none; border-color: var(--kf-ink); }
.kf-nl-reihe .kf-btn-primary { flex: none; white-space: nowrap; }
.kf-nl-fehler { font-size: 12.5px; color: var(--kf-fehler); margin-top: 8px; text-align: left; }
.kf-nl-datenschutz { font-size: 11px; line-height: 1.5; color: var(--kf-mid); margin-top: 12px; }
.kf-nl-erfolg { padding: 8px 0 4px; }
.kf-nl-haken {
  width: 46px; height: 46px; margin: 0 auto 12px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.05); color: var(--kf-ink);
}
.kf-nl-haken svg, .kf-nl-haken .i-haken { width: 22px; height: 22px; }
.kf-nl-erfolg p { font-size: 14px; line-height: 1.55; color: var(--kf-ink); }
/* Ausverkaufte Größe als Benachrichtigungs-Trigger (ganze Kachel klickbar) */
.kf-groesse-benachrichtigen { cursor: pointer; }
.kf-groesse-benachrichtigen .kf-groesse-toggle,
.kf-groesse-benachrichtigen input { pointer-events: none; }

/* ── Zuschneiden-Modal (Doppelklick auf ein Bild-Design) ── */
.kf-crop-box { max-width: 560px; }
.kf-crop-buehne {
  position: relative; margin: 4px auto 0; max-width: 100%;
  /* Schachbrett = Transparenz sichtbar (v.a. bei freigestellten KI-Designs) */
  background: repeating-conic-gradient(#eeeeec 0% 25%, #fff 0% 50%) 50% / 18px 18px;
  border-radius: 8px; overflow: hidden; touch-action: none; user-select: none; line-height: 0;
}
.kf-crop-buehne img { display: block; width: 100%; height: 100%; pointer-events: none; }
.kf-crop-rahmen {
  position: absolute; border: 1.5px dashed #fff; cursor: move; box-sizing: border-box;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45); /* dunkelt alles außerhalb ab */
  outline: 1px solid rgba(0, 0, 0, 0.35);
}
.kf-crop-griff {
  position: absolute; width: 14px; height: 14px; background: #fff; border: 1.5px solid var(--kf-akzent);
  border-radius: 3px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.kf-crop-griff[data-ecke="tl"] { left: -8px; top: -8px; cursor: nwse-resize; }
.kf-crop-griff[data-ecke="tr"] { right: -8px; top: -8px; cursor: nesw-resize; }
.kf-crop-griff[data-ecke="bl"] { left: -8px; bottom: -8px; cursor: nesw-resize; }
.kf-crop-griff[data-ecke="br"] { right: -8px; bottom: -8px; cursor: nwse-resize; }
.kf-crop-verhaeltnisse { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 16px; }
.kf-crop-verhaeltnisse button {
  padding: 8px 13px; min-height: 38px; border: 1px solid var(--kf-border); border-radius: 9px;
  background: #fff; color: var(--kf-ink); font-family: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer;
}
.kf-crop-verhaeltnisse button:hover { border-color: var(--kf-border-strong); }
.kf-crop-verhaeltnisse button.active { background: var(--kf-ink); color: #fff; border-color: var(--kf-ink); }
.kf-crop-verhaeltnisse .kf-crop-trim { margin-left: auto; color: var(--kf-akzent); border-color: rgba(29, 107, 255, 0.35); }
.kf-crop-verhaeltnisse .kf-crop-trim:hover { background: rgba(29, 107, 255, 0.06); }
.kf-crop-aktionen { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }

/* ── Responsive: Breite ─────────────────────────────────── */
@media (max-width: 920px) {
  /* Mobil/Tablet hochkant: Bühne als kompakte Vorschau oben (Schritt 1 groß,
     ab Schritt 2 schmaler Streifen), Panel füllt den Rest — Seite scrollt NICHT. */
  .kf-body {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 38%) minmax(0, 1fr);
    padding: 10px 14px 10px;
  }
  .kf-stage { padding-right: 0; margin-bottom: 10px; flex-direction: column; gap: 8px; }
  .kf-stage-wrap { border-radius: 8px; }
  .kf-thumb { width: 40px; height: 48px; }

  .kf-thumb-tag { display: none; }
  .kf-upload { margin-top: 8px; }
  .kf-upload-hint { display: none; }
  .kf-tabs { justify-content: flex-start; }
  /* Ab Schritt 2: Produktansicht standardmäßig ausgeklappt (Julian, 18.08.2026 —
     „standard ausgeklappt, durchscrollen, bei Bedarf zuklappen"). Höhe 34% in
     ALLEN Schritten ab 2 (Julian: wie in der Anfrage — kompakter gefiel besser,
     das Panel behält mehr Raum). Zugeklappt (Chevron/Tap → Body-Klasse
     kf-mini-zu) wird sie zum 76px-Streifen. */
  /* body.kf-ab-schritt-2 gibt es seit dem 30.09.2026 nicht mehr — es hing an
     der Vorstellung, dass Gestalten ab Schritt 2 vorbei ist. Die Zeilen dafür
     (34 % bzw. 76 px) sind mit ihr entfallen. */
  body.kf-mini-zu .kf-body { grid-template-rows: 76px minmax(0, 1fr); }
  body.kf-mini-zu .kf-thumbs { display: none; }
  .kf-sonder-label { margin-top: 10px; }
}
/* Handy quer: nebeneinander wie Desktop, Bühne schmal, Breite nutzen */
@media (max-width: 920px) and (max-height: 500px) {
  .kf-body { grid-template-columns: 34% 1fr; grid-template-rows: 1fr; }
  .kf-stage { margin-bottom: 0; padding-right: 14px; }
  body.kf-mini-zu .kf-body { grid-template-rows: 1fr; }
  /* Spalten-Layout: die Portrait-Regel (54%-Zeile im Design-Schritt) gilt hier nicht */
  body.kf-design-aktiv .kf-body { grid-template-rows: 1fr; }
  .kf-groessen { grid-template-columns: repeat(auto-fit, minmax(44px, 1fr)); }
  .kf-vered-grid { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }   /* drei nur, wenn sie passen (Bild 40, 12.10.2026) */
  .kf-summary-bar { margin-bottom: 6px; }
  .kf-stufen-hint { display: none; }
  .kf-option-badge { display: none; }
  .kf-option { padding: 3px 10px; margin-bottom: 3px; }
  .kf-radios label { min-height: 24px; font-size: 11px; }
  .kf-sonder-label { margin-top: 6px; }
  .kf-modus-btn { min-height: 18px; padding: 1px 8px; font-size: 8.5px; }
  .kf-info-i { width: 16px; height: 16px; font-size: 9px; }
  .kf-groessen-kopf .kf-label, .kf-modus { margin-bottom: 2px; }
  #kf-groessen-block { margin-top: 10px; }
  .kf-groessen-status { display: none; }
  .kf-summary-bar { margin-bottom: 4px; }
  .kf-design-hint { display: none; }
  .kf-sonder-label { margin-top: 3px; }
  .kf-option { margin-bottom: 2px; }
  .kf-option-name { font-size: 11px; }
}
@media (max-width: 920px) {
  /* Kompakter, damit die Schritte ohne Scrollen ins Panel passen */
  .kf-option-text { display: none; }
  .kf-option { padding: 8px 12px; margin-bottom: 6px; }
  .kf-block { margin-top: 8px; }
  #kf-groessen-block { margin-top: 16px; }
  .kf-nav-row { margin-top: 8px; }
  .kf-card { padding: 12px 13px; margin-bottom: 8px; }
  .kf-summary-zeile { padding: 4px 0; font-size: 12.5px; }
  .kf-stufen-tabelle td { padding: 2px 8px; font-size: 10.5px; }
  .kf-lieferzeit { padding: 8px 12px; margin-bottom: 8px; }
  .kf-stepper, .kf-preisbox { height: 44px; }
  .kf-familien { margin-bottom: 10px; }
  .kf-radios label { min-height: 40px; }
  .kf-groesse input { min-height: 40px; padding: 6px 8px; }
  .kf-vered { padding: 8px 12px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
  .kf-vered-name { font-size: 13px; margin-bottom: 0; }
  .kf-zwei { gap: 8px; }
  .kf-summary-zeile { padding: 3px 0; }
  .kf-stufen-tabelle td { padding: 2px 6px; font-size: 10px; }
  .kf-preis-kopf { margin-bottom: 6px; }
  .kf-chip { min-height: 44px; padding: 8px 12px; }
  .kf-upload { margin-top: 6px; }
  .kf-groessen-status, .kf-stufen-hint, .kf-moq-hint { font-size: 11.5px; margin-top: 5px; }
  .kf-liefer-final, .kf-preis-fussnote { font-size: 10.5px; margin-top: 4px; }
  .kf-preis-kopf { margin-bottom: 8px; }
  .kf-form-hinweis { margin: 2px 0 8px; }
  .kf-feld { margin-bottom: 7px; }
  .kf-feld input, .kf-feld textarea { min-height: 42px; padding: 8px 11px; }
  .kf-label { margin-bottom: 5px; }
  .kf-btn-primary, .kf-btn-ghost { min-height: 44px; padding-top: 11px; padding-bottom: 11px; }
  .kf-modus-btn { min-height: 26px; padding: 2px 10px; font-size: 10px; }
  .kf-groessen-kopf .kf-label, .kf-modus { margin-bottom: 4px; }
  .kf-stepper, .kf-preisbox { height: 42px; }
  .kf-design-hint { margin-top: 2px; font-size: 11px; }
  .kf-zuordnung { margin-top: 4px; font-size: 11px; }
}
@media (max-width: 480px) {
  .kf-header { padding: 0 14px; }
  .kf-zwei { grid-template-columns: 1fr 1fr; }
  .kf-styles { grid-template-columns: 1fr 1fr; }
  /* Veredelung 2 × 2 (Julian, 16.10.2026: „Vektordatei, SVG und PDF … rausnehmen, oder …
     die 4 in 2er reinmachen"): beides — das Vektor-Abzeichen fällt mobil weg (das „i" der
     Kachel und der Upload-Hinweis sagen es weiter), damit passen zwei nebeneinander. */
  .kf-vered-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .kf-vered-grid .kf-vered-badge { display: none; }
  .kf-vered-grid .kf-vered { padding: 13px 12px; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between; gap: 8px; }
  .kf-vered-grid .kf-vered-name { font-size: 14px; padding-right: 24px; margin-bottom: 0; }
  .kf-vered-grid .kf-vered-moq { margin: 0; position: static; }
  .kf-nav-row { flex-wrap: wrap; }
  .kf-nav-row .kf-btn-primary { flex: 1; }
  .kf-produkt-name { font-size: 19px; }
}

/* ── Responsive: Höhe (alles auf einen Blick, ohne Scrollen) ── */
@media (max-height: 860px) {
  .kf-body { padding-top: 12px; padding-bottom: 12px; }
  .kf-block { margin-top: 14px; }
  .kf-nav-row { margin-top: 14px; }
  .kf-stepper, .kf-preisbox { height: 50px; }
  .kf-preisbox strong, .kf-stepper input { font-size: 17px; }
  .kf-vered { padding: 10px 14px; }
  .kf-vered-name { font-size: 13.5px; margin-bottom: 4px; }
  .kf-option { padding: 9px 14px; margin-bottom: 6px; }
  .kf-radios label { min-height: 38px; }
  .kf-card { padding: 14px 16px; margin-bottom: 10px; }
  .kf-summary-zeile { padding: 6px 0; }
  .kf-stufen-tabelle td { padding: 5px 10px; }
  .kf-groesse input { padding: 8px 10px; }
  .kf-lieferzeit { padding: 10px 14px; margin-bottom: 12px; }
  .kf-familien { margin-bottom: 12px; }
  .kf-familie { padding: 7px 14px; min-height: 36px; }
  .kf-produkt-name { font-size: 20px; }
  .kf-label { margin-bottom: 6px; }
  .kf-groessen-status, .kf-stufen-hint { margin-top: 6px; }
  .kf-btn-primary, .kf-btn-ghost { min-height: 44px; padding-top: 12px; padding-bottom: 12px; }
  .kf-modus-btn { min-height: 24px; padding: 2px 10px; font-size: 10px; }
  .kf-groessen-kopf .kf-label, .kf-modus { margin-bottom: 5px; }
  .kf-design-hint { margin-top: 2px; font-size: 11.5px; }
  .kf-zuordnung { margin-top: 5px; font-size: 11.5px; }
}
@media (max-height: 700px) {
  .kf-upload-hint, .kf-option-text { display: none; }
  .kf-thumb { width: 48px; height: 56px; }
  .kf-thumb-tag { display: none; }
  .kf-seite-canvas { aspect-ratio: 1 / 0.8; }
  .kf-produkt-name { font-size: 18px; }
  .kf-option-koerper { margin-top: 10px; padding-top: 10px; }
  .kf-erfolg { padding: 20px; }
  .kf-form-hinweis { margin: 2px 0 8px; }
  .kf-feld { margin-bottom: 8px; }
  .kf-feld input, .kf-feld textarea { padding: 8px 12px; }
  .kf-feld textarea { min-height: 44px; height: 44px; }
}
/* Breite Desktops mit wenig Höhe: die BREITE nutzen — Größen in eine Reihe,
   Veredelung so viele Spalten, wie ganz hineinpassen (fest drei schoben die
   dritte Karte über den Rand, Julian 12.10.2026: „rechts ist das gecuttet"). */
@media (min-width: 921px) and (max-height: 780px) {
  .kf-groessen { grid-template-columns: repeat(auto-fit, minmax(58px, 1fr)); }
  .kf-vered-grid { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }   /* drei nur, wenn sie passen (Bild 40, 12.10.2026) */
  .kf-option-text { display: none; }
  .kf-option-koerper { margin-top: 10px; padding-top: 10px; }
  .kf-summary-bar { margin-bottom: 12px; }
  .kf-card { padding: 14px 16px; margin-bottom: 10px; }
  .kf-summary-zeile { padding: 5px 0; font-size: 13.5px; }
  .kf-stufen-tabelle td { padding: 4px 8px; font-size: 11.5px; }
}
@media (min-width: 921px) and (max-height: 660px) {
  .kf-block { margin-top: 10px; }
  .kf-nav-row { margin-top: 10px; }
  .kf-stepper, .kf-preisbox { height: 42px; flex-direction: row; gap: 6px; }
  .kf-preisbox strong, .kf-stepper input { font-size: 15px; }
  .kf-vered { padding: 8px 12px; min-height: 40px; }
  .kf-vered-name { font-size: 12.5px; margin-bottom: 2px; }
  .kf-vered-moq { padding: 2px 7px; }
  .kf-option { padding: 8px 12px; margin-bottom: 6px; }
  .kf-radios label { min-height: 34px; }
  .kf-card { padding: 10px 12px; margin-bottom: 8px; }
  .kf-summary-zeile { padding: 4px 0; font-size: 13px; }
  .kf-stufen-tabelle td { padding: 3px 8px; font-size: 11px; }
  .kf-groesse input { padding: 5px 8px; min-height: 34px; font-size: 14px; }
  .kf-lieferzeit { padding: 7px 12px; margin-bottom: 8px; }
  .kf-familie { padding: 5px 12px; min-height: 32px; font-size: 11px; }
  /* Nur die ALTEN runden Farb-Punkte verkleinern — die Produktbild-Kacheln
     (.kf-farbe-mock) behalten immer ihre volle Größe (Julian, 18.08.2026:
     Bilder wurden in flachen Fenstern winzig). */
  .kf-farbe:not(.kf-farbe-mock) { width: 24px; height: 24px; }
  .kf-produkt-name { font-size: 17px; }
  .kf-chip { min-height: 40px; padding: 6px 12px; }
  .kf-btn-primary, .kf-btn-ghost { min-height: 38px; padding-top: 9px; padding-bottom: 9px; }
  .kf-upload-btn { min-height: 38px; padding: 7px 12px; }
  .kf-upload-hint { display: none; }
  .kf-liefer-final, .kf-preis-fussnote { margin-top: 5px; font-size: 10.5px; }
  .kf-stufen-hint, .kf-groessen-status { font-size: 11.5px; }
  .kf-erfolg { padding: 14px; }
  .kf-label { margin-bottom: 4px; }
  .kf-korb-item { padding: 6px 0; }
  .kf-korb-swatch { width: 30px; height: 30px; }
  .kf-feld { margin-bottom: 6px; }
  .kf-feld input, .kf-feld textarea { padding: 6px 10px; min-height: 36px; font-size: 14px; }
  .kf-feld label { margin-bottom: 2px; }
  .kf-form-hinweis { margin: 2px 0 8px; }
}
/* Sehr flache Fenster (z.B. Laptop-Halbfenster): Bühne schmaler statt Panel quetschen */
@media (min-width: 921px) and (max-height: 560px) {
  .kf-body { grid-template-columns: 34% 1fr; padding-top: 10px; padding-bottom: 10px; }
  .kf-tabs { height: 38px; }
  :root { --kf-header-h: 50px; --kf-tabs-h: 38px; }
  .kf-logo img { height: 22px; }

  .kf-thumb-tag { display: none; }
}
/* Extrem flach (Halb-Fenster / Handy quer): maximale Verdichtung */
@media (min-width: 921px) and (max-height: 545px), (max-width: 920px) and (max-height: 500px) {
  .kf-block { margin-top: 6px; }
  .kf-nav-row { margin-top: 6px; }
  .kf-body { padding-top: 6px; padding-bottom: 6px; }
  .kf-lieferzeit { padding: 4px 10px; margin-bottom: 4px; font-size: 10.5px; }
  .kf-block { margin-top: 4px; }
  .kf-nav-row { margin-top: 4px; }
  .kf-stepper, .kf-preisbox { height: 34px; }
  .kf-preisbox strong, .kf-stepper input { font-size: 13px; }
  .kf-preisbox .mono { display: none; }
  .kf-groesse input { min-height: 26px; padding: 2px 6px; font-size: 12.5px; }
  .kf-groesse label { font-size: 8px; margin-bottom: 1px; }
  .kf-vered { padding: 4px 10px; min-height: 30px; display: flex; align-items: center; gap: 8px; }
  .kf-vered-name { font-size: 11px; margin: 0; }
  .kf-vered-moq { font-size: 7.5px; padding: 1px 6px; }
  .kf-option { padding: 4px 10px; margin-bottom: 4px; }
  .kf-radios label { min-height: 26px; font-size: 11.5px; }
  .kf-option-name { font-size: 12px; }
  .kf-card { padding: 8px 10px; margin-bottom: 6px; }
  .kf-summary-zeile { padding: 2px 0; font-size: 11.5px; }
  .kf-stufen-tabelle td { padding: 1px 6px; font-size: 9.5px; }
  .kf-mwst { min-height: 26px; }
  .kf-preis-kopf { margin-bottom: 6px; }
  .kf-liefer-final, .kf-preis-fussnote { display: none; }
  .kf-btn-primary, .kf-btn-ghost { min-height: 30px; padding: 5px 12px; font-size: 9.5px; }
  .kf-upload-btn { min-height: 30px; padding: 4px 10px; font-size: 11px; }
  .kf-chip { min-height: 32px; padding: 4px 10px; }
  .kf-chip-titel { font-size: 11px; }
  .kf-produkt-name { font-size: 15px; }
  .kf-farbe:not(.kf-farbe-mock) { width: 22px; height: 22px; }
  .kf-familie { padding: 3px 10px; min-height: 26px; font-size: 10px; }
  .kf-label { font-size: 9px; margin-bottom: 3px; }
  .kf-stufen-hint, .kf-groessen-status, .kf-moq-hint { font-size: 10px; margin-top: 3px; }
  .kf-feld { margin-bottom: 4px; }
  .kf-feld input, .kf-feld textarea { min-height: 28px; padding: 4px 8px; font-size: 12.5px; }
  .kf-feld label { font-size: 10px; margin-bottom: 1px; }
  .kf-korb-item { padding: 4px 0; }
  .kf-korb-swatch { width: 24px; height: 24px; }
  .kf-korb-name { font-size: 12px; }
  .kf-korb-info { font-size: 11px; }
  .kf-btn-klein { margin-top: 6px; }
  .kf-form-hinweis { display: none; }
}

/* ── Werkzeuge mobil: Rail als horizontale Leiste unter der Bühne, das
     offene Flyout legt sich als Zeile darunter ── */
@media (max-width: 920px) {
  .kf-toolbar {
    order: 3; width: auto; margin-right: 0;
    max-height: 0; transform: translateY(-8px);
    transition: max-height 0.3s ease, opacity 0.25s ease, transform 0.3s ease, margin-top 0.3s ease;
  }
  body.kf-design-aktiv .kf-toolbar { width: auto; max-height: 76px; margin-top: 8px; opacity: 1; transform: none; }
  /* Höhe bleibt IMMER 64px (nur die Rail) — auch mobil schwebt das Flyout
     als Overlay über der Bühne statt Platz wegzunehmen */
  /* Im Design-Schritt dominiert das Produkt: Bühne + Werkzeugleiste nehmen den
     Großteil des Screens ein (Julian, 18.08.2026) — zur Produktauswahl
     (Familie/Farben) scrollt man im Panel darunter einfach nach unten. */
  /* 68 % für die Bühne waren richtig, solange rechts nur die Produktauswahl
     stand. Seit dem 30.09.2026 steckt dort die ganze Konfiguration — Menge,
     Größen, Veredelung, Ausstattung. Also teilen sich beide die Höhe, und wer
     mehr Platz zum Lesen braucht, klappt die Bühne über die Lasche auf 170 px
     zusammen (kf-mini-zu). */
  /* Wie eine Produktseite im Shop (Julian, 06.10.2026): oben das Produkt groß;
     beim Herunterscrollen im Panel schiebt es sich auf den Streifen zusammen
     (kf-mini-zu, konfigurator.js → setzeMiniBuehne). Vorher 42 %. */
  /* Fast Vollbild seit 17.10.2026 (Julian: „so fast Vollbild geben, dass unten nur diese
     Bearbeitungsleiste ist … dann kann man das hochswipen“) — vom Panel schauen 64 px
     hervor (Griff + Anfang „Produkt“), der Rest kommt per Wisch. Vorher 70 %, davor 62 %. */
  body.kf-design-aktiv .kf-body { grid-template-rows: minmax(0, calc(100% - 64px)) minmax(0, 1fr); }
  .kf-toolbar-inner { flex-direction: row; height: auto; gap: 6px; }
  /* Alle Werkzeuge OHNE horizontales Scrollen sichtbar (Julian, 18.08.2026:
     „Bibliothek/Ebenen waren abgeschnitten"): gleich breite Spalten, Icon über
     kleinem Label — Labels enden notfalls mit … statt die Leiste zu sprengen. */
  .kf-rail {
    width: 100%; flex-direction: row; align-items: stretch; gap: 2px;
    padding: 5px 6px; overflow: visible;
  }
  .kf-rail-btn {
    flex: 1 1 0; width: auto; min-width: 0; min-height: 52px;
    /* 1 px Seitenpolster statt 2: „Ebenen" braucht bei 360 px genau die
       Labelbreite, und bei exakt passender Breite kappt Chrome wegen
       Subpixel-Rundung trotzdem (belegt 10.09.2026 im Screenshot). */
    flex-direction: column; gap: 4px; padding: 6px 1px; font-size: 9px;
  }
  .kf-rail-btn span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Acht Werkzeuge in einer Zeile lassen je 32 px (360 px) bis 43 px (430 px)
     fürs Label — „Hochladen" (47 px), „Grafiken" (37) und „Bibliothek" (44)
     endeten mit „…". Unter 560 px stehen deshalb die Kurzformen (Upload,
     Grafik, Archiv), und die Laufweite geht auf 0, damit auch „Ebenen" ganz
     bleibt. Die Symbole sind in jedem Knopf schon über dem Wort
     (Julian, 10.09.2026). */
  @media (max-width: 560px) {
    .kf-rail-btn span { letter-spacing: 0; }
    .kf-rail-lang { display: none; }
    .kf-rail-kurz { display: inline; }
  }
  .kf-rail-spacer { flex: 0 0 0; }
  .kf-undo-btn { align-self: center; }
  /* Grid-/Flex-Kinder dürfen schmaler als ihr Inhalt werden — sonst weiten
     Rail-Buttons/Tabs die Spalte über die Viewport-Breite (Overflow auf ≤360px). */
  .kf-stage, .kf-panel, .kf-toolbar, .kf-toolbar-inner { min-width: 0; }
  /* Flyout öffnet mobil NACH OBEN über die Rail (die Rail sitzt unten) */
  .kf-flyout {
    left: 0; right: 0; top: auto; bottom: calc(100% + 8px); width: auto; height: auto; max-height: 260px;
    max-width: 100%; box-sizing: border-box;
    transform: translateY(8px);
  }
  /* Ebenen braucht mobil mehr Raum als die 68%-Regel (die sich sonst auf die
     kleine Rail-Höhe bezöge) — eigener fester Wert statt der Desktop-Prozentzahl */
  .kf-toolbar[data-panel="ebenen"] .kf-flyout { max-height: 320px; }
  .kf-toolbar[data-panel="ebenen"] .kf-flyout-panel { max-height: 320px; }
  .kf-toolbar[data-panel="ki"] .kf-flyout { max-height: 400px; }
  .kf-toolbar[data-panel="ki"] .kf-flyout-panel { max-height: 400px; }
  .kf-flyout-panel { min-width: 0; max-height: 260px; padding: 10px 10px 10px; }
  /* Mobil: klarer Schließer oben rechts im Panel (× statt versteckt) — der
     ‹-Glyph wird ausgeblendet, das ×-Zeichen kommt aus ::before. */
  .kf-flyout-zu {
    display: flex; left: auto; right: 6px; top: 6px; bottom: auto; transform: none;
    width: 40px; height: 40px; z-index: 5; font-size: 0; box-shadow: 0 1px 5px rgba(0, 0, 0, 0.14);
  }
  .kf-flyout-zu::before { content: "\00d7"; font-size: 23px; line-height: 1; }
  .kf-flyout-panel .kf-tb-label,
  .kf-flyout-panel .kf-tb-kopf { padding-right: 40px; } /* Platz für den × */
  .kf-fonts-grid { grid-template-columns: repeat(3, 1fr); }
  .kf-tb-hint { display: none; }
  .kf-ebenen-liste { flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .kf-ebene { width: auto; min-height: 32px; padding: 4px 6px; }
  .kf-ebene-name { max-width: 72px; font-size: 10px; }
  /* Kontext-Pille mobil: kompakter, Slider schmaler. Die Standard-POSITION
     (unten statt oben) setzt das JS in anwenden() — es positioniert die Leiste
     ohnehin inline über top/left (verschiebbarer Griff); ein CSS-bottom hier
     würde mit dem Inline-top kollidieren und die Pille aufspannen. */
  /* Umbruch statt seitlichem Scrollen (Mobil-Audit 15.09.2026): der Inhalt ist
     379 px breit, der Container bei 360 px Bildschirm nur 314 px. Die Leiste
     scrollte zwar, zeigte das aber nicht an — Duplizieren und Löschen standen
     damit außerhalb des Bildes, und Löschen ist sonst nur über den 22-px-Griff
     erreichbar. Mit flex-wrap kann kein Kind mehr über den Rand hinausragen. */
  /* width zusätzlich zu max-width: die Leiste ist absolut positioniert und
     schrumpft sonst auf Inhaltsbreite — mit flex-wrap stapelten sich dadurch
     16 Elemente auf 226 px Höhe übereinander und verdeckten das Design. */
  .kf-ctx { top: 6px; padding: 3px 6px; flex-wrap: wrap; justify-content: center;
            row-gap: 3px; width: calc(100% - 16px); }
  #kf-ctx-groesse { width: 60px; }
  .kf-ctx-slider .mono { display: none; }
  /* Trennstriche sind reine Gruppierungs-Deko und erzeugen beim Umbruch nur
     zusätzliche Zeilen — mobil weg (15.09.2026). */
  .kf-ctx-sep { display: none; }
}

/* Handy quer: der Portrait-Split (54%-Bühnenzeile im Design-Schritt) gilt
   im Spalten-Layout nicht — muss NACH dem Portrait-Block stehen */
@media (max-width: 920px) and (max-height: 500px) {
  body.kf-design-aktiv .kf-body { grid-template-rows: 1fr; }
}

/* Sample-Hinzufügen: Wrapper fürs Doppelt-Tooltip; fester Sample-Name */
.kf-sample-add-wrap { position: relative; display: block; }
.kf-korb-titel-fix { border-bottom: none; cursor: default; }

/* ── Mobil-Umbau (Julian, 18.08.2026): Zoom raus (Pinch übernimmt), Streifen
     ausklappbar, Ausstattungs-Popups als Bottom-Sheet, Anfrage-Liste als
     einziger Scroller — alles NUR ≤920px bzw. Touch. ── */

/* Zuklapp-Chevron an der Produktansicht: nur mobil sichtbar (alle Schritte) */
.kf-mini-toggle { display: none; }

@media (max-width: 920px) {
  /* Zoom-Regler weg — gezoomt wird wie überall auf dem Handy mit zwei Fingern
     (Pinch, s. konfigurator.js). Der Vollbild-Button bleibt. */
  .kf-zoom { display: none; }

  /* Kontext-Leiste offen (Element ausgewählt): alles, was mit ihr kollidieren
     kann, tritt zurück — Hilfslinien-Schalter/Design-Kacheln (oben) sowie
     Seiten-Thumbs/Pille/Vollbild (unten, dort sitzt die Leiste jetzt). Tap
     auf die leere Bühne hebt die Auswahl auf, dann ist alles wieder da. */
  .kf-stage-wrap:has(#kf-ctx:not([hidden])) .kf-hilfslinien-btn,
  .kf-stage-wrap:has(#kf-ctx:not([hidden])) .kf-stage-designs,
  .kf-stage-wrap:has(#kf-ctx:not([hidden])) .kf-thumbs,
  .kf-stage-wrap:has(#kf-ctx:not([hidden])) .kf-ansicht-pille,
  .kf-stage-wrap:has(#kf-ctx:not([hidden])) .kf-view-controls {
    opacity: 0; pointer-events: none;
  }

  /* Zuklapp-Chevron: sitzt in ALLEN Schritten genau AUF der unteren Bildkante —
     halb auf dem Bild, halb darunter (Julian, 18.08.2026). Als layout-neutrales
     Flex-Kind ZWISCHEN Bühne und Werkzeugleiste (nicht im Wrap: dessen
     overflow:hidden würde die untere Hälfte abschneiden; nicht absolut: im
     Design-Schritt hängt die Toolbar mit variabler Höhe darunter). Die
     Negativ-Margins heben Eigenhöhe (23px) + das zusätzliche flex-gap (8px)
     exakt auf: -19.5 = 11.5 (halbe Höhe) + 8 (gap davor). */
  .kf-mini-toggle {
    display: flex; align-items: center; justify-content: center;
    position: relative; z-index: 31; align-self: center;
    margin: -19.5px 0 -11.5px;
    width: 46px; height: 23px; border: none; border-radius: 999px;
    background: var(--kf-zoom-chip); color: rgba(17, 17, 17, 0.65);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.14);
  }
  /* Unsichtbar vergrößerte Hitbox (Tap-Ziel ≥44px) — optisch bleibt die Pille klein */
  .kf-mini-toggle::after { content: ""; position: absolute; inset: -11px -10px; }
  /* Standard = AUSGEKLAPPT → Chevron zeigt nach oben (zuklappen); zugeklappt nach unten */
  .kf-mini-toggle svg { transition: transform 0.2s ease; transform: rotate(180deg); }
  body.kf-mini-zu .kf-mini-toggle svg { transform: rotate(0deg); }
  /* Design-Schritt zugeklappt: Produkt als schmaler Streifen, Werkzeugleiste
     bleibt voll da — die Produktauswahl darunter ist ohne Scrollen erreichbar. */
  /* Klein ohne Werkzeugleiste (Abnahme 07.10.2026): der Streifen braucht nur
     noch Platz fürs Produkt — 130 statt 170 px. Der Wechsel gleitet. */
  body.kf-design-aktiv.kf-mini-zu .kf-body { grid-template-rows: minmax(0, 130px) minmax(0, 1fr); }
  .kf-body { transition: grid-template-rows 0.35s cubic-bezier(0.2, 0.7, 0.2, 1); }
  body.kf-design-aktiv.kf-mini-zu .kf-toolbar:not([data-panel]) { max-height: 0; margin-top: 0; opacity: 0; transform: translateY(-8px); pointer-events: none; }
  /* Im zugeklappten Streifen nur das Mini-Produkt zeigen — Thumbs, „Logo
     ablegen"-Kachel, Hilfslinien-Schalter und Seiten-Pille passen da nicht
     rein und lagen übereinander (Audit 18.08.2026, i2-Screenshot). */
  body.kf-design-aktiv.kf-mini-zu .kf-thumbs,
  body.kf-design-aktiv.kf-mini-zu .kf-stage-designs,
  body.kf-design-aktiv.kf-mini-zu .kf-hilfslinien-btn,
  body.kf-design-aktiv.kf-mini-zu .kf-ansicht-pille { display: none; }

  /* Ausstattung: Logo-/Bibliothek-Popup als fixes Bottom-Sheet — rechtsbündig
     am Button verankert ragte es 150px+ aus dem Screen (Audit 18.08.2026,
     rect x:-155). bottom über dem Ansprechpartner-Widget, wie .kf-upload-info-pop. */
  .kf-ausst-logopop {
    position: fixed; left: 12px; right: 12px; top: auto; bottom: 84px;
    width: auto; max-width: none; max-height: min(62vh, 480px); overflow-y: auto;
    z-index: 120;
  }
  .kf-ausst-bibpop { width: auto; }
  .kf-ausst-bibpicker { max-height: 46vh; }

  /* Anfrage-Schritt mit GESCHLOSSENEM Formular: wie Desktop scrollt NUR die
     Artikelliste — Summe, Rabatt/MwSt und die Buttons bleiben stehen. Das
     Panel selbst steht still; öffnet sich das Kontaktformular, scrollt das
     Panel wieder normal (das Formular ist lang). */
  /* overflow-y:auto statt hidden (03.09.2026): auf 375×667 mit zwei Artikeln
     passt selbst die Minimal-Höhe nicht — dann scrollt das Panel als Ganzes,
     statt dass AGB-Zeile und Buttons ineinanderrutschen (Deep Dive). */
  .kf-panel:has(.kf-step[data-step-panel="4"]:not([hidden]) #kf-form[hidden]) { overflow-y: auto; overflow-x: hidden; }
  /* WICHTIG: :not([hidden]) — display:flex würde sonst das [hidden]-Attribut
     des inaktiven Schritts überschreiben und die Anfrage-Zusammenfassung
     klebte in JEDEM Schritt unten im Panel (Julian, 18.08.2026, Screenshot). */
  .kf-step[data-step-panel="4"]:not([hidden]):has(#kf-form[hidden]) {
    height: 100%; min-height: 0; display: flex; flex-direction: column;
    /* Ecke fürs Ansprechpartner-Widget freihalten — der Avatar (fix unten rechts) lag
       sonst über dem gepinnten „Anfrage fertigstellen". So knapp wie möglich
       (Julian, 18.08.2026: Abstand unten verringern) — das Widget ist in diesem
       Zustand zusätzlich kompakter, s. Regel unten. */
    padding-bottom: 20px;
  }
  /* Ansprechpartner im gepinnten Anfrage-Schritt: kompakter + tiefer in die Ecke, damit
     die Button-Reihe trotz kleinerer Bodenreserve frei bleibt. */
  body.kf-page:has(.kf-step[data-step-panel="4"]:not([hidden]) #kf-form[hidden]) .mmd-berater { right: 8px; bottom: 6px; }
  body.kf-page:has(.kf-step[data-step-panel="4"]:not([hidden]) #kf-form[hidden]) .mmd-berater-avatar { width: 40px; height: 40px; }
  .kf-step[data-step-panel="4"]:not([hidden]):has(#kf-form[hidden]) #kf-korb-card:not([hidden]) {
    flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; margin-bottom: 0;
  }
  /* Die Artikelliste ist der einzige Flex-Kandidat, der Höhe abgibt (alles
     darunter ist flex-shrink: 0) — mit min-height: 56px blieb beim Aufklappen
     von „Bestellung fertigstellen" ein 56-px-Schlitz von einem 390–500 px
     hohen Artikel: kein Produktname, keine Stückzahl, kein Preis (gemessen
     10.09.2026 auf 360/390/430). Jetzt bleibt ein ganzer Artikel stehen und
     die Liste scrollt in sich; reicht die Panelhöhe nicht, scrollt das Panel
     (overflow-y: auto oben) — dann ist der Kaufknopf einen Wisch entfernt,
     statt dass die Bestellübersicht verschwindet. */
  .kf-step[data-step-panel="4"]:not([hidden]):has(#kf-form[hidden]) #kf-korb {
    flex: 0 1 auto; min-height: 260px; max-height: none; overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Nur die Artikelliste gibt Höhe ab — Summe, Rabatt/MwSt, AGB-Checkbox,
     Buttons und Fußnote behalten ihre Höhe. Ohne das presste der Flex-Stapel
     die dreizeilige AGB-Zeile auf 24px und die Buttons lagen darüber. */
  .kf-step[data-step-panel="4"]:not([hidden]):has(#kf-form[hidden]) #kf-korb-card:not([hidden]) > :not(#kf-korb) { flex-shrink: 0; }
  /* Korb-Buttons mobil: EINZEILIG statt zweizeilig umgebrochen („verzogen",
     Julian 18.08.2026) — etwas kleinere Schrift/Spationierung, damit
     „+ Artikel konfigurieren" und „Anfrage fertigstellen" nebeneinander in
     je eine Zeile passen. */
  .kf-korb-buttons { gap: 8px; }
  .kf-korb-buttons .kf-btn-primary,
  .kf-korb-buttons .kf-btn-ghost {
    white-space: nowrap; font-size: 9.5px; letter-spacing: 0.06em;
    padding-left: 8px; padding-right: 8px;
  }
}
/* Handy quer (Spalten-Layout): nichts zu klappen — Griff weg, Zeilen bleiben 1fr */
@media (max-width: 920px) and (max-height: 500px) {
  .kf-mini-toggle { display: none; }
  body.kf-design-aktiv.kf-mini-zu .kf-body { grid-template-rows: 1fr; }
}

/* Pseudo-Vollbild (iOS Safari kann kein Element-Fullscreen für DIVs): die
   Bühne legt sich als fixes Overlay über alles — gleiche Optik wie echtes
   Vollbild. Ansprechpartner-Widget solange ausblenden (läge sonst über dem Produkt). */
body.kf-pseudo-vollbild #kf-stage-wrap {
  position: fixed; inset: 0; z-index: 300; border-radius: 0;
}
body.kf-pseudo-vollbild .mmd-berater { display: none; }
/* Im Pseudo-Vollbild gelten die „immer sichtbar"-Regeln wie im echten Vollbild */
body.kf-pseudo-vollbild .kf-view-controls,
body.kf-pseudo-vollbild .kf-hilfslinien-btn,
body.kf-pseudo-vollbild .kf-vorschau-edit,
body.kf-pseudo-vollbild .kf-vorschau-full {
  opacity: 1; transform: none; pointer-events: auto;
}
body.kf-pseudo-vollbild .kf-mini-toggle { display: none; }

/* Read-only-Vorschau (Anfrage-Schritt) auf Touch: Stift/Vollbild/Seiten-Thumbs
   erschienen nur per Hover — auf dem Handy also nie. Dauerhaft zeigen, die
   redundante Seiten-Pille dafür weglassen (Thumbs zeigen die Seite ohnehin). */
@media (hover: none) {
  .kf-vorschau-edit, .kf-vorschau-full { opacity: 1; pointer-events: auto; }
  .kf-vorschau-thumbs { opacity: 1; transform: none; pointer-events: auto; }
  .kf-vorschau-pille { opacity: 0; }
}

/* ── Einheitliche Feldtext-Größe (Julian, 18.08.2026) ──
   ALLE Text-Eingaben im Konfigurator gleich groß: Desktop (echte Maus) 13px,
   auf Touch bleiben die 16px-Basisregeln (verhindert den iOS-Auto-Zoom beim
   Fokus). Bewusst am DATEIENDE, damit der Block jede Basisregel überstimmt —
   der frühere Override griff beim Anpassen-Feld nie, weil dessen Basisregel
   später im Stylesheet stand. */
@media (hover: hover) and (pointer: fine) {
  .kf-ki-prompt,
  #kf-rabatt-input,
  .kf-feld input,
  .kf-feld textarea { font-size: 13px; }
}

/* Lade-Zustand beim Anpassen: seit dem 06.10.2026 in dai-laden.css. */

/* ── D.AI-Branding (Julian, 20.08.2026): überall wo die KI auftaucht, heißt
   sie D.AI und trägt den Pink/Lila-Gradient der Website („MERCH MY D.AI"). */
.kf-dai-gradient {
  background: linear-gradient(90deg, #f472b6, #8b5cf6);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #ec4899; /* Fallback ohne background-clip */
}

/* Zwei leise Nebenwege nebeneinander („Aufs Board" · „Sample anfragen") statt
   zweier breiter Knöpfe untereinander — der Hauptweg darunter behält dadurch
   sein Gewicht (Julian, 25.08.2026). */
/* Ausverkauft: „Benachrichtigen lassen" bekommt die volle Zeile — als halbe
   Spalte brach das Label zweizeilig aus der Pille (Julian, 03.09.2026). */
.kf-sample-btn--notify span { white-space: nowrap; }

/* ══ Geteilte Kachel-Bausteine (.apc-*) ══════════════════════════════════════
   Standen bis 27.08.2026 in konfi-eigen.css. Das Designboard baut damit seine
   Blanks- und Symbol-Panels — seit „Eigenes Produkt" abschaltbar ist
   (config/konfigurator.php → funktionen), wird jene Datei nicht mehr immer
   geladen, und das Board stand plötzlich ohne Kachel-Optik da. Ein geteilter
   Baustein gehört in die Datei, die immer da ist. */
.apc-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.apc-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 8px 4px 9px;
  background: #fff; border: 1.5px solid rgba(13, 13, 13, 0.12); border-radius: 12px;
  cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s;
}
.apc-tile:hover { border-color: rgba(13, 13, 13, 0.32); }
.apc-tile.active { border-color: #0d0d0d; box-shadow: 0 0 0 1px #0d0d0d; }
.apc-tile-img {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 54px; background: var(--kf-kachel); border-radius: 8px;
  overflow: hidden; color: rgba(13, 13, 13, 0.72);
}
.apc-tile-img svg { width: 46px; height: 46px; }
.apc-tile.active .apc-tile-img { background: #0d0d0d; color: #fff; }
.apc-tile-label {
  font-family: 'DM Sans', sans-serif; font-size: 10.5px; font-weight: 600;
  color: rgba(13, 13, 13, 0.66); text-align: center; line-height: 1.25;
}
.apc-colors { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.apc-color {
  padding: 3px; background: #fff; border: 1.5px solid rgba(13, 13, 13, 0.12);
  border-radius: 12px; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s;
}
.apc-color > span {
  display: block; width: 100%; aspect-ratio: 1/1; border-radius: 9px;
  position: relative; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);
}
.apc-color > span::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(255,255,255,0.42) 0%, rgba(255,255,255,0.05) 42%, rgba(0,0,0,0.06) 62%, rgba(255,255,255,0.18) 100%);
}
.apc-color:hover { border-color: rgba(13, 13, 13, 0.32); }
.apc-color.active { border-color: #0d0d0d; box-shadow: 0 0 0 1px #0d0d0d; }

/* ══ Designs & Symbole (Julian, 27.08.2026) ══════════════════════════════════
   Ein Panel-Bauteil, zwei Kategorien. Der einzige Unterschied ist die
   Kachelgröße: ein Schriftzug wie „Keine Macken, nur Extras" braucht Breite,
   um überhaupt lesbar zu sein — ein Stern nicht. Deshalb zwei Spalten bei den
   Designs, vier bei den Symbolen. */
/* Das Grafiken-Panel zeigt bis zu hundert Kacheln — mit den 440px der
   Standard-Flyouts sah man fünf Reihen und scrollte den Rest blind. Es darf
   deshalb so hoch werden, wie die Bühne hergibt. */
.kf-toolbar[data-panel="grafiken"] .kf-flyout { max-height: min(680px, calc(100svh - 190px)); }
.kf-formen-suche {
  width: 100%; padding: 7px 10px; border: 1.5px solid var(--kf-border); border-radius: 8px;
  font-family: 'DM Sans', sans-serif; color: var(--kf-ink); background: #fff;
  /* 16px als Grundwert, kleiner nur mit echtem Zeiger: unter 16px zoomt iOS
     beim Antippen in das Feld hinein und verlässt die Seitenbreite. */
  font-size: 16px;
}
@media (hover: hover) and (pointer: fine) { .kf-formen-suche { font-size: 13px; } }
.kf-formen-suche:focus { outline: none; border-color: var(--kf-akzent); }
.kf-formen-body { display: flex; flex-direction: column; gap: 8px; }
/* Alle Kacheln gleich groß (Julian, 27.08.2026). Vorher belegten Schriftzüge
   und Motive zwei Spalten — begründet mit der Lesbarkeit, aber im Raster sah
   es aus wie eine Rangfolge, die es nicht gibt. Dafür jetzt drei Spalten statt
   vier: die Kachel wird breit genug, dass auch „Sunday Coffee Club" als Wort
   erkennbar bleibt. */
.kf-formen-gitter { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.kf-formen-kachel {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 3px 7px; background: #fff;
  border: 1.5px solid var(--kf-border); border-radius: 10px; cursor: pointer;
  transition: border-color 0.13s, transform 0.13s;
}
.kf-formen-kachel:hover { border-color: var(--kf-akzent); transform: translateY(-1px); }
.kf-formen-bild {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 60px; background: var(--kf-kachel); border-radius: 7px;
  overflow: hidden; padding: 5px;
}
.kf-formen-bild img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.kf-formen-label {
  font-size: 10px; line-height: 1.2; color: rgba(17, 17, 17, 0.6); text-align: center;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; word-break: break-word;
}

/* ── Kauf-Flow: Abschluss-Bereich im Warenkorb (31.08.2026) ──────────────
   Kompakter Stapel unter der Summen-Tabelle: AGB-Checkbox → Gesamtbetrag
   (rechtsbündig, direkt über dem Bestell-Button — § 312j Abs. 2 BGB) →
   Buttons → EINE kleine Fußnote (Stripe-Zahlarten + Widerrufs-Ausschluss). */
/* Professioneller Datencheck: Häkchen-Zeile mit Titel, Preis und Erklärung */
.kf-datencheck { margin: 14px 0 0; padding: 12px 14px; border: 1px solid var(--kf-border); border-radius: 10px; align-items: flex-start; gap: 10px; }
.kf-datencheck:has(input:checked) { border-color: var(--kf-ink); }
.kf-datencheck-text { display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.kf-datencheck-kopf { display: flex; justify-content: space-between; gap: 10px; }
.kf-datencheck-preis { font-weight: 600; white-space: nowrap; }
.kf-datencheck-titel { display: inline-flex; align-items: center; gap: 8px; }
.kf-datencheck-info .kf-info-i { width: 16px; height: 16px; font-size: 9.5px; }
/* Tipp öffnet nach rechts unten — das „i" sitzt links im Warenkorb, rechts wäre er abgeschnitten */
.kf-datencheck { position: relative; }
.kf-datencheck-info { position: static; }
/* Tipp legt sich unter die Datencheck-Box, so breit wie die Box — rechts vom „i" wäre er aus dem Warenkorb gelaufen */
.kf-datencheck-info .kf-info-tip { left: 0; right: 0; top: calc(100% + 6px); width: auto; }
/* Das Größen-„i" fährt erst beim Hover heraus — dieses hier ist immer da */
@media (hover: hover) { .kf-info-wrap.kf-datencheck-info { max-width: none; opacity: 1; overflow: visible; margin-left: 0; } }
.kf-datencheck-sub { font-size: 12px; color: var(--kf-mid); line-height: 1.45; }
.kf-agb-check--kauf { margin: 16px 0 2px; }
/* Versandland + E-Mail vor dem Bestellknopf (Pakete K und L, 18.09.2026).
   Beide stehen im ausgeklappten Warenkorb direkt über dem Knopf und werden in
   der kompakten Ansicht mit ausgeblendet (Liste oben). */
.kf-versandland { margin: 16px 0 0; font-size: 12.5px; color: var(--kf-mid); }
.kf-kauf-email-feld { margin: 10px 0 2px; }
.kf-feld-hinweis { font-size: 12px; color: var(--kf-mid); line-height: 1.45; }
/* Vertrauens-Block unter der Stripe-Fußnote: Zahlarten-Pillen + vier Vorteile */
.kf-vertrauen { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--kf-border); }
/* Zahlarten eng nebeneinander (wie in jedem Shop). Der Umbruch ergibt sich aus
   der Breite; damit dabei nie eine einzelne Kachel allein in der letzten Zeile
   landet, verschmälert ordneZahlarten() (konfigurator.js) die Reihe im Zweifel
   um eine Kachel — dann rutschen zwei zusammen (Julian, 09.09.2026). */
.kf-zahlarten { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.kf-zahlart { display: block; width: 40px; height: 26px; border-radius: 4px; }
/* Vektor-Hinweis ab 101 Stück mit Pixeldatei (Schritt 2) */
.kf-vektor-hinweis { display: flex; gap: 9px; align-items: flex-start; margin: 10px 0 0; padding: 10px 12px; border-radius: 9px; background: rgba(245, 158, 11, 0.12); color: #7a4a00; font-size: 12.5px; line-height: 1.45; }
.kf-vektor-hinweis svg { flex: none; margin-top: 2px; }
.kf-vektor-hinweis strong { font-weight: 600; }
.kf-vektor-hinweis[hidden] { display: none; }

.kf-kauf-fussnote { margin: 14px 0 0; font-size: 12px; line-height: 1.6; color: #8a8a8a; display: flex; align-items: center; gap: 7px; }
.kf-kauf-fussnote strong { color: #555; font-weight: 600; }
/* Details am „i" (Julian, 01.09.2026) — Karte im .kf-info-tip-Look, öffnet nach
   OBEN: die Fußnote ist das letzte Element der Korb-Karte, nach unten wäre die
   Karte außerhalb des Sichtbereichs. */
.kf-kauf-info-wrap { position: relative; display: inline-flex; }
.kf-kauf-info-pop {
  position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 70;
  width: min(270px, calc(100vw - 40px));
  background: var(--kf-karte-bg); border: var(--kf-karte-border); border-radius: var(--kf-karte-radius);
  box-shadow: var(--kf-karte-shadow); padding: 12px 14px;
  color: rgba(17, 17, 17, 0.75); font-size: var(--kf-karte-size); line-height: 1.55;
  opacity: 0; visibility: hidden; transform: translateY(4px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
}
/* Touch: der Anker sitzt mitten in der Zeile (x ≈ 195), die 270-px-Karte lief
   dadurch bis 121 px über den Panelrand und wurde abgeschnitten — jede Zeile
   verlor ihr Ende (gemessen 10.09.2026). Auf Touch spannt sie deshalb über die
   Kartenbreite, wie der Datencheck-Tooltip. */
/* Auch schmale Fenster mit Maus (≤ 820 px): dort lief die Karte 73 px über
   den Seitenrand und ließ die ganze Warenkorbseite seitlich wackeln
   (Prüfrunde 05.10.2026). */
@media (hover: none), (max-width: 820px) {
  /* Bezug ist die Fußnoten-ZEILE, nicht der schmale Anker: sie läuft über die
     Kartenbreite, also passt „left/right: 0" genau in die Karte und
     „bottom: calc(100% + 8px)" bleibt direkt über der Fußnote. Mit dem Anker
     als Bezug lief die 270-px-Karte 49–122 px über den Panelrand, mit body als
     Bezug 14 px (beides gemessen 10.09.2026). */
  .kf-kauf-fussnote { position: relative; }
  .kf-kauf-info-wrap { position: static; }
  .kf-kauf-info-pop { left: 0; right: 0; width: auto; }
}
@media (hover: hover) {
  .kf-kauf-info-wrap:hover .kf-kauf-info-pop,
  #kf-kauf-info-btn:focus-visible ~ .kf-kauf-info-pop {
    opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
    transition-delay: 0s;
  }
}
.kf-kauf-info-wrap.offen .kf-kauf-info-pop {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
  transition-delay: 0s;
}

/* Der Rechte-Hinweis stand vom 01.09. bis zum 30.09.2026 als eigene Zeile mit
   eigenem „i" unter der Ablagefläche. Er steckt jetzt im ⓘ der Überschrift
   (Julian: „hier reicht nur das i neben Design hochladen") — .kf-upload-rechte
   und .kf-rechte-info-* sind damit weg. */

/* D.AI-Ausfall: Hilfe-Zeile unter der Fehlermeldung (eigenes Design hochladen /
   anrufen / E-Mail) — Pillen, klein wie der Statustext (02.09.2026). */
.kf-ki-hilfe { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.kf-ki-hilfe a, .kf-ki-hilfe button {
  display: inline-flex; align-items: center; padding: 5px 10px; border-radius: 999px;
  background: var(--kf-ink); color: #fff; border: none; cursor: pointer;
  font-family: inherit; font-size: 11px; font-weight: 600; line-height: 1; text-decoration: none;
}
.kf-ki-hilfe a:hover, .kf-ki-hilfe button:hover { opacity: 0.85; }

/* D.AI-Transparenz: „i" neben dem Panel-Titel, Karte öffnet nach UNTEN (Titel
   ist das erste Element im Panel). Gleiche Mechanik wie Upload-/Rechte-i. */
.kf-dai-gradient { display: inline-block; }
.kf-dai-info-wrap { position: relative; display: inline-flex; flex: none; }
.kf-dai-info-pop {
  position: absolute; left: 0; top: calc(100% + 8px); z-index: 70;
  width: min(290px, calc(100vw - 40px));
  background: var(--kf-karte-bg); border: var(--kf-karte-border); border-radius: var(--kf-karte-radius);
  box-shadow: var(--kf-karte-shadow); padding: 12px 14px;
  color: rgba(17, 17, 17, 0.75); font-size: var(--kf-karte-size); line-height: 1.55;
  font-weight: 400; letter-spacing: 0; text-transform: none;
  opacity: 0; visibility: hidden; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
}
@media (hover: hover) {
  .kf-dai-info-wrap:hover .kf-dai-info-pop,
  #kf-dai-info-btn:focus-visible ~ .kf-dai-info-pop {
    opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; transition-delay: 0s;
  }
}
.kf-dai-info-wrap.offen .kf-dai-info-pop {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; transition-delay: 0s;
}
/* KI-Abzeichen auf D.AI-Designs in der Bibliothek */
.kf-bib-ki {
  position: absolute; top: 4px; left: 4px; z-index: 2; pointer-events: none;
  padding: 2px 5px; border-radius: 999px; background: rgba(17, 17, 17, 0.82); color: #fff;
  font-size: 8.5px; font-weight: 700; letter-spacing: 0.08em; line-height: 1; text-transform: uppercase;
}

/* Warenkorb-Schritt: Panel-Scroll bleibt im Panel (s. Kommentar an .kf-panel) */
body:has(.kf-step[data-step-panel="4"]:not([hidden])) .kf-panel { overscroll-behavior: contain; }

/* ══════════════════════════════════════════════════════════════════════════
   BEREICH UNTER DEM KONFIGURATOR (.kfu — partials/konfi-unten.blade.php)
   Vorlage: „Export Konfigurator WL" (Julian, 04.09.2026). Helle Sektion in
   DM Sans (max. 700 — Regel Designsystem), Breakpoints 1000/820/560.
   ══════════════════════════════════════════════════════════════════════════ */
.kfu { background: #f5f5f3; color: #111; font-weight: 400; }
.kfu-wrap { max-width: 1200px; margin: 0 auto; padding: 0 32px; }
.kfu-sec { padding-top: 88px; }
.kfu-head { text-align: center; max-width: 640px; margin: 0 auto 40px; }
.kfu-kicker { font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase; color: rgba(17, 17, 17, 0.38); margin-bottom: 12px; }
.kfu-h { font-size: clamp(28px, 3.2vw, 44px); font-weight: 700; letter-spacing: -0.025em; line-height: 1.08; margin: 0 0 12px; }
.kfu-p { font-size: 16px; line-height: 1.6; color: rgba(17, 17, 17, 0.55); margin: 0; }
.kfu-count { font-variant-numeric: tabular-nums; }

/* USP-Leiste: vier Punkte in einer Reihe, Icons als Schatten+Vordergrund */
.kfu-uspbar { background: #fff; padding: 34px 0 30px; border-top: 1px solid rgba(0, 0, 0, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.06); }
.kfu-usp { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 24px 32px; justify-items: center; }
.kfu-usp-it { display: flex; gap: 14px; align-items: center; }
.kfu-usp-ic { position: relative; width: 34px; height: 34px; flex-shrink: 0; }
.kfu-usp-ic svg { position: absolute; inset: 0; width: 34px; height: 34px; overflow: visible; stroke-linecap: round; stroke-linejoin: round; }
.kfu-usp-ic .sh { transform: translate(2.5px, 2.5px); fill: #e2e2e0; stroke: none; }
.kfu-usp-ic .fg { fill: #fff; stroke: #111; stroke-width: 1.4; }
.kfu-usp-t { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; }
.kfu-usp-s { font-size: 13px; color: rgba(17, 17, 17, 0.5); margin-top: 3px; line-height: 1.35; }
@media (max-width: 560px) { .kfu-usp { grid-template-columns: 1fr; gap: 16px; } }

/* Laufschrift und Vorteile-Reveal liegen seit 26.09.2026 in
   css/everplain-vorteile.css — sie werden auch von /produkte gebraucht.
   Diese Seite lädt beide Dateien. */

/* Vollbild-Banner mit Text-Overlay (Reveal + Parallax) */
.kfu-banner { position: relative; height: min(90vh, 760px); height: min(90svh, 760px); min-height: 520px; overflow: hidden; background: #111; margin-top: 96px; display: grid; place-items: center; text-align: center; color: #fff; }
.kfu-banner-img { position: absolute; left: 0; top: -12%; width: 100%; height: 124%; object-fit: cover; object-position: center 35%; will-change: transform; }
.kfu-banner::after { content: ''; position: absolute; inset: 0; background: rgba(0, 0, 0, 0.38); }
.kfu-banner-in { position: relative; z-index: 1; padding: 0 24px; max-width: 820px; opacity: 0; transform: translateY(28px); transition: opacity 0.9s ease, transform 0.9s ease; }
.kfu-banner.is-in .kfu-banner-in { opacity: 1; transform: none; }
.kfu-banner-k { font-size: 18px; font-weight: 700; margin-bottom: 10px; }
.kfu-banner-h { font-size: clamp(40px, 6vw, 84px); font-weight: 700; letter-spacing: -0.03em; line-height: 1; margin: 0 0 34px; }
.kfu-banner-btns { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.kfu-btn { display: inline-block; font-family: inherit; font-size: 16px; font-weight: 700; padding: 18px 34px; border-radius: 2px; text-decoration: none; border: 2px solid #fff; cursor: pointer; transition: background 0.18s, color 0.18s; }
.kfu-btn-fill { background: #fff; color: #111; }
.kfu-btn-fill:hover { background: #111; color: #fff; }
.kfu-btn-line { background: transparent; color: #fff; }
.kfu-btn-line:hover { background: #fff; color: #111; }

/* Accordion (Technische Details, FAQ) */
.kfu-acc { max-width: 760px; margin: 0 auto; border-top: 1px solid rgba(0, 0, 0, 0.1); }
.kfu-acc details { border-bottom: 1px solid rgba(0, 0, 0, 0.1); }
.kfu-acc summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 22px 0; font-size: 17px; font-weight: 600; min-height: 44px; }
.kfu-acc summary::-webkit-details-marker { display: none; }
.kfu-acc summary::after { content: '+'; font-size: 24px; font-weight: 300; color: rgba(17, 17, 17, 0.45); transition: transform 0.2s; flex-shrink: 0; }
.kfu-acc details[open] summary::after { transform: rotate(45deg); }
.kfu-acc-b { padding: 0 0 24px; font-size: 15px; line-height: 1.7; color: rgba(17, 17, 17, 0.6); max-width: 640px; }
.kfu-acc-b b { color: #111; font-weight: 600; }

/* Referenz-Logos + Kundenstimmen */
/* Kundenlogos als flüssiges Endlos-Laufband (Julian, 04.09.2026: „in einer
   Reihe, als Loop ganz flüssig"): zwei identische Sätze, Track wandert um 50 %.
   Weiche Kanten links/rechts per Mask. */
.kfu-logos { width: 100vw; margin: 8px 0 0 calc(50% - 50vw); overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); }
.kfu-logos-track { display: flex; align-items: center; width: max-content; animation: kfuMarq 42s linear infinite; will-change: transform; }
.kfu-logos-track img { height: 30px; width: auto; max-width: 130px; object-fit: contain; flex: none; margin: 0 34px; filter: brightness(0); opacity: 0.5; transition: opacity 0.2s; }
.kfu-logos-track img:hover { opacity: 1; }
.kfu-logos:hover .kfu-logos-track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .kfu-logos-track { animation: none; } }
@media (max-width: 640px) { .kfu-logos-track img { height: 22px; max-width: 96px; margin: 0 20px; } }
.kfu-rev { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 56px; }
.kfu-rev-it { background: #fff; border: 1px solid rgba(0, 0, 0, 0.06); border-radius: 18px; padding: 28px 28px 24px; }
.kfu-stars { color: #111; font-size: 13px; letter-spacing: 3px; margin-bottom: 14px; }
.kfu-rev-q { font-size: 15px; line-height: 1.6; margin: 0 0 16px; }
.kfu-rev-n { font-size: 12px; color: rgba(17, 17, 17, 0.45); letter-spacing: 0.04em; }
@media (max-width: 1000px) { .kfu-rev { grid-template-columns: 1fr; } }

/* Kontakt-Zeile unter dem FAQ: Anrufen / E-Mail / WhatsApp / Schreib uns */
.kfu-kontakt { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 14px 22px; margin-top: 36px; }
.kfu-kontakt-t { font-size: 17px; font-weight: 600; }
.kfu-pillen { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.kfu-pille { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border-radius: 100px; border: 1px solid rgba(0, 0, 0, 0.14); background: #fff; color: #111; text-decoration: none; font-size: 13px; font-weight: 600; letter-spacing: 0.02em; transition: background 0.15s, color 0.15s, border-color 0.15s; }
.kfu-pille:hover { background: #111; color: #fff; border-color: #111; }
.kfu-pille-voll { background: #111; color: #fff; border-color: #111; }
.kfu-pille-voll:hover { background: #333; border-color: #333; }

/* Instagram-Streifen */
.kfu-ig { margin-top: 96px; padding-bottom: 0; }
.kfu-ig-head { text-align: center; margin-bottom: 24px; }
.kfu-ig-k { font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase; color: rgba(17, 17, 17, 0.38); margin-bottom: 12px; }
/* Kopf: Instagram-Zeichen + Handle als ein Link, hebt sich beim Hover an */
.kfu-ig-s { display: inline-flex; align-items: center; gap: 10px; font-size: 20px; font-weight: 700; letter-spacing: -0.01em; color: #111; text-decoration: none; margin: 0; padding: 6px 10px; border-radius: 100px; transition: background 0.15s, transform 0.15s; }
.kfu-ig-s svg { width: 24px; height: 24px; stroke: #111; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.kfu-ig-s:hover { background: #fff; transform: translateY(-1px); }
.kfu-ig-strip { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding: 0 0 6px; }
.kfu-ig-strip::-webkit-scrollbar { display: none; }
.kfu-ig-it { position: relative; flex: 0 0 auto; width: clamp(220px, 25vw, 400px); aspect-ratio: 1 / 1; overflow: hidden; background: #eee; display: block; }
.kfu-ig-it img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.5s ease; }
.kfu-ig-it:hover img { transform: scale(1.04); }
.kfu-ig-it::after { content: ''; position: absolute; inset: 0; background: rgba(0, 0, 0, 0); transition: background 0.25s; }
.kfu-ig-it:hover::after { background: rgba(0, 0, 0, 0.18); }
.kfu-ig-it svg { position: absolute; left: 50%; top: 50%; width: 28px; height: 28px; transform: translate(-50%, -50%); stroke: #fff; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; z-index: 1; opacity: 0; transition: opacity 0.25s; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4)); }
/* Icon NUR bei Hover (Julian, 04.09.2026: das dauerhafte Icon auf der ersten
   Kachel sah nach Bug aus) — das Instagram-Zeichen sitzt stattdessen oben im Kopf */
.kfu-ig-it:hover svg { opacity: 1; }

/* Schwebender Hoch-Knopf ganz unten RECHTS (Produktbild +
   Pfeil), erscheint per JS. Rechts seit 04.09.2026 — links unten sitzt der Cookie-Knopf
   (Julian). */
.kfu-hoch { position: fixed; right: 16px; bottom: 16px; z-index: 95; display: flex; align-items: center; gap: 8px; background: #fff; border: 1px solid rgba(0, 0, 0, 0.08); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); border-radius: 100px; padding: 6px; cursor: pointer; font: inherit; transform: translateY(120%); opacity: 0; pointer-events: none; transition: transform 0.3s, opacity 0.3s; }
.kfu-hoch.an { transform: none; opacity: 1; pointer-events: auto; }
.kfu-hoch img { width: 38px; height: 38px; object-fit: contain; border-radius: 50%; background: #f3f3f1; display: block; }
.kfu-hoch-up { width: 38px; height: 38px; border-radius: 50%; background: #111; display: grid; place-items: center; transition: transform 0.2s; }
.kfu-hoch:hover .kfu-hoch-up { transform: translateY(-2px); }
.kfu-hoch-up svg { width: 16px; height: 16px; stroke: #fff; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

@media (max-width: 820px) {
  .kfu-sec { padding-top: 64px; }
  .kfu-sec-vorteile { padding-top: 28px; }
  .kfu-wrap { padding: 0 20px; }
  .kfu-banner { margin-top: 64px; min-height: 440px; }
  .kfu-ig { margin-top: 64px; }
}

/* ===================================================================   Prüfrunde 1 (07.09.2026) — Fixes Konfigurator-Client. EIN Block am Ende,
   damit parallele CSS-Arbeit nicht kollidiert. Inhalt: Drop-Hinweis über
   Sprachdatei, Touch-Ziele ≥ 44 px, Mobile-Schwellen (Inputs 16 px, CTA 12 px),
   Kontextleiste mobil mit Scroll-Hinweis, Ebenen-Griff auf Touch sichtbar,
   Wortumbruch langer Texte, Zeichen-Zähler, ungültige Korb-Artikel, flache
   Fenster (Schritt-1-CTA sticky).
   ========================================================================== */
/* Drop-Hinweis auf der Bühne kommt aus lang/<sprache>/konfigurator.php
   (js_design_hier_ablegen) — der CSS-content stand vorher fest auf Deutsch. */
.kf-stage-wrap.kf-stage-drop::after { content: attr(data-drop-text); }
/* Warenkorb: Artikel mit offenem Fehler (MOQ/Verteilung) zählt nicht in die Summe
   und bekommt einen roten Rahmen; die Warnzeile im Summenblock erklärt es (F-3). */
/* Rahmen-Geometrie wie beim blauen Ring (Julian, 09.09.2026: „warum sind die
   Linien so unpassend?"). Der rote Rahmen lag ohne Luft direkt auf der
   Textkante — die Trennstriche der Detailzeilen (.kf-summary-zeile) liefen
   deshalb in ihn hinein, und Preis, „Artikel bearbeiten" und Lieferzeit klebten
   rechts am Rahmen. Gleiche Lösung wie bei .kf-korb-gewaehlt: den Artikel 14 px
   nach außen ziehen und innen zurückpolstern — 14 px Luft zum Inhalt, 6 px zur
   Kartenkante. Der Listen-Trennstrich verschwindet, solange der Rahmen steht,
   sonst kreuzt er ihn an der Unterkante. */
.kf-korb-item.kf-korb-item-ungueltig {
  margin: 0 -14px; padding-left: 14px; padding-right: 14px;
  border-radius: 12px; border-bottom-color: transparent;
  box-shadow: inset 0 0 0 2px var(--kf-fehler);   /* gleiche Stärke wie der blaue Ring (Julian, 09.09.2026) */
}
.kf-korb-item.kf-korb-item-ungueltig:first-child { margin-top: -14px; padding-top: 14px; }
@media (max-width: 920px) {
  /* Mobile .kf-card hat 12px/13px Padding — dieselben 6px Luft wie der blaue Ring */
  .kf-korb-item.kf-korb-item-ungueltig { margin: 0 -7px; padding-left: 7px; padding-right: 7px; }
  .kf-korb-item.kf-korb-item-ungueltig:first-child { margin-top: -6px; padding-top: 6px; }
}
.kf-korb-item.kf-korb-item-ungueltig .kf-korb-gesamt { color: var(--kf-fehler); text-decoration: line-through; text-decoration-thickness: 1px; }
.kf-summe-warn { color: var(--kf-fehler); font-weight: 600; }
/* Schritt 1: „Ohne Design bestellst du unbedruckte Blanks" über dem Bestätigen-Knopf */
/* Schritt 3 ohne Stückzahl: Hinweis statt Sperr-Badges */
.kf-stueck-hint { margin-bottom: 12px; }
/* Editor: langes Wort ohne Leerzeichen bricht um, statt über Rahmen, Zone und
   Shirt zu laufen (Design-Editor F-03). Normale Wörter bleiben weiter zusammen —
   „anywhere" greift erst, wenn ein Wort allein nicht in die Zonenbreite passt. */
.kf-text-inhalt { overflow-wrap: anywhere; }
/* Zeichen-Zähler während der Textbearbeitung (ab 160/200 Zeichen sichtbar) */
.kf-text-zaehler {
  position: absolute; right: -4px; bottom: -22px; z-index: 5; pointer-events: none;
  padding: 2px 7px; border-radius: 999px; background: var(--kf-ink); color: #fff;
  font-family: "DM Sans", sans-serif; font-size: 10px; font-weight: 600; letter-spacing: 0.04em; line-height: 1.4; white-space: nowrap;
}
.kf-text-zaehler.voll { background: var(--kf-fehler); }
/* Kontextleiste mobil: passt nicht alles in eine Zeile, blendet der rechte Rand
   aus — Hinweis, dass man schieben kann (Design-Editor F-08). Klasse setzt das JS. */
@media (max-width: 920px) {
  .kf-ctx.kf-ctx--scrollt {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 36px), rgba(0, 0, 0, 0.12));
    mask-image: linear-gradient(to right, #000 calc(100% - 36px), rgba(0, 0, 0, 0.12));
  }
}
/* Touch: Ebenen-Griff ist auf Desktop hover-only — ohne Hover immer sichtbar (F-14) */
@media (hover: none) {
  .kf-ebene-griff { width: 12px; opacity: 1; margin-right: 0; }
}
/* Touch-Ziele ≥ 44 px über unsichtbare ::after-Flächen (Mobile-Checkliste, F-09/M7).
   Waagerecht bleiben die Flächen schmal, wo Knöpfe direkt nebeneinander liegen —
   sonst gewinnt beim Tippen das später gezeichnete Nachbar-Element. */
@media (pointer: coarse) {
  .kf-eckpunkt::after, .kf-griff::after, .kf-ctx-btn::after, .kf-undo-btn::after,
  .kf-ebene-x::after, .kf-ebene-auge::after, .kf-korb-entfernen::after, .kf-korb-titel-stift::after,
  .kf-info-i::after, .kf-vered-i::after, .kf-groesse-toggle::after, .kf-korb-details-btn::after,
  .kf-bib-x::after, .kf-korb-ausst-plus::after, .kf-ctx-griff::after {
    content: ""; position: absolute; inset: -8px;
  }
  .kf-ctx-btn, .kf-undo-btn, .kf-ebene-x, .kf-ebene-auge, .kf-korb-titel-stift, .kf-info-i,
  .kf-groesse-toggle, .kf-korb-details-btn, .kf-bib-x, .kf-korb-ausst-plus, .kf-ctx-griff { position: relative; }
  .kf-eckpunkt::after { inset: -17px; }           /* 11 px → 45 px */
  .kf-griff::after { inset: -11px; }              /* 22 px → 44 px */
  .kf-ctx-btn::after { inset: -8px 0; }           /* 28 px hoch → 44 px; seitlich Nachbarn */
  .kf-ctx-griff::after { inset: -9px -4px; }
  .kf-undo-btn::after { inset: -7px -3px; }       /* 30 px → 44 px */
  .kf-ebene-x::after { inset: -12px -2px; }       /* 20 px → 44 px */
  .kf-ebene-auge::after { inset: -11px -2px; }    /* 22 px → 44 px */
  .kf-korb-entfernen::after { inset: -6px; }      /* 32 px → 44 px */
  .kf-korb-titel-stift::after { inset: -9px -4px; }
  .kf-info-i::after { inset: -12px; }             /* 20 px → 44 px */
  .kf-datencheck-info .kf-info-i::after { inset: -14px; } /* 16 px → 44 px */
  .kf-vered-i::after { inset: -9px; }             /* 26 px → 44 px */
  .kf-groesse-toggle::after { inset: -14px 0; }   /* 17 px hoch → 45 px */
  .kf-korb-details-btn::after { inset: -13px 0; } /* 18 px hoch → 44 px */
  .kf-bib-x::after { inset: -10px; }
  .kf-korb-ausst-plus::after { inset: -14px 0; }
  /* Formularfelder ≥ 16 px auf Touch, sonst zoomt iOS beim Fokus (M7) */
  .kf-korb-titel, .kf-korb-stueck, .kf-korb-groesse input, #kf-stueck, .kf-groesse input,
  #kf-grafiken-suche, #kf-ki-prompt, #kf-rabatt-input { font-size: 16px; }
  .kf-korb-titel { letter-spacing: 0.08em; }
  .kf-korb-groesse > span { font-size: 11px; }
}
/* Primär-CTA mobil: 12 px statt 9,5 px in der breiten Variante (Mobile-Checkliste) */
@media (max-width: 820px) {
  .kf-btn-primary, .kf-btn-ghost, #kf-form-toggle, #kf-design-weiter { font-size: 12px; letter-spacing: 0.1em; }
  .kf-btn-primary.kf-btn-breit { padding-left: 14px; padding-right: 14px; }
  .kf-sd-tile > span { font-size: 9px; }
}
/* Flache Fenster (1366×650, 1280×600): „Design bestätigen" lag unter der Falz,
   ohne dass das Panel Scrollen signalisierte (F-12/F-06). Die CTA-Zeile des
   Design-Schritts bleibt sticky am unteren Rand des scrollenden Panels sichtbar. */
@media (min-width: 921px) and (max-height: 760px) {
  .kf-step[data-step-panel="1"] .kf-nav-row--voll {
    position: sticky; bottom: 0; z-index: 3; margin-top: 10px;
    padding: 10px 0 12px; background: #fff;
    box-shadow: 0 -14px 14px -10px rgba(0, 0, 0, 0.08);
  }
}
/* ═══ Prüfrunde 1 (07.09.2026) — Barrierefreiheit + Design-Tokens (F-07, F-09) ═══
   Bewusst als Block am Dateiende (Konfliktvermeidung mit dem Konfigurator-Agenten). */
:root { --radius-btn: 999px; }                                 /* ein Knopf-Radius für alle Systeme (Pille, 09.10.2026) */
.kf-btn-primary, .kf-btn-ghost { border-radius: var(--radius-btn); }
.kf-tab { color: rgba(17, 17, 17, 0.62); }                    /* inaktive Schritt-Tabs 3,0:1 → ≈5:1 auf --kf-bg */
:focus-visible { outline: 2px solid var(--kf-ink); outline-offset: 2px; } /* Tastatur-Fokus statt Browser-Blau; spezifischere Ringe (.kf-ctx-griff …) bleiben */
/* ═══ Fix-Runde 3 (07.09.2026) — Konfigurator-Client (Prüfrunde 2: F-4 Tap-Ziele, F-8 Crop-Griffe,
   Brand F-02/F-04 Korb-Knöpfe, Rabatt-Neuprüfung). Block am Dateiende, wie in Runde 1. ═══ */
/* Rabatt-Chip, solange der Server den Code für den geänderten Korb noch nicht bestätigt hat */
.kf-rabatt-chip-prueft { opacity: 0.6; }
/* Crop-Griffe lagen zur Hälfte außerhalb der Bühne (overflow: hidden schnitt sie ab —
   greifbar ~7 px). Jetzt sitzen sie innen an der Ecke; die unsichtbare ::after-Fläche
   macht sie zum 44-px-Ziel (F-8). */
.kf-crop-griff { width: 18px; height: 18px; }
.kf-crop-griff::after { content: ""; position: absolute; inset: -13px; }
.kf-crop-griff[data-ecke="tl"] { left: -2px; top: -2px; }
.kf-crop-griff[data-ecke="tr"] { right: -2px; top: -2px; }
.kf-crop-griff[data-ecke="bl"] { left: -2px; bottom: -2px; }
.kf-crop-griff[data-ecke="br"] { right: -2px; bottom: -2px; }
/* Touch (Handy UND Tablet — Kriterium ist der grobe Zeiger, nicht die Breite): echte
   44-px-Boxen statt nur unsichtbarer ::after-Flächen — Finger und Messwerkzeug sehen
   dasselbe. Wo ein Knopf in einer Textzeile sitzt (Info-i, Stift), heben negative
   Außenabstände die Mehrhöhe wieder auf; der sichtbare Kreis wird per ::before gezeichnet. */
@media (pointer: coarse) {
  .kf-ctx { gap: 0; padding: 2px 6px; }
  .kf-ctx-btn { min-height: 44px; min-width: 44px; padding: 3px 10px; }
  .kf-ctx-icon { width: 44px; padding: 3px 0; }
  .kf-ctx-griff { width: 44px; height: 44px; margin-left: -6px; }
  .kf-ctx-slider { min-height: 44px; }
  #kf-ctx-groesse { height: 44px; } /* Schiene/Griff zeichnen die Pseudo-Elemente, die Box wird zum Tap-Ziel */
  .kf-ctx-sep { height: 24px; }
  .kf-ctx-btn::after, .kf-ctx-griff::after { display: none; }
  .kf-undo-btn { width: 44px; height: 44px; }
  .kf-undo-btn::after { display: none; }
  /* Korb-Karte */
  .kf-korb-titel-stift { width: 44px; height: 44px; margin: -9px -6px -9px -4px; }
  .kf-korb-titel-stift::after { display: none; }
  .kf-korb-entfernen { min-width: 44px; min-height: 44px; right: -14px; }
  .kf-korb-entfernen::after { display: none; }
  .kf-korb-details-btn, .kf-korb-bearbeiten, .kf-korb-ausst-plus, .kf-dateien-btn {
    min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; margin-top: 0;
  }
  .kf-korb-details-btn::after, .kf-korb-ausst-plus::after { display: none; }
  .kf-korb-groessen-auto, .kf-korb-vered-chip { min-height: 44px; display: inline-flex; align-items: center; }
  .kf-korb-stueck, .kf-korb-groesse input, .kf-groesse input, #kf-stueck { min-height: 44px; }
  .kf-rabatt-auf { min-height: 44px; }
  .kf-rabatt-ok, .kf-rabatt-weg { width: 44px; height: 44px; }
  .kf-loeschen-ja, .kf-loeschen-nein { min-height: 44px; padding: 8px 16px; }
  /* Info-„i" (Größen-Automatik, Datencheck, Zahlung): 44-px-Knopf, Kreis per ::before */
  .kf-info-i {
    width: 44px; height: 44px; margin: -12px; border: none; background: none; position: relative;
  }
  /* Kein zweiter Kreis: das SVG bringt seinen eigenen mit (14.10.2026) */
  .kf-info-i::before { display: none; }
  .kf-info-i::after { display: none; }
  .kf-datencheck-info .kf-info-i { width: 44px; height: 44px; margin: -14px; }
  /* Veredelungs-„i" (Kachel-Ecke und Überschrift) */
  .kf-vered-i { width: 44px; height: 44px; top: -4px; right: -4px; border: none; background: none !important; }
  /* Das „i" ist hier 44 px groß und ragt entsprechend weit in die Kachel. Ohne
     Platz rechts liegt es über der MOQ-Pille und dem Vektor-Badge — gemessen
     28 × 18 px Überdeckung bei „ab 25 Stk." und 22 × 20 px bei „Vektordatei
     (SVG/PDF)", beides also halb verdeckt und nicht antippbar (10.09.2026). */
  .kf-vered { padding-right: 46px; }
  /* AGB- und Datencheck-Haken: 16 px waren als einzige Korb-Bedienelemente
     nicht mit vergrößert. Das Label ist groß und fängt 86 % der Treffer ab —
     der Haken selbst soll aber auch treffbar sein (10.09.2026). */
  .kf-check input { width: 24px; height: 24px; }
  .kf-check { min-height: 44px; }
  .kf-mwst-klein { min-height: 44px; }
  input.kf-korb-titel { min-height: 44px; }
  /* Bei 360 px brach der Datencheck-Titel und das „i" stand allein auf der
     zweiten Zeile — es gehört an das letzte Wort. */
  .kf-datencheck-titel { white-space: nowrap; }
  /* …aber nicht der Tooltip darin: er erbte das nowrap und lief als eine
     2400-px-Zeile nach rechts — die Kasse wurde auf Touch-Geräten 2461 px
     breit und das Handy zoomte heraus (Prüfrunde 05.10.2026). */
  .kf-datencheck-titel .kf-info-tip { white-space: normal; }
  .kf-vered-i::before { display: none; }   /* keine Scheibe hinter dem i (Julian, 14.10.2026) */
  .kf-vered:hover .kf-vered-i, .kf-vered-i:hover, .kf-vered-i:focus-visible { color: rgba(17, 17, 17, 0.75); }
  .kf-vered-i::after { display: none; }
  .kf-vered-i.kf-label-i { position: relative; width: 44px; height: 44px; margin: -13px -13px -13px -6px; }
  /* Schritt 2: Größen-Modus-Pillen, Größen-Toggles */
  .kf-modus-btn { min-height: 44px; padding: 4px 14px; }
  .kf-groesse-toggle { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 0; }
  .kf-groesse-toggle::after { display: none; }
}
/* Korb-Knöpfe auf Handy: 12 px wie jeder Primär-CTA; „+ Artikel konfigurieren" darf
   umbrechen statt in den Nachbar-Knopf zu laufen (Brand F-02/F-04) — beide bleiben
   nebeneinander (Julian, 14./18.08.2026). „Design bestätigen" bleibt am unteren Rand
   sichtbar, statt 1,4 Bildschirme tief zu liegen (Brand F-06 / F-04). */
@media (max-width: 820px) {
  #kf-korb-aufklappen { font-size: 12px; letter-spacing: 0.08em; }
  .kf-korb-buttons .kf-btn-primary, .kf-korb-buttons .kf-btn-ghost {
    white-space: normal; line-height: 1.25; font-size: 12px; letter-spacing: 0.06em; min-height: 44px;
    padding-left: 8px; padding-right: 8px;
  }
  .kf-step[data-step-panel="1"] .kf-nav-row--voll {
    position: sticky; bottom: 0; z-index: 3; margin-top: 10px;
    padding: 10px 0 12px; background: #fff;
    box-shadow: 0 -14px 14px -10px rgba(0, 0, 0, 0.08);
  }
}

/* ═══ Prüfrunde 2 (07.09.2026) — Kontrast: Text im --kf-*-Grau auf ≥ 4,5:1 (F-07 / Runde 1 F-10) ═══
   Eigener Block am Dateiende (Konfliktvermeidung mit dem Konfigurator-Agenten). Nur Textfarben —
   Rahmen und Icons behalten ihr bisheriges Grau. Rechnung: #666 = 5,7:1 auf Weiß, 4,95:1 auf --kf-bg;
   rgba(17,17,17,.62) ≈ #6b auf Weiß (5,7:1) bzw. #66 auf --kf-bg (4,95:1); Akzent-Dunkel #1558d6 =
   5,3:1 auf --kf-bg statt 3,9:1 für das Akzentblau. axe „color-contrast" Konfigurator Desktop vorher
   30–41 Knoten je Schritt (Screenshots + Zahlen im Fix-Bericht fix3/brand-i18n-a11y). */
:root { --kf-mid: #666666; }                                                         /* vorher #888888 (3,5:1) */
.kf-note-i { border-color: #888888; }                                                /* Rahmen (Nicht-Text) bleibt */
.kf-kauf-fussnote { color: var(--kf-mid); }                                          /* vorher #8a8a8a */
.kf-label, .kf-tb-label, .kf-marke-hint, .kf-summary-zeile span, .kf-korb-groesse > span,
.kf-korb-design-anzahl, .kf-korb-details-btn, .kf-zeilen-btn, .kf-staffel-btn,
.kfu-p, .kf-modus-opt-text em, .kf-info-modell-label, .kf-modus-btn, .kfu-usp-s,
.kf-info-modell-hint { color: rgba(17, 17, 17, 0.62); }                              /* vorher .4–.55 */
.kf-korb-titel::placeholder { color: rgba(17, 17, 17, 0.62); }
.kf-chip-status, .kf-tech-punkt b, .kfu-rev-n { color: rgba(17, 17, 17, 0.6); } /* vorher .45 */
/* Ausverkaufte Familie: blass, NICHT durchgestrichen (Julian, 22.09.2026).
   Der Durchstrich kam aus der Kontrast-Runde, dort war aber die Farbe das
   Problem (.4 = 2,6:1). Die 0.62 bleibt und trägt den Kontrast allein; dass
   etwas nicht lieferbar ist, sagt jetzt der Titel statt einer Linie. */
.kf-familie.ausverkauft { color: rgba(17, 17, 17, 0.62); }
.kf-familie.ausverkauft.active { color: rgba(240, 238, 236, 0.75); }                 /* aktiver Tab wie bisher */
.kf-option.gesperrt .kf-option-kopf, .kf-option.gesperrt > .kf-option-text { opacity: 0.7; } /* vorher .42 (1,8–2,8:1) */
.kf-option.gesperrt > .kf-option-text { color: rgba(17, 17, 17, 0.85); }
#kf-rail-upload, .kf-groesse-toggle { color: var(--kf-akzent-dunkel); }              /* Akzentblau auf Beige/Hellblau < 4,5:1 */
.kf-groesse.aus .kf-groesse-toggle { color: rgba(17, 17, 17, 0.62); }                /* abgewählte Größe: vorher .3 */
.kf-korb-titel, .kfu-kicker, .kfu-ig-k { color: rgba(17, 17, 17, 0.62); }          /* Artikelname im Korb (.55), Kicker der USP-Sektion (.45) */
/* Schriftprobe „Aa" im Korb-Aufklapper trägt die Original-Textfarbe des Designs — helle Farben
   standen unsichtbar auf der Bühnenfarbe (1,5:1). Dünner dunkler Saum statt Farbwechsel: die
   Probe bleibt die echte Farbe, ist aber auch in Weiß lesbar. */
.kf-datei-thumb-text { text-shadow: 0 0 1px rgba(0, 0, 0, 0.8), 0 0 1px rgba(0, 0, 0, 0.8); }

/* ── Mobil-Nachlese 15.09.2026 ──────────────────────────────────────────────
   Trefferflächen im Kauf-Flow, gemessen bei 360/390/414px mit Touch-Emulation.
   Die sichtbaren Kästen bleiben unverändert — auf dem Gestaltungsbereich würden
   größere Knöpfe das Motiv verdecken, deshalb wachsen nur unsichtbare Felder. */
@media (hover: none) and (pointer: coarse) {
  .kf-view-btn, .kf-flyout-zu, .kf-modal-close, .kf-thumb, .kf-rail-btn { position: relative; }
  .kf-view-btn::before, .kf-flyout-zu::before, .kf-modal-close::before,
  .kf-thumb::before, .kf-rail-btn::before {
    content: ""; position: absolute; left: 50%; top: 50%;
    min-width: 44px; min-height: 44px; width: 100%; height: 100%;
    transform: translate(-50%, -50%);
  }
  /* Werkzeug-Beschriftungen standen auf 9px. Seit dem 06.10.2026 ALLE auf
     11 px — vorher nur die Kurzformen (Upload, Grafik, Archiv), D.AI, Text und
     Ebenen blieben klein daneben (Julian: „abstände passen nicht"). 10,5 px,
     weil „Ebenen" bei 11 px in der 41-px-Spalte (390 px) mit „…" endete. */
  .kf-rail-btn > span { font-size: 10.5px; }
}
/* Schmale Handys (360 px): die Spalten sind 37 px breit — alle gemeinsam kleiner, nicht nur einzelne */
@media (hover: none) and (pointer: coarse) and (max-width: 374px) {
  .kf-rail-btn > span { font-size: 9.5px; }
}

/* Querformat: die Felder fielen auf 12,5px, darunter zoomt iOS Safari beim
   Fokus automatisch in die Seite hinein — mitten im Bestellvorgang. Der
   Platzgewinn war 3,5px pro Zeile, der Preis ein springendes Layout.
   (Mobil-Audit 15.09.2026, aus dem CSS gelesen und hier korrigiert.) */
@media (min-width: 921px) and (max-height: 545px), (max-width: 920px) and (max-height: 500px) {
  .kf-feld input, .kf-feld textarea, .kf-feld select { font-size: 16px; }
}

/* ════════════════════════════════════════════════════════════════════════
   Die Warenkorbseite (/create/warenkorb, Julian 01.10.2026)

   „Der Warenkorb soll sich als eigene Seite öffnen … also kein
   Warenkorb-Popup mehr." Links die Artikel, rechts die Zusammenfassung.

   Es ist DASSELBE Markup wie im Konfigurator — AGB-Haken, E-Mail-Feld und
   Bestellknopf hängen über form="kf-form" am Bestellformular, und der
   Absende-Weg baut die Druckdateien aus dem laufenden Zustand. Hier wird
   deshalb nur umgelegt, nicht umgebaut: Bühne und Panel aus, der Korb wird
   zur Seite, seine Beilagen wandern in eine zweite Spalte.
   ════════════════════════════════════════════════════════════════════════ */

/* Die Seite scrollt normal — der App-Rahmen klemmt sich sonst auf 100svh */
.kf-app-korbseite { height: auto; min-height: 100svh; overflow: visible; }
.kf-app-korbseite .kf-body { display: none; }

/* Aus dem Fenster wird der Seitenkörper */
.kf-app-korbseite #kf-korb-modal {
  position: static; inset: auto; display: block;
  width: min(1280px, 100%); margin: 0 auto; padding: 0 clamp(16px, 4vw, 40px) 64px;
  background: none;
}
.kf-app-korbseite .kf-korb-modal-box {
  position: static; max-height: none; width: auto; box-shadow: none;
  border-radius: 0; background: none; overflow: visible;
}
.kf-app-korbseite .kf-korb-modal-kopf { padding: 28px 0 18px; border: 0; }
.kf-app-korbseite .kf-korb-modal-titel { font-size: clamp(26px, 3vw, 36px); letter-spacing: -0.02em; }
.kf-app-korbseite .kf-korb-modal-inhalt { padding: 0; overflow: visible; max-height: none; }

/* Zwei Spalten, ohne das Markup anzufassen: die Artikelliste bekommt die
   linke Spalte über alle Zeilen, alles danach (Summe, Rabatt, Datencheck,
   AGB, E-Mail, Knopf, Fußnote) stapelt sich rechts. Ein Wrapper-<div> hätte
   die Reihenfolge angefasst, die § 312j BGB vorgibt und vier Tests
   zeichengenau festhalten. */
@media (min-width: 981px) {
  .kf-app-korbseite #kf-korb-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(340px, 420px);
    column-gap: 32px; align-items: start;
  }
  .kf-app-korbseite #kf-korb { grid-column: 1; }
  /* Die ganze Zusammenfassung läuft beim Scrollen mit (09.10.2026) — vorher nur die Kompaktzeile */
  .kf-app-korbseite #kf-korb-card > .kf-korb-abschluss { grid-column: 2; position: sticky; top: calc(var(--lab-kopf-h, 56px) + 20px); }
  /* Das Adressformular steht unter beiden Spalten, nicht in einer */
  .kf-app-korbseite #kf-form { max-width: 820px; }
}

/* Mobil bleibt es eine Spalte — das ist die natürliche Reihenfolge */
@media (max-width: 980px) {
  .kf-app-korbseite #kf-korb-modal { padding-bottom: 40px; }
}

/* ── Warenkorbseite, zweite Runde (Julian, 01.10.2026) ───────────────────── */

/* Der Strich über „5 Artikel · 306 Teile" trennte Artikel von Zusammenfassung,
   als beide untereinander standen. Nebeneinander trennt die Spalte schon —
   Julian: „nimm nur oben den Strich weg". */
.kf-app-korbseite .kf-korb-summe-zeile,
.kf-app-korbseite #kf-korb-card.kf-korb-kompakt .kf-korb-kompakt-zeile { border-top: 0; padding-top: 0; margin-top: 0; }

/* Der Datencheck sieht aus wie das AGB-Feld darunter: Haken, Text, kein
   eigener Kasten. Der Preis bleibt rechts, er ist die Information. */
.kf-app-korbseite .kf-datencheck { border: 0; padding: 0; margin-top: 16px; }
.kf-app-korbseite .kf-datencheck:has(input:checked) { border: 0; }
.kf-app-korbseite .kf-datencheck-sub { color: var(--kf-mid); }

/* Kein Fenster im Fenster mehr: links wie rechts komplett ausgefahren, die
   längere Spalte bestimmt die Höhe der Seite (Julian: „mach das jetzt nicht
   mehr scrollbar als eigenes Fenster"). Der innere Scrollbalken stammte vom
   Korb-Panel, das als Fenster gedacht war. */
.kf-app-korbseite #kf-korb,
.kf-app-korbseite #kf-korb-card,
.kf-app-korbseite .kf-korb-modal-inhalt,
.kf-app-korbseite .kf-korb-modal-box { max-height: none; overflow: visible; }
.kf-app-korbseite #kf-panel { max-height: none; overflow: visible; }

/* ── Hierarchie in der rechten Spalte (Julian, 01.10.2026) ────────────────
   „Das wirkt so übervoll … zudem fehlt mir generell die Hierarchie."
   Stimmt: Summe, Zusatzleistung, Einwilligung, Knöpfe, Zahlarten und
   Vertrauenspunkte standen alle etwa gleich laut nebeneinander.

   Drei Stufen, wie in jedem gut gebauten Warenkorb:
     LAUT   die Summenbox — sie beantwortet „was kostet das"
     MITTEL der Bestellbereich — Datencheck, Einwilligung, E-Mail, der EINE
            schwarze Knopf
     LEISE  der Fuß — Stripe-Zeile, Zahlarten, Vertrauenspunkte

   Gilt überall, wo die Korb-Karte steht: auf /create/warenkorb wie im
   Panel des Konfigurators. Dort ist die Spalte schmaler — da hilft die
   Abstufung sogar mehr (Julian, 01.10.2026: „hinüberziehen").

   Was dabei NICHT kleiner wird: „Gesamt" und der Bestellknopf. Der Gesamtpreis
   unmittelbar über dem Knopf ist § 312j Abs. 2 BGB, keine Geschmacksfrage. */

/* ── MITTEL ── */
#kf-korb-card .kf-datencheck { margin-top: 18px; }
.kf-datencheck-text { font-size: 12.5px; }
.kf-datencheck-sub { font-size: 11.5px; line-height: 1.4; }
.kf-datencheck-preis { font-size: 12.5px; }
.kf-agb-check { font-size: 11.5px; line-height: 1.45; margin: 12px 0 14px; color: var(--kf-mid); }
.kf-agb-check a { color: var(--kf-ink); }
.kf-kauf-email-feld label { font-size: 11.5px; }
.kf-kauf-email-feld input { font-size: 13px; padding-top: 10px; padding-bottom: 10px; }
/* iOS zoomt bei Feldern unter 16 px hinein — beim Antippen der E-Mail sprang
   die ganze Kasse (Prüfrunde 05.10.2026, Mobil-Checkliste: Eingaben ≥ 16 px) */
@media (max-width: 820px) { .kf-kauf-email-feld input { font-size: 16px; } }

/* Eine Handlung: „Jetzt kaufen" (der stille Textweg „Weitere Artikel"
   daneben ist am 06.10.2026 entfallen). */
.kf-korb-buttons { align-items: center; gap: 16px; margin-top: 16px; }
.kf-korb-buttons > * { flex: 0 0 auto; }
.kf-korb-buttons .kf-form-toggle-wrap { flex: 1 1 auto; }
.kf-korb-buttons .kf-form-toggle-wrap { min-width: 0; }
.kf-korb-buttons .kf-form-toggle-wrap #kf-form-toggle { width: 100%; }

/* ── LEISE ── ein Trennstrich, dann der ganze Fuß gedämpft */
.kf-kauf-fussnote { font-size: 11.5px; margin-top: 16px; }
.kf-vertrauen { margin-top: 14px; padding-top: 14px; }
.kf-zahlart { width: 32px; height: 21px; }
.kf-zahlarten { gap: 5px; margin-bottom: 14px; opacity: .75; }

/* ════════════════════════════════════════════════════════════════════════
   D.AI-Panel, Paket vom 01.10.2026 (Julians Liste vom 28.09.)
   Diktat · Mehrfachauswahl · „Erweiterte Vorgaben" · Referenz-Fenster
   ════════════════════════════════════════════════════════════════════════ */

/* Mikrofon sitzt IM Feld, unten rechts — wie bei den Chat-Oberflächen, die
   das vormachen. Läuft die Aufnahme, pulst es dezent. */
.kf-ki-prompt-wrap { position: relative; }
.kf-ki-prompt-wrap .kf-ki-prompt { padding-right: 42px; }
.kf-ki-mikro {
  position: absolute; right: 8px; bottom: 8px;
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--kf-border); background: #fff; color: var(--kf-mid);
  cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.kf-ki-mikro:hover { color: var(--kf-ink); border-color: var(--kf-ink); }
.kf-ki-mikro.aktiv { background: var(--kf-ink); border-color: var(--kf-ink); color: #fff; }
.kf-ki-mikro.aktiv::after {
  content: ''; position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid var(--kf-ink); opacity: .35; animation: kf-mikro-puls 1.4s ease-out infinite;
}
@keyframes kf-mikro-puls { from { transform: scale(.9); opacity: .45; } to { transform: scale(1.35); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .kf-ki-mikro.aktiv::after { animation: none; } }

/* ── Bogen: Formen und Stärke (Julian, 02.10.2026) ──────────────────────
   Dieselbe Bauform wie das Deckkraft-Fenster: Spalte, Kopfzeile, Regler. */
.kf-ctx-bogen-wrap { position: relative; display: inline-flex; }
.kf-ctx-pop-bogen { display: block; width: 232px; max-width: 232px; padding: 11px 12px 12px; }
.kf-bogen-formen { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.kf-bogen-form {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 8px 4px; border: 1px solid var(--kf-border); border-radius: 10px;
  background: #fff; color: var(--kf-ink); cursor: pointer;
  font-family: 'DM Sans', sans-serif; font-size: 10.5px; font-weight: 600;
}
.kf-bogen-form:hover { border-color: var(--kf-border-strong); }
.kf-bogen-form.aktiv { background: var(--kf-ink); border-color: var(--kf-ink); color: #fff; }
.kf-bogen-stark { display: block; margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--kf-border); }
.kf-bogen-stark[hidden] { display: none; }
.kf-bogen-stark input[type="range"] { width: 100%; margin-top: 8px; display: block; }
/* Regler mit Mitte (06.10.2026): links nach unten, rechts nach oben; der
   Strich in der Mitte zeigt „flach" */
.kf-bogen-regler { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.kf-bogen-regler input[type="range"] {
  flex: 1; min-width: 0; margin: 0;
  background: linear-gradient(var(--kf-border-strong), var(--kf-border-strong)) 50% 50% / 2px 12px no-repeat;
}
.kf-bogen-richtung { width: 18px; height: 9px; flex: none; color: var(--kf-mid); }
/* Gebogener Text: das SVG ersetzt die Zeile, der Span bleibt als Anker fuer
   die Bearbeitung im Markup — unsichtbar und ohne Platzbedarf. */
.kf-text-gebogen .kf-text-inhalt { position: absolute; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; }
/* Beim Bearbeiten steht gebogener Text gerade und lesbar da — vorher tippte man
   in ein unsichtbares 1-px-Feld (07.10.2026); der Bogen kommt danach zurück. */
.kf-text-gebogen.editiert .kf-text-inhalt { position: static; width: auto; height: auto; overflow: visible; opacity: 1; pointer-events: auto; }
.kf-text-gebogen.editiert .kf-text-kurve { visibility: hidden; }
.kf-text-kurve { display: block; overflow: visible; }

/* ── Deckkraft-Regler in der Kontextleiste (Julian, 02.10.2026) ─────────
   Ein Knopf mit halb gefuelltem Kreis, dahinter Regler, Prozentwert und der
   Druckhinweis. Der Hinweis steht IM Fenster und bleibt stehen, solange die
   Deckkraft unter 100 % liegt — ein Toast waere weg, bevor man ihn liest. */
.kf-ctx-deck-wrap { position: relative; display: inline-flex; }
.kf-ctx-pop-deck {
  /* .kf-ctx-pop ist eine Flex-Zeile und bei 210px gedeckelt — fuer Kopf,
     Regler und Hinweis braucht es eine Spalte und etwas mehr Platz. */
  display: block; width: 240px; max-width: 240px; padding: 11px 12px 12px;
}
.kf-deck-kopf {
  display: flex; align-items: baseline; gap: 7px;
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--kf-mid);
}
.kf-deck-wert { color: var(--kf-ink); font-weight: 700; font-size: 11.5px; letter-spacing: 0; }
.kf-ctx-pop-deck input[type="range"] { width: 100%; margin: 8px 0 0; display: block; }
/* Das „i" neben der Beschriftung: dasselbe Bauteil wie in der Abschlussleiste
   und im Rest des Konfigurators, nur kleiner. Der Satz zum Druck kommt beim
   Hovern aus dem globalen Tooltip (Julian, 02.10.2026). */
.kf-deck-i { width: 16px; height: 16px; margin-right: auto; align-self: center; }
.kf-deck-i .i-info { width: 12px; height: 12px; }

/* ── Eine Vorgabenleiste statt dreier Chip-Reihen (Julian, 02.10.2026) ──
   Die „Erweiterten Vorgaben" als Ausklapper sind damit weg. Jede Vorgabe ist
   eine Pille, die ihren aktuellen Wert trägt und ihr Menü aufklappt; die
   Referenzbilder sind die erste Pille und öffnen ihr Fenster. Die Reihe sitzt
   direkt unter der Beschreibung — wie in dem Vorbild, das Julian danebenlegte. */
/* Die Vorgaben gehoeren zum Feld darueber, nicht zum Knopf darunter (Julian,
   02.10.2026: „die Auswahlfunktionen müssen deutlich näher ans Feld als an den
   Design-generieren-Knopf"). Deshalb ruecken sie gegen den 10px-Abstand der
   Spalte nach oben und halten nach unten mehr Luft. */
.kf-ki-leiste { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: -5px 0 7px; }
.kf-ki-dd { position: relative; }
.kf-ki-pille {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 11px; border-radius: 999px;
  border: 1px solid var(--kf-border); background: #fff; color: var(--kf-ink);
  font-family: 'DM Sans', sans-serif; font-size: 11.5px; font-weight: 600;
  cursor: pointer; transition: border-color .15s, background .15s;
}
.kf-ki-pille:hover { border-color: var(--kf-border-strong); background: #fbfbfa; }
/* Nur der gewaehlte Wert steht in der Pille — kein Zeichen, kein Pfeil, nicht
   der Name der Kategorie (Julian, 02.10.2026: „mach das mal ohne die Icons und
   Pfeile, so dass es alles in einer Zeile stehen kann … würde auch einfach nur
   anzeigen was ausgewählt wurde, gar nicht wie die Kategorie heißt, weil die
   das ja beim Draufklicken sehen"). Die Kategorie steht ueber dem Menue und
   fuer Vorleseprogramme im aria-label, das konfigurator.js mitfuehrt. */
.kf-ki-pille-wert { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kf-ki-dd.offen .kf-ki-pille { border-color: var(--kf-ink); }
/* Gesetzt, sobald etwas anderes als die Vorgabe gewählt ist — sonst sieht man
   der zugeklappten Leiste nicht an, dass sie etwas enthält. */
.kf-ki-pille.gesetzt { border-color: var(--kf-ink); background: var(--kf-ink); color: #fff; }
/* Das Menü hängt am Viewport, nicht am Panel (Julian, 02.10.2026: „die
   Dropdown-Fenster müssen nicht nur auf das Fenster beschränkt sein, finde das
   darf auch dann außerhalb angezeigt werden"). Das Panel scrollt und schneidet
   ab — wie beim globalen Tooltip (#kf-tip) rechnet deshalb konfigurator.js die
   Stelle aus und setzt sie hier ein. */
.kf-ki-dd-menue {
  position: fixed; z-index: 90;
  min-width: 215px; max-width: min(320px, calc(100vw - 24px)); padding: 11px 12px 12px;
  border: 1px solid var(--kf-border); border-radius: 12px; background: #fff;
  box-shadow: 0 16px 36px rgba(0, 0, 0, .14);
}
.kf-ki-dd-menue[hidden] { display: none; }

/* Referenzbilder: die Reihe trägt immer das Plus und sitzt in der Leiste,
   also auf Pillenhöhe statt als eigener Block mit 46px-Kacheln. */
.kf-ki-ref-strip { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 0; }
.kf-ki-ref-strip.aktiv { outline: 2px dashed var(--kf-ink); outline-offset: 4px; border-radius: 10px; }
.kf-ki-ref-plus {
  width: 32px; height: 32px; flex: none; border-radius: 999px;
  border: 1.5px dashed var(--kf-border); background: #fff; color: var(--kf-mid);
  font-size: 17px; line-height: 1; cursor: pointer; font-family: inherit;
  display: inline-flex; align-items: center; justify-content: center;
}
.kf-ki-ref-plus:hover { border-color: var(--kf-ink); color: var(--kf-ink); }
.kf-ki-leiste .kf-ki-ref-thumb { width: 32px; height: 32px; border-radius: 8px; }
.kf-ki-leiste .kf-ki-ref-thumb button { width: 15px; height: 15px; top: -5px; right: -5px; font-size: 9px; border-width: 1.5px; }

/* Der Hauptknopf trägt die bewegte Markenfarbe (Julian, 02.10.2026: „den
   Generieren Button auch in der bewegten Farbe wie wir das sonst auch haben")
   — derselbe Verlauf und dieselbe Bewegung wie die MMD-Pille in der Navigation
   (.nav-lab-pille). */
#kf-ki-gen {
  background: linear-gradient(90deg, #ff5fa2, #7c5cff, #ff5fa2);
  background-size: 220% 100%; border-color: transparent; color: #fff;
  animation: kf-ki-gen-fluss 14s ease-in-out infinite;
}
#kf-ki-gen:hover { opacity: .93; }
@keyframes kf-ki-gen-fluss { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@media (prefers-reduced-motion: reduce) { #kf-ki-gen { animation: none; } }

/* Das Fenster hinter dem Plus */
.kf-refw {
  border: 0; padding: 0; margin: auto; width: 420px; max-width: calc(100vw - 32px);
  max-height: calc(100svh - 48px); border-radius: 18px; background: #fff; color: var(--kf-ink);
  box-shadow: 0 28px 70px rgba(0,0,0,.3); overflow: auto;
}
.kf-refw::backdrop { background: rgba(13,13,13,.5); }
.kf-refw[open] { display: block; }
.kf-refw-kopf { display: flex; align-items: center; justify-content: space-between; padding: 18px 18px 8px; }
.kf-refw-kopf b { font-size: 16px; font-weight: 700; }
.kf-refw-zu { width: 30px; height: 30px; border-radius: 50%; border: 0; background: var(--kf-flaeche, #f4f4f2); font-size: 17px; line-height: 1; cursor: pointer; color: var(--kf-ink); }
.kf-refw-stand { margin: 0 18px 12px; font-size: 11.5px; color: var(--kf-mid); }
.kf-refw-upload {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: 0 18px 16px; width: calc(100% - 36px); min-height: 44px;
  border: 1.5px dashed var(--kf-border); border-radius: 12px; background: #fff;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--kf-ink); cursor: pointer;
}
.kf-refw-upload:hover { border-color: var(--kf-ink); }
.kf-refw-bib-titel { margin: 0 18px 8px; font-size: 11.5px; font-weight: 600; color: var(--kf-mid); }
.kf-refw-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; padding: 0 18px 18px; }
.kf-refw-kachel {
  aspect-ratio: 1; border-radius: 10px; border: 1.5px solid transparent;
  background: var(--kf-flaeche, #f4f4f2); padding: 4px; cursor: pointer; overflow: hidden;
}
.kf-refw-kachel img { width: 100%; height: 100%; object-fit: contain; display: block; }
.kf-refw-kachel.aktiv { border-color: var(--kf-ink); }
.kf-refw-leer { margin: 0 18px 18px; font-size: 12.5px; color: var(--kf-mid); }

.kf-refw-stand--voll { color: #c2410c; font-weight: 600; }

/* ── Leerer Warenkorb (Prüfrunde 05.10.2026) ── die Kasse geht weg, ein Satz
   und zwei Wege stehen da. !important, weil die Warenkorbseite die Karte
   sonst per Layout-Regel zeigt, obwohl sie hidden trägt. */
body.kf-korb-ist-leer #kf-korb-card { display: none !important; }
.kf-korb-leer-seite { grid-column: 1 / -1; max-width: 520px; margin: 24px auto; padding: 32px 24px; text-align: center; }
.kf-korb-leer-seite[hidden] { display: none; }
.kf-korb-leer-titel { margin: 0; font-size: 20px; font-weight: 700; color: var(--kf-ink); }
.kf-korb-leer-text { margin: 8px 0 0; font-size: 14px; line-height: 1.55; color: var(--kf-mid); }
.kf-korb-leer-wege { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 20px; }
.kf-korb-leer-wege a { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; padding: 0 20px; }

/* ── Text-/Element-Leiste auf dem Handy (Prüfrunde 05.10.2026) ──────────────
   Vorher brach sie in zwei Zeilen um und lag über dem Motiv, und Bogen /
   Deckkraft hingen als Fenster darunter — die Bühne schnitt sie ab. Jetzt:
   EINE Zeile zum Wischen (die Maske am rechten Rand zeigt, dass es weitergeht,
   .kf-ctx--scrollt), und jedes Fenster öffnet als Blatt am unteren
   Bildschirmrand. Ohne transform an der Leiste — sonst hinge das feste Blatt
   an ihr statt am Bildschirm. */
@media (max-width: 820px) {
  .kf-ctx {
    left: 8px; right: 8px; width: auto; transform: none;
    flex-wrap: nowrap; justify-content: flex-start;
    overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain;
  }
  .kf-ctx::-webkit-scrollbar { display: none; }
  .kf-ctx > * { flex: none; }
  /* Keine Maske: mask-image macht die Leiste zum Bezugsrahmen fester Kinder —
     das Blatt hing an der Leiste und wurde mit ausgeblendet. Das angeschnittene
     letzte Symbol am Rand zeigt auch so, dass man wischen kann. */
  .kf-ctx, .kf-ctx.kf-ctx--scrollt { -webkit-mask-image: none; mask-image: none; }
  .kf-ctx .kf-ctx-pop {
    /* Über der festen Warenkorb-Leiste (≈ 120 px): die Bühne ist eine eigene
       Stapel-Ebene, gegen die kein z-index ankommt — darunter läge das Blatt
       unsichtbar hinter der Leiste. */
    position: fixed; top: auto; left: 8px; right: 8px; bottom: calc(132px + env(safe-area-inset-bottom, 0px)); transform: none;
    max-width: none; max-height: 60vh; max-height: 60svh; overflow-y: auto;
    z-index: 120; border-radius: 16px; padding: 14px 14px 16px;
    box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.22);
  }
}

/* Mobil-Runde 2 (16.10.2026): solange ein Blatt der Kontextleiste offen ist,
   lag der Bühnen-Griff ˄ darüber — er gehört dann nicht ins Bild. Die Lage
   des Blatts setzt legeCtxBlatt() (konfigurator.js). */
@media (min-width: 821px) and (max-width: 920px) {
  .kf-ctx .kf-ctx-pop { position: fixed; transform: none; overflow-y: auto; z-index: 120; border-radius: 16px; padding: 14px 14px 16px; box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.22); }
}
@media (max-width: 920px) {
  body.kf-ctx-blatt-offen .kf-mini-toggle { visibility: hidden; }
  .kf-ctx .kf-ctx-pop-fonts .kf-fonts-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Spiegel-Menü mit Symbol je Richtung (Abnahme 07.10.2026, Vorbild Canva) */
.kf-spiegel-aktion { display: flex; align-items: center; gap: 10px; }
.kf-spiegel-ic { flex: none; }

/* Spiegeln (07.10.2026): darunter nur zwei Symbolknöpfe nebeneinander,
   ohne Text und ohne Haken — in Konfigurator und Board gleich */
.kf-ctx-pop-spiegel { gap: 4px; padding: 6px; align-items: center; }
.kf-ctx-pop-spiegel .kf-spiegel-knopf { width: 34px; height: 34px; }

/* Schloss (07.10.2026): gesperrt = keine Griffe, kleines Schloss am Element */
.kf-logo-item.kf-gesperrt .kf-eckpunkt,
.kf-logo-item.kf-gesperrt .kf-griff { display: none !important; }
.kf-logo-item.kf-gesperrt { cursor: default; }
.kf-schloss-zeichen { position: absolute; top: -9px; right: -9px; width: 18px; height: 18px; border-radius: 50%; background: #0a0a0a; color: #fff; display: flex; align-items: center; justify-content: center; pointer-events: none; z-index: 3; }

/* Ebenen-Menü mit Symbolen, in Konfigurator und Board gleich (07.10.2026) */
.kf-ebenen-aktion { display: flex; align-items: center; gap: 9px; }
.kf-ebenen-aktion .kf-ebenen-ic { flex: none; opacity: 0.8; }

/* Gesperrter Knopf, der seinen Hinweis trotzdem zeigt (aria-disabled statt
   disabled — deaktivierte Knöpfe lösen in manchen Browsern kein Hover aus) */
.kf-ctx-btn[aria-disabled="true"] { opacity: 0.35; cursor: not-allowed; }

/* Produkt-Zeile mit „Neu beginnen" rechts (07.10.2026) */
.kf-abschnitt-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.kf-neu-beginnen { background: none; border: 0; padding: 4px 0; min-height: 32px; font: inherit; font-size: 13px; color: rgba(17, 17, 17, 0.6); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.kf-neu-beginnen:hover { color: #111; }
.kf-neu-beginnen--frage { color: #c2410c; }

/* Regler mit 0 in der Mitte (Julian, 07.10.2026: „in der Mitte immer ganz klar
   0") — Bogenstärke und Zeichenabstand, in Konfigurator und Board. Der Strich
   markiert die 0, dort rastet der Regler ein. Keine Zahl daneben. */
.kf-regler-mitte { display: block; flex: 1; min-width: 0; position: relative; }
.kf-regler-mitte input[type="range"] {
  width: 100%; display: block; margin: 8px 0 0;
  background: linear-gradient(var(--kf-ink, #111), var(--kf-ink, #111)) 50% 50% / 2px 14px no-repeat;
}
.kf-bogen-regler .kf-regler-mitte input[type="range"] { margin: 0; }
/* Zeilenabstand (16.10.2026) im selben Fenster: ein Faktor, keine 0 in der Mitte — darum ohne Strich */
.kf-regler-zeilen { display: block; flex: 1; min-width: 0; }
.kf-regler-zeilen input[type="range"] { width: 100%; display: block; margin: 8px 0 0; }
.kf-deck-kopf--zweit { margin-top: 12px; }
/* Bogen-Kacheln nur mit Symbol (07.10.2026) */
.kf-bogen-form { padding: 10px 4px; }
.kf-bogen-form svg { width: 22px; height: 22px; }
/* Aktive Wahl in Ausrichtungs-Menüs (07.10.2026) */
.kf-ebenen-aktion[data-ausricht].aktiv, .kf-ebenen-aktion[data-fausricht].aktiv { font-weight: 700; }

/* ═══ Knöpfe = Pille wie auf der Startseite (Julian, 09.10.2026) ═══
   „Orientiere dich an diesem Button von der Startseite … immer gleich in dieser
   Pillenform." Form und Schrift für alle Text-Knöpfe, die FARBEN bleiben (Julian:
   „jetzt aber keine Knöpfe groß farbig anpassen"). Ersetzt die Regel vom 10.09.2026
   („mit Text nicht mehr rund"). Regeln: docs/MMD-DESIGN-DNA.md „Knöpfe = Pille". */
:root { --radius-btn: 999px; }
.kf-btn-primary, .kf-btn-ghost, .kf-modus-btn, .kf-loeschen-ja, .kf-loeschen-nein,
.kf-korb-buttons .kf-btn-primary, .kf-korb-buttons .kf-btn-ghost,
#kf-form-toggle, #kf-design-weiter, #kf-korb-aufklappen {
  border-radius: var(--radius-btn); text-transform: none; letter-spacing: 0; font-weight: 600;
}
.kf-btn-primary, .kf-btn-ghost, #kf-form-toggle, #kf-design-weiter { font-size: 13.5px; }
.kf-korb-buttons .kf-btn-primary, .kf-korb-buttons .kf-btn-ghost { font-size: 13px; }
a.kf-btn-primary { display: inline-flex; align-items: center; justify-content: center; }
a.kf-btn-primary:not(:has(svg))::after {
  content: ""; display: inline-block; width: 14px; height: 14px; margin-left: 10px; flex: none; vertical-align: -2px;
  background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E") no-repeat center / contain; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* ── Warenkorb in zwei Kästen (Julian, 09.10.2026) ─────────────────────────
   „links Produkte in eigenem Kasten, rechts die Bestell-Zusammenfassung …
   farblich unterlegt (Shopify-Shops ansehen); außen und innen mehr Luft —
   klare Regeln für beide Kästen". Eine Regel für beide: 16 px Rundung,
   28 px Innenabstand, 32 px Abstand dazwischen. Links weiß mit Rahmen (die
   Ware), rechts ohne Rahmen auf warmem Grau (die Kasse) — wie bei Shopify. */
:root { --kf-korb-flaeche: #f4f4f1; }
.kf-app-korbseite #kf-korb-card { border: 0; background: none; padding: 0; border-radius: 0; }
.kf-app-korbseite #kf-korb { margin: 0; background: #fff; border: 1px solid var(--kf-border); border-radius: 16px; padding: 12px 28px; }
.kf-app-korbseite .kf-korb-abschluss { background: var(--kf-korb-flaeche); border-radius: 16px; padding: 28px; }
/* Die letzte Trennlinie in der Liste stößt sonst an den Kastenrand */
.kf-app-korbseite #kf-korb > :last-child { border-bottom: 0; }
/* Zahlarten in EINER Zeile (Bild 17): elf Kacheln teilen sich die Breite */
.kf-app-korbseite .kf-zahlarten { flex-wrap: nowrap; gap: 4px; }
.kf-app-korbseite .kf-zahlart { flex: 1 1 0; min-width: 0; max-width: 36px; width: auto; height: auto; aspect-ratio: 40 / 26; }
@media (max-width: 980px) {
  .kf-app-korbseite #kf-korb { padding: 12px 18px; }
  .kf-app-korbseite .kf-korb-abschluss { margin-top: 16px; padding: 22px 18px; }
}

/* ── Grafik-Bibliothek: Suche + EIN Filter (Julian, 09./14.10.2026) ─────────
   Suchfeld mit Lupe, daneben „Filter" (Symbol + Wort + Zahl der aktiven
   Filter). Tippt man in die Suche, fährt sie aus und der Filter schrumpft
   auf sein Symbol. Im Menü: Eigenschaften (Haken), dann Kategorien. Der
   Kopf bleibt beim Scrollen der Kacheln oben stehen. Konfigurator und Board
   zeichnen dieselbe Leiste (konfi-formen.js). */
.kf-formen-kopf {
  position: sticky; top: -12px; z-index: 5; flex: none;
  margin: -12px -12px 0; padding: 12px 12px 8px; background: #fff;
  display: flex; flex-direction: column; gap: 8px;
}
.kf-formen-kopfzeile { position: relative; display: flex; align-items: center; gap: 6px; flex: none; }
.kf-formen-kopfzeile .kf-formen-suche {
  flex: 1 1 auto; min-width: 0; width: auto; height: 36px; padding: 0 10px 0 31px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") no-repeat 10px 50%;
}
.kf-formen-filterplatz { flex: none; }
.kf-formen-filter { display: flex; }
.kf-formen-fknopf {
  height: 36px; padding: 0 11px; border-radius: 8px; gap: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--kf-border); background: #fff; color: var(--kf-ink); cursor: pointer;
  font-family: 'DM Sans', sans-serif; font-size: 12.5px; font-weight: 600; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, padding .22s ease;
}
.kf-formen-fknopf:hover { border-color: var(--kf-border-strong); }
.kf-formen-fknopf[aria-pressed="true"] { border-color: var(--kf-ink); }
.kf-formen-fknopf[aria-expanded="true"] { background: var(--kf-ink); border-color: var(--kf-ink); color: #fff; }
.kf-formen-fknopf-text {
  display: inline-block; max-width: 60px; overflow: hidden;
  transition: max-width .22s ease, opacity .18s ease;
}
.kf-formen-fknopf-zahl {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--kf-ink); color: #fff; font-size: 10.5px; line-height: 18px; text-align: center;
}
.kf-formen-fknopf[aria-expanded="true"] .kf-formen-fknopf-zahl { background: #fff; color: var(--kf-ink); }
/* Suche aktiv: das Wort schiebt sich in den Knopf, das Feld bekommt den Platz */
.kf-formen-kopfzeile--suche .kf-formen-fknopf { padding: 0 10px; gap: 0; }
.kf-formen-kopfzeile--suche .kf-formen-fknopf-text { max-width: 0; opacity: 0; }
.kf-formen-kopfzeile--suche .kf-formen-fknopf-zahl { margin-left: 5px; }
@media (prefers-reduced-motion: reduce) { .kf-formen-fknopf, .kf-formen-fknopf-text { transition: none; } }
.kf-formen-katmenue {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; width: 220px;
  max-height: 340px; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 2px; padding: 6px;
  background: #fff; border: 1px solid var(--kf-border); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .14);
}
.kf-formen-katmenue-titel {
  margin: 6px 10px 3px; font-size: 10px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--kf-mid);
}
.kf-formen-katmenue-titel:not(:first-child) { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--kf-border); }
.kf-formen-eigenschaft, .kf-formen-katmenue .kf-board-chip {
  width: 100%; display: flex; align-items: center; gap: 9px; justify-content: flex-start; text-align: left;
  border: 0; border-radius: 8px; background: none; padding: 8px 10px; min-height: 34px;
  font-family: 'DM Sans', sans-serif; font-size: 13px; font-weight: 500; color: var(--kf-ink); cursor: pointer;
}
.kf-formen-eigenschaft:hover, .kf-formen-katmenue .kf-board-chip:hover { background: var(--kf-bg, #f4f4f2); }
.kf-formen-katmenue .kf-board-chip.active { background: var(--kf-ink); color: #fff; }
.kf-formen-haken {
  width: 16px; height: 16px; flex: none; border-radius: 4px; border: 1.5px solid var(--kf-border-strong);
  display: inline-flex; align-items: center; justify-content: center;
}
.kf-formen-eigenschaft[aria-checked="true"] .kf-formen-haken { background: var(--kf-ink); border-color: var(--kf-ink); }
.kf-formen-eigenschaft[aria-checked="true"] .kf-formen-haken::after {
  content: ''; width: 8px; height: 4px; border-left: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(-45deg) translate(1px, -1px);
}
.kf-formen-aktiv { display: flex; flex-wrap: wrap; gap: 4px; flex: none; }
.kf-formen-aktiv:empty { display: none; }
.kf-formen-aktiv-pille {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px;
  border-radius: 999px; border: 0; background: var(--kf-bg, #f1f1ef); color: var(--kf-ink);
  font-family: 'DM Sans', sans-serif; font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.kf-formen-aktiv-pille span { color: var(--kf-mid); font-size: 13px; line-height: 1; }
.kf-formen-aktiv-pille:hover span { color: var(--kf-ink); }
.kf-bib-leer .kf-textlink { margin-top: 6px; }
/* Touch: jede Tapfläche ≥ 44 px (Mobil-Checkliste) */
@media (pointer: coarse) {
  .kf-formen-fknopf, .kf-formen-kopfzeile .kf-formen-suche { height: 44px; }
  .kf-formen-aktiv-pille { height: 44px; padding: 0 14px; }
  .kf-formen-eigenschaft, .kf-formen-katmenue .kf-board-chip { min-height: 44px; }
  .kf-bib-leer .kf-textlink { display: inline-flex; align-items: center; min-height: 44px; }
}

/* Kachel wandelt gerade D.AI-Motive in Vektoren (14.10.2026) */
.kf-vered--wandelt { pointer-events: none; opacity: .6; cursor: progress; }

/* Blocksatz (16.10.2026): jede Zeile ein Block, außer der letzten auf die Breite der
   längsten gestreckt — auch vor einem festen Umbruch (text-align-last) —, die letzte
   mittig; wie der Druck (DesignRenderer::zeichneZeileBlocksatz) */
.kf-bz-zeile { display: block; text-align: justify; text-align-last: justify; white-space: nowrap; }
.kf-bz-letzte { text-align-last: center; }

/* ── Mobil-Runde 2 (Julian, 16.10.2026): Werkzeug-Fenster bis 920 px ────────
   Höhe aus hoeheFlyoutMobil() (konfigurator.js): die ganze Bühne statt 260 px.
   Die Regeln stehen am Dateiende, damit sie die Panel-Sonderwerte (Bibliothek
   84 %, Grafiken, Ebenen, D.AI) schlagen — sonst öffnete die Bibliothek 54 px
   hoch. Der ×-Schließer stand im Touch-Block auf position: relative und rutschte
   als weißer Kreis ohne × nach unten links. */
@media (max-width: 920px) and (min-height: 501px) {
  .kf-toolbar .kf-flyout, .kf-toolbar[data-panel] .kf-flyout { width: auto; max-width: 100%; max-height: var(--kf-fly-max, 260px); }
  .kf-toolbar[data-panel] .kf-flyout-panel { max-height: var(--kf-fly-max, 260px); }
  body.kf-panel-offen-mobil .kf-mini-toggle { visibility: hidden; }
}
@media (max-width: 920px) and (hover: none) and (pointer: coarse) {
  .kf-flyout .kf-flyout-zu { position: absolute; }
  .kf-flyout .kf-flyout-zu::before { content: "\00d7"; position: static; transform: none; min-width: 0; min-height: 0; width: auto; height: auto; }
}

/* ── Bühne fährt mit dem Scrollen ein (Mobil-Runde 2, 16.10.2026) ───────────
   Werte aus einfahren() (konfigurator.js): --kf-ein = abgegebene Höhe in px,
   --kf-ein-p = 0 … 1. Ohne Übergang, damit sie dem Finger folgt; nur beim
   Umschalten von Hand (kf-ein-gleiten) gleiten Bühne und Abstand gemeinsam. */
@media (max-width: 920px) and (min-height: 501px) {
  body.kf-design-aktiv.kf-einfahren .kf-body { grid-template-rows: minmax(0, calc(100% - 64px - var(--kf-ein, 0px))) minmax(0, 1fr); transition: none; }
  /* Scroll-Anker aus: der wachsende Abstand oben ließ Chrome den Scrollstand
     nachschieben — aus 20 px wurden 160 (gemessen 16.10.2026). */
  body.kf-design-aktiv #kf-panel { overflow-anchor: none; }
  body.kf-design-aktiv.kf-einfahren #kf-panel::before { content: ""; display: block; flex: none; height: var(--kf-ein, 0px); }
  body.kf-design-aktiv.kf-einfahren .kf-toolbar:not([data-panel]) { max-height: calc(76px - var(--kf-ein-p, 0) * 76px); opacity: calc(1 - var(--kf-ein-p, 0) * 1.6); overflow: hidden; transition: none; }
  body.kf-design-aktiv.kf-einfahren .kf-thumbs,
  body.kf-design-aktiv.kf-einfahren .kf-stage-designs,
  body.kf-design-aktiv.kf-einfahren .kf-hilfslinien-btn,
  body.kf-design-aktiv.kf-einfahren .kf-ansicht-pille { opacity: calc(1 - var(--kf-ein-p, 0) * 2.5); }
  body.kf-design-aktiv.kf-einfahren.kf-ein-gleiten .kf-body { transition: grid-template-rows 0.35s cubic-bezier(0.2, 0.7, 0.2, 1); }
  body.kf-design-aktiv.kf-einfahren.kf-ein-gleiten #kf-panel::before { transition: height 0.35s cubic-bezier(0.2, 0.7, 0.2, 1); }
  body.kf-design-aktiv.kf-einfahren.kf-ein-gleiten .kf-toolbar:not([data-panel]) { transition: max-height 0.35s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.35s; }
}


/* Kein Doppeltipp-Zoom auf Bedienelementen (Julian, 16.10.2026: „bei der
   Stückzahl Plus und Minus … schnell tippt, zoomt er dann so rein"). Safari
   wertete zwei schnelle Tipps auf + oder − als Zoom-Geste. manipulation lässt
   Tippen und Pinch-Zoom zu und nimmt nur den Doppeltipp-Zoom (und die 300-ms-
   Wartezeit) weg. Steht in jedem Haupt-Stylesheet, weil nicht jede Seite alle lädt.
   :where() hält die Spezifität bei 0 — sonst schlug [role="button"] eigene
   touch-action: none wie den Griff der Kontextleiste (Review 16.10.2026). */
:where(a, button, input, select, textarea, label, summary, [role="button"], [role="switch"], [onclick]) { touch-action: manipulation; }

/* ── Warenkorbseite mobil als Blatt (Mobil-Runde 2, 16.10.2026) ─────────────
   Klassen aus konfigurator.js (korbBlattMobil): kf-korb-blatt = Blatt aktiv,
   kf-korb-kompakt = eingeklappt. Eingeklappt sitzt unten nur „1 Artikel ·
   100 Teile — Gesamt" und „Bestellung fertigstellen"; ausgeklappt fährt der
   ganze Abschluss hoch und scrollt in sich. Der Artikel-Kasten verliert dafür
   seine Mindesthöhe von 260 px — die stand für das Fenster, hier ließ sie ihn
   halb leer. */
@media (max-width: 980px) {
  /* !important: die Fenster-Regel (Schritt 4 mit :has) ist spezifischer als alles hier */
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt #kf-korb { min-height: 0 !important; max-height: none; overflow: visible; }
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt { padding-bottom: calc(150px + env(safe-area-inset-bottom, 0px)); }
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt > .kf-korb-abschluss {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 140;
    max-height: 86vh; max-height: 86svh; overflow-y: auto; overscroll-behavior: contain;
    margin: 0; border-radius: 20px 20px 0 0;
    padding: 6px 18px calc(16px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -10px 34px rgba(0, 0, 0, 0.16);
    animation: kf-korb-blatt-ein 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  /* Ausgeklappt: die Seite dahinter dunkelt ab */
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt:not(.kf-korb-kompakt) > .kf-korb-blatt-schleier { display: block; position: fixed; inset: 0; z-index: 139; background: rgba(0, 0, 0, 0.32); }
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt.kf-korb-kompakt .kf-korb-kompakt-zeile { cursor: pointer; padding: 4px 0 12px; }
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt .kf-korb-blatt-griff {
    display: flex; align-items: center; justify-content: center; position: sticky; top: -6px; z-index: 2;
    width: calc(100% + 36px); height: 34px; margin: -6px -18px 2px; padding: 0; border: 0; background: inherit; color: var(--kf-mid); cursor: pointer;
  }
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt .kf-korb-blatt-griff::before { content: ""; position: absolute; top: 7px; width: 38px; height: 4px; border-radius: 4px; background: rgba(17, 17, 17, 0.16); }
  .kf-korb-blatt-griff svg { margin-top: 10px; transition: transform 0.25s ease; }
  .kf-app-korbseite #kf-korb-card.kf-korb-blatt:not(.kf-korb-kompakt) .kf-korb-blatt-griff svg { transform: rotate(180deg); }
}
.kf-korb-blatt-griff, .kf-korb-blatt-schleier { display: none; }   /* nur im Blatt (oben, bis 980 px) */
@keyframes kf-korb-blatt-ein { from { transform: translateY(24px); opacity: 0.6; } }
@media (prefers-reduced-motion: reduce) { .kf-app-korbseite #kf-korb-card.kf-korb-blatt > .kf-korb-abschluss { animation: none; } }

/* ── Anpassungsleiste mobil, zweiter Blick (Julian, 16.10.2026: „die ganze
   Anpassungsleiste … nochmal anschauen") ── Bei Text standen 6 von 15
   Knöpfen im Bild, und nichts zeigte, dass rechts Bogen, Abstand, Kontur,
   Deckkraft, Spiegeln, Ebenen, Duplizieren, Sperren und Löschen warten.
   Jetzt Scroll-Schatten an der Kante, an der es weitergeht (reiner
   Hintergrund mit background-attachment: local — keine Maske, die machte die
   Blätter unsichtbar). Der Bühnen-Griff ˄ lag auf der Leiste: solange sie
   steht, ist er weg. */
@media (max-width: 920px) {
  .kf-ctx {
    background:
      linear-gradient(90deg, var(--kf-leiste-grund) 40%, rgba(255, 255, 255, 0)) left center / 34px 100% no-repeat local,
      linear-gradient(270deg, var(--kf-leiste-grund) 40%, rgba(255, 255, 255, 0)) right center / 34px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)) left center / 18px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)) right center / 18px 100% no-repeat scroll,
      var(--kf-leiste-grund);
  }
  .kf-stage:has(#kf-ctx:not([hidden])) .kf-mini-toggle { visibility: hidden; }
}

/* ── Größe als Blatt, Farben groß (Mobil-Runde 2, Julian 16.10.2026: „größer,
   kleiner … muss man aufklappen können … wenn man auf Farbe drückt, müssen die
   einzelnen Sachen gut sichtbar sein") ── Desktop: Knopf aus, das Blatt liegt
   flach in der Leiste (display: contents), alles wie vorher. */
.kf-ctx-groesse-knopf { display: none; }
@media (min-width: 921px) {
  .kf-ctx .kf-ctx-pop-groesse { display: contents; }
}
@media (max-width: 920px) {
  .kf-ctx-groesse-knopf { display: inline-flex; }
  .kf-ctx .kf-ctx-pop-groesse .kf-ctx-slider { display: flex; width: 100%; gap: 12px; min-height: 52px; }
  .kf-ctx .kf-ctx-pop-groesse .kf-ctx-slider .mono { display: inline; font-size: 12px; flex: none; }
  .kf-ctx .kf-ctx-pop-groesse input[type="range"] { flex: 1 1 auto; width: auto; min-width: 0; height: 32px; }
  .kf-ctx-groesse-knopf[aria-expanded="true"], .kf-ctx-btn[aria-expanded="true"] { background: var(--kf-akzent-hell, #e8efff); }
  /* Farben: 36 statt 20 px, mit Luft — das sind die Knöpfe, die man treffen muss */
  .kf-ctx .kf-ctx-pop .kf-farbreihe { gap: 12px; justify-content: flex-start; }
  .kf-ctx .kf-ctx-pop .kf-farbe-swatch { width: 36px; height: 36px; border-width: 2px; }
  .kf-ctx .kf-ctx-pop .kf-farbe-swatch.active { box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--kf-akzent); }
}

/* ── Konfigurator mobil, dritte Runde (Julian, 17.10.2026) ──────────────────
   „Diese Grafiken oben würde ich rausnehmen, weil das auch vom Bild abweicht";
   das „i" neben „Automatisch" und hinter den Preis-Pillen der Ausstattung
   („das sagt es ja auch schon"); „Polybag Verpackung" in eine Zeile; die
   Farben als wischbare Reihe statt drei Zeilen untereinander. Nur hochkant —
   quer bleibt das kompakte Layout (Review 17.10.2026). */
@media (max-width: 920px) and (min-height: 501px) {
  .kf-stage-designs { display: none !important; }
  .kf-modus .kf-info-wrap { display: none; }
  .kf-option-badge svg { display: none; }
  .kf-option-kopf { flex-wrap: nowrap; gap: 8px; }
  .kf-option-name { white-space: nowrap; font-size: 14.5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .kf-option-badge { white-space: nowrap; flex: none; padding-inline: 8px; }
  .kf-option-kopf .kf-radios { flex: none; margin-left: auto; gap: 10px; }
  .kf-farben {
    display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; scrollbar-width: none; -webkit-overflow-scrolling: touch;
    margin: 0 -14px; padding: 2px 14px 6px; scroll-padding: 0 14px;
  }
  .kf-farben::-webkit-scrollbar { display: none; }
  .kf-farben > .kf-farbe-mock { flex: 0 0 74px; scroll-snap-align: start; }
  .kf-farben > .kf-farbe:not(.kf-farbe-mock) { flex: none; scroll-snap-align: start; align-self: center; }   /* Farbkreis ohne Mockup bleibt rund */
}

/* Handy hoch, Design-Modus: Modellbilder nur auf Tipp, Leiste angedockt, unten
   ohne Werktage und — solange das Bild groß ist — ohne Stückzahl/Preis
   (Julian, 17.10.2026: „Wenn das dann ausgefahren ist, kann auch diese Anzeige
   … unten raus … nur Stückzahl und Preis, einfach damit es cleaner aussieht"). */
@media (max-width: 920px) and (min-height: 501px) {
  body.kf-design-aktiv:not(.kf-modelle-an) .kf-thumbs .kf-thumb-modell,
  body.kf-design-aktiv:not(.kf-modelle-an) .kf-thumbs .kf-thumb-trenner { display: none; }
  .kf-abschluss-liefer { display: none !important; }
  body.kf-design-aktiv:not(.kf-mini-zu):not(.kf-ein-halb) .kf-abschluss-zahlen { display: none; }
  body.kf-ctx-gedockt #kf-ctx {
    position: relative; left: auto; right: auto; top: auto; transform: none;
    order: 3; width: 100%; max-width: 100%; margin: 8px 0 0; box-sizing: border-box;
    border-radius: 14px; padding: 4px 8px; height: 64px; min-height: 64px; z-index: 130;   /* über Thumbs/Vollbild-Knopf der Bühne (z 12) — sonst lägen ihre Blätter darunter */   /* genau so hoch wie die Werkzeugleiste: das Bild springt beim Auswählen nicht */
  }
  body.kf-ctx-gedockt #kf-ctx .kf-ctx-griff { display: none !important; }
  /* Eingefahren ist der Streifen 130 px — dort keine 72-px-Leiste: das Bild bliebe 50 px.
     Hochscrollen bringt sie mit dem Bild zurück (Review 17.10.2026). */
  body.kf-ctx-gedockt.kf-mini-zu #kf-ctx, body.kf-ctx-gedockt.kf-ein-halb #kf-ctx { display: none; }
  body.kf-ctx-gedockt .kf-stage:has(#kf-ctx:not([hidden])) .kf-toolbar:not([data-panel]) { display: none; }
}

/* 360 px: „Polybagverpackung" ganz lesbar statt mit … (Review 17.10.2026) */
@media (max-width: 374px) and (min-height: 501px) {
  .kf-option-name { font-size: 12.5px; letter-spacing: -0.01em; }
  .kf-option-kopf .kf-radios label { gap: 3px; }
  .kf-option-badge { font-size: 11px; padding-inline: 6px; }
  .kf-option-kopf { gap: 6px; }
  .kf-option-kopf .kf-radios { gap: 8px; }
}

/* ── Vierte Runde (Julian, 17.10.2026) ── Solange das Bild groß ist, steht unten
   nichts außer den Werkzeugen und einem Griff zum Hochwischen; der Warenkorb-
   Abschluss kommt mit dem Einfahren. Und: kein Mitziehen der ganzen Seite —
   iOS gab das Scrollen am Ende des Panels an die Seite weiter („dass man
   dieses auch unten mit dem Warenkorb hochzieht"). */
@media (max-width: 920px) and (min-height: 501px) {
  html:has(body.kf-design-aktiv), body.kf-design-aktiv { overflow: hidden; overscroll-behavior: none; }
  body.kf-design-aktiv #kf-panel { overscroll-behavior: contain; }
  /* nicht auf der Warenkorbseite — dort ist der Abschluss die Kasse (gleiche Vorlage) */
  body.kf-design-aktiv:not(.kf-mini-zu):not(.kf-ein-halb) .kf-app:not(.kf-app-korbseite) .kf-abschluss { display: none; }
  body.kf-design-aktiv #kf-panel > .kf-spalte::before {
    content: ""; display: block; width: 40px; height: 4px; border-radius: 4px;
    margin: 8px auto 10px; background: rgba(17, 17, 17, 0.18);
  }
}

