(() => {
  'use strict';

  /* =========================
     Modal-Backbone Utilities
     ========================= */

  /**
   * Zeigt ein Modal erst, wenn das aktuelle vollständig ausgeblendet ist.
   * Verwendet hidden.bs.modal {once:true} statt setTimeout/rAF.
   * Fallback: wenn kein aktives Modal offen ist, direkt zeigen.
   *
   * @param {HTMLElement|null} fromEl   - Modal-Element das gerade geschlossen wird (kann null sein)
   * @param {string}           toId    - ID des nächsten Modal-Elements
   * @param {object}           [opts]  - Bootstrap Modal-Optionen
   */
  function showAfter(fromEl, toId, opts = { backdrop: 'static', keyboard: false }) {
    const toEl = document.getElementById(toId);
    if (!toEl) return;

    const doShow = () => {
      // getOrCreateInstance: verhindert doppelte Bootstrap-Instanzen
      bootstrap.Modal.getOrCreateInstance(toEl, opts).show();
    };

    if (fromEl && fromEl.classList.contains('show')) {
      // Modal A noch sichtbar: warten bis hidden.bs.modal gefeuert hat,
      // dann Modal B sofort (synchron) zeigen. Der Backdrop von B ist
      // dann schon da, wenn cleanupModalArtifacts prueft.
      fromEl.addEventListener('hidden.bs.modal', doShow, { once: true });
    } else {
      // Kein aktives Modal: direkt zeigen, kein rAF noetig.
      doShow();
    }
  }

  window.PRICEFUCHS_showAfter = showAfter;

  /* =========================
     Globale Bereinigung nach Modal-Close.
     Raumt nur body-Klassen/Styles auf - Backdrops entfernt Bootstrap selbst.
     Synchron (kein rAF): Element-level Handler haben bereits gefeuert (Bubbling),
     Bootstrap hat seinen Backdrop bereits erstellt wenn dieses hier lauft.
     Backdrop vorhanden = Transition lauft noch - nichts tun.
     ========================= */
  function cleanupModalArtifacts() {
    const anyActive =
      document.querySelector('.modal.show') ||
      document.querySelector('.modal-backdrop');
    if (anyActive) return;

    document.body.classList.remove('modal-open');
    document.body.style.removeProperty('padding-right');
    document.body.style.removeProperty('overflow');
  }

  document.addEventListener('hidden.bs.modal', cleanupModalArtifacts);


window.PRICEFUCHS_RESULTS = window.PRICEFUCHS_RESULTS || {
  quizzes: {}
};

function saveQuizResult(taskKey, payload) {
  window.PRICEFUCHS_RESULTS.quizzes[taskKey] = {
    ...payload,
    timestamp: new Date().toISOString()
  };
}


  /* =========================
     App Restart (Brand-Click)
     ========================= */
  function restartAppToStart() {
    // Modals/Backdrops sauber entfernen (falls gerade was offen ist)
    try {
      document.querySelectorAll('.modal.show').forEach(m => {
        if (window.bootstrap?.Modal) {
          const inst = bootstrap.Modal.getInstance(m) || new bootstrap.Modal(m);
          inst.hide();
        }
      });
    } catch (_) {}

    cleanupModalArtifacts();

    // Hash entfernen (falls irgendwo mit Anchors gearbeitet wird)
    try {
      history.replaceState(null, '', window.location.pathname + window.location.search);
    } catch (_) {}

    // Hard reset: alles wieder auf Anfang
    window.location.reload();
  }

  // Brand oben klickbar: Neustart
  document.addEventListener('DOMContentLoaded', () => {
    const brand = document.querySelector('.navbar .brand');
    if (!brand) return;

    const fire = (e) => {
      e.preventDefault();
      restartAppToStart();
    };

    brand.addEventListener('click', fire);
    brand.addEventListener('keydown', (e) => {
      if (e.key === 'Enter' || e.key === ' ') fire(e);
    });
  });

  /* =========================
     0a) Zentrale Quiz-Definitionen (einheitlich für alle Aufgaben)
     - Hier pflegst du künftig nur noch Texte + richtige Antwort
     ========================= */
  const QUIZ_BANK = {
    task1: {
      key: 'task1',
      modalId: 'task1QuizModal',
      correctValue: 'd',
      correctLabel: 'Dynamic Pricing',
      maxAttempts: 2,
      explanation:
        'Die Preise bilden sich entsprechend der aktuellen Nachfrage. Diese hängt z. B. vom Wochentag, dem Wetter oder der Tageszeit ab.',
      nextLabel: 'Weiter zur nächsten Aufgabe'
    },
    task2: {
      key: 'task2',
      modalId: 'task2QuizModal',
      correctValue: 'c',
      correctLabel: 'Referenzpreise (Ankerpreise)',
      maxAttempts: 2,
      explanation:
        'Referenzpreise (Ankerpreise) können das Verbraucherverhalten beeinflussen. ' +
        'Wird neben einem reduzierten Preis ein höherer Ankerpreis angezeigt, erscheint das Produkt wertiger ' +
        'und kann Verbraucherinnen und Verbraucher eher zum Kauf anregen.',
      nextLabel: 'Weiter zur nächsten Aufgabe'
    }
  };

  /* =========================
     0b) Quiz-Engine (generisch, kein Copy/Paste pro Aufgabe)
     Erwartet im Modal:
     - [data-quiz-form]
       - Buttons: [data-quiz-option][data-value]
     - [data-quiz-submit], [data-quiz-next]
     - [data-quiz-try], [data-quiz-feedback]
     - optional: [data-quiz-context]
     ========================= */
  function createQuizEngine(cfg) {
    const modalEl = document.getElementById(cfg.modalId);
    if (!modalEl || !window.bootstrap?.Modal) return null;

    const bsModal = new bootstrap.Modal(modalEl, { backdrop: 'static', keyboard: false });

    const formEl = modalEl.querySelector('[data-quiz-form]');
    const ctxEl = modalEl.querySelector('[data-quiz-context]');
    const tryEl = modalEl.querySelector('[data-quiz-try]');
    const feedbackEl = modalEl.querySelector('[data-quiz-feedback]');
    const submitBtn = modalEl.querySelector('[data-quiz-submit]');
    const nextBtn = modalEl.querySelector('[data-quiz-next]');

    const state = {
      locked: false,
      attemptsUsed: 0,
      answers: [],
      payload: {}
    };

    function options() {
      return formEl ? [...formEl.querySelectorAll('[data-quiz-option][data-value]')] : [];
    }

    function setFeedback(html) {
      if (feedbackEl) feedbackEl.innerHTML = html;
    }

    function setTry(n) {
      if (tryEl) tryEl.textContent = String(n);
    }

    function setContext(text) {
      if (ctxEl) ctxEl.textContent = text || '';
    }

    function resetUI() {
      state.locked = false;
      state.attemptsUsed = 0;
      state.answers = [];

      setTry(1);
      setFeedback('');

      options().forEach(btn => {
        btn.classList.remove('active', 'right', 'wrong', 'disabled');
        btn.classList.add('btn-quiz-answer');
        btn.setAttribute('aria-pressed', 'false');
        btn.disabled = false;
        btn.style.pointerEvents = '';
        btn.removeAttribute('aria-disabled');
      });

      if (submitBtn) {
        submitBtn.disabled = false;
        submitBtn.classList.remove('d-none');
      }
      if (nextBtn) nextBtn.classList.add('d-none');
    }

    function setActive(value) {
      if (state.locked) return;
      options().forEach(btn => {
        const isThis = btn.getAttribute('data-value') === value;
        btn.classList.toggle('active', isThis);
        btn.setAttribute('aria-pressed', isThis ? 'true' : 'false');
      });
    }

    function getSelected() {
      const active = formEl?.querySelector('[data-quiz-option].active');
      return active ? active.getAttribute('data-value') : null;
    }

    function markBtn(value, ok) {
      const btn = formEl?.querySelector(`[data-quiz-option][data-value="${value}"]`);
      if (!btn) return;
      btn.classList.add(ok ? 'right' : 'wrong');
    }

    function markCorrect() {
      const btn = formEl?.querySelector(`[data-quiz-option][data-value="${cfg.correctValue}"]`);
      if (!btn) return;
      btn.classList.remove('wrong');
      btn.classList.add('right');
    }

    function lockQuiz() {
      state.locked = true;

      if (submitBtn) submitBtn.classList.add('d-none');
      if (nextBtn) {
        nextBtn.textContent = cfg.nextLabel || 'Weiter';
        nextBtn.classList.remove('d-none');
      }

      // robustes Disable (auch optisch)
      options().forEach(btn => {
        btn.disabled = true;
        btn.classList.add('disabled');
        btn.setAttribute('aria-disabled', 'true');
        btn.style.pointerEvents = 'none';
      });
    }

    function finish(correct, correctAttempt) {
      saveQuizResult(cfg.key, {
        correct,
        correctAttempt,
        attemptsUsed: state.attemptsUsed,
        answers: [...state.answers],
        meta: cfg.metaProvider ? cfg.metaProvider(state.payload) : undefined
      });

      lockQuiz();
      if (typeof cfg.onComplete === 'function') {
        cfg.onComplete({ correct, correctAttempt, attemptsUsed: state.attemptsUsed, answers: [...state.answers], payload: state.payload });
      }
    }

    function renderSuccess() {
      setFeedback(`<div class="alert alert-success mb-0"><strong>Richtig!</strong></div>`);
    }

    function renderTryAgain() {
      setFeedback(`<div class="alert alert-danger mb-0"><strong>Leider falsch.</strong> Du hast noch einen zweiten Versuch.</div>`);
    }

    function renderFinalWrong() {
      setFeedback(`<div class="alert alert-danger mb-0"><strong>Leider falsch.</strong></div>`);
    }

    function submit() {
      if (state.locked) return;

      const selected = getSelected();
      if (!selected) {
        setFeedback(`<div class="alert alert-warning mb-0">Bitte wähle eine Antwort aus.</div>`);
        return;
      }

      state.attemptsUsed += 1;
      state.answers.push(selected);

      const ok = (selected === cfg.correctValue);
      markBtn(selected, ok);

      if (ok) {
        renderSuccess();
        finish(true, state.attemptsUsed);
        return;
      }

      if (state.attemptsUsed < (cfg.maxAttempts || 2)) {
        setTry(state.attemptsUsed + 1);
        renderTryAgain();
        return;
      }

      // final falsch
      markCorrect();
      renderFinalWrong();
      finish(false, 0);
    }

    // Delegierte Click-Handler im Modal
    modalEl.addEventListener('click', (e) => {
      const opt = e.target.closest('[data-quiz-option][data-value]');
      if (opt) return setActive(opt.getAttribute('data-value'));

      if (e.target.closest('[data-quiz-submit]')) return submit();

      if (e.target.closest('[data-quiz-next]')) {
        // Standard: schließen; konkrete Navigation macht cfg.onNext
        if (typeof cfg.onNext === 'function') return cfg.onNext({ hide: () => bsModal.hide(), payload: state.payload });
        return bsModal.hide();
      }
    });

    // Nach dem Schließen: Focus sinnvoll zurück
    modalEl.addEventListener('hidden.bs.modal', () => {
      if (typeof cfg.onHidden === 'function') cfg.onHidden();
    });

    function open(payload = {}) {
      state.payload = payload || {};
      resetUI();
      if (cfg.contextText) setContext(cfg.contextText(payload));
      bsModal.show();

      requestAnimationFrame(() => {
        const first = formEl?.querySelector('[data-quiz-option][data-value]');
        if (first) first.focus();
      });
    }

    return { open, hide: () => bsModal.hide(), modalEl };
  }
  // Exporte (damit spätere Module/Tasks ohne Redundanz andocken können)
  window.PRICEFUCHS_QUIZ_BANK = QUIZ_BANK;
  window.PRICEFUCHS_createQuizEngine = createQuizEngine;
  window.saveQuizResult = saveQuizResult;

  /* =========================
     Multi-Select Quiz Engine (Task 3 + Task 4)
     Konsolidierte Engine für Multiple-Choice-Aufgaben mit N richtigen Antworten.

     Verhalten:
       - Alle Antworten sind auswählbar (kein Limit)
       - 2 Versuche
       - Versuch 1 korrekt → alle Richtigen grün → fertig
       - Versuch 1 falsch, aber ALLE ausgewählt → sofort Lösung zeigen (kein 2. Versuch)
       - Versuch 1 teilweise falsch → korrekt getroffene grün+gesperrt,
         falsch getroffene zurückgesetzt → 2. Versuch
       - Versuch 2 falsch → vollständige Lösung zeigen

     cfg:
       modalId        – ID des Modal-Elements
       optionAttr     – data-Attribut der Antwort-Buttons  (z. B. 'data-task3-option')
       submitAttr     – data-Attribut des Prüfen-Buttons   (z. B. 'data-task3-submit')
       nextAttr       – data-Attribut des Weiter-Buttons   (z. B. 'data-task3-next')
       feedbackAttr   – data-Attribut des Feedback-Bereichs
       triesAttr      – data-Attribut der Versuchs-Anzeige
       correctValues  – Set<string> der richtigen data-value-Werte
       maxAttempts    – max. Versuche (Standard: 2)
       onNext(fn)     – Callback wenn „Weiter" geklickt wird: fn({ hide })
       onComplete(fn) – optionaler Callback nach Abschluss: fn({ correct, attemptsUsed, selected })
     ========================= */
  function createMultiSelectQuizEngine(cfg) {
    const modalEl = document.getElementById(cfg.modalId);
    if (!modalEl || !window.bootstrap?.Modal) return null;

    const bsModal   = new bootstrap.Modal(modalEl, { backdrop: 'static', keyboard: false });
    const maxAtt    = cfg.maxAttempts ?? 2;
    const correct   = cfg.correctValues; // Set<string>

    let attemptsUsed = 0;
    let done         = false;
    let selected     = new Set();

    // --- DOM shortcuts ---
    const opts       = () => [...modalEl.querySelectorAll(`[${cfg.optionAttr}]`)];
    const totalOpts  = () => opts().length;
    const $submit    = () => modalEl.querySelector(`[${cfg.submitAttr}]`);
    const $next      = () => modalEl.querySelector(`[${cfg.nextAttr}]`);
    const $feedback  = () => modalEl.querySelector(`[${cfg.feedbackAttr}]`);
    const $tries     = () => modalEl.querySelector(`[${cfg.triesAttr}]`);

    const setFeedback = (html) => { const el = $feedback(); if (el) el.innerHTML = html || ''; };
    const setTries    = (n)    => { const el = $tries();    if (el) el.textContent = String(n); };

    const updateSubmitState = () => {
      const btn = $submit();
      if (btn) btn.disabled = done || selected.size === 0;
    };

    // --- Colour helpers ---
    const clearBtn = (btn) =>
      btn.classList.remove('right', 'wrong', 'active');

    function setsEqual(a, b) {
      if (a.size !== b.size) return false;
      for (const v of a) if (!b.has(v)) return false;
      return true;
    }

    // Zeige nur ausgewählte Antworten (richtig/falsch), Rest neutral
    function paintCurrent() {
      opts().forEach(btn => {
        const v = btn.getAttribute('data-value');
        clearBtn(btn);
        if (selected.has(v)) {
          btn.classList.add(correct.has(v) ? 'right' : 'wrong');
        } else {
          btn.classList.add('btn-quiz-answer');
        }
      });
    }

    // Vollständige Lösung: Richtige grün, falsch-ausgewählte rot, Rest neutral
    function revealSolution() {
      opts().forEach(btn => {
        const v = btn.getAttribute('data-value');
        clearBtn(btn);
        if (correct.has(v))          btn.classList.add('right');
        else if (selected.has(v))    btn.classList.add('wrong');
        else                         btn.classList.add('btn-quiz-answer');
      });
    }

    function lockAll() {
      opts().forEach(btn => { btn.disabled = true; btn.classList.add('disabled'); });
    }

    function finish(isCorrect) {
      done = true;
      lockAll();

      const sub  = $submit();
      const nxt  = $next();
      if (sub) sub.classList.add('d-none');
      if (nxt) nxt.classList.remove('d-none');

      setFeedback(isCorrect
        ? `<div class="alert alert-success mb-0"><strong>Richtig!</strong></div>`
        : `<div class="alert alert-danger mb-0"><strong>Leider falsch.</strong></div>`
      );

      if (typeof cfg.onComplete === 'function') {
        cfg.onComplete({ correct: isCorrect, attemptsUsed, selected: [...selected] });
      }
    }

    function reset() {
      attemptsUsed = 0;
      done         = false;
      selected     = new Set();

      opts().forEach(btn => {
        clearBtn(btn);
        btn.classList.add('btn-quiz-answer');
        btn.disabled = false;
        btn.classList.remove('disabled');
      });

      const sub = $submit();
      const nxt = $next();
      if (sub) { sub.classList.remove('d-none'); sub.disabled = true; }
      if (nxt) nxt.classList.add('d-none');

      setFeedback('');
      setTries(1);
    }

    // --- Event delegation im Modal ---
    modalEl.addEventListener('click', (e) => {

      // Option-Toggle
      const opt = e.target.closest(`[${cfg.optionAttr}][data-value]`);
      if (opt && !done) {
        const v = opt.getAttribute('data-value');
        if (opt.disabled) return;

        if (selected.has(v)) {
          selected.delete(v);
          clearBtn(opt);
          opt.classList.add('btn-quiz-answer');
        } else {
          selected.add(v);
          clearBtn(opt);
          opt.classList.add('active', 'btn-quiz-answer');
        }

        setFeedback('');
        updateSubmitState();
        return;
      }

      // Prüfen-Button
      const sub = e.target.closest(`[${cfg.submitAttr}]`);
      if (sub && !done) {
        if (selected.size === 0) {
          setFeedback(`<div class="alert alert-warning mb-0">Bitte wähle mindestens <strong>eine</strong> Antwort aus.</div>`);
          return;
        }

        attemptsUsed++;
        setTries(Math.min(attemptsUsed + 1, maxAtt));

        // Korrekt?
        if (setsEqual(selected, correct)) {
          revealSolution();
          finish(true);
          return;
        }

        // Alle ausgewählt ODER Versuche aufgebraucht → sofort vollständige Lösung
        if (selected.size === totalOpts() || attemptsUsed >= maxAtt) {
          revealSolution();
          finish(false);
          return;
        }

        // Zweiter Versuch vorbereiten: richtig getroffene fixieren, falsche zurücksetzen
        const keepSelected = new Set([...selected].filter(v => correct.has(v)));

        opts().forEach(btn => {
          const v    = btn.getAttribute('data-value');
          const keep = keepSelected.has(v);
          clearBtn(btn);

          if (keep) {
            btn.classList.add('right', 'active');
            btn.disabled = true;
            btn.classList.add('disabled');
          } else {
            btn.classList.add('btn-quiz-answer');
            btn.disabled = false;
            btn.classList.remove('disabled');
          }
        });

        selected = keepSelected;
        updateSubmitState();
        setFeedback(`<div class="alert alert-danger mb-0"><strong>Noch nicht ganz richtig.</strong> Du hast noch einen weiteren Versuch.</div>`);
        return;
      }

      // Weiter-Button
      const nxt = e.target.closest(`[${cfg.nextAttr}]`);
      if (nxt) {
        if (typeof cfg.onNext === 'function') {
          cfg.onNext({ hide: () => bsModal.hide() });
        } else {
          bsModal.hide();
        }
      }
    });

    return { open: () => { reset(); bsModal.show(); }, hide: () => bsModal.hide(), modalEl };
  }

  window.PRICEFUCHS_createMultiSelectQuizEngine = createMultiSelectQuizEngine;



  /* =========================
     1) Navigation: Start -> Info
     ========================= */
  document.addEventListener('DOMContentLoaded', () => {
    const btnStart = document.getElementById('btnStart');
    const screenStart = document.getElementById('screen-start');
    const screenInfo = document.getElementById('screen-info');
    const stage = document.querySelector('main.stage');

    if (!btnStart || !screenStart || !screenInfo) return;

    btnStart.addEventListener('click', () => {
      screenStart.classList.add('d-none');
      screenInfo.classList.remove('d-none');

      if (stage) stage.classList.add('shop');

      if (typeof window.updateStageBackground === 'function') {
        window.updateStageBackground();
      }

      // Intro-Modal öffnen – kein manueller Backdrop-Eingriff nötig
      window.PRICEFUCHS_showAfter(null, 'task1IntroModal');
    });
  });

  /* =========================
     2) Task 1: Dynamic Pricing + Found Counter + Next Button + Quiz
     ========================= */
  const screenInfo = document.getElementById('screen-info');
  if (!screenInfo) return;

  // WICHTIG: data-task1-root sollte auf einem gemeinsamen Container liegen,
  // der Shop + Widgets + Taskbar enthält.
  const root = screenInfo.querySelector('[data-task1-root]') || screenInfo;

  const stage = document.querySelector('main.stage');

  // --- Konfiguration ---
  const products = [
    { name: 'AeroStep Classic', basePrice: 49.90 },
    { name: 'MetroRunner Pro', basePrice: 69.95 },
    { name: 'Nimbus Street',   basePrice: 120.00 },
  ];

  const weatherStates = [
    { key: 'sunny', label: '☀️ Sonnig',           priceMultiplier: 1.00 },
    { key: 'rain',  label: '🌧️ Stark regnerisch', priceMultiplier: 1.15 },
  ];

  const timeSlots = [
    { key: 'morning', label: '08:15', multiplier: 1.00 },
    { key: 'noon',    label: '12:30', multiplier: 1.08 },
    { key: 'evening', label: '18:45', multiplier: 1.18 },
    { key: 'late',    label: '22:10', multiplier: 1.25 },
  ];

  const dayMultipliers = {
    1: 1.00, // Mo
    2: 0.99, // Di
    3: 1.01, // Mi
    4: 1.00, // Do
    5: 1.02, // Fr
    6: 1.20, // Sa
    0: 1.25, // So
  };

  const timeClassMap = {
    morning: 'morgens',
    noon: 'mittags',
    evening: 'abends',
    late: 'nachts',
  };

  const currencyFormatter = new Intl.NumberFormat('de-DE', {
    style: 'currency',
    currency: 'EUR'
  });

  function formatPriceHTML(value) {
  return currencyFormatter
    .format(value)
    .replace('€', '<span class="euro">€</span>');
}

  const DEFAULT_WEATHER_INDEX = 0;
  const DEFAULT_TIME_INDEX = 0;
  const DEFAULT_DAY_OFFSET = 0;

  // --- State ---
  let weatherIndex = DEFAULT_WEATHER_INDEX;
  let timeIndex = DEFAULT_TIME_INDEX;
  const baseDate = new Date();
  let dayOffset = DEFAULT_DAY_OFFSET;

  let activeFactor = 'none'; // 'weather'|'time'|'date'|'none'
  const found = { weather: false, date: false, time: false };

  // --- Elements ---
  const weatherLabelEls = [...root.querySelectorAll('[data-task1-weather-label]')];
  const dateLabelEls    = [...root.querySelectorAll('[data-task1-date-label]')];
  const timeLabelEls    = [...root.querySelectorAll('[data-task1-time-label]')];
  const statusEl = root.querySelector('[data-task1-status]'); // optional

  const foundCountEl = root.querySelector('[data-task1-found-count]');
  const nextBtnEl = root.querySelector('[data-task1-next]');

  // Modals (bestehende)
  const introModalEl = document.getElementById('task1IntroModal');
  const emailModalEl = document.getElementById('task1EmailModal');
  const werbungModalEl = document.getElementById('task1Werbung');

  const introModal = introModalEl ? new bootstrap.Modal(introModalEl, { backdrop: 'static', keyboard: false }) : null;
  const emailModal = emailModalEl ? new bootstrap.Modal(emailModalEl) : null;
  const werbungModal = werbungModalEl ? new bootstrap.Modal(werbungModalEl) : null;

  // Quiz Modal (neu)
  const quizModalEl = document.getElementById('task1QuizModal');
  const quizModal = quizModalEl ? new bootstrap.Modal(quizModalEl, { backdrop: 'static', keyboard: false }) : null;

//   const quizForm = document.getElementById('task1QuizForm');
//   const quizSubmitBtn = document.getElementById('task1QuizSubmit');
//   const quizCloseBtn = document.getElementById('task1QuizClose');
//   const quizTryEl = document.getElementById('task1QuizTry');
//   const quizFeedbackEl = document.getElementById('task1QuizFeedback');

  // A11y: Fokus nach Intro-Modal schließen sinnvoll setzen
  if (introModalEl) {
    introModalEl.addEventListener('hidden.bs.modal', () => {
      const firstWidget = document.querySelector('#screen-info [data-task1-action]');
      if (firstWidget) firstWidget.focus();
    });
  }

  /* =========================
     Helpers
     ========================= */
  function getWeather() { return weatherStates[weatherIndex]; }
  function getTimeSlot() { return timeSlots[timeIndex]; }

  function getCurrentDate() {
    const d = new Date(baseDate);
    d.setDate(baseDate.getDate() + dayOffset);
    return d;
  }

  function getDayMultiplier(d) {
    return dayMultipliers[d.getDay()] ?? 1.00;
  }

  function resetWeather() { weatherIndex = DEFAULT_WEATHER_INDEX; }
  function resetTime()    { timeIndex = DEFAULT_TIME_INDEX; }
  function resetDate()    { dayOffset = DEFAULT_DAY_OFFSET; }

  function enforceSingleFactor(nextActive) {
    if (nextActive !== 'weather') resetWeather();
    if (nextActive !== 'time')    resetTime();
    if (nextActive !== 'date')    resetDate();
    activeFactor = nextActive;
  }

  function syncWeatherClass() {
    if (!stage) return;
    stage.classList.toggle('regen', getWeather().key === 'rain');
  }

  function syncTimeClass() {
    if (!stage) return;
    ['morgens', 'mittags', 'abends', 'nachts'].forEach(c => stage.classList.remove(c));
    const cls = timeClassMap[getTimeSlot().key];
    if (cls) stage.classList.add(cls);
  }

  function renderWeather() {
    const txt = getWeather().label;
    weatherLabelEls.forEach(el => { if (el) el.textContent = txt; });
  }

  function renderTime() {
    const txt = getTimeSlot().label;
    timeLabelEls.forEach(el => { if (el) el.textContent = txt; });
  }

  function renderDate() {
    const d = getCurrentDate();
    const txt = d.toLocaleDateString('de-DE', {
      weekday: 'short', day: '2-digit', month: '2-digit', year: 'numeric'
    });
    dateLabelEls.forEach(el => { if (el) el.textContent = txt; });
  }

  function updateFoundUI() {
    const count = (found.weather ? 1 : 0) + (found.date ? 1 : 0) + (found.time ? 1 : 0);
    if (foundCountEl) foundCountEl.textContent = String(count);
    if (nextBtnEl) nextBtnEl.classList.toggle('d-none', count < 3);
  }

  function recalcPrices() {
    const wMul = getWeather().priceMultiplier;
    const tMul = getTimeSlot().multiplier;
    const d = getCurrentDate();
    const dMul = getDayMultiplier(d);

    const finalMul = wMul * tMul * dMul;

    products.forEach((p, i) => {
      const price = p.basePrice * finalMul;
      const el = root.querySelector(`[data-task1-price="${i}"]`);
      if (el) el.innerHTML = formatPriceHTML(price);
    });

    if (statusEl) {
      const dayKey = d.getDay();
      const dayName = ['So','Mo','Di','Mi','Do','Fr','Sa'][dayKey];
      statusEl.textContent = `Aktiv: ${activeFactor} • Wetter: ${getWeather().key} • Zeit: ${getTimeSlot().key} • Tag: ${dayName}`;
    }
  }

  function refreshAll() {
    renderWeather();
    renderTime();
    renderDate();
    syncWeatherClass();
    syncTimeClass();
    recalcPrices();
    updateFoundUI();

    if (typeof window.updateStageBackground === 'function') {
      window.updateStageBackground();
    }
  }

  /* =========================
     Actions (Single-Factor)
     ========================= */
  function onWeatherClick() {
    found.weather = true;
    enforceSingleFactor('weather');
    weatherIndex = (weatherIndex + 1) % weatherStates.length;
    refreshAll();
  }

  function onTimeClick() {
    found.time = true;
    enforceSingleFactor('time');
    timeIndex = (timeIndex + 1) % timeSlots.length;
    refreshAll();
  }

  function onDateClick() {
    found.date = true;
    enforceSingleFactor('date');
    dayOffset = (dayOffset + 1) % 7;
    refreshAll();
  }

/* =========================
   Next: öffnet Quiz statt Screenwechsel
   ========================= */

// --- Quiz Engines (Task 1) ---
// Task 1 Quiz: wird über den "Weiter"-Button in der Taskbar geöffnet
const quizTask1 = createQuizEngine({
  ...QUIZ_BANK.task1,
  onNext: ({ hide }) => {
    // Zuerst Modal vollständig schließen lassen, dann Task 2 Intro öffnen.
    // KEIN manueller Backdrop-Eingriff – Bootstrap verwaltet das selbst.
    const quizEl = document.getElementById('task1QuizModal');

    const afterHide = () => {
      const screenInfoEl  = document.getElementById('screen-info');
      const screenTask2El = document.getElementById('screen-streichpreise');
      if (screenInfoEl)  screenInfoEl.classList.add('d-none');
      if (screenTask2El) screenTask2El.classList.remove('d-none');

      if (typeof window.updateStageBackground === 'function') {
        window.updateStageBackground();
      }

      window.PRICEFUCHS_showAfter(null, 'task2IntroModal');
    };

    if (quizEl && quizEl.classList.contains('show')) {
      quizEl.addEventListener('hidden.bs.modal', afterHide, { once: true });
      hide();
    } else {
      hide();
      afterHide();
    }
  }
});

// Task 2 Quiz wird im Task-2-Modul weiter unten vollständig konfiguriert.
// Hier KEINE zweite createQuizEngine-Instanz für task2QuizModal anlegen.




function goNext() {
  const count = (found.weather ? 1 : 0) + (found.date ? 1 : 0) + (found.time ? 1 : 0);
  if (count < 3) return;
  if (quizTask1) quizTask1.open();
}


  /* =========================
     Events (delegiert)
     ========================= */
  root.addEventListener('click', (e) => {
    // Next button in taskbar
    const nextBtn = e.target.closest('[data-task1-next]');
    if (nextBtn) return goNext();

    const btn = e.target.closest('[data-task1-action]');
    if (!btn) return;

    const action = btn.getAttribute('data-task1-action');

    if (action === 'weather') return onWeatherClick();
    if (action === 'time')    return onTimeClick();
    if (action === 'date')    return onDateClick();

    if (action === 'email') {
      enforceSingleFactor('none');
      refreshAll();
      if (emailModal) emailModal.show();
      return;
    }

    if (action === 'werbung') {
      enforceSingleFactor('none');
      refreshAll();
      if (werbungModal) werbungModal.show();
      return;
    }
  });

  // Init
  enforceSingleFactor('none');
  refreshAll();

  // Intro-Modal wird durch Navigation geöffnet
  window.showScreenInfoIntroModal = () => {
    if (introModal) introModal.show();
  };
})();
/* =========================
   Task 2: Produktklick -> Quiz + Datenübernahme für Screen 3 (Dringlichkeit)
   ========================= */
(() => {
  const screenTask2 = document.getElementById('screen-streichpreise');
  if (!screenTask2) return;

  // Globaler State für Auswahl (einfach + sauber)
  window.PRICEFUCHS_APP = window.PRICEFUCHS_APP || {};
  const APP = window.PRICEFUCHS_APP;

  // Info-Modal für den regulären Preis (Sneaker 1)
  const task2InfoEl = document.getElementById('task2InfoModal');
  const task2InfoModal = (task2InfoEl && window.bootstrap?.Modal)
    ? new bootstrap.Modal(task2InfoEl)
    : null;

function extractProductFromCard(card) {
  const idx = card.getAttribute('data-task2-product');

  const imgEl  = card.querySelector('img');
  const nameEl = card.querySelector('.card-body .fw-semibold');
  const descEl = card.querySelector('.card-body .text-muted.small:not(.mb-1)');

  const priceCurrentEl =
    card.querySelector(`[data-price-current="${idx}"]`) ||
    card.querySelector('.price-current');

  const priceOldEl =
    card.querySelector(`[data-price-old="${idx}"]`) ||
    card.querySelector('.price-old');

  return {
    productIndex: Number(idx),
    imgSrc: imgEl ? imgEl.getAttribute('src') : '',
    imgAlt: imgEl ? (imgEl.getAttribute('alt') || '') : '',
    name: nameEl ? nameEl.textContent.trim() : '',
    desc: descEl ? descEl.textContent.trim() : '',
    price: priceCurrentEl ? priceCurrentEl.textContent.trim() : '',
    oldPrice: priceOldEl ? priceOldEl.textContent.trim() : '' // <- NEU
  };
}


function renderDringlichkeitProduct(prod) {
  const screenTask3 = document.getElementById('screen-dringlichkeit');
  if (!screenTask3 || !prod) return;

  const img   = screenTask3.querySelector('[data-dr-prod-img]');
  const name  = screenTask3.querySelector('[data-dr-prod-name]');
  const desc  = screenTask3.querySelector('[data-dr-prod-desc]');
  const price = screenTask3.querySelector('[data-dr-prod-price]');
  const oldP  = screenTask3.querySelector('[data-dr-prod-old]');

  if (img) {
    img.src = prod.imgSrc || '';
    img.alt = prod.imgAlt || prod.name || 'Produktbild';
  }
  if (name)  name.textContent  = prod.name || '—';
  if (desc)  desc.textContent  = prod.desc || '—';
  if (price) price.textContent = prod.price || '—';

  // Streichpreis nur anzeigen, wenn vorhanden
  if (oldP) {
    const hasOld = !!(prod.oldPrice && prod.oldPrice.trim());
    oldP.textContent = hasOld ? prod.oldPrice : '—';
    oldP.classList.toggle('d-none', !hasOld);
  }
}


  // Quiz Engine Task 2 (Referenzpreise) – nutzt deine zentrale Engine
  const quizTask2 = window.PRICEFUCHS_createQuizEngine
    ? window.PRICEFUCHS_createQuizEngine({
        ...(window.PRICEFUCHS_QUIZ_BANK ? window.PRICEFUCHS_QUIZ_BANK.task2 : {}),
        contextText: ({ productIndex }) => {
          if (productIndex === 0) return 'Du hast dich für den Sneaker zum regulären Preis entschieden.';
          return 'Du hast dich für einen reduzierten Sneaker entschieden.';
        },
        metaProvider: ({ productIndex }) => ({ productIndex }),
        onNext: ({ hide }) => {
          const quizEl = document.getElementById('task2QuizModal');

          const afterHide = () => {
            const screenTask2El = document.getElementById('screen-streichpreise');
            const screenTask3El = document.getElementById('screen-dringlichkeit');

            if (screenTask2El) screenTask2El.classList.add('d-none');
            if (screenTask3El) screenTask3El.classList.remove('d-none');

            renderDringlichkeitProduct(APP.selectedProduct);

            if (typeof window.updateStageBackground === 'function') {
              window.updateStageBackground();
            }

            window.PRICEFUCHS_showAfter(null, 'task3IntroModal');
          };

          if (quizEl && quizEl.classList.contains('show')) {
            quizEl.addEventListener('hidden.bs.modal', afterHide, { once: true });
            hide();
          } else {
            hide();
            afterHide();
          }
        },
        onHidden: () => {
          const el = document.querySelector('#screen-streichpreise [data-task2-product]');
          if (el) el.focus?.();
        }
      })
    : null;

  // Klick auf Produkt -> Auswahl speichern + Quiz öffnen
  screenTask2.addEventListener('click', (e) => {
    const card = e.target.closest('[data-task2-product]');
    if (!card) return;

    const productData = extractProductFromCard(card);

    // Sneaker 1 (regulärer Preis): kein Quiz, sondern Infofenster
    if (productData.productIndex === 0) {
      if (task2InfoModal) task2InfoModal.show();
      return;
    }

    if (!quizTask2) return;

    APP.selectedProduct = productData;
    quizTask2.open({ productIndex: productData.productIndex });
  });
})();
/* =========================
   Task 3 (Dringlichkeit + Social Proof) – NEU
   - 3 Phänomene finden:
     1) Social Proof (watchers)
     2) Dringlichkeit: Angebot endet in (offer)
     3) Dringlichkeit: Nur noch X verfügbar (stock)
   - 1 gemeinsames Multiple-Choice Quiz (2 richtige Antworten)
   ========================= */
(() => {
  const screen = document.getElementById('screen-dringlichkeit');
  if (!screen) return;

  const found = { watchers: false, offer: false, stock: false };

  const els = {
    watchersNum: screen.querySelector('[data-dr-watchers]'),
    timer:       screen.querySelector('[data-offer-timer]'),
    stockNum:    screen.querySelector('[data-dr-stock]'),

    foundCount:  screen.querySelector('[data-task3-found-count]'),
    openQuizBtn: screen.querySelector('[data-task3-open-quiz]')
  };

  const infoModalEl = document.getElementById('task3InfoModal');
  const infoModal = (infoModalEl && window.bootstrap?.Modal) ? new bootstrap.Modal(infoModalEl) : null;

  // Quiz-Modal wird von der MultiSelect-Engine intern verwaltet

  function goToCheckoutScreen(fromModalEl) {
    const switchScreens = () => {
      const s3 = document.getElementById('screen-dringlichkeit');
      const s4 = document.getElementById('screen-checkout');
      if (s3) s3.classList.add('d-none');
      if (s4) s4.classList.remove('d-none');

      if (typeof window.updateStageBackground === 'function') {
        window.updateStageBackground();
      }

      window.PRICEFUCHS_showAfter(null, 'taskCheckoutIntroModal');
    };

    if (fromModalEl && fromModalEl.classList.contains('show')) {
      fromModalEl.addEventListener('hidden.bs.modal', switchScreens, { once: true });
    } else {
      switchScreens();
    }
  }

  const countFound = () => (found.watchers ? 1 : 0) + (found.offer ? 1 : 0) + (found.stock ? 1 : 0);

  function updateProgressUI() {
    const c = countFound();
    if (els.foundCount) els.foundCount.textContent = String(c);
    if (els.openQuizBtn) els.openQuizBtn.classList.toggle('d-none', c < 3);
  }

  function markFound(key) {
    if (found[key]) return;
    found[key] = true;
    updateProgressUI();
  }

  // --- Watchers Auto-Change (nach Klick aktiv) ---
  let watchersActive = false;
  let watchersTimer = null;

  function startWatchersAuto() {
    if (!els.watchersNum) return;
    if (watchersActive) return;

    watchersActive = true;
    markFound('watchers');

    let value = parseInt(els.watchersNum.textContent, 10);
    if (!Number.isFinite(value)) value = 35;

    watchersTimer = setInterval(() => {
      const delta = Math.floor(Math.random() * 7) - 3; // -3..+3
      value = Math.max(10, Math.min(99, value + delta));
      els.watchersNum.textContent = String(value);
    }, 2500);
  }

  // --- Offer Countdown (startet erst nach Klick) ---
  let offerActive = false;
  let offerInterval = null;
  let offerRemaining = 5 * 60; // 5 Minuten

  function fmt(sec) {
    const m = Math.floor(sec / 60);
    const s = sec % 60;
    return `${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`;
  }

  function renderOfferTimer() {
    if (!els.timer) return;
    els.timer.textContent = fmt(offerRemaining);
  }

  function startOfferCountdown() {
    if (!els.timer) return;
    if (offerActive) return;

    offerActive = true;
    markFound('offer');

    renderOfferTimer();

    offerInterval = setInterval(() => {
      offerRemaining -= 1;
      if (offerRemaining <= 0) {
        offerRemaining = 0;
        renderOfferTimer();
        clearInterval(offerInterval);
        offerInterval = null;
        return;
      }
      renderOfferTimer();
    }, 1000);
  }

  // --- Stock Click (3 -> 2) ---
  function reduceStockOnce() {
    if (!els.stockNum) return;

    markFound('stock');

    let value = parseInt(els.stockNum.textContent, 10);
    if (!Number.isFinite(value)) value = 3;
    if (value > 2) value = 2;
    els.stockNum.textContent = String(value);
  }

  /* =========================
     Task 3 Quiz – nutzt konsolidierte MultiSelect-Engine
     Richtige Antworten: social + scarcity
     ========================= */
  const task3Quiz = window.PRICEFUCHS_createMultiSelectQuizEngine
    ? window.PRICEFUCHS_createMultiSelectQuizEngine({
        modalId:       'task3QuizModal',
        optionAttr:    'data-task3-option',
        submitAttr:    'data-task3-submit',
        nextAttr:      'data-task3-next',
        feedbackAttr:  'data-task3-feedback',
        triesAttr:     'data-task3-tries',
        correctValues: new Set(['social', 'scarcity']),
        maxAttempts:   2,
        onNext: ({ hide }) => {
          const quizEl = document.getElementById('task3QuizModal');
          hide();
          goToCheckoutScreen(quizEl);
        }
      })
    : null;

  function openQuiz() {
    if (task3Quiz) task3Quiz.open();
  }

  // --- Click delegation im Screen ---
  screen.addEventListener('click', (e) => {
    // Quiz öffnen
    const openBtn = e.target.closest('[data-task3-open-quiz]');
    if (openBtn) {
      e.preventDefault();
      openQuiz();
      return;
    }

    const highlightTarget = e.target.closest('[data-dr-highlight]');
    if (highlightTarget) highlightTarget.classList.add('dr-highlight');

    const actionEl = e.target.closest('[data-dr-action]');
    if (!actionEl) return;

    const action = actionEl.getAttribute('data-dr-action');

    if (action === 'watchers') return startWatchersAuto();
    if (action === 'offer') return startOfferCountdown();
    if (action === 'stock') return reduceStockOnce();
    if (action === 'info') return infoModal && infoModal.show();
  });

  // init
  renderOfferTimer();
  updateProgressUI();
})();

/* =========================
   Flow: Task 3 -> Checkout (Task 4)
   Voraussetzung:
   - screen-dringlichkeit existiert
   - screen-checkout existiert
   - Task3 hat zwei Quizzes (Social + Urgency)
   - Checkout hat Intro-Modal #taskCheckoutIntroModal
   - Checkout Quiz Modal #taskCheckoutQuizModal
   ========================= */
(() => {
  // --- zentraler App-State ---
  window.PRICEFUCHS_APP = window.PRICEFUCHS_APP || {};
  const APP = window.PRICEFUCHS_APP;

  // Kein manuelles backdropSafety/showIntroModal mehr –
  // window.PRICEFUCHS_showAfter übernimmt das sauber.

  function goToCheckoutScreen() {
    const s3 = document.getElementById('screen-dringlichkeit');
    const s4 = document.getElementById('screen-checkout');

    if (s3) s3.classList.add('d-none');
    if (s4) s4.classList.remove('d-none');

    if (typeof window.updateStageBackground === 'function') {
      window.updateStageBackground();
    }

    // Intro-Modal erst zeigen, wenn kein anderes Modal mehr offen ist
    window.PRICEFUCHS_showAfter(null, 'taskCheckoutIntroModal');
  }

  /* =========================
     TASK 4 (Checkout): Finder + Quiz-Öffnung
     Gesucht:
       - Confirm Shaming (Button-Block)
       - Pre-Selection (vorausgewählte Absicherung)
     ========================= */
  const checkoutScreen = document.getElementById('screen-checkout');
  if (!checkoutScreen) return;

  const found = { confirm: false, preselect: false };

  const ui = {
    count: checkoutScreen.querySelector('[data-task4-found-count]'),
    openQuizBtn: checkoutScreen.querySelector('[data-task4-open-quiz]')
  };

  // Selektoren im Checkout (passen zu deinem Mockup)
  // Confirm-Shaming: der Block mit beiden Rabatt-Buttons
  const confirmBlock =
    checkoutScreen.querySelector('[data-task4-confirm]') ||
    checkoutScreen.querySelector('.checkout-confirm') ||
    checkoutScreen.querySelector('#task4ConfirmBlock') ||
    checkoutScreen.querySelector('.d-grid.gap-2'); // fallback: Button-Stack im Mockup

  // Pre-Selection: vorausgewählte Checkbox "Kauf absichern"
  const preselectInput =
    checkoutScreen.querySelector('#insuranceCheck') ||
    checkoutScreen.querySelector('[data-task4-preselect-input]');

  // Pre-Selection "Bist du sicher?" Modal (wenn Schutz entfernt werden soll)
  const insuranceConfirmEl = document.getElementById('task4InsuranceConfirmModal');
  const insuranceConfirmModal = (insuranceConfirmEl && window.bootstrap?.Modal)
    ? new bootstrap.Modal(insuranceConfirmEl)
    : null;

  // Wenn User den Haken entfernen will -> erst nachfragen
  function interceptInsuranceUncheck(ev) {
    if (!preselectInput) return;
    // Nur abfangen, wenn aktuell angehakt und der Klick zum Entfernen führen würde
    if (!preselectInput.checked) {
      ev.preventDefault();
      if (insuranceConfirmModal) insuranceConfirmModal.show();
    }
  }

  const insuranceLabel = checkoutScreen.querySelector('.insuranceCheck');
  if (preselectInput) {
    preselectInput.addEventListener('click', interceptInsuranceUncheck);
  }
  if (insuranceLabel) {
    insuranceLabel.addEventListener('click', interceptInsuranceUncheck);
  }

  // Modal Buttons
  if (insuranceConfirmEl) {
    insuranceConfirmEl.addEventListener('click', (e) => {
      const keep = e.target.closest('[data-task4-keep-insurance]');
      const drop = e.target.closest('[data-task4-drop-insurance]');

      if (keep) {
        if (preselectInput) preselectInput.checked = true;
        insuranceConfirmModal?.hide();
        return;
      }

      if (drop) {
        if (preselectInput) preselectInput.checked = false;
        insuranceConfirmModal?.hide();
        return;
      }
    });
  }

  function countFound() {
    return (found.confirm ? 1 : 0) + (found.preselect ? 1 : 0);
  }

  function updateCheckoutUI() {
    const c = countFound();
    if (ui.count) ui.count.textContent = String(c);
    if (ui.openQuizBtn) ui.openQuizBtn.classList.toggle('d-none', c < 2);
  }

  function markFound(key) {
    if (found[key]) return;
    found[key] = true;
    updateCheckoutUI();
  }

  // Highlight (nur echte Phänomene)
  function highlight(el) {
    if (!el) return;
    el.classList.add('dr-highlight'); // du hast die Klasse schon eingeführt (rot outline)
  }

  // Klicks im Checkout screen

  checkoutScreen.addEventListener('click', (e) => {
  // 1) Weiter-Button -> Quiz öffnen
  const openQuiz = e.target.closest('[data-task4-open-quiz]');
  if (openQuiz) {
    e.preventDefault();
    openCheckoutQuiz();
    return;
  }

  // 2) Confirm-Shaming: Klick auf einen der beiden Rabatt-Buttons reicht
  // (Wir nehmen hier absichtlich nur die beiden Buttons, nicht irgendein d-grid)
  const confirmYes = e.target.closest('.btn.btn-primary');
  const confirmNo  = e.target.closest('.btn.btn-outline-secondary');

  // Falls deine Buttons im Checkout eindeutig sind, reicht das.
  // Falls du mehrere Outline-Buttons im Screen hast: gib den beiden Buttons IDs und prüfe die IDs.
  if (confirmYes || confirmNo) {
    // Nur wenn der Klick wirklich im Checkout-Confirm-Block passiert:
    const confirmWrapper =
      checkoutScreen.querySelector('[data-task4-confirm]') ||
      checkoutScreen.querySelector('#task4ConfirmBlock') ||
      checkoutScreen.querySelector('.d-grid.gap-2');

    if (confirmWrapper && confirmWrapper.contains(e.target)) {
      markFound('confirm');
      highlight(confirmWrapper);
    }
  }

  // 3) Pre-Selection: Checkbox/Label "Kauf absichern"
  if (preselectInput && (e.target === preselectInput || e.target.closest('label[for="insuranceCheck"]'))) {
    markFound('preselect');
    highlight(preselectInput.closest('.form-check') || preselectInput);
  }
});


  // initial UI
  updateCheckoutUI();

  /* =========================
     TASK 4 QUIZ – nutzt konsolidierte MultiSelect-Engine
     Richtige Antworten: preselect + confirm
     ========================= */
  const task4Quiz = window.PRICEFUCHS_createMultiSelectQuizEngine
    ? window.PRICEFUCHS_createMultiSelectQuizEngine({
        modalId:       'taskCheckoutQuizModal',
        optionAttr:    'data-task4-option',
        submitAttr:    'data-task4-submit',
        nextAttr:      'data-task4-next',
        feedbackAttr:  'data-task4-feedback',
        triesAttr:     'data-task4-tries',
        correctValues: new Set(['preselect', 'confirm']),
        maxAttempts:   2,
        onNext: ({ hide }) => {
          const quizEl = document.getElementById('taskCheckoutQuizModal');

          const afterHide = () => {
            const screenCheckoutEl  = document.getElementById('screen-checkout');
            const screenChecklistEl = document.getElementById('screen-checklist');

            if (screenCheckoutEl)  screenCheckoutEl.classList.add('d-none');
            if (screenChecklistEl) screenChecklistEl.classList.remove('d-none');

            // Shop-Background ausblenden
            const stageEl     = document.querySelector('main.stage');
            const stageEprice = document.querySelector('.price-bg');
            if (stageEl)     stageEl.classList.remove('shop');
            if (stageEprice) stageEprice.classList.add('d-none');

            if (typeof window.updateStageBackground === 'function') {
              window.updateStageBackground();
            }

            window.PRICEFUCHS_showAfter(null, 'taskChecklistIntroModal');
          };

          if (quizEl && quizEl.classList.contains('show')) {
            quizEl.addEventListener('hidden.bs.modal', afterHide, { once: true });
            hide();
          } else {
            hide();
            afterHide();
          }
        }
      })
    : null;

  function openCheckoutQuiz() {
    if (task4Quiz) task4Quiz.open();
  }

})();

/* =========================
   Screen Checklist: Drag & Drop Top-5
   ========================= */
(() => {
  const screen = document.getElementById('screen-checklist');
  if (!screen) return;
const finishBtn = screen.querySelector('[data-cl-finish]');
  const pool = screen.querySelector('[data-cl-pool]');
  const slotsWrap = screen.querySelector('[data-cl-slots]');
  const countEl = screen.querySelector('[data-cl-count]');
  const nextBtn = screen.querySelector('[data-cl-next]');

  if (!pool || !slotsWrap || !countEl || !nextBtn) return;

  const slots = Array.from(slotsWrap.querySelectorAll('[data-cl-slot]'));
  let draggedEl = null;

  // Central storage
  window.PRICEFUCHS_APP = window.PRICEFUCHS_APP || {};
  window.PRICEFUCHS_APP.results = window.PRICEFUCHS_APP.results || {};
  window.PRICEFUCHS_APP.results.checklist = window.PRICEFUCHS_APP.results.checklist || [];

  function getFilledCount() {
    return slots.filter(s => s.classList.contains('filled')).length;
  }

function updateUI() {
  const c = getFilledCount();
  countEl.textContent = String(c);
  nextBtn.classList.toggle('d-none', c < 5);

  // NEU: Abschluss-Button unter Vorschlägen
  if (finishBtn) finishBtn.classList.toggle('d-none', c < 5);

  // Save selection (order = slot order)
  const chosen = slots.map(s => {
    const item = s.querySelector('.cl-item');
    if (!item) return null;
    return {
      id: item.getAttribute('data-cl-item'),
      text: item.textContent.trim()
    };
  }).filter(Boolean);

  window.PRICEFUCHS_APP.results.checklist = chosen;
}

  // Helper: zum Abschluss-Screen navigieren
  function proceedToFinalScreen() {
    const screenChecklistEl = document.getElementById('screen-checklist');
    const screenFinalEl = document.getElementById('screen-abschluss');

    if (screenChecklistEl) screenChecklistEl.classList.add('d-none');
    if (screenFinalEl) screenFinalEl.classList.remove('d-none');

    const priceBgEl = document.querySelector('.price-bg');
    if (priceBgEl) priceBgEl.classList.remove('d-none');

    if (typeof window.updateStageBackground === 'function') {
      window.updateStageBackground();
    }
  }
  window._pfProceedToFinalScreen = proceedToFinalScreen;

if (finishBtn) {
  finishBtn.addEventListener('click', () => {
    if (getFilledCount() < 5) return;

    // Prüfen ob Checkliste bereits gespeichert wurde
    const alreadySaved = window.PRICEFUCHS_APP && window.PRICEFUCHS_APP.checklistSaved;

    if (!alreadySaved) {
      // Hinweis-Modal anzeigen
      const unsavedModalEl = document.getElementById('modalChecklistUnsaved');
      if (unsavedModalEl) {
        bootstrap.Modal.getOrCreateInstance(unsavedModalEl).show();
      } else {
        // Fallback falls Modal nicht gefunden
        proceedToFinalScreen();
      }
      return;
    }

    proceedToFinalScreen();
  });
}

// Buttons im "nicht gespeichert"-Modal verdrahten
document.addEventListener('DOMContentLoaded', () => {
  const unsavedModalEl = document.getElementById('modalChecklistUnsaved');
  if (!unsavedModalEl) return;

  // "Checkliste speichern"-Button im Modal
  const btnModalSave = document.getElementById('btnModalSaveChecklist');
  if (btnModalSave) {
    btnModalSave.addEventListener('click', () => {
      saveChecklistAsImage();
      bootstrap.Modal.getOrCreateInstance(unsavedModalEl).hide();
      unsavedModalEl.addEventListener('hidden.bs.modal', () => {
        if (typeof window._pfProceedToFinalScreen === 'function') {
          window._pfProceedToFinalScreen();
        }
      }, { once: true });
    });
  }

  // "Trotzdem fortfahren"-Button im Modal
  const btnModalProceed = document.getElementById('btnModalProceedAnyway');
  if (btnModalProceed) {
    btnModalProceed.addEventListener('click', () => {
      bootstrap.Modal.getOrCreateInstance(unsavedModalEl).hide();
      unsavedModalEl.addEventListener('hidden.bs.modal', () => {
        if (typeof window._pfProceedToFinalScreen === 'function') {
          window._pfProceedToFinalScreen();
        }
      }, { once: true });
    });
  }
});


  function makeItemDraggable(el) {
    el.addEventListener('dragstart', (e) => {
      draggedEl = el;
      el.classList.add('is-dragging');
      e.dataTransfer.effectAllowed = 'move';
      e.dataTransfer.setData('text/plain', el.getAttribute('data-cl-item') || 'item');
    });

    el.addEventListener('dragend', () => {
      el.classList.remove('is-dragging');
      draggedEl = null;
      pool.classList.remove('is-over');
      slots.forEach(s => s.classList.remove('is-over'));
    });
  }

  // init items
  pool.querySelectorAll('.cl-item[draggable="true"]').forEach(makeItemDraggable);

  /* =========================
     Touch/Pointer Drag & Drop (Mobile)
     HTML5-DnD works poorly on touch. We implement a lightweight
     pointer-based drag with a ghost element.
     ========================= */
  const supportsPointer = 'PointerEvent' in window;

  function getDropTarget(clientX, clientY) {
    const el = document.elementFromPoint(clientX, clientY);
    if (!el) return { type: null, el: null };
    const slot = el.closest('[data-cl-slot]');
    if (slot) return { type: 'slot', el: slot };
    const inPool = el.closest('[data-cl-pool]');
    if (inPool) return { type: 'pool', el: inPool };
    return { type: null, el: null };
  }

  function clearOverStates() {
    pool.classList.remove('is-over');
    slots.forEach(s => s.classList.remove('is-over'));
  }

  function placeIntoPool(item) {
    pool.appendChild(item);
    // recompute filled states
    slots.forEach(s => {
      const hasItem = !!s.querySelector('.cl-item');
      s.classList.toggle('filled', hasItem);
      const ph = s.querySelector('.cl-slot-drop');
      if (ph) ph.classList.toggle('d-none', hasItem);
    });
    updateUI();
  }

  function placeIntoSlot(item, slot) {
    const already = slot.querySelector('.cl-item');
    if (already && already !== item) return false; // don't overwrite

    // clear old slot if moving from another slot
    slots.forEach(s => {
      if (s !== slot && s.contains(item)) {
        s.classList.remove('filled');
        const ph = s.querySelector('.cl-slot-drop');
        if (ph) ph.classList.remove('d-none');
      }
    });

    const placeholder = slot.querySelector('.cl-slot-drop');
    if (placeholder) placeholder.classList.add('d-none');

    slot.appendChild(item);
    slot.classList.add('filled');
    updateUI();
    return true;
  }

  function enablePointerDnD(item) {
    // Avoid double-binding
    if (item.__pfPointerBound) return;
    item.__pfPointerBound = true;

    const start = (ev) => {
      // Only touch/pen should use this path. Mouse keeps native HTML5 DnD.
      const pt = ev.pointerType || 'mouse';
      if (pt === 'mouse') return;

      ev.preventDefault();

      const originParent = item.parentElement;
      const originNext = item.nextElementSibling;

      item.classList.add('is-dragging');

      const rect = item.getBoundingClientRect();

      // Ghost
      const ghost = item.cloneNode(true);
      ghost.removeAttribute('draggable');
      ghost.style.position = 'fixed';
      ghost.style.left = rect.left + 'px';
      ghost.style.top = rect.top + 'px';
      ghost.style.width = rect.width + 'px';
      ghost.style.zIndex = '9999';
      ghost.style.pointerEvents = 'none';
      ghost.style.opacity = '.92';
      ghost.style.transform = 'translate3d(0,0,0)';
      document.body.appendChild(ghost);

      // Hide original while dragging (keeps layout stable)
      item.style.visibility = 'hidden';

      let lastTarget = { type: null, el: null };

      const move = (e) => {
        e.preventDefault();

        const x = e.clientX;
        const y = e.clientY;

        ghost.style.left = (x - rect.width / 2) + 'px';
        ghost.style.top = (y - rect.height / 2) + 'px';

        const t = getDropTarget(x, y);

        if (t.type !== lastTarget.type || t.el !== lastTarget.el) {
          clearOverStates();
          if (t.type === 'pool') pool.classList.add('is-over');
          if (t.type === 'slot') t.el.classList.add('is-over');
          lastTarget = t;
        }
      };

      const end = (e) => {
        e.preventDefault();

        clearOverStates();
        ghost.remove();

        item.style.visibility = '';
        item.classList.remove('is-dragging');

        // Determine final target at end position
        const t = getDropTarget(e.clientX, e.clientY);

        let dropped = false;
        if (t.type === 'slot') dropped = placeIntoSlot(item, t.el);
        if (t.type === 'pool') { placeIntoPool(item); dropped = true; }

        if (!dropped) {
          // restore to origin
          if (originNext && originNext.parentElement === originParent) {
            originParent.insertBefore(item, originNext);
          } else {
            originParent.appendChild(item);
          }
          // recompute slot UI (in case origin was a slot)
          slots.forEach(s => {
            const hasItem = !!s.querySelector('.cl-item');
            s.classList.toggle('filled', hasItem);
            const ph = s.querySelector('.cl-slot-drop');
            if (ph) ph.classList.toggle('d-none', hasItem);
          });
          updateUI();
        }

        window.removeEventListener('pointermove', move, { passive: false });
        window.removeEventListener('pointerup', end, { passive: false });
        window.removeEventListener('pointercancel', end, { passive: false });
      };

      window.addEventListener('pointermove', move, { passive: false });
      window.addEventListener('pointerup', end, { passive: false });
      window.addEventListener('pointercancel', end, { passive: false });
    };

    item.addEventListener('pointerdown', start, { passive: false });
  }

  // Bind pointer DnD to all items (including future moves between pool/slots)
  // We bind once per element; listeners travel with the element when moved.
  screen.querySelectorAll('.cl-item').forEach(enablePointerDnD);


  // Allow dropping back into pool (remove from slot)
  pool.addEventListener('dragover', (e) => {
    e.preventDefault();
    pool.classList.add('is-over');
    e.dataTransfer.dropEffect = 'move';
  });

  pool.addEventListener('dragleave', () => pool.classList.remove('is-over'));

  pool.addEventListener('drop', (e) => {
    e.preventDefault();
    pool.classList.remove('is-over');
    if (!draggedEl) return;

    // If item is currently inside a slot, return it to pool
    pool.appendChild(draggedEl);

    // Clear the slot it came from
    slots.forEach(s => {
      if (s.contains(draggedEl)) return;
    });

    // Ensure any slot that had no item is unfilled (we re-check)
    slots.forEach(s => {
      const hasItem = !!s.querySelector('.cl-item');
      s.classList.toggle('filled', hasItem);
      if (!hasItem) s.querySelector('.cl-slot-drop')?.classList.remove('d-none');
    });

    updateUI();
  });

  // Slots drop logic
  slots.forEach((slot) => {
    slot.addEventListener('dragover', (e) => {
      e.preventDefault();
      slot.classList.add('is-over');
      e.dataTransfer.dropEffect = 'move';
    });

    slot.addEventListener('dragleave', () => slot.classList.remove('is-over'));

    slot.addEventListener('drop', (e) => {
      e.preventDefault();
      slot.classList.remove('is-over');
      if (!draggedEl) return;

      // Max 5 enforced by having exactly 5 slots; but prevent overwriting unless you want replacement:
      const already = slot.querySelector('.cl-item');
      if (already && already !== draggedEl) {
        // If slot already filled, do nothing (or swap — kann ich dir auch bauen)
        return;
      }

      // If dragged from another slot, clear that old slot
      slots.forEach(s => {
        if (s !== slot && s.contains(draggedEl)) {
          s.classList.remove('filled');
          const ph = s.querySelector('.cl-slot-drop');
          if (ph) ph.classList.remove('d-none');
        }
      });

      // Place into slot (after label)
      const placeholder = slot.querySelector('.cl-slot-drop');
      if (placeholder) placeholder.classList.add('d-none');

      slot.appendChild(draggedEl);
      slot.classList.add('filled');

      updateUI();
    });
  });

  // Next button (you decide what’s next)
  nextBtn.addEventListener('click', () => {
    // Example: event to proceed
    screen.dispatchEvent(new CustomEvent('pricefuchs:checklist:complete', { bubbles: true }));
  });

  // Intro modal helper (optional)
  window.showChecklistIntroModal = () => {
    window.PRICEFUCHS_showAfter(null, 'taskChecklistIntroModal');
  };

  updateUI();
})();

/* =========================
   Stage Background Crossfade (wiederhergestellt)
   Voraussetzungen:
   - HTML enthält in <main class="stage">:
     <div class="stage-bg" aria-hidden="true">
       <div class="bg-layer bg-a"></div>
       <div class="bg-layer bg-b"></div>
     </div>
   - CSS: stage-bg/layer + opacity nur bei .shop (siehe unten)
   ========================= */
(() => {
  const stage = document.querySelector('main.stage');
  if (!stage) return;

  const layerA = stage.querySelector('.bg-a');
  const layerB = stage.querySelector('.bg-b');
  if (!layerA || !layerB) {
    // Wenn du das HTML noch nicht ergänzt hast, passiert hier nichts.
    return;
  }

  let active = layerA;
  let inactive = layerB;

  // Deine bisherige Bildlogik 1:1
  const BG = {
    shop:    'files/bg0.png',
    regen:   'files/bg4.png',
    morgens: 'files/bg0.png',
    mittags: 'files/bg1.png',
    abends:  'files/bg2.png',
    nachts:  'files/bg3.png',
  };

  const cache = new Set();

  function preload(url) {
    if (!url || cache.has(url)) return Promise.resolve();
    return new Promise((resolve) => {
      const img = new Image();
      img.onload = () => { cache.add(url); resolve(); };
      img.onerror = () => resolve(); // nicht blockieren
      img.src = url;
    });
  }

  function pickBgUrl() {
    // Hintergrund nur im Shop-Modus
    if (!stage.classList.contains('shop')) return null;

    // Regen überschreibt alles
    if (stage.classList.contains('regen')) return BG.regen;

    // Tageszeit
    if (stage.classList.contains('nachts'))  return BG.nachts;
    if (stage.classList.contains('abends'))  return BG.abends;
    if (stage.classList.contains('mittags')) return BG.mittags;
    if (stage.classList.contains('morgens')) return BG.morgens;

    // Default im Shop
    return BG.shop;
  }

  async function setStageBackground() {
    const url = pickBgUrl();

    // Wenn kein Shop: Layer ausblenden/leer
    if (!url) {
      active.classList.remove('is-active');
      inactive.classList.remove('is-active');
      active.style.backgroundImage = '';
      inactive.style.backgroundImage = '';
      return;
    }

    await preload(url);

    inactive.style.backgroundImage = `url("${url}")`;
    inactive.classList.add('is-active');
    active.classList.remove('is-active');

    [active, inactive] = [inactive, active];
  }

  // Initial setzen (falls du direkt im Shop startest oder bei erstem Wechsel)
  (async () => {
    const url = pickBgUrl();
    if (!url) return;
    await preload(url);
    active.style.backgroundImage = `url("${url}")`;
    active.classList.add('is-active');
  })();

  // global verfügbar, damit dein bestehender Code weiter funktioniert
  window.updateStageBackground = setStageBackground;

  // Preload, damit beim ersten Wechsel kein „leerer“ Moment entsteht
  preload(BG.shop);
  preload(BG.regen);
  preload(BG.morgens);
  preload(BG.mittags);
  preload(BG.abends);
  preload(BG.nachts);
})();


function saveChecklistAsImage() {
  const el = document.querySelector('[data-cl-clipboard]');
  if (!el || typeof html2canvas === 'undefined') return;

  html2canvas(el, { scale: 2 }).then(canvas => {
    const link = document.createElement('a');
    link.download = 'checkliste.png';
    link.href = canvas.toDataURL('image/png');
    link.click();

    // Flag: Checkliste wurde gespeichert
    window.PRICEFUCHS_APP = window.PRICEFUCHS_APP || {};
    window.PRICEFUCHS_APP.checklistSaved = true;
  });
}

// Button verwenden
document.addEventListener('click', (e) => {
  const btn = e.target.closest('[data-cl-next]');
  if (!btn) return;

  saveChecklistAsImage();
});