/* Konfigurator — Smartmacherei.at
   Pfad-aware (altbau/neubau/gewerbe), 4 Schritte:
   0) Methode wählen   1) Räume erfassen   2) Module pro Raum   3) Empfehlung+Preis
*/

/* Cyan-on-dark — passend zum Rest der Website */
const KFG_PALETTE = {
  ink:    "#ffffff",                    // Vordergrund-Text (war: dunkel)
  paper:  "#0A1B28",                    // Sektion-Hintergrund (leicht heller als bg-deep)
  card:   "#0D2030",                    // Karten / Eingabe-Flächen
  accent: "#3ABDD0",                    // Cyan-Akzent
  warm:   "#8DDBEA",                    // sekundärer Akzent
  muted:  "rgba(141,219,234,0.55)",     // gedämpfter Text
  line:   "rgba(141,219,234,0.18)",     // Linien / Borders
};

/* ----- Demo-Daten: EFH Basting (echte Werte aus Plan) -----
   windowSides: ["top"|"right"|"bottom"|"left"] gibt die Wand pro Fenster an.
   doorSide:    Wand der (Haupt-)Tür. Falls leer → "bottom". */
const BASTING_ROOMS = [
  { id:"r1",  name:"Wohnen/Essen", area:31.62, type:"living",  floor:"EG", windows:3, windowSides:["bottom","bottom","right"], doorSide:"left" },
  { id:"r2",  name:"Kochen",       area:10.31, type:"kitchen", floor:"EG", windows:1, windowSides:["left"],   doorSide:"bottom" },
  { id:"r3",  name:"Speiß",        area: 4.50, type:"storage", floor:"EG", windows:0, doorSide:"bottom" },
  { id:"r4",  name:"VR",           area:10.02, type:"hall",    floor:"EG", windows:0, doorSide:"right" },
  { id:"r5",  name:"WC",           area: 2.16, type:"wc",      floor:"EG", windows:1, windowSides:["right"],  doorSide:"left" },
  { id:"r6",  name:"WiRa/HT",      area: 4.81, type:"tech",    floor:"EG", windows:0, doorSide:"right" },
  { id:"r7",  name:"Bad",          area: 9.00, type:"bath",    floor:"EG", windows:1, windowSides:["top"],    doorSide:"bottom" },
  { id:"r8",  name:"Schlafzimmer", area:19.22, type:"bedroom", floor:"EG", windows:2, windowSides:["top","left"], doorSide:"right" },
  { id:"r9",  name:"K Zimmer 1",   area:13.60, type:"bedroom", floor:"EG", windows:1, windowSides:["top"],    doorSide:"bottom" },
  { id:"r10", name:"K Zimmer 2",   area:13.13, type:"bedroom", floor:"EG", windows:1, windowSides:["top"],    doorSide:"bottom" },
  { id:"r11", name:"Zimmer",       area: 9.49, type:"room",    floor:"EG", windows:1, windowSides:["right"],  doorSide:"left" },
  { id:"r12", name:"Garderobe",    area: 7.13, type:"hall",    floor:"EG", windows:0, doorSide:"left" },
  { id:"r13", name:"Terrasse",     area:31.88, type:"terrace", floor:"EG", windows:0, outdoor:true },
  { id:"r14", name:"Zugang",       area: 3.55, type:"entry",   floor:"EG", windows:0, doorSide:"bottom" },
];

/* ----- DIN 18015-2 / RAL-RG 678 Ausstattungsklassen -----
 * Mindestempfehlung pro Raumtyp und Klasse. Werte sind
 * Branchen-Faustregeln aus RAL-RG 678 + Hersteller-Empfehlungen
 * (HEA, Hager, Elektro+, Voltimum). Annaeherung an die Norm,
 * Detail-Auswahl im Konfigurator durch User justierbar.
 *
 * Indexen:  0 = Mindestausstattung  (1*) DIN 18015-2 minimum
 *           1 = Standardausstattung (2*) ueblich im EFH-Neubau
 *           2 = Komfortausstattung  (3*) gehobener Standard
 */
const DIN_18015_2 = {
  living:  { sockets: [4, 6, 8],  light_circuits: [1, 2, 3], data: [1, 2, 3] },
  bedroom: { sockets: [3, 5, 7],  light_circuits: [1, 1, 2], data: [0, 1, 2] },
  kitchen: { sockets: [6, 8, 10], light_circuits: [1, 2, 3], data: [0, 1, 1] },
  bath:    { sockets: [1, 2, 3],  light_circuits: [1, 1, 2], data: [0, 0, 0] },
  wc:      { sockets: [0, 1, 1],  light_circuits: [1, 1, 1], data: [0, 0, 0] },
  hall:    { sockets: [1, 2, 3],  light_circuits: [1, 1, 2], data: [0, 0, 1] },
  room:    { sockets: [3, 4, 6],  light_circuits: [1, 1, 2], data: [0, 1, 2] },
  tech:    { sockets: [2, 4, 6],  light_circuits: [1, 1, 1], data: [0, 1, 1] },
  storage: { sockets: [1, 1, 2],  light_circuits: [1, 1, 1], data: [0, 0, 0] },
};

const KLASSE_LABELS = ["Mindest (DIN)", "Standard", "Komfort"];

function dinValue(roomType, axis, klasse) {
  const row = DIN_18015_2[roomType] || DIN_18015_2.room;
  return (row[axis] || [1, 1, 1])[klasse] ?? 1;
}

/* ----- WKO-Regiestundensaetze 2026 (Oesterreich, AT) -----
 * Quelle: wko.at/oe/gewerbe-handwerk/elektro-gebaeude-alarm-kommunikation
 * Stand Mai 2026.
 */
const WKO_STUNDENSATZ = {
  monteur: 70.66,        // Standard-Elektriker
  spezial_monteur: 91.28, // KNX/Bus-Programmierung, Inbetriebnahme
  spezial: 131.62,       // SPS / Spezial-PLC
};

/* ----- Modul-Katalog (pfad-spezifisch) -----
 * Erweiterte Felder fuer DIN-/Preis-Modell:
 *   material_unit  EUR pro Stueck (Aktor-Anteil + Sensor + Zubehoer)
 *   material_base  EUR einmalig pro Raum (Verkabelung, UV-Anschluss)
 *   install_minutes        Min pro Stueck
 *   install_minutes_base   Min einmalig pro Raum
 *   defaultCount(room, klasse) -- klasse=0|1|2 (Mindest/Standard/Komfort)
 *
 * Backwards-Compat: unitPrice/base/price-Wrapper bleiben (geben material_unit
 * etc. zurueck), damit getModulePrice + KfgRoomPreview unveraendert
 * weiterlaufen.
 */
/* Helper fuer Counts pro Raum + Klasse. Wenn Klasse nicht uebergeben,
 * Standard-Klasse (1) verwenden -- Backwards-Compat fuer alte Aufrufe. */
const _din = (axis) => (r, klasse = 1) => dinValue(r.type, axis, klasse);

const MODULES_NEUBAU = {
  licht: {
    label: "Licht (KNX/DALI)", icon: "💡",
    countable: true, unit: "Schaltkreise",
    defaultCount: _din("light_circuits"),
    // KNX-Aktor (4-fach Median ~150 EUR -> 38/Kanal) + Verkabelung pro Kreis.
    material_unit: 60,    // Aktor-Anteil + Bus-Kabel
    material_base: 180,   // Tastsensor + UV-Anteil + Verkabelung Raum
    install_minutes: 35,  // pro Schaltkreis
    install_minutes_base: 60,
    default: ["living","kitchen","bedroom","bath","hall","room","tech"],
  },
  steckdosen: {
    label: "Schaltbare Steckdosen", icon: "⏻",
    countable: true, unit: "Steckdosen",
    defaultCount: _din("sockets"),
    material_unit: 35,    // Steckdose + Klemme
    material_base: 0,
    install_minutes: 22,
    install_minutes_base: 0,
    default: ["living","bedroom","kitchen","room","tech"],
  },
  beschattung: {
    label: "Beschattung", icon: "⬇",
    countable: true, unit: "Fenster",
    defaultCount: (r) => r.windows || 0,
    material_unit: 220,   // Beschattungsaktor anteilig + Antrieb-Vorbereitung
    material_base: 0,
    install_minutes: 35,
    install_minutes_base: 0,
    default: ["living","bedroom","kitchen","room"],
  },
  heizung: {
    label: "Einzelraum-Heizung", icon: "🌡",
    price: () => 220,    // legacy fixed -- ein Heizungsaktor-Kanal + Stellantrieb
    material_unit: 0, material_base: 220,
    install_minutes: 0, install_minutes_base: 50,
    default: ["living","bedroom","bath","room","kitchen","wc"],
  },
  klima: {
    label: "Klima/Lüftung", icon: "❄",
    price: () => 580,
    material_unit: 0, material_base: 580,
    install_minutes: 0, install_minutes_base: 90,
    default: ["living","bedroom"],
  },
  zutritt: {
    label: "Zutritt/Sicherheit", icon: "🔐",
    price: () => 420,
    material_unit: 0, material_base: 420,
    install_minutes: 0, install_minutes_base: 80,
    default: ["entry","hall"],
  },
  multimedia: {
    label: "Multimedia/Audio", icon: "♪",
    price: () => 380,
    material_unit: 0, material_base: 380,
    install_minutes: 0, install_minutes_base: 60,
    default: ["living"],
  },
  sensorik: {
    label: "Sensorik (Bewegung/CO₂)", icon: "◉",
    price: () => 180,
    material_unit: 0, material_base: 180,
    install_minutes: 0, install_minutes_base: 30,
    default: ["living","bath","wc","entry","hall"],
  },
};

const MODULES_ALTBAU = {
  licht: {
    label: "Licht (Funk)", icon: "💡",
    countable: true, unit: "Schaltkreise",
    defaultCount: _din("light_circuits"),
    material_unit: 55,    // Funk-Schaltaktor pro Kreis (Eltako/Loxone Air)
    material_base: 100,   // Funk-Sensor pro Raum
    install_minutes: 25,
    install_minutes_base: 30,
    default: ["living","kitchen","bedroom","bath","hall","room","tech"],
  },
  steckdosen: {
    label: "Smart-Steckdosen", icon: "⏻",
    countable: true, unit: "Steckdosen",
    defaultCount: _din("sockets"),
    material_unit: 28,    // Funk-/Zwischenstecker / Unterputz-Schaltaktor
    material_base: 0,
    install_minutes: 8,   // bei Funk minimal -- nur tauschen
    install_minutes_base: 0,
    default: ["living","bedroom","kitchen","room"],
  },
  beschattung: {
    label: "Beschattung (Funk)", icon: "⬇",
    countable: true, unit: "Fenster",
    defaultCount: (r) => r.windows || 0,
    material_unit: 180,
    material_base: 0,
    install_minutes: 30,
    install_minutes_base: 0,
    default: ["living","bedroom","kitchen","room"],
  },
  heizung: {
    label: "Smart-Heizkörper-Ventil", icon: "🌡",
    price: () => 180,
    material_unit: 0, material_base: 180,
    install_minutes: 0, install_minutes_base: 25,
    default: ["living","bedroom","bath","room","kitchen"],
  },
  zutritt: {
    label: "Zutritt (Smart-Lock)", icon: "🔐",
    price: () => 380,
    material_unit: 0, material_base: 380,
    install_minutes: 0, install_minutes_base: 60,
    default: ["entry"],
  },
  multimedia: {
    label: "Multimedia", icon: "♪",
    price: () => 320,
    material_unit: 0, material_base: 320,
    install_minutes: 0, install_minutes_base: 45,
    default: ["living"],
  },
  sensorik: {
    label: "Sensorik (Funk)", icon: "◉",
    price: () => 140,
    material_unit: 0, material_base: 140,
    install_minutes: 0, install_minutes_base: 15,
    default: ["living","bath","entry"],
  },
};

const MODULES_GEWERBE = {
  licht: {
    label: "Licht (DALI/KNX)", icon: "💡",
    countable: true, unit: "Schaltkreise",
    defaultCount: (r, klasse = 1) => Math.ceil(r.area / 10) + (klasse === 0 ? 0 : klasse), // mehr Kreise bei Komfort
    material_unit: 90,    // DALI-Treiber + KNX-Aktor anteilig
    material_base: 320,
    install_minutes: 45,
    install_minutes_base: 90,
    default: ["living","room","office","bedroom","kitchen","tech","hall","entry","storage"],
  },
  beschattung: {
    label: "Beschattung wetterabh.", icon: "⬇",
    countable: true, unit: "Fenster",
    defaultCount: (r) => r.windows || 0,
    material_unit: 280,
    material_base: 220,   // Wetterstation anteilig
    install_minutes: 40,
    install_minutes_base: 60,
    default: ["living","room","office","bedroom"],
  },
  klima: {
    label: "HLK-Steuerung", icon: "❄",
    price: () => 720,
    material_unit: 0, material_base: 720,
    install_minutes: 0, install_minutes_base: 120,
    default: ["living","room","office","bedroom"],
  },
  zutritt: {
    label: "Zutritt + Rollen", icon: "🔐",
    price: () => 880,
    material_unit: 0, material_base: 880,
    install_minutes: 0, install_minutes_base: 150,
    default: ["entry","hall"],
  },
  energie: {
    label: "Energie + Submetering", icon: "⚡",
    price: () => 320,
    material_unit: 0, material_base: 320,
    install_minutes: 0, install_minutes_base: 45,
    default: ["tech"],
  },
  sensorik: {
    label: "Sensorik (Präsenz/CO₂)", icon: "◉",
    price: () => 240,
    material_unit: 0, material_base: 240,
    install_minutes: 0, install_minutes_base: 30,
    default: ["living","room","office","bedroom","hall","entry"],
  },
  alarm: {
    label: "Status + Eskalation", icon: "⚠",
    price: () => 540,
    material_unit: 0, material_base: 540,
    install_minutes: 0, install_minutes_base: 90,
  },
};

const MODULE_SETS = {
  altbau: MODULES_ALTBAU,
  neubau: MODULES_NEUBAU,
  gewerbe: MODULES_GEWERBE,
};

/* Resolve count for a (room,module): user override > default > 0.
 * klasse=0|1|2 wird an mod.defaultCount durchgereicht. */
function getModuleCount(mod, room, counts, roomId, modKey, klasse = 1) {
  if (!mod.countable) return 1;
  const override = counts && counts[roomId] && counts[roomId][modKey];
  if (typeof override === "number") return Math.max(0, override);
  if (!mod.defaultCount) return 0;
  // defaultCount kann (room) ODER (room, klasse) signature sein -- beide
  // unterstuetzt fuer backwards-compat.
  return Math.max(0, mod.defaultCount(room, klasse));
}

/* Compute price for a (room,module). Bevorzugt material_unit/material_base
 * (neues Modell), fallback auf legacy unitPrice/base/price. */
function getModulePrice(mod, room, counts, roomId, modKey, klasse = 1) {
  const baseMat = mod.material_base ?? (mod.base ? mod.base(room) : 0);
  if (mod.countable) {
    const c = getModuleCount(mod, room, counts, roomId, modKey, klasse);
    const unitMat = mod.material_unit ?? (mod.unitPrice ? mod.unitPrice(room) : 0);
    return baseMat + c * unitMat;
  }
  // non-countable: material_base bevorzugt, sonst price()
  return baseMat || (mod.price ? mod.price(room) : 0);
}

/* Aufschluesselung: Material vs. Installation vs. Inbetriebnahme.
 * Liefert {material, install_cost, commissioning_cost, total, range_low, range_high}. */
function priceBreakdown(rooms, assignments, modules, moduleCounts, klasse = 1, pathKey = "neubau") {
  let material = 0;
  let minutes = 0;
  let base_minutes = 0;
  const indoorRooms = (rooms || []).filter(r => r && !r.outdoor);
  for (const r of indoorRooms) {
    const mods = (assignments && assignments[r.id]) || [];
    for (const k of mods) {
      const m = modules[k]; if (!m) continue;
      const count = getModuleCount(m, r, moduleCounts, r.id, k, klasse);
      const matUnit = m.material_unit ?? (m.unitPrice ? m.unitPrice(r) : 0);
      const matBase = m.material_base ?? (m.base ? m.base(r) : 0);
      const flatPrice = (m.countable ? 0 : (m.price ? m.price(r) : 0));
      // flatPrice nur wenn material_base nicht gesetzt ist
      material += matBase + count * matUnit + (matBase ? 0 : flatPrice);
      minutes += count * (m.install_minutes ?? 0);
      base_minutes += (m.install_minutes_base ?? 0);
    }
  }
  // Inbetriebnahme/Programmierung: 0.2 Stunden je Innenraum, mind. 4 h.
  const commissioning_hours = Math.max(4, indoorRooms.length * 0.2);
  const install_hours = (minutes + base_minutes) / 60;
  const install_cost = install_hours * WKO_STUNDENSATZ.monteur;
  const commissioning_cost = commissioning_hours * WKO_STUNDENSATZ.spezial_monteur;
  // Pfad-Faktor (Komplexitaet, nicht Stundensatz):
  const factor = pathKey === "gewerbe" ? 1.10 : 1.00;
  const total = (material + install_cost + commissioning_cost) * factor;
  return {
    material: Math.round(material),
    install_hours: Math.round(install_hours * 10) / 10,
    install_cost: Math.round(install_cost),
    commissioning_hours: Math.round(commissioning_hours * 10) / 10,
    commissioning_cost: Math.round(commissioning_cost),
    total: Math.round(total),
    range_low: Math.round(total * 0.92 / 100) * 100,
    range_high: Math.round(total * 1.18 / 100) * 100,
  };
}

window.getModuleCount = getModuleCount;
window.getModulePrice = getModulePrice;
window.priceBreakdown = priceBreakdown;
window.WKO_STUNDENSATZ = WKO_STUNDENSATZ;
window.KLASSE_LABELS = KLASSE_LABELS;

/* Default-Module pro Raumtyp anwenden. klasse=0|1|2 (Mindest/Standard/Komfort)
 * beeinflusst aktuell NICHT welche Module dabei sind, sondern nur die counts.
 * Eventuell spaeter: bei Mindest -> Multimedia/Klima ausschliessen. */
function applyDefaults(rooms, modules, klasse = 1) {
  const out = {};
  for (const r of rooms) {
    if (r.outdoor) { out[r.id] = []; continue; }
    out[r.id] = Object.entries(modules)
      .filter(([k, m]) => {
        if (!m.default) return false;
        if (!m.default.includes(r.type)) return false;
        // Beschattung: nur defaultmaessig wenn Fenster vorhanden -- User kann manuell.
        if (k === "beschattung" && (!r.windows || r.windows === 0)) return false;
        // Bei Mindestklasse: Multimedia + Klima nicht voreingestellt
        if (klasse === 0 && (k === "multimedia" || k === "klima")) return false;
        return true;
      })
      .map(([k]) => k);
  }
  return out;
}

/* ===========================================================
   HAUPT-KOMPONENTE
============================================================ */
function KonfiguratorSection({ pathKey, onStateChange }) {
  const [step, setStep] = React.useState(0);
  const [method, setMethod] = React.useState(null); // "manual" | "import"
  const [rooms, setRooms] = React.useState([]);
  const [activeFloor, setActiveFloor] = React.useState("EG");
  const modules = MODULE_SETS[pathKey] || MODULES_NEUBAU;
  const [assignments, setAssignments] = React.useState({});
  const [moduleCounts, setModuleCounts] = React.useState({}); // { roomId: { modKey: number } }
  // 0 = Mindest (DIN 18015-2), 1 = Standard, 2 = Komfort.
  const [ausstattungsklasse, setAusstattungsklasse] = React.useState(1);

  const reset = () => {
    setStep(0); setMethod(null); setRooms([]);
    setAssignments({}); setModuleCounts({});
    setAusstattungsklasse(1);
  };

  React.useEffect(() => { reset(); }, [pathKey]);

  // Beim Klassen-Wechsel: counts + assignments NICHT komplett ersetzen,
  // sondern frische Defaults einrechnen fuer Raeume die noch keine
  // manuellen User-Overrides haben. Aktuell vereinfacht: re-applyDefaults,
  // manuelle Counts in moduleCounts bleiben unangetastet (override greift).
  React.useEffect(() => {
    if (rooms.length > 0) {
      setAssignments(applyDefaults(rooms, modules, ausstattungsklasse));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ausstattungsklasse]);

  // Push state up so the Grundriss viewer can read it
  React.useEffect(() => {
    if (onStateChange) onStateChange({ rooms, assignments, moduleCounts, modules, pathKey, ausstattungsklasse });
  }, [rooms, assignments, moduleCounts, modules, pathKey, ausstattungsklasse]);

  return (
    <section id="konfigurator" className="kfg-section">
      <KfgStyles />
      <div className="kfg-container">
        <KfgHeader step={step} onJump={setStep} method={method} pathKey={pathKey} />

        {step === 0 && (
          <KfgStep0Method
            pathKey={pathKey}
            onPick={(m) => {
              setMethod(m);
              if (m === "import") {
                setStep(1);
              } else {
                setRooms([]);
                setStep(1);
              }
            }}
          />
        )}

        {step === 1 && method === "manual" && (
          <KfgStep1Manual
            pathKey={pathKey}
            rooms={rooms}
            setRooms={setRooms}
            activeFloor={activeFloor}
            setActiveFloor={setActiveFloor}
            onNext={() => {
              setAssignments(applyDefaults(rooms, modules, ausstattungsklasse));
              setStep(2);
            }}
            onBack={() => setStep(0)}
          />
        )}

        {step === 1 && method === "import" && (
          <KfgStep1Import
            pathKey={pathKey}
            onComplete={(detected) => {
              setRooms(detected);
              setAssignments(applyDefaults(detected, modules, ausstattungsklasse));
              setStep(2);
            }}
            onBack={() => setStep(0)}
          />
        )}

        {step === 2 && (
          <KfgStep2Modules
            pathKey={pathKey}
            rooms={rooms}
            modules={modules}
            assignments={assignments}
            setAssignments={setAssignments}
            moduleCounts={moduleCounts}
            setModuleCounts={setModuleCounts}
            ausstattungsklasse={ausstattungsklasse}
            setAusstattungsklasse={setAusstattungsklasse}
            onNext={() => setStep(3)}
            onBack={() => setStep(1)}
          />
        )}

        {step === 3 && (
          <KfgStep3Summary
            pathKey={pathKey}
            rooms={rooms}
            modules={modules}
            assignments={assignments}
            moduleCounts={moduleCounts}
            ausstattungsklasse={ausstattungsklasse}
            onBack={() => setStep(2)}
            onRestart={reset}
          />
        )}
      </div>
    </section>
  );
}

/* ===========================================================
   STYLES
============================================================ */
function KfgStyles() {
  return (
    <style>{`
      .kfg-section{
        padding: 120px 0 140px;
        background: ${KFG_PALETTE.paper};
        position: relative;
        scroll-margin-top: 80px;
        --font-display: 'Outfit', serif;
        --font-mono: 'JetBrains Mono', monospace;
        font-family: 'Inter', system-ui, sans-serif;
        color: ${KFG_PALETTE.ink};
      }
      .kfg-section::before{
        content:""; position:absolute; inset:0 0 auto 0; height:1px;
        background: linear-gradient(90deg, transparent, ${KFG_PALETTE.line}, transparent);
      }
      .kfg-container{ max-width: 1280px; margin: 0 auto; padding: 0 32px; }

      /* Header / Stepper */
      .kfg-eyebrow{ font-family: var(--font-mono, monospace); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: ${KFG_PALETTE.muted}; margin-bottom: 12px; }
      .kfg-eyebrow .dot{ display:inline-block; width:6px; height:6px; border-radius:50%; background: ${KFG_PALETTE.accent}; margin-right: 10px; transform: translateY(-1px); }
      .kfg-title{ font-family: var(--font-display, serif); font-size: clamp(38px, 5vw, 64px); line-height: 1.05; letter-spacing: -0.02em; color: ${KFG_PALETTE.ink}; margin: 0 0 8px; font-weight: 400; }
      .kfg-title em{ font-style: italic; color: ${KFG_PALETTE.accent}; }
      .kfg-sub{ color: ${KFG_PALETTE.muted}; font-size: 17px; max-width: 620px; line-height: 1.5; margin: 0 0 36px; }

      .kfg-stepper{ display:flex; gap:0; align-items:stretch; margin: 28px 0 56px; border-top:1px solid ${KFG_PALETTE.line}; border-bottom:1px solid ${KFG_PALETTE.line}; }
      .kfg-step-item{ flex:1; padding: 18px 20px; display:flex; align-items:center; gap:14px; border-right:1px solid ${KFG_PALETTE.line}; cursor:pointer; transition: background 0.2s; position:relative; }
      .kfg-step-item:last-child{ border-right:none; }
      .kfg-step-item:hover{ background: rgba(107,142,78,0.04); }
      .kfg-step-item.disabled{ cursor: default; opacity: 0.5; }
      .kfg-step-item.active{ background: ${KFG_PALETTE.ink}; color: ${KFG_PALETTE.paper}; }
      .kfg-step-item.done{ color: ${KFG_PALETTE.accent}; }
      .kfg-step-num{ font-family: var(--font-mono, monospace); font-size: 11px; opacity: 0.6; min-width: 28px; }
      .kfg-step-label{ font-size: 14px; font-weight: 500; }

      /* Content */
      .kfg-content{ background: ${KFG_PALETTE.card}; border: 1px solid ${KFG_PALETTE.line}; border-radius: 6px; padding: 48px; min-height: 560px; }

      /* Method picker (Step 0) */
      .kfg-methods{ display:grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 32px; }
      .kfg-method-card{ position:relative; padding: 36px 32px 32px; border: 1px solid ${KFG_PALETTE.line}; background: ${KFG_PALETTE.paper}; cursor: pointer; transition: all 0.3s cubic-bezier(.2,.7,.3,1); text-align: left; font-family: inherit; color: inherit; }
      .kfg-method-card:hover{ border-color: ${KFG_PALETTE.ink}; transform: translateY(-2px); box-shadow: 0 12px 32px rgba(0,0,0,0.08); }
      .kfg-method-card .num{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.muted}; letter-spacing: 0.15em; }
      .kfg-method-card h3{ font-family: var(--font-display, serif); font-size: 32px; line-height: 1.1; font-weight: 400; margin: 12px 0 12px; letter-spacing: -0.01em; }
      .kfg-method-card p{ color: ${KFG_PALETTE.muted}; font-size: 15px; line-height: 1.55; margin: 0 0 24px; }
      .kfg-method-card .feats{ list-style:none; padding:0; margin: 0 0 28px; display:flex; flex-direction:column; gap:8px; }
      .kfg-method-card .feats li{ font-size: 13px; display:flex; align-items:center; gap:10px; }
      .kfg-method-card .feats li::before{ content: "→"; color: ${KFG_PALETTE.accent}; font-family: var(--font-mono, monospace); }
      .kfg-method-card .pick-cta{ display:inline-flex; align-items:center; gap:10px; font-size: 14px; font-weight: 500; color: ${KFG_PALETTE.ink}; padding-top: 16px; border-top: 1px solid ${KFG_PALETTE.line}; }
      .kfg-method-card .pick-cta::after{ content:"→"; transition: transform 0.25s; }
      .kfg-method-card:hover .pick-cta::after{ transform: translateX(6px); }
      .kfg-method-illu{ height: 140px; margin: 0 -8px 0; opacity: 0.85; }

      /* Manual room picker */
      .kfg-floors{ display:flex; gap: 0; border:1px solid ${KFG_PALETTE.line}; padding:4px; border-radius:4px; width: fit-content; margin-bottom: 24px; }
      .kfg-floor-tab{ padding: 8px 18px; font-size: 13px; font-weight:500; cursor:pointer; border-radius: 2px; background: transparent; border:none; color: ${KFG_PALETTE.muted}; font-family: inherit; }
      .kfg-floor-tab.active{ background: ${KFG_PALETTE.ink}; color: ${KFG_PALETTE.paper}; }

      .kfg-manual-grid{ display:grid; grid-template-columns: 1fr 460px; gap: 36px; }
      .kfg-room-library{ }
      .kfg-room-library h4{ font-size: 12px; font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase; color: ${KFG_PALETTE.muted}; margin: 0 0 14px; }
      .kfg-room-types{ display:grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
      .kfg-room-type-btn{ display:flex; align-items:center; gap:12px; padding: 12px 14px; border: 1px solid ${KFG_PALETTE.line}; background: ${KFG_PALETTE.card}; cursor:pointer; transition: all 0.18s; font-family: inherit; color: inherit; text-align: left; }
      .kfg-room-type-btn:hover{ border-color: ${KFG_PALETTE.accent}; background: rgba(107,142,78,0.04); }
      .kfg-room-type-btn .ic{ width: 32px; height: 32px; display:grid; place-items:center; background: ${KFG_PALETTE.paper}; border-radius: 4px; flex-shrink: 0; }
      .kfg-room-type-btn .lbl{ font-size: 13px; font-weight: 500; line-height: 1.2; }
      .kfg-room-type-btn .sub{ font-size: 11px; color: ${KFG_PALETTE.muted}; margin-top: 2px; }

      .kfg-room-list-panel{ background: ${KFG_PALETTE.paper}; border: 1px solid ${KFG_PALETTE.line}; padding: 24px; min-height: 460px; display:flex; flex-direction:column; }
      .kfg-room-list-head{ display:flex; justify-content: space-between; align-items: baseline; margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid ${KFG_PALETTE.line}; }
      .kfg-room-list-head h4{ margin:0; font-family: var(--font-display, serif); font-size: 22px; font-weight: 400; }
      .kfg-room-list-head .count{ font-family: var(--font-mono, monospace); font-size: 12px; color: ${KFG_PALETTE.muted}; }
      .kfg-room-list{ list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap: 8px; flex: 1; overflow-y: auto; max-height: 380px; }
      .kfg-room-item{ display:grid; grid-template-columns: 28px 1fr 70px 30px; align-items:center; gap: 10px; padding: 10px 12px; background: ${KFG_PALETTE.card}; border: 1px solid ${KFG_PALETTE.line}; }
      .kfg-room-item .ic{ font-size: 14px; opacity: 0.7; }
      .kfg-room-item .name{ font-size: 13px; font-weight: 500; }
      .kfg-room-item .name input{ background: transparent; border:none; padding: 2px 0; font-family: inherit; font-size: 13px; font-weight: 500; width: 100%; outline: none; border-bottom: 1px dashed transparent; color: inherit; }
      .kfg-room-item .name input:focus{ border-bottom-color: ${KFG_PALETTE.accent}; }
      .kfg-room-item .area{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.muted}; text-align: right; }
      .kfg-room-item .area input{ background: transparent; border:none; width: 50px; text-align: right; font-family: inherit; font-size: 11px; color: ${KFG_PALETTE.muted}; outline: none; }
      .kfg-room-item .rm{ background: transparent; border: none; cursor: pointer; color: ${KFG_PALETTE.muted}; font-size: 16px; line-height: 1; padding: 4px; }
      .kfg-room-item .rm:hover{ color: #b85c4f; }
      .kfg-room-empty{ padding: 32px 16px; text-align: center; color: ${KFG_PALETTE.muted}; font-size: 13px; line-height: 1.5; border: 1px dashed ${KFG_PALETTE.line}; }

      /* Plan Import */
      .kfg-import-stage{ position: relative; min-height: 480px; }
      .kfg-import-drop{ border: 2px dashed ${KFG_PALETTE.line}; padding: 60px 40px; text-align: center; transition: all 0.25s; cursor: pointer; background: ${KFG_PALETTE.paper}; }
      .kfg-import-drop:hover{ border-color: ${KFG_PALETTE.accent}; background: rgba(107,142,78,0.04); }
      .kfg-import-drop h4{ font-family: var(--font-display, serif); font-size: 28px; font-weight: 400; margin: 18px 0 8px; }
      .kfg-import-drop p{ color: ${KFG_PALETTE.muted}; font-size: 14px; margin: 0 0 24px; }
      .kfg-import-drop .demo-link{ display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; background: ${KFG_PALETTE.ink}; color: ${KFG_PALETTE.paper}; font-size: 13px; font-weight: 500; cursor: pointer; border:none; font-family: inherit; }
      .kfg-import-drop .demo-link:hover{ background: ${KFG_PALETTE.accent}; }
      .kfg-import-formats{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.muted}; margin-top: 24px; letter-spacing: 0.1em; }

      .kfg-scan-stage{ display:grid; grid-template-columns: 1fr 1fr; gap: 32px; align-items: start; }
      .kfg-scan-doc{ position: relative; aspect-ratio: 1.4 / 1; background: ${KFG_PALETTE.card}; border: 1px solid ${KFG_PALETTE.line}; overflow: hidden; }
      .kfg-scan-doc svg{ width:100%; height:100%; display:block; }
      .kfg-scan-line{ position:absolute; left: 0; right: 0; height: 80px; background: linear-gradient(180deg, transparent, rgba(58,189,208,0.22) 50%, transparent); pointer-events: none; animation: kfgScan 2.4s linear infinite; }
      @keyframes kfgScan{ 0%{ top: -80px; } 100%{ top: 100%; } }
      .kfg-scan-status{ display:flex; flex-direction:column; gap: 14px; }
      .kfg-scan-status h4{ font-family: var(--font-display, serif); font-size: 26px; font-weight: 400; margin: 0; }
      .kfg-scan-log{ list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:6px; max-height: 320px; overflow-y: auto; }
      .kfg-scan-log li{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.ink}; padding: 6px 10px; background: ${KFG_PALETTE.paper}; border-left: 2px solid ${KFG_PALETTE.accent}; opacity:0; transform: translateX(-8px); animation: kfgFadeIn 0.3s forwards; }
      .kfg-scan-log li.detect{ border-left-color: ${KFG_PALETTE.warm}; }
      .kfg-scan-log li.done{ border-left-color: ${KFG_PALETTE.accent}; background: rgba(58,189,208,0.10); }
      @keyframes kfgFadeIn{ to { opacity:1; transform: translateX(0);} }
      @keyframes kfgLightPulse{
        0%, 8%   { opacity: 0.35; }
        12%, 28% { opacity: 1; }
        32%, 100%{ opacity: 0.35; }
      }
      @keyframes kfgLightGlow{
        0%, 8%   { opacity: 0; }
        14%, 26% { opacity: 0.55; }
        32%, 100%{ opacity: 0; }
      }
      @keyframes kfgSocketPulse{
        0%, 30%  { opacity: 0.55; transform: scale(1); }
        45%, 60% { opacity: 1;    transform: scale(1.25); }
        75%, 100%{ opacity: 0.55; transform: scale(1); }
      }
      @keyframes kfgSocketGlow{
        0%, 30%  { opacity: 0; }
        45%, 60% { opacity: 0.45; }
        75%, 100%{ opacity: 0; }
      }
      .kfg-scan-progress{ height: 4px; background: ${KFG_PALETTE.line}; overflow: hidden; }
      .kfg-scan-progress .bar{ height:100%; background: ${KFG_PALETTE.accent}; transition: width 0.3s; }

      /* Review phase (after scan) */
      .kfg-review-stage{ display:grid; grid-template-columns: 1.1fr 1fr; gap: 32px; align-items: start; }
      .kfg-review-plan{ position: relative; aspect-ratio: 1.4 / 1; background: ${KFG_PALETTE.card}; border: 1px solid ${KFG_PALETTE.line}; overflow: hidden; }
      .kfg-review-plan svg{ width:100%; height:100%; display:block; }
      .kfg-review-tag{ position:absolute; top: 14px; left: 14px; display:flex; align-items:center; gap: 8px; background: rgba(58,189,208,0.12); border:1px solid ${KFG_PALETTE.accent}; color: ${KFG_PALETTE.accent}; font-family: var(--font-mono, monospace); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; padding: 6px 12px; border-radius: 100px; }
      .kfg-review-tag .dot{ width: 6px; height: 6px; border-radius: 50%; background: ${KFG_PALETTE.accent}; box-shadow: 0 0 0 4px rgba(58,189,208,0.18); }
      .kfg-review-summary{ display:flex; flex-direction:column; gap: 18px; }
      .kfg-review-stats{ display:grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 1px; background: ${KFG_PALETTE.line}; border: 1px solid ${KFG_PALETTE.line}; }
      .kfg-review-stats .stat{ background: ${KFG_PALETTE.card}; padding: 14px 12px; }
      .kfg-review-stats .num{ font-family: var(--font-display, serif); font-size: 28px; font-weight: 400; line-height: 1; color: ${KFG_PALETTE.ink}; }
      .kfg-review-stats .num .u{ font-size: 12px; color: ${KFG_PALETTE.muted}; margin-left: 3px; font-family: var(--font-mono, monospace); }
      .kfg-review-stats .lbl{ font-family: var(--font-mono, monospace); font-size: 10px; color: ${KFG_PALETTE.muted}; text-transform: uppercase; letter-spacing: 0.1em; margin-top: 6px; }
      .kfg-review-roomlist{ background: ${KFG_PALETTE.card}; border: 1px solid ${KFG_PALETTE.line}; max-height: 280px; overflow-y: auto; }
      .kfg-review-roomlist .rl-head{ padding: 10px 14px; font-family: var(--font-mono, monospace); font-size: 10px; color: ${KFG_PALETTE.muted}; text-transform: uppercase; letter-spacing: 0.12em; border-bottom: 1px solid ${KFG_PALETTE.line}; position: sticky; top: 0; background: ${KFG_PALETTE.card}; }
      .kfg-review-roomlist .rl-row{ display:grid; grid-template-columns: 1fr auto auto; align-items: baseline; gap: 12px; padding: 8px 14px; border-bottom: 1px solid ${KFG_PALETTE.line}; }
      .kfg-review-roomlist .rl-row:last-child{ border-bottom: 0; }
      .kfg-review-roomlist .rl-row.out{ opacity: 0.7; }
      .kfg-review-roomlist .rl-name{ font-size: 13px; color: ${KFG_PALETTE.ink}; }
      .kfg-review-roomlist .rl-meta{ font-family: var(--font-mono, monospace); font-size: 10px; color: ${KFG_PALETTE.muted}; }
      .kfg-review-roomlist .rl-area{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.accent}; min-width: 56px; text-align: right; }

      /* Step 2 — room preview canvas */
      .kfg-roompreview{ position: relative; background: ${KFG_PALETTE.paper}; border: 1px solid ${KFG_PALETTE.line}; aspect-ratio: 1.6 / 1; margin-bottom: 16px; overflow: hidden; }
      .kfg-roompreview svg{ width: 100%; height: 100%; display: block; }
      .kfg-roompreview .legend{ position:absolute; right: 10px; bottom: 10px; display: flex; flex-direction: column; gap: 4px; font-family: var(--font-mono, monospace); font-size: 10px; color: ${KFG_PALETTE.muted}; background: rgba(13,32,48,0.85); padding: 8px 10px; border: 1px solid ${KFG_PALETTE.line}; border-radius: 4px; max-height: 140px; overflow-y: auto; }
      .kfg-roompreview .legend .row{ display:flex; align-items: center; gap: 6px; }
      .kfg-roompreview .legend .sw{ width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

      /* ========== Step 2 · B2-Layout: HA-Hero (volle breite, text als header) ========== */
      .kfg-mod-hero{
        display: flex; flex-direction: column; gap: 18px;
        padding: 24px;
        background: #0a1620;
        color: #ffffff;
        border-radius: 6px;
        margin-bottom: 28px;
        border: 1px solid rgba(58,189,208,0.18);
      }
      .kfg-mod-hero-header{
        display: flex; align-items: flex-start; justify-content: space-between;
        gap: 24px; flex-wrap: wrap;
      }
      .kfg-mod-hero-text{ flex: 1 1 480px; min-width: 0; }
      .kfg-mod-hero-eyebrow{
        font-family: var(--font-mono, monospace); font-size: 10px;
        letter-spacing: 0.18em; color: ${KFG_PALETTE.accent};
        text-transform: uppercase; margin-bottom: 8px;
      }
      .kfg-mod-hero-title{
        font-family: var(--font-display, serif); font-size: 24px;
        font-weight: 400; line-height: 1.2; margin: 0 0 6px;
        letter-spacing: -0.01em; color: #ffffff;
      }
      .kfg-mod-hero-title em{ font-style: normal; color: #3ABDD0; }
      .kfg-mod-hero-sub{
        font-size: 12.5px; line-height: 1.55;
        color: rgba(255,255,255,0.7); margin: 0;
      }
      .kfg-mod-hero-controls{
        display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
        flex-shrink: 0;
      }
      .kfg-mod-hero-pills{ display: inline-flex; gap: 0;
        border: 1px solid rgba(255,255,255,0.18); border-radius: 100px;
        padding: 3px; background: rgba(255,255,255,0.04);
      }
      .kfg-mod-hero-pills button{
        font-family: var(--font-mono, monospace); font-size: 10px;
        padding: 6px 14px; border-radius: 100px;
        border: 0; cursor: pointer; background: transparent;
        color: rgba(255,255,255,0.65); letter-spacing: 0.06em;
        text-transform: uppercase; transition: all 0.15s;
      }
      .kfg-mod-hero-pills button.on{
        background: ${KFG_PALETTE.accent}; color: #ffffff; font-weight: 600;
      }
      .kfg-mod-hero-maximize{
        display: inline-flex; align-items: center; gap: 6px;
        padding: 6px 12px; border-radius: 100px;
        background: rgba(255,255,255,0.04); color: rgba(255,255,255,0.7);
        border: 1px solid rgba(255,255,255,0.18);
        font-family: var(--font-mono, monospace); font-size: 10px;
        letter-spacing: 0.06em; text-transform: uppercase;
        cursor: pointer; transition: all 0.15s;
      }
      .kfg-mod-hero-maximize:hover{
        border-color: ${KFG_PALETTE.accent}; color: #ffffff;
      }
      .kfg-mod-hero-cap{
        font-family: var(--font-mono, monospace); font-size: 9px;
        letter-spacing: 0.1em; color: rgba(255,255,255,0.45) !important;
      }
      .kfg-mod-hero-tablet{ display:flex; flex-direction:column; align-items:center; gap: 8px; width: 100%; }
      .kfg-mod-hero-bezel{
        background: #1a1a1a; border-radius: 14px; padding: 10px;
        border: 1px solid #2a2a2a;
        box-shadow: 0 28px 60px -25px rgba(0,0,0,0.6);
        width: 100%; max-width: 1100px;
      }
      .kfg-mod-hero-screen{
        background: #0d1922; border-radius: 8px;
        border: 1px solid rgba(58,189,208,0.18);
        /* keine feste aspect-ratio -- der screen waechst mit dem inhalt
           damit alle modul-sektionen sichtbar bleiben. min-height haelt
           die tablet-anmutung wenn nur wenige module aktiv sind. */
        min-height: 360px;
      }
      .kfg-mod-hero-screen .kfg-live-preview{
        position: static; max-height: none; border-radius: 0;
        padding: 22px 26px;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-auto-rows: auto;
        column-gap: 20px; row-gap: 16px;
      }
      .kfg-mod-hero-screen .kfg-live-preview > *:first-child{
        grid-column: 1 / -1;
      }
      .kfg-mod-hero-screen .kfg-live-preview .kfg-live-section,
      .kfg-mod-hero-screen .kfg-live-preview > div:not(:first-child){
        margin-bottom: 0;
      }
      .kfg-mod-hero-screen .kfg-live-preview > *{
        min-width: 0;
      }
      .kfg-mod-hero-phone-wrap{ display:flex; align-items:center; justify-content:center; width: 100%; }
      .kfg-mod-hero-phone{ display:flex; flex-direction:column; align-items:center; gap: 8px; justify-content: center; }
      .kfg-mod-hero-phone-bezel{
        background: #1a1a1a; border-radius: 30px; padding: 8px;
        border: 1px solid #2a2a2a; position: relative;
        box-shadow: 0 28px 60px -25px rgba(0,0,0,0.6);
        width: 100%; max-width: 280px;
      }
      .kfg-mod-hero-phone-notch{
        position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
        width: 60px; height: 14px; background: #0a0a0a; border-radius: 100px;
        z-index: 2;
      }
      .kfg-mod-hero-phone-screen{
        background: #0d1922; border-radius: 22px; overflow: hidden;
        border: 1px solid rgba(58,189,208,0.18);
        max-height: 520px; overflow-y: auto;
      }
      .kfg-mod-hero-phone-screen .kfg-live-preview{
        position: static; max-height: none; border-radius: 0;
        padding: 32px 14px 16px;
      }

      /* Fullscreen-Modal fuer maximierte Vorschau */
      .kfg-mod-hero-fs-overlay{
        position: fixed; inset: 0; z-index: 9999;
        background: rgba(5,11,17,0.92);
        display: flex; align-items: center; justify-content: center;
        padding: 40px; backdrop-filter: blur(6px);
      }
      .kfg-mod-hero-fs-frame{
        position: relative; width: 100%; height: 100%;
        max-width: 1400px; max-height: 900px;
        display: flex; flex-direction: column; gap: 14px;
      }
      .kfg-mod-hero-fs-close{
        position: absolute; top: -10px; right: -10px;
        width: 36px; height: 36px; border-radius: 50%;
        background: ${KFG_PALETTE.ink}; color: ${KFG_PALETTE.paper};
        border: 1px solid rgba(255,255,255,0.2);
        font-size: 18px; cursor: pointer; line-height: 1;
        display: grid; place-items: center;
      }
      .kfg-mod-hero-fs-close:hover{ background: ${KFG_PALETTE.accent}; }
      .kfg-mod-hero-fs-screen{
        flex: 1; min-height: 0;
        background: #0d1922; border-radius: 10px; overflow: hidden;
        border: 1px solid rgba(58,189,208,0.25);
      }
      .kfg-mod-hero-fs-screen .kfg-live-preview{
        position: static; max-height: 100%; height: 100%;
        border-radius: 0; padding: 28px 32px;
        overflow-y: auto;
      }
      .kfg-mod-hero-fs-cap{
        font-family: var(--font-mono, monospace); font-size: 10px;
        letter-spacing: 0.1em; color: rgba(255,255,255,0.55);
        text-align: center;
      }

      /* Räume — horizontale Tabs (kompakt) */
      .kfg-mod-roombar-head{
        display:flex; align-items:center; gap: 14px; margin-bottom: 8px;
      }
      .kfg-mod-roombar-eyebrow{
        font-family: var(--font-mono, monospace); font-size: 10px;
        letter-spacing: 0.18em; color: ${KFG_PALETTE.muted};
        text-transform: uppercase;
      }
      .kfg-mod-roombar-line{ flex: 1; height: 1px; background: ${KFG_PALETTE.line}; }
      .kfg-mod-roombar-stat{
        font-family: var(--font-mono, monospace); font-size: 10px;
        color: ${KFG_PALETTE.muted};
      }
      .kfg-mod-roombar{
        display:flex; gap: 8px; overflow-x: auto;
        padding-bottom: 4px; margin-bottom: 22px;
        scrollbar-width: thin;
      }
      .kfg-mod-roomtab{
        flex: 0 0 auto; min-width: 130px;
        position: relative;
        padding: 9px 14px; cursor: pointer;
        background: ${KFG_PALETTE.card};
        border: 1px solid ${KFG_PALETTE.line};
        font-family: inherit; color: inherit;
        text-align: left; transition: all 0.15s;
        display: flex; flex-direction: column; gap: 1px;
      }
      .kfg-mod-roomtab:hover{ border-color: ${KFG_PALETTE.ink}; }
      .kfg-mod-roomtab.active{
        border-color: ${KFG_PALETTE.accent};
        background: rgba(58,189,208,0.06);
      }
      .kfg-mod-roomtab .pill{
        position: absolute; top: 7px; right: 9px;
        flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%;
        background: ${KFG_PALETTE.accent}; color: ${KFG_PALETTE.paper};
        font-family: var(--font-mono, monospace); font-size: 10px;
        font-weight: 600; display:grid; place-items: center;
      }
      .kfg-mod-roomtab .pill.zero{ background: ${KFG_PALETTE.line}; color: ${KFG_PALETTE.muted}; }
      .kfg-mod-roomtab .info{ padding-right: 22px; }
      .kfg-mod-roomtab .info .nm{ font-size: 12.5px; font-weight: 500; line-height: 1.2; }
      .kfg-mod-roomtab .info .meta{
        font-family: var(--font-mono, monospace); font-size: 9.5px;
        color: ${KFG_PALETTE.muted}; margin-top: 2px; letter-spacing: 0.04em;
      }

      .kfg-mod-detail{ padding: 4px; }
      .kfg-mod-detail-head{ display:flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; padding-bottom: 14px; border-bottom: 1px solid ${KFG_PALETTE.line}; margin-bottom: 22px; }
      .kfg-mod-detail-head h3{ font-family: var(--font-display, serif); font-size: 28px; font-weight: 400; margin: 0; letter-spacing: -0.01em; }
      .kfg-mod-detail-head .meta{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.muted}; }

      .kfg-mod-grid3{
        display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
      }
      .kfg-mod-card{
        position: relative; padding: 18px;
        background: ${KFG_PALETTE.card};
        border: 1px solid ${KFG_PALETTE.line};
        cursor: pointer; transition: all 0.15s;
        display:flex; flex-direction: column; gap: 14px;
      }
      .kfg-mod-card:hover{ border-color: ${KFG_PALETTE.ink}; }
      .kfg-mod-card.on{
        border-color: ${KFG_PALETTE.accent};
        background: rgba(58,189,208,0.04);
      }
      .kfg-mod-card-tog{
        position: absolute; top: 16px; right: 16px;
        width: 36px; height: 20px; border-radius: 100px;
        background: ${KFG_PALETTE.line}; padding: 2px;
        display:flex; justify-content: flex-start;
        transition: all 0.15s;
      }
      .kfg-mod-card-tog::after{
        content: ""; width: 16px; height: 16px; border-radius: 50%;
        background: ${KFG_PALETTE.paper};
      }
      .kfg-mod-card.on .kfg-mod-card-tog{
        background: ${KFG_PALETTE.accent}; justify-content: flex-end;
      }
      .kfg-mod-card-head{ display:flex; gap: 12px; align-items: center; padding-right: 44px; }
      .kfg-mod-card-head .ic{
        width: 38px; height: 38px; border-radius: 8px;
        background: ${KFG_PALETTE.paper};
        display:grid; place-items: center; font-size: 16px;
        flex-shrink: 0;
      }
      .kfg-mod-card.on .kfg-mod-card-head .ic{
        background: ${KFG_PALETTE.accent}; color: ${KFG_PALETTE.paper};
      }
      .kfg-mod-card-head .lbl{ font-size: 14px; font-weight: 500; }
      .kfg-mod-card-head .desc{ font-size: 11px; color: ${KFG_PALETTE.muted}; margin-top: 2px; }
      .kfg-mod-card-foot{
        display:flex; justify-content: space-between; align-items: center;
        margin-top: auto;
      }
      .kfg-mod-card-foot .price{
        font-family: var(--font-mono, monospace); font-size: 13px;
        color: ${KFG_PALETTE.muted};
      }
      .kfg-mod-card.on .kfg-mod-card-foot .price{
        color: ${KFG_PALETTE.accent}; font-weight: 600;
      }

      .kfg-mod-counter{ display: inline-flex; align-items: center; gap: 0; border: 1px solid ${KFG_PALETTE.line}; border-radius: 4px; background: ${KFG_PALETTE.paper}; height: 28px; }
      .kfg-mod-counter .cb{ width: 26px; height: 26px; border: 0; background: transparent; cursor: pointer; color: ${KFG_PALETTE.ink}; font-size: 16px; line-height: 1; padding: 0; display: grid; place-items: center; font-family: inherit; }
      .kfg-mod-counter .cb:hover{ background: ${KFG_PALETTE.card}; }
      .kfg-mod-counter .cv{ min-width: 28px; text-align: center; font-family: var(--font-mono, monospace); font-size: 13px; color: ${KFG_PALETTE.ink}; padding: 0 2px; border-left: 1px solid ${KFG_PALETTE.line}; border-right: 1px solid ${KFG_PALETTE.line}; height: 100%; display: grid; place-items: center; }
      .kfg-mod-card.on .kfg-mod-counter{ border-color: ${KFG_PALETTE.accent}; }

      .kfg-mod-disabled{ opacity: 0.4; cursor: not-allowed; }
      .kfg-mod-disabled:hover{ border-color: ${KFG_PALETTE.line}; }

      @media (max-width: 1400px){
        .kfg-mod-hero{ grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 24px; }
      }
      @media (max-width: 1100px){
        .kfg-mod-grid3{ grid-template-columns: repeat(2, 1fr); }
      }
      .kfg-live-preview{ background: ${KFG_PALETTE.ink}; color: ${KFG_PALETTE.paper};
        padding: 22px; position: sticky; top: 24px; max-height: calc(100vh - 60px);
        overflow-y: auto; border-radius: 4px; }
      .kfg-live-head{ display:flex; align-items: center; gap: 12px; padding-bottom: 18px;
        margin-bottom: 18px; border-bottom: 1px solid rgba(245,241,232,0.15); }
      .kfg-live-head .dot{ width: 8px; height: 8px; border-radius: 50%;
        background: ${KFG_PALETTE.accent}; box-shadow: 0 0 0 4px rgba(58,189,208,0.18);
        flex-shrink: 0; }
      .kfg-live-head .title{ font-family: var(--font-display, serif); font-size: 17px;
        font-weight: 400; line-height: 1.2; }
      .kfg-live-head .sub{ font-family: var(--font-mono, monospace); font-size: 10px;
        color: rgba(245,241,232,0.55); letter-spacing: 0.08em; margin-top: 2px;
        text-transform: uppercase; }
      .kfg-live-empty{ font-size: 12px; line-height: 1.55; color: rgba(245,241,232,0.55);
        background: rgba(245,241,232,0.04); padding: 14px; border-radius: 4px;
        border: 1px dashed rgba(245,241,232,0.15); }
      .kfg-live-section{ margin-bottom: 18px; }
      .kfg-live-section:last-child{ margin-bottom: 0; }
      .kfg-live-section h4{ font-family: var(--font-mono, monospace); font-size: 10px;
        letter-spacing: 0.14em; text-transform: uppercase;
        color: rgba(245,241,232,0.55); margin: 0 0 10px;
        display:flex; justify-content: space-between; align-items: baseline;
        font-weight: 500; }
      .kfg-live-section h4 .cnt{ font-size: 10px; color: ${KFG_PALETTE.accent};
        font-weight: 600; }
      .kfg-live-entities{ display:flex; flex-direction: column; gap: 6px; }
      .kfg-live-entity{ display:flex; align-items: center; gap: 10px;
        padding: 8px 10px; background: rgba(245,241,232,0.04);
        border: 1px solid rgba(245,241,232,0.08); border-radius: 4px;
        transition: background 0.15s; }
      .kfg-live-entity:hover{ background: rgba(58,189,208,0.10); }
      .kfg-live-entity .bullet{ width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
      .kfg-live-entity .lbl{ flex: 1; min-width: 0; }
      .kfg-live-entity .nm{ font-size: 13px; color: ${KFG_PALETTE.paper};
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
      .kfg-live-entity .st{ font-family: var(--font-mono, monospace); font-size: 10px;
        color: rgba(245,241,232,0.55); margin-top: 2px; letter-spacing: 0.04em; }

      /* Summary (Step 3) */
      .kfg-sum-grid{ display:grid; grid-template-columns: 1fr 380px; gap: 40px; align-items: start; }
      .kfg-sum-rooms{ display:flex; flex-direction:column; gap: 0; }
      .kfg-sum-room{ display:grid; grid-template-columns: 1fr auto; padding: 18px 0; border-bottom: 1px solid ${KFG_PALETTE.line}; gap: 8px 24px; }
      .kfg-sum-room:last-child{ border-bottom: none; }
      .kfg-sum-room .name{ font-family: var(--font-display, serif); font-size: 19px; font-weight: 400; line-height: 1.2; }
      .kfg-sum-room .meta{ font-family: var(--font-mono, monospace); font-size: 11px; color: ${KFG_PALETTE.muted}; margin-top: 2px; }
      .kfg-sum-room .price{ font-family: var(--font-mono, monospace); font-size: 14px; font-weight: 600; }
      .kfg-sum-room .mods{ grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
      .kfg-sum-room .mod-chip{ font-size: 11px; padding: 3px 9px; background: ${KFG_PALETTE.paper}; border: 1px solid ${KFG_PALETTE.line}; border-radius: 999px; color: ${KFG_PALETTE.ink}; }
      .kfg-sum-room .mod-chip .ic{ margin-right: 5px; opacity: 0.7; }

      .kfg-sum-card{ background: ${KFG_PALETTE.paper}; color: ${KFG_PALETTE.ink}; padding: 32px; position: sticky; top: 40px; border: 1px solid ${KFG_PALETTE.line}; border-radius: 4px; }
      .kfg-sum-card h4{ font-family: var(--font-mono, monospace); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(245,241,232,0.6); margin: 0 0 24px; font-weight: 400; }
      .kfg-sum-total{ font-family: var(--font-display, serif); font-size: 56px; line-height: 1; font-weight: 400; letter-spacing: -0.02em; margin-bottom: 6px; }
      .kfg-sum-total .from{ font-size: 14px; color: rgba(245,241,232,0.6); margin-right: 8px; vertical-align: top; font-family: var(--font-mono, monospace); }
      .kfg-sum-range{ font-family: var(--font-mono, monospace); font-size: 12px; color: rgba(245,241,232,0.5); margin-bottom: 28px; }
      .kfg-sum-breakdown{ display: flex; flex-direction: column; gap: 10px; padding: 20px 0; border-top: 1px solid rgba(245,241,232,0.15); border-bottom: 1px solid rgba(245,241,232,0.15); margin-bottom: 24px; }
      .kfg-sum-breakdown .row{ display:flex; justify-content: space-between; font-size: 13px; }
      .kfg-sum-breakdown .row .lbl{ color: rgba(245,241,232,0.7); }
      .kfg-sum-breakdown .row .v{ font-family: var(--font-mono, monospace); }
      .kfg-sum-actions{ display:flex; flex-direction: column; gap: 10px; }
      .kfg-btn{ display: inline-flex; align-items: center; justify-content: center; gap: 10px; padding: 14px 22px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; border: none; font-family: inherit; }
      .kfg-btn-primary{ background: ${KFG_PALETTE.accent}; color: ${KFG_PALETTE.paper}; }
      .kfg-btn-primary:hover{ background: ${KFG_PALETTE.warm}; }
      .kfg-btn-ghost{ background: transparent; color: inherit; border: 1px solid ${KFG_PALETTE.line}; }
      .kfg-btn-ghost-light{ background: transparent; color: ${KFG_PALETTE.ink}; border: 1px solid rgba(245,241,232,0.25); }
      .kfg-btn-ghost-light:hover{ border-color: ${KFG_PALETTE.ink}; }
      .kfg-sum-disclaimer{ font-size: 11px; color: rgba(245,241,232,0.45); line-height: 1.5; margin-top: 18px; }

      /* Footer nav */
      .kfg-footer-nav{ display:flex; justify-content: space-between; align-items: center; margin-top: 40px; padding-top: 28px; border-top: 1px solid ${KFG_PALETTE.line}; }
      .kfg-footer-nav .left, .kfg-footer-nav .right{ display:flex; gap: 12px; align-items: center; }
      .kfg-back{ background: transparent; border: 1px solid ${KFG_PALETTE.line}; padding: 12px 20px; font-size: 13px; cursor: pointer; font-family: inherit; color: inherit; transition: all 0.18s; }
      .kfg-back:hover{ border-color: ${KFG_PALETTE.ink}; }
      .kfg-next{ background: ${KFG_PALETTE.ink}; color: ${KFG_PALETTE.paper}; border: none; padding: 14px 28px; font-size: 14px; font-weight: 500; cursor: pointer; font-family: inherit; transition: all 0.2s; }
      .kfg-next:hover{ background: ${KFG_PALETTE.accent}; }
      .kfg-next:disabled{ opacity: 0.4; cursor: not-allowed; }

      /* Floorplan viz */
      .kfg-floorplan{ background: ${KFG_PALETTE.paper}; border: 1px solid ${KFG_PALETTE.line}; padding: 20px; }
      .kfg-floorplan svg{ width:100%; height: auto; display:block; }
      .kfg-floorplan .fp-room{ fill: ${KFG_PALETTE.card}; stroke: ${KFG_PALETTE.ink}; stroke-width: 1.2; }
      .kfg-floorplan .fp-room.outdoor{ fill: rgba(212,165,116,0.15); stroke-dasharray: 4 3; }
      .kfg-floorplan .fp-label{ font-family: var(--font-mono, monospace); font-size: 9px; fill: ${KFG_PALETTE.ink}; text-anchor: middle; }
      .kfg-floorplan .fp-area{ font-family: var(--font-mono, monospace); font-size: 7px; fill: ${KFG_PALETTE.muted}; text-anchor: middle; }
      .kfg-floorplan .fp-mod{ font-family: var(--font-mono, monospace); font-size: 9px; }

      @media (max-width: 900px){
        .kfg-methods{ grid-template-columns: 1fr; }
        .kfg-manual-grid, .kfg-sum-grid, .kfg-scan-stage{ grid-template-columns: 1fr; }
        .kfg-content{ padding: 28px; }
        .kfg-mod-hero{ grid-template-columns: 1fr; padding: 22px; }
        .kfg-mod-grid3{ grid-template-columns: 1fr; }
      }

      @media (max-width: 640px){
        .kfg-section{ padding: 80px 0 90px; }
        .kfg-container{ padding: 0 18px; }
        .kfg-content{ padding: 18px 16px; min-height: 0; }
        .kfg-title{ font-size: clamp(30px, 9vw, 40px); }
        .kfg-sub{ font-size: 15px; margin-bottom: 28px; }
        .kfg-stepper{ margin: 20px 0 32px; }
        .kfg-step-item{ flex-direction: column; align-items: flex-start; gap: 4px; padding: 12px 10px; }
        .kfg-step-num{ min-width: 0; }
        .kfg-step-label{ font-size: 11px; line-height: 1.2; }
        .kfg-method-card{ padding: 26px 22px 24px; }
        .kfg-method-card h3{ font-size: 26px; }
        .kfg-mod-hero-screen .kfg-live-preview{ grid-template-columns: repeat(2, 1fr); }
        .kfg-review-stats{ grid-template-columns: repeat(2, 1fr); }
        .kfg-sum-card{ padding: 24px; }
        .kfg-sum-total{ font-size: 44px; }
        .kfg-footer-nav{ flex-wrap: wrap; gap: 12px; }
        .kfg-footer-nav .left, .kfg-footer-nav .right{ width: 100%; }
        .kfg-footer-nav .right{ justify-content: flex-end; }
        .kfg-import-drop{ padding: 40px 22px; }
      }

      @media (max-width: 400px){
        .kfg-room-types{ grid-template-columns: 1fr; }
        .kfg-mod-hero-screen .kfg-live-preview{ grid-template-columns: 1fr; }
        .kfg-step-label{ font-size: 10px; }
        .kfg-next{ padding: 14px 20px; }
      }

      /* PDF-Export oeffnet ein neues Fenster mit eigenem druck-optimiertem
         HTML (siehe buildPdfHtml in konfigurator-steps.jsx). Das vorherige
         @media print mit sm-printing-summary Class-Hack wurde entfernt --
         war fragil weil React-Tree mehrfach geschachtelt ist. */
    `}</style>
  );
}

/* ===========================================================
   HEADER + STEPPER
============================================================ */
function KfgHeader({ step, onJump, method, pathKey }) {
  const isGewerbe = pathKey === "gewerbe";
  const steps = [
    { n: "01", lbl: "Methode" },
    { n: "02", lbl: method === "import" ? "Plan-Import" : (isGewerbe ? "Bereiche erfassen" : "Räume erfassen") },
    { n: "03", lbl: isGewerbe ? "Funktionen wählen" : "Module wählen" },
    { n: "04", lbl: "Empfehlung" },
  ];
  return (
    <>
      <div className="kfg-eyebrow"><span className="dot"></span>03 · KONFIGURATOR</div>
      <h2 className="kfg-title">
        {isGewerbe ? <>Lass uns dein <em>Gewerbeobjekt</em> planen.</> : <>Lass uns dein <em>Smart-Home</em> planen.</>}
      </h2>
      <p className="kfg-sub">
        {isGewerbe
          ? "In vier Schritten zur ersten Orientierung für Betriebsgebäude, Büro oder Hotel — Bereiche erfassen, Funktionen wählen, Grobschätzung erhalten."
          : "In vier Schritten zur ersten Schätzung — entweder Räume manuell erfassen oder einen Bauplan importieren. Du bekommst direkt eine Empfehlung mit Grobpreis."}
      </p>
      <div className="kfg-stepper">
        {steps.map((s, i) => (
          <button key={s.n} className={`kfg-step-item ${i===step?"active":""} ${i<step?"done":""} ${i>step?"disabled":""}`}
            onClick={() => i <= step && onJump(i)}>
            <span className="kfg-step-num">{s.n}</span>
            <span className="kfg-step-label">{s.lbl}</span>
          </button>
        ))}
      </div>
    </>
  );
}

/* ===========================================================
   STEP 0 — Methode wählen
============================================================ */
function KfgStep0Method({ pathKey, onPick }) {
  const isGewerbe = pathKey === "gewerbe";
  return (
    <div className="kfg-content">
      <h3 style={{ fontFamily: "var(--font-display, serif)", fontSize: 28, fontWeight: 400, margin: "0 0 6px" }}>Wie möchtest du starten?</h3>
      <p style={{ color: KFG_PALETTE.muted, fontSize: 14, margin: 0 }}>
        {isGewerbe
          ? "Beide Wege führen zur gleichen Orientierung — manuell über Objektbereiche oder per Plan-Import."
          : "Beide Wege führen zum gleichen Ergebnis — wähle was sich für dich angenehmer anfühlt."}
      </p>
      <div className="kfg-methods">
        <button className="kfg-method-card" onClick={() => onPick("manual")}>
          <div className="num">A · GEFÜHRT</div>
          <KfgIlluManual isGewerbe={isGewerbe} />
          <h3>{isGewerbe ? <>Bereiche manuell<br/>erfassen.</> : <>Räume manuell<br/>erfassen.</>}</h3>
          <p>{isGewerbe ? "Stockwerk für Stockwerk Betriebsbereiche hinzufügen. Praktisch, wenn du nur Büro, Hotelzimmer, Technik oder einzelne Zonen betrachten willst." : "Stockwerk für Stockwerk Räume hinzufügen. Praktisch wenn du keinen Plan zur Hand hast oder einzelne Bereiche planst."}</p>
          <ul className="feats">
            <li>{isGewerbe ? "Bereichstypen aus Bibliothek wählen" : "Raumtypen aus Bibliothek wählen"}</li>
            <li>Größe und Fenster anpassen</li>
            <li>~3 Minuten</li>
          </ul>
          <div className="pick-cta">Manuell starten</div>
        </button>
        <button className="kfg-method-card" onClick={() => onPick("import")}>
          <div className="num">B · IMPORT</div>
          <KfgIlluImport isGewerbe={isGewerbe} />
          <h3>Bauplan<br/>importieren.</h3>
          <p>{isGewerbe ? "Lade einen Objektplan hoch — Bereiche, Flächen und Fenster werden automatisch erkannt. Du musst nur noch Funktionen wählen." : "Lade einen PDF-Plan hoch — Räume, Flächen und Fenster werden automatisch erkannt. Du musst nur noch Module wählen."}</p>
          <ul className="feats">
            <li>PDF / DWG / Bild</li>
            <li>{isGewerbe ? "Automatische Bereichserkennung" : "Automatische Raumerkennung"}</li>
            <li>~30 Sekunden</li>
          </ul>
          <div className="pick-cta">Plan hochladen</div>
        </button>
      </div>
    </div>
  );
}

function KfgIlluManual({ isGewerbe = false }) {
  return (
    <svg className="kfg-method-illu" viewBox="0 0 320 140" fill="none">
      <g stroke={KFG_PALETTE.ink} strokeWidth="1.4" fill="none">
        <rect x="20" y="30" width="100" height="80"/>
        <rect x="125" y="30" width="60" height="40"/>
        <rect x="125" y="75" width="60" height="35"/>
        <rect x="190" y="30" width="50" height="80" strokeDasharray="3 3" stroke={KFG_PALETTE.warm}/>
      </g>
      <g fontFamily="monospace" fontSize="8" fill={KFG_PALETTE.muted} textAnchor="middle">
        <text x="70" y="73">{isGewerbe ? "Büro" : "Wohnen"}</text>
        <text x="70" y="83">31m²</text>
        <text x="155" y="53">{isGewerbe ? "Meeting" : "Küche"}</text>
        <text x="155" y="95">{isGewerbe ? "Technik" : "Bad"}</text>
      </g>
      <g stroke={KFG_PALETTE.accent} strokeWidth="1.5" fill="none">
        <circle cx="215" cy="70" r="12"/>
        <line x1="215" y1="64" x2="215" y2="76"/>
        <line x1="209" y1="70" x2="221" y2="70"/>
      </g>
      <text x="270" y="60" fontFamily="monospace" fontSize="8" fill={KFG_PALETTE.accent}>+ {isGewerbe ? "Bereich" : "Raum"}</text>
      <text x="270" y="72" fontFamily="monospace" fontSize="8" fill={KFG_PALETTE.accent}>hinzu-</text>
      <text x="270" y="84" fontFamily="monospace" fontSize="8" fill={KFG_PALETTE.accent}>fügen</text>
    </svg>
  );
}

function KfgIlluImport({ isGewerbe = false }) {
  return (
    <svg className="kfg-method-illu" viewBox="0 0 320 140" fill="none">
      <g stroke={KFG_PALETTE.ink} strokeWidth="1.2" fill={KFG_PALETTE.card}>
        <rect x="40" y="20" width="110" height="100"/>
      </g>
      <g stroke={KFG_PALETTE.ink} strokeWidth="0.8" fill="none">
        <line x1="40" y1="60" x2="150" y2="60"/>
        <line x1="80" y1="20" x2="80" y2="120"/>
        <line x1="115" y1="60" x2="115" y2="120"/>
      </g>
      <g fontFamily="monospace" fontSize="6" fill={KFG_PALETTE.muted}>
        <text x="48" y="34">{isGewerbe ? "OBJ" : "EFH"}</text>
        <text x="48" y="42">PDF</text>
      </g>
      {/* Scan line */}
      <line x1="40" y1="80" x2="150" y2="80" stroke={KFG_PALETTE.accent} strokeWidth="2" opacity="0.7"/>
      {/* Arrow */}
      <g stroke={KFG_PALETTE.muted} strokeWidth="1" fill="none">
        <line x1="160" y1="70" x2="200" y2="70"/>
        <polyline points="195,65 200,70 195,75"/>
      </g>
      {/* Detected rooms */}
      <g stroke={KFG_PALETTE.accent} strokeWidth="1.4" fill="rgba(107,142,78,0.08)">
        <rect x="210" y="20" width="50" height="48"/>
        <rect x="265" y="20" width="40" height="30"/>
        <rect x="265" y="55" width="40" height="38"/>
        <rect x="210" y="74" width="50" height="46"/>
      </g>
      <g fontFamily="monospace" fontSize="7" fill={KFG_PALETTE.accent} textAnchor="middle">
        <text x="235" y="46">{isGewerbe ? "Büro" : "Wohnen"}</text>
        <text x="285" y="36">{isGewerbe ? "Meet" : "Küche"}</text>
        <text x="285" y="76">{isGewerbe ? "Tech" : "Bad"}</text>
        <text x="235" y="100">{isGewerbe ? "Hotel" : "Schlafz."}</text>
      </g>
      <text x="280" y="115" fontFamily="monospace" fontSize="7" fill={KFG_PALETTE.muted}>4/4 erkannt</text>
    </svg>
  );
}

window.KonfiguratorSection = KonfiguratorSection;
window.BASTING_ROOMS = BASTING_ROOMS;
window.MODULE_SETS = MODULE_SETS;
window.applyDefaults = applyDefaults;
window.KFG_PALETTE = KFG_PALETTE;
