<style>

  #fritz-widget-container {

    position: fixed;

    bottom: 20px;

    right: 20px;

    z-index: 999999;

    font-family: ‚Lato‘, Arial, sans-serif;

  }

 

  #fritz-toggle-btn {

    width: 64px;

    height: 64px;

    border-radius: 50%;

    background: #ff0000;

    border: none;

    box-shadow: 0 4px 12px rgba(0,0,0,0.25);

    cursor: pointer;

    display: flex;

    align-items: center;

    justify-content: center;

    padding: 0;

    transition: transform 0.2s ease;

  }

  #fritz-toggle-btn:hover { transform: scale(1.06); }

  #fritz-toggle-btn img {

    width: 44px;

    height: 44px;

    border-radius: 50%;

  }

 

  #fritz-chat-window {

    display: none;

    flex-direction: column;

    position: absolute;

    bottom: 80px;

    right: 0;

    width: 360px;

    max-width: 90vw;

    height: 520px;

    max-height: 75vh;

    background: #ffffff;

    border-radius: 12px;

    box-shadow: 0 8px 30px rgba(0,0,0,0.25);

    overflow: hidden;

  }

  #fritz-chat-window.open { display: flex; }

 

  #fritz-header {

    background: #ff0000;

    color: #ffffff;

    padding: 14px 16px;

    display: flex;

    align-items: center;

    gap: 10px;

  }

  #fritz-header img {

    width: 36px;

    height: 36px;

    border-radius: 50%;

    background: #ffffff;

  }

  #fritz-header-text { flex: 1; }

  #fritz-header-name { font-weight: 700; font-size: 15px; line-height: 1.2; }

  #fritz-header-sub { font-size: 11px; opacity: 0.9; }

  #fritz-close-btn {

    background: none;

    border: none;

    color: #ffffff;

    font-size: 20px;

    cursor: pointer;

    line-height: 1;

    padding: 4px;

  }

 

  #fritz-messages {

    flex: 1;

    overflow-y: auto;

    padding: 14px;

    background: #f7f7f7;

    display: flex;

    flex-direction: column;

    gap: 10px;

  }

 

  .fritz-msg {

    max-width: 80%;

    padding: 9px 13px;

    border-radius: 14px;

    font-size: 14px;

    line-height: 1.4;

    word-wrap: break-word;

  }

  .fritz-msg.bot {

    background: #ffffff;

    color: #565656;

    align-self: flex-start;

    border: 1px solid #e2e2e2;

    border-bottom-left-radius: 4px;

  }

  .fritz-msg.user {

    background: #ff0000;

    color: #ffffff;

    align-self: flex-end;

    border-bottom-right-radius: 4px;

  }

  .fritz-msg.typing {

    background: #ffffff;

    color: #999999;

    border: 1px solid #e2e2e2;

    align-self: flex-start;

    font-style: italic;

    border-bottom-left-radius: 4px;

  }

 

  #fritz-privacy-note {

    font-size: 11px;

    color: #888888;

    padding: 6px 14px;

    background: #f7f7f7;

    border-top: 1px solid #ececec;

  }

  #fritz-privacy-note a { color: #565656; }

 

  #fritz-input-row {

    display: flex;

    border-top: 1px solid #e2e2e2;

    padding: 10px;

    gap: 8px;

    background: #ffffff;

  }

  #fritz-input {

    flex: 1;

    border: 1px solid #cccccc;

    border-radius: 20px;

    padding: 9px 14px;

    font-size: 14px;

    outline: none;

    font-family: ‚Lato‘, Arial, sans-serif;

  }

  #fritz-input:focus { border-color: #ff0000; }

  #fritz-send-btn {

    background: #ff0000;

    color: #ffffff;

    border: none;

    border-radius: 50%;

    width: 38px;

    height: 38px;

    cursor: pointer;

    font-size: 16px;

    flex-shrink: 0;

  }

  #fritz-send-btn:disabled { background: #cccccc; cursor: default; }

 

  @media (max-width: 480px) {

    #fritz-chat-window { width: 92vw; right: -4px; }

  }

</style>

 

<div id="“fritz-widget-container“">

  <div id="“fritz-chat-window“">

    <div id="“fritz-header“">

      <img src=“https://www.steinlen.de/fritz-data/Steinlen_Fritz_512x512.png“ alt=“Fritz“>

      <div id="“fritz-header-text“">

        <div id="“fritz-header-name“">Fritz</div>

        <div id="“fritz-header-sub“">Digitaler Praktikant · Steinlen</div>

      </div>

      <button id=“fritz-close-btn“ aria-label=“Schliessen“>&times;</button>

    </div>

    <div id="“fritz-messages“"></div>

    <div id="“fritz-privacy-note“">

      Bitte keine personenbezogenen Daten eingeben. <a href=“https://steinlen.de/datenschutz/“ target=“_blank“ rel=“noopener“>Datenschutzhinweis</a>

    </div>

    <div id="“fritz-input-row“">

      <input type=“text“ id=“fritz-input“ placeholder=“Frag Fritz etwas…“ autocomplete=“off“>

      <button id=“fritz-send-btn“ aria-label=“Senden“>&#10148;</button>

    </div>

  </div>

 

  <button id=“fritz-toggle-btn“ aria-label=“Chat mit Fritz öffnen“>

    <img src=“https://www.steinlen.de/fritz-data/Steinlen_Fritz_512x512.png“ alt=“Fritz“>

  </button>

</div>

 

<script>

(function () {

  // ============================================================

  // SEITEN-BESCHRAENKUNG — Widget erscheint NUR auf dieser Seite

  // ============================================================

  const ALLOWED_PATH = ‚/konfigurator/‘;

  if (window.location.pathname.indexOf(ALLOWED_PATH) === -1) {

    return; // Auf allen anderen Seiten: Widget gar nicht erst aufbauen

  }

 

  // ============================================================

  // KONFIGURATION — diese 3 Werte vor dem Einsatz pruefen!

  // ============================================================

  const WEBHOOK_URL = ‚http://10.56.4.56:5678/webhook/fritz-chat‘; // TODO: interne IP pruefen/anpassen

  const AUTH_TOKEN   = ‚C?=hK~8Jj!Z6:Ry=‘;                          // muss mit n8n-Node uebereinstimmen

  const AUTO_POPUP_DELAY_MS = 4000; // Chat-Fenster nach 4s automatisch oeffnen (einmalig pro Sitzung)

  // ============================================================

 

  const container   = document.getElementById(‚fritz-widget-container‘);

  const toggleBtn   = document.getElementById(‚fritz-toggle-btn‘);

  const closeBtn    = document.getElementById(‚fritz-close-btn‘);

  const chatWindow  = document.getElementById(‚fritz-chat-window‘);

  const messagesEl  = document.getElementById(‚fritz-messages‘);

  const inputEl     = document.getElementById(‚fritz-input‘);

  const sendBtn     = document.getElementById(‚fritz-send-btn‘);

 

  // Einfache Session-ID pro Browser-Tab (kein Tracking, nur fuer Konversationskontext)

  let sessionId = sessionStorage.getItem(‚fritz_session_id‘);

  if (!sessionId) {

    sessionId = ‚web-‚ + Date.now() + ‚-‚ + Math.random().toString(36).slice(2, 9);

    sessionStorage.setItem(‚fritz_session_id‘, sessionId);

  }

 

  function detectLanguage() {

    const htmlLang = (document.documentElement.lang || “).toLowerCase();

    return htmlLang.startsWith(‚en‘) ? ‚en‘ : ‚de‘;

  }

 

  function addMessage(text, role) {

    const div = document.createElement(‚div‘);

    div.className = ‚fritz-msg ‚ + role;

    div.textContent = text;

    messagesEl.appendChild(div);

    messagesEl.scrollTop = messagesEl.scrollHeight;

    return div;

  }

 

  function openChat() {

    chatWindow.classList.add(‚open‘);

    if (messagesEl.children.length === 0) {

      const greeting = detectLanguage() === ‚en‘

        ? „Hi, I’m Fritz! I’m still learning, but happy to help with questions about Steinlen. What can I do for you?“

        : ‚Hallo, ich bin Fritz! Ich lerne noch, helfe aber gerne bei Fragen rund um Steinlen. Was kann ich für dich tun?‘;

      addMessage(greeting, ‚bot‘);

    }

    inputEl.focus();

  }

 

  function closeChat() {

    chatWindow.classList.remove(‚open‘);

  }

 

  toggleBtn.addEventListener(‚click‘, function () {

    if (chatWindow.classList.contains(‚open‘)) closeChat();

    else openChat();

  });

  closeBtn.addEventListener(‚click‘, closeChat);

 

  async function sendMessage() {

    const text = inputEl.value.trim();

    if (!text) return;

 

    addMessage(text, ‚user‘);

    inputEl.value = “;

    sendBtn.disabled = true;

 

    const typingEl = addMessage(

      detectLanguage() === ‚en‘ ? ‚Fritz is thinking…‘ : ‚Fritz überlegt…‘,

      ‚typing‘

    );

 

    try {

      const response = await fetch(WEBHOOK_URL, {

        method: ‚POST‘,

        headers: { ‚Content-Type‘: ‚application/json‘ },

        body: JSON.stringify({

          sessionId: sessionId,

          message: text,

          language: detectLanguage(),

          token: AUTH_TOKEN

        })

      });

 

      const data = await response.json();

      typingEl.remove();

 

      if (data && data.ok !== false && data.reply) {

        addMessage(data.reply, ‚bot‘);

      } else {

        const errText = (data && data.reply)

          ? data.reply

          : (detectLanguage() === ‚en‘

              ? ‚Sorry, something went wrong. Please contact us directly.‘

              : ‚Entschuldigung, da ist etwas schiefgelaufen. Bitte kontaktiere uns direkt.‘);

        addMessage(errText, ‚bot‘);

      }

    } catch (err) {

      typingEl.remove();

      addMessage(

        detectLanguage() === ‚en‘

          ? „Sorry, I can’t be reached right now. Please contact us directly.“

          : ‚Entschuldigung, ich bin gerade nicht erreichbar. Bitte kontaktiere uns direkt.‘,

        ‚bot‘

      );

    } finally {

      sendBtn.disabled = false;

      inputEl.focus();

    }

  }

 

  sendBtn.addEventListener(‚click‘, sendMessage);

  inputEl.addEventListener(‚keydown‘, function (e) {

    if (e.key === ‚Enter‘) sendMessage();

  });

 

  // Automatisches Aufpoppen (einmal pro Browser-Sitzung)

  if (!sessionStorage.getItem(‚fritz_auto_popup_shown‘)) {

    setTimeout(function () {

      if (!chatWindow.classList.contains(‚open‘)) {

        openChat();

        sessionStorage.setItem(‚fritz_auto_popup_shown‘, ‚1‘);

      }

    }, AUTO_POPUP_DELAY_MS);

  }

})();

</script>