'use strict';

/* =================================================================
   Das Einkauszentrum von Sachsenotto – Ein Text-mit-Klick-Adventure
   game.js – Vollständige Spiellogik
   ================================================================= */

// ── Spielzustand ────────────────────────────────────────────
const S = {
  phase: 'prolog',
  room: null,
  inv: [],
  stamps: [false, false, false, false, false],
  p: { // Puzzle-Flags
    kerze_befreit:    false,
    sekt_befreit:     false,
    ballon_gefunden:  false,
    schluessel_befreit: false,
    blumen_befreit:   false,
    aufkleber_lesbar: false,
    kombi_bekannt:    false,
    klavier_offen:    false,
    kanone3:          false,
    fenster_offen:    false,
    schublade_offen:  false,
    karton_offen:     false,
    heizung_aus:      false,
    papst_maske:      false,
    kanone2_gezuendet: false,
    eiskuebel_voll:   false,
    stempelkarte_erhalten: false,
    // Dialog-Einmalflags
    dlg_baeck_wo:    false, dlg_baeck_wen:   false,
    dlg_kund_best:   false, dlg_kund_baeck:  false, dlg_kund_leid:   false,
    dlg_krit_konz:   false, dlg_krit_and:    false, dlg_krit_markt:  false,
    dlg_getr_lang:   false, dlg_getr_gitt:   false,
    dlg_gper_j2007:  false, dlg_gper_anl:    false, dlg_gper_nicht:  false,
    dlg_parv_lief:   false, dlg_parv_lag:    false, dlg_parv_kan:    false,
    dlg_phil_form:   false, dlg_phil_funk:   false, dlg_phil_drau:   false, dlg_phil_war: false,
    dlg_blum_lue:    false, dlg_blum_vit:    false, dlg_blum_hei:    false,
    dlg_infl_con:    false, dlg_infl_bild:   false, dlg_infl_sch:    false,
    dlg_all_kein:    false, dlg_all_war:     false, dlg_all_frag:    false,
    dlg_musk_schl:   false, dlg_musk_wer:    false,
    dlg_stim_weg:    false, dlg_stim_schl:   false, dlg_stim_tee:    false,
    dlg_serv_was:    false, dlg_serv_wer:    false,
  },
  verb: null,
  verbStep: 1,
  firstObj: null, // { id, kind: 'room'|'inv' }
  visited: new Set(),
  defIdx: 0,
  prologIdx: 0,
  phoneStep: 0,
};

// ── Speichern / Laden ───────────────────────────────────────
const SAVE_KEY = 'eut_save';

function saveGame() {
  try {
    localStorage.setItem(SAVE_KEY, JSON.stringify({
      room:    S.room,
      inv:     S.inv,
      stamps:  S.stamps,
      p:       S.p,
      visited: [...S.visited],
      defIdx:  S.defIdx,
    }));
  } catch(e) {}
}

function loadGame() {
  try {
    const raw = localStorage.getItem(SAVE_KEY);
    if (!raw) return false;
    const d = JSON.parse(raw);
    S.room    = d.room;
    S.inv     = d.inv     || [];
    S.stamps  = d.stamps  || [false,false,false,false,false];
    S.defIdx  = d.defIdx  || 0;
    Object.assign(S.p, d.p || {});
    S.visited = new Set(d.visited || []);
    return true;
  } catch(e) { return false; }
}

// ── Standard-Reaktionen ─────────────────────────────────────
const DEF_REACTIONS = [
  'Das ergibt keinen Sinn.',
  'Das können Sie versuchen. Es hilft nicht.',
  'Mit dem besten Willen: nein.',
  'Das ist eine interessante Idee. Sie funktioniert nicht.',
  'Nichts passiert. Vielleicht war das zu erwarten.',
  'Die Kombination hat noch niemand versucht. Jetzt haben Sie es versucht. Nichts.',
  'Das geht so nicht. Das wird auch so nicht gehen.',
  'Sie probieren es. Es klappt nicht. Sie sind trotzdem noch hier.',
];
const defR = () => DEF_REACTIONS[(S.defIdx++) % DEF_REACTIONS.length];

// ── Inventar-Hilfsfunktionen ────────────────────────────────
const hasItem = id => S.inv.includes(id);

function addItem(id) {
  if (!S.inv.includes(id)) S.inv.push(id);
  renderInventory();
  return true;
}

function removeItem(id) {
  const i = S.inv.indexOf(id);
  if (i !== -1) S.inv.splice(i, 1);
  renderInventory();
}

// ── Items (Inventar-Objekte) ────────────────────────────────
const ITEMS = {
  schere:       { name: 'Schere',           icon: '✂️',  desc: 'Groß und scharf. Gut für Folie.' },
  brotmesser:   { name: 'Brotmesser',       icon: '🔪',  desc: 'Lang, schmal. Passt in enge Spalten.' },
  oel:          { name: 'Öl',               icon: '🫙',  desc: 'Schmiermittel. Nicht für Salat.' },
  eiskuebel:    { name: 'Eiskübel',         icon: '🪣',  get desc() { return S.p.eiskuebel_voll ? 'Voll Wasser.' : 'Leer.'; } },
  taschenlampe: { name: 'Taschenlampe',     icon: '🔦',  desc: 'Funktioniert. Wirft Licht.' },
  kerze:        { name: 'Kerze',            icon: '🕯️',  desc: 'Folie entfernt. Bereit.' },
  sektflasche:  { name: 'Sektflasche',      icon: '🍾',  desc: 'Eine Flasche Sekt.' },
  luftballon:   { name: 'Luftballon',       icon: '🎈',  desc: 'Gold. Aufschrift: 19.' },
  blumenstrauss:{ name: 'Blumenstrauß',     icon: '💐',  desc: 'Frisch. Aus der Kühlvitrine.' },
  stimmgabel:   { name: 'Stimmgabel',       icon: '🎵',  desc: 'Gibt einen reinen Ton.' },
  papst_maske:  { name: 'Papst-Maske',      icon: '👑',  desc: 'Weiß. Aufwendig. Definitiv der Papst.' },
  stempelkarte: { name: 'Stempelkarte',     icon: '🎫',  get desc() { const n = S.stamps.filter(Boolean).length; return n === 0 ? 'Leer.' : n === 5 ? 'Vollständig. Fünf Stempel.' : `${n} von 5 Stempeln.`; } },
};

const STAMP_ORDER = ['kerze', 'sektflasche', 'luftballon', 'blumenstrauss', 'stimmgabel'];
const STAMP_WORDS  = ['einen', 'zwei', 'drei', 'vier', 'fünf'];
const STAMP_ICONS  = ['🕯️',  '🍾',          '🎈',          '💐',            '🎵'];

// ── Raum-Objekte ────────────────────────────────────────────
// Jedes Objekt: { name, room, visible?, verbs:{verb:fn|str}, useWith?:{itemId:fn}, giveTo?:{itemId:fn} }
// Sonderfall: look auf Inventar-Item kommt vom ITEMS.desc

const OBJECTS = {

  // ═══════════════════════════════════════════════════════════
  // PASSAGE
  // ═══════════════════════════════════════════════════════════
  passage_tuer: {
    name: 'Tür zur Dachterrasse',
    room: 'glasfront',
    verbs: {
      look: 'Die Tür ist verschlossen. Neben der Tür ist ein Scanner für Stempelkarten.',
      open: () => 'Die Tür lässt sich nicht einfach öffnen. Vielleicht hilft die Stempelkarte.',
    },
    useWith: {
      stempelkarte: () => {
        if (!S.stamps.every(Boolean)) {
          const n = S.stamps.filter(Boolean).length;
          return `Die Karte ist noch nicht vollständig. [${n}/5 Stempel]`;
        }
        showOutro();
        return null;
      },
    },
  },

  passage_schild: {
    name: 'Schild an der Tür',
    room: 'glasfront',
    verbs: {
      look: 'Sammeln Sie fünf Stempel in unseren Partnergeschäften und lösen Sie sie im Service-Center ein. Ihr Gewinn: Zugang zur Party-Dachterrasse.',
    },
  },

  passage_centerplan: {
    name: 'Centerplan',
    room: 'glasfront',
    verbs: {
      look: 'Hier sind alle Läden eingezeichnet. Praktisch. Obwohl es gar nicht so viele Läden gibt. Das Service-Center liegt genau in der Mitte.',
      use:  'Wenn Sie einen Laden auf dem Plan antippen, leuchtet er kurz auf. Tolle Funktion, aber vollkommen nutzlos.',
    },
  },

  passage_ballons: {
    name: 'Eröffnungsballons',
    room: 'glasfront',
    verbs: {
      look: 'Gold und weiß. Einer ist schon schlaff.',
      take: 'Der schlaffe Ballon macht ein trauriges Geräusch.',
    },
    useWith: {
      schere:           () => 'Sie schneiden einen Ballon ab. Er steigt in die Luft. Gute Reise! (Das war kein Rätsel.)',
      party_schere:     () => 'Sie schneiden einen Ballon ab. Er steigt in die Luft. Gute Reise! (Das war kein Rätsel.)',
      brotmesser:       () => 'Sie stechen den Ballon an. Er platzt mit einem kleinen Knall. (Das War auch kein Rätsel.)',
      baeck_brotmesser: () => 'Sie stechen den Ballon an. Er platzt mit einem kleinen Knall. (Das War auch kein Rätsel.)',
    },
  },

  passage_glasfront: {
    name: 'Glasfront',
    room: 'glasfront',
    verbs: {
      look:  'Man sieht Partytische, Pflanzen, Lichterketten. Schade, dass sie nicht eintreten können. Und sitzt da hinten nicht Teddy? Sie springen auf und ab und rufen, aber er sieht und hört sie nicht. Dafür ist hier alles zu gut isoliert. Und vielleicht von innen verspiegelt.',
      push:  'Teddy schaut kurz auf. Nickt. Trinkt weiter Kaffee.',
      pull:  'Teddy schaut kurz auf. Nickt. Trinkt weiter Kaffee.',
      talk:  'Sie können durch die Glasfront nicht sprechen. Die Person scheint das nicht zu stören.',
    },
  },

  // ═══════════════════════════════════════════════════════════
  // BÄCKEREI
  // ═══════════════════════════════════════════════════════════
  baeck_torte: {
    name: 'Torte',
    room: 'baeckerei',
    verbs: {
      look: 'Eine wunderbare Jubiläumstorte. Oben thronen eine Esel-Figur und eine Teddy-Figur aus Marzipan.',
      take: 'Der Bäcker schaut Sie an.',
    },
    useWith: {
      schere:           () => 'Sie schneiden Torten mit der Schere? Ach herrje. Das lassen wir hier mal lieber.',
      party_schere:     () => 'Sie schneiden Torten mit der Schere? Ach herrje. Das lassen wir hier mal lieber.',
      brotmesser:       () => 'Sie könnten anschneiden. Aber das ist hier und heute nicht Ihre Aufgabe.',
      baeck_brotmesser: () => 'Sie könnten anschneiden. Aber das ist hier und heute nicht Ihre Aufgabe.',
    },
    giveTo: {
      baeck_kundin:  () => '»Das ist nicht meine Torte. Ich hatte was mit Mohn bestellt.«',
      baeck_kritiker: () => '»Sie wollen mir die Torte geben?« Er weicht zurück. »Das würde meine Objektivität kompromittieren.«',
    },
  },

  baeck_kerzen: {
    name: 'Kerze',
    room: 'baeckerei',
    visible: () => !S.p.kerze_befreit,
    verbs: {
      look: 'Die Kerze ist in Folie eingeschweißt, die sich nicht aufreißen lässt.',
      take: 'Die Folie lässt sich nicht aufreißen.',
    },
    useWith: {
      schere: () => {
        S.p.kerze_befreit = true;
        addItem('kerze');
        return 'Die Schere schneidet sauber durch die Folie. Die Kerze ist freigelegt und Sie nehmen sie an sich, als niemand schaut.';
      },
      party_schere: () => {
        S.p.kerze_befreit = true;
        addItem('kerze');
        return 'Die Schere schneidet sauber durch die Folie. Die Kerze ist freigelegt und Sie nehmen sie an sich, als niemand schaut.';
      },
      brotmesser:      () => 'Wie eklig ist das denn: Wachs am Brotmesser! Nein, so geht das nicht!',
      baeck_brotmesser: () => 'Wie eklig ist das denn: Wachs am Brotmesser! Nein, so geht das nicht!',
    },
  },

  baeck_kerze_frei: {
    name: 'Kerze',
    room: 'baeckerei',
    visible: () => S.p.kerze_befreit && !hasItem('kerze') && !S.stamps[0],
    verbs: {
      look: 'Die Folie ist entfernt.',
      take: () => { addItem('kerze'); return 'Sie nehmen die Kerze. Der Bäcker schaut kurz rüber. Dann wieder auf seinen Teig.'; },
    },
  },

  baeck_brotmesser: {
    name: 'Brotmesser',
    room: 'baeckerei',
    visible: () => !hasItem('brotmesser'),
    verbs: {
      look: 'Lang, schmal, gut in Form. Das trifft nicht auf alle hier zu.',
      take: () => { addItem('brotmesser'); return 'Sie nehmen das Brotmesser. Der Bäcker hat es nicht gesehen.'; },
    },
  },

  baeck_baecker: {
    name: 'Bäcker',
    npc: true,
    room: 'baeckerei',
    verbs: {
      look: 'Er wirkt angespannt und hat Mehl im Haar.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('baecker'),
      push: 'Das sollten Sie lieber lassen.',
    },
    giveTo: {
      schere: () => {
        if (S.p.kerze_befreit) return 'Er winkt ab. »Ich hab alles, was ich brauche.«';
        S.p.kerze_befreit = true;
        removeItem('schere');
        addItem('kerze');
        return 'Er nimmt die Schere, schneidet die Folie auf, drückt Ihnen die Kerze in die Hand. »Danke. Und – schönen Geburtstag, wem auch immer.«';
      },
      brotmesser: () => 'Er nimmt es. Pause. »Haben Sie zufällig auch eine Schere?« Er gibt das Messer zurück.',
      kerze: () => 'Er schaut auf die Kerze. »Die ist fürs Service-Center, glaube ich. Nicht für mich.«',
    },
  },

  baeck_kuehlschrank: {
    name: 'Kühlschrank',
    room: 'baeckerei',
    verbs: {
      look:  'Er ist abgeschlossen. Auf einem Aufkleber steht: Nur für Personal.',
      open:  'Abgeschlossen.',
      close: 'Schon zu.',
    },
    useWith: {
      brotmesser:       () => 'Das Brotmesser ist kein Dietrich.',
      baeck_brotmesser: () => 'Das Brotmesser ist kein Dietrich.',
      schere:           () => 'Wie viele Kühlschränke haben Sie schon mit einer Schere geöffnet? Eben. Diesen hier auch nicht.',
      party_schere:     () => 'Wie viele Kühlschränke haben Sie schon mit einer Schere geöffnet? Eben. Diesen hier auch nicht.',
    },
  },

  baeck_kassenschublade: {
    name: 'Kassenschublade',
    room: 'baeckerei',
    verbs: {
      look:  () => S.p.schublade_offen ? 'Jetzt ist die Kasse offen. Aber leer. Zahlen wohl alle nur noch mit Karte.' : 'Die Kasse ist geschlossen.',
      open:  () => {
        if (S.p.schublade_offen) return 'Schon offen. Immer noch leer.';
        S.p.schublade_offen = true;
        return 'Sie springt auf. Leer.';
      },
      push:  () => {
        if (S.p.schublade_offen) return 'Schon offen. Immer noch leer.';
        S.p.schublade_offen = true;
        return 'Sie springt auf. Leer.';
      },
      close: () => {
        if (!S.p.schublade_offen) return 'Schon geschlossen.';
        S.p.schublade_offen = false;
        return 'Sie schließen die Schublade.';
      },
    },
  },

  baeck_mehlsack: {
    name: 'Mehlsack',
    room: 'baeckerei',
    verbs: {
      look: '25 Kilo. Steht am Boden.',
      take: 'Zu schwer.',
      pull: 'Er rutscht. Darunter: Boden.',
    },
    useWith: {
      schere:           () => 'Sie öffnen den Sack. Mehl quillt auf den Boden. Der Bäcker schaut Sie fassungslos an.',
      party_schere:     () => 'Sie öffnen den Sack. Mehl quillt auf den Boden. Der Bäcker schaut Sie fassungslos an.',
      brotmesser:       () => 'Sie stechen das Messer in den Sack. Mehl rieselt heraus. Der Bäcker schaut Sie fassungslos an.',
      baeck_brotmesser: () => 'Sie stechen das Messer in den Sack. Mehl rieselt heraus. Der Bäcker schaut Sie fassungslos an.',
    },
  },

  baeck_schuerze: {
    name: 'Schürze',
    room: 'baeckerei',
    verbs: {
      look: 'Weiß. Mit Mehlflecken. Warum auch immer man das erkennen kann auf einer weißen Schürze.',
      take: 'Der Bäcker schaut Sie an. Lange.',
    },
  },

  baeck_telefon: {
    name: 'Telefon',
    room: 'baeckerei',
    verbs: {
      look:  'Ein altes Wandtelefon. Nostalgie pur.',
      use:   'Besetzt.',
      talk:  'Besetzt.',
      push:  'Besetzt.',
    },
  },

  baeck_fenster: {
    name: 'Fenster',
    room: 'baeckerei',
    verbs: {
      look:  () => S.p.fenster_offen ? 'Sie schauen durch das geöffnete Fenster in den Innenhof. In der Ferne sieht man auch die Dachterrasse.' : 'Sie schauen durch das geschlossene Fenster in den Innenhof. In der Ferne sieht man auch die Dachterrasse.',
      open:  () => {
        if (S.p.fenster_offen) return 'Das Fenster ist bereits offen.';
        S.p.fenster_offen = true;
        return 'Geht auf. Frische Luft. Aber Sie sind im ersten Stock.';
      },
      close: () => {
        if (!S.p.fenster_offen) return 'Das Fenster ist schon geschlossen.';
        S.p.fenster_offen = false;
        return 'Sie schließen es wieder.';
      },
    },
  },

  baeck_brotlaib: {
    name: 'Brotlaib',
    room: 'baeckerei',
    verbs: {
      look: 'Frisch gebacken. Lecker. Aber irrelevant.',
      take: '»Der ist zum Verkauf.« – Der Bäcker.',
    },
    useWith: {
      brotmesser:       () => 'Wollen Sie hier als Bäckereifachverkäufer anfangen? Sie haben doch einen anderen Job zu erledigen!',
      baeck_brotmesser: () => 'Wollen Sie hier als Bäckereifachverkäufer anfangen? Sie haben doch einen anderen Job zu erledigen!',
      schere:       () => 'Mit einer Schere Brot schneiden? Der Bäcker versucht, nicht hinzuschauen. Es gelingt ihm aber nicht. Und Ihnen deshalb auch nicht.',
      party_schere: () => 'Mit einer Schere Brot schneiden? Der Bäcker versucht, nicht hinzuschauen. Es gelingt ihm aber nicht. Und Ihnen deshalb auch nicht.',
    },
  },


  baeck_kundin: {
    name: 'Wartende Kundin',
    npc: true,
    room: 'baeckerei',
    verbs: {
      look: 'Sie steht wohl seit einiger Zeit an der Theke. Sie wirkt geduldig. Oder resigniert.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('baeck_kundin'),
    },
    giveTo: {
      blumenstrauss: () => 'Sie schaut auf die Blumen. Dann auf den Bäcker. »Das ist nett. Aber ich hatte Mohn bestellt.«',
      luftballon:    () => 'Sie schaut auf den Ballon, dann auf ihren Zettel. »Steht nicht drauf.«',
      stimmgabel:    () => 'Sie hält sie kurz. »Können Sie damit ein Mohnbrötchen machen?« Sie gibt sie zurück.',
      kerze:         () => '»Eine Kerze. Das ist schön.« Pause. »Ich warte trotzdem noch auf meinen Mohn.«',
    },
  },

  baeck_kritiker: {
    name: 'Tortenkritiker',
    npc: true,
    room: 'baeckerei',
    verbs: {
      look: 'Er betrachtet die Torten mit verschränkten Armen. Er hat ein Notizbuch in der Hand.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('baeck_kritiker'),
    },
    giveTo: {
      kerze:         () => '»Die Kerze zurück zur Torte – das ist konzeptuell stark. Ich revidiere meine Bewertung. 7,5 von 10.«',
      luftballon:    () => '»Ein Ballon. Ephemer. Hat etwas.« Er macht eine Notiz. »6 von 10.«',
      blumenstrauss: () => '»Blumen und Torte. Interessant. Falsche Kategorie, aber mutig.«',
    },
  },

  // ═══════════════════════════════════════════════════════════
  // GETRÄNKELADEN
  // ═══════════════════════════════════════════════════════════
  getr_sektflasche: {
    name: 'Sektflasche',
    room: 'getraenkeladen',
    visible: () => !S.p.sekt_befreit,
    verbs: {
      look: 'Jahrgang 2007. Goldene Folie. Unerreichbar.',
      take: 'Das Gitter ist im Weg.',
    },
    useWith: {
      oel: () => {
        if (S.p.sekt_befreit) return 'Das Gitter ist bereits offen.';
        S.p.sekt_befreit = true;
        return 'Das Öl tropft durch die Gitterstäbe auf das Schloss. Nach einem Moment gibt es nach. Das Gitter öffnet sich.';
      },
      blum_oel: () => {
        if (S.p.sekt_befreit) return 'Das Gitter ist bereits offen.';
        S.p.sekt_befreit = true;
        return 'Das Öl tropft durch die Gitterstäbe auf das Schloss. Nach einem Moment gibt es nach. Das Gitter öffnet sich.';
      },
    },
  },

  getr_sektflasche_frei: {
    name: 'Sektflasche',
    room: 'getraenkeladen',
    visible: () => S.p.sekt_befreit && !hasItem('sektflasche') && !S.stamps[1],
    verbs: {
      look: 'Jahrgang 2007. Das Gitter ist jetzt offen.',
      take: () => { addItem('sektflasche'); return 'Sie nehmen die Sektflasche. Der Verkäufer nickt. Er wusste, dass Sie die wollten.'; },
    },
  },

  getr_schloss: {
    name: 'Vorhängeschloss',
    room: 'getraenkeladen',
    visible: () => !S.p.sekt_befreit,
    verbs: {
      look:  'Komplett verrostet. Da bewegt sich nichts keinen Millimeter.',
      open:  'Womit denn? Zumal es wirklich total verrostet ist.',
      push:  'Das Schloss ist stärker als Sie.',
      pull:  'Das Schloss ist stärker als Sie.',
    },
    useWith: {
      oel: () => {
        S.p.sekt_befreit = true;
        return 'Das Öl dringt in den Rost. Nach einem Moment gibt das Schloss nach. Das Gitter schwingt auf.';
      },
      blum_oel: () => {
        S.p.sekt_befreit = true;
        return 'Das Öl dringt in den Rost. Nach einem Moment gibt das Schloss nach. Das Gitter schwingt auf.';
      },
      brotmesser:       () => 'Kein Hebel der Welt.',
      baeck_brotmesser: () => 'Kein Hebel der Welt.',
      schere:           () => 'Eine Schere hilft hier nicht.',
      party_schere:     () => 'Eine Schere hilft hier nicht.',
      eiskuebel:        () => 'Wasser löst keinen Rost. Das hier braucht Öl.',
      getr_eiskuebel:   () => 'Wasser löst keinen Rost. Das hier braucht Öl.',
    },
  },

  getr_eiskuebel: {
    name: 'Eiskübel',
    room: 'getraenkeladen',
    visible: () => !hasItem('eiskuebel'),
    verbs: {
      look: 'Er steht zur Deko leer neben dem Eingang. Silber, etwas verbeult.',
      take: () => { addItem('eiskuebel'); return 'Sie nehmen den Eiskübel. Der Verkäufer hat es nicht gesehen.'; },
    },
  },

  getr_flaschen: {
    name: 'Andere Flaschen',
    room: 'getraenkeladen',
    verbs: {
      look: 'Ein gutes Sortiment. Aber keine Flasche ist aus dem Jahr 2007.',
      take: '»Zum Trinken erst nach dem Kauf.« – Der Verkäufer.',
    },
  },

  getr_verkaeufer: {
    name: 'Verkäufer',
    npc: true,
    room: 'getraenkeladen',
    verbs: {
      look: 'Wirkt professionell. Etwas resigniert.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('getr_verkaeufer'),
    },
    giveTo: {
      oel: () => {
        if (S.p.sekt_befreit) return '»Die Flasche haben Sie doch schon.« Er schaut zur leeren Vitrine.';
        S.p.sekt_befreit = true;
        addItem('sektflasche');
        return 'Er ölt das Schloss, öffnet das Gitter, gibt Ihnen die Flasche. »Jahrgang 2007. Guter Jahrgang.«';
      },
      stimmgabel: () => 'Er schlägt sie an. Nickt. »Stimmt.« Gibt sie zurück.',
      luftballon:  () => 'Er schaut den Ballon kurz an. »Gold. 19.« Pause. »Guter Jahrgang.«',
    },
  },

  getr_preisschild: {
    name: 'Preisschild',
    room: 'getraenkeladen',
    verbs: {
      look: 'Sektflasche. Premiumjahrgang 2007. Preis: unbezahlbar.',
    },
  },

  getr_schluesselb: {
    name: 'Schlüsselbrett',
    room: 'getraenkeladen',
    verbs: {
      look: 'Ein Brett mit vielen Haken. Alle sind leer. Es hätte hier einen Schlüssel für das Schloss geben sollen.',
    },
  },

  getr_karton: {
    name: 'Karton',
    room: 'getraenkeladen',
    verbs: {
      look:  () => S.p.karton_offen ? 'Geöffnet. Styropor. Leere Flaschen. Wer verschickt denn so etwas?' : 'Ungeöffnete Lieferung.',
      open:  () => {
        if (S.p.karton_offen) return 'Schon offen. Styropor. Leere Flaschen.';
        S.p.karton_offen = true;
        return 'Styropor. Leere Flaschen.';
      },
    },
    useWith: {
      brotmesser:       () => {
        if (S.p.karton_offen) return 'Schon offen.';
        S.p.karton_offen = true;
        return 'Sie öffnen den Karton fachgerecht. Und finden: Styropor. Und leere Flaschen.';
      },
      baeck_brotmesser: () => {
        if (S.p.karton_offen) return 'Schon offen.';
        S.p.karton_offen = true;
        return 'Sie öffnen den Karton fachgerecht. Und finden: Styropor. Und leere Flaschen.';
      },
      schere:           () => {
        if (S.p.karton_offen) return 'Schon offen.';
        S.p.karton_offen = true;
        return 'Sie schneiden den Karton auf. Und finden: Styropor. Und leere Flaschen.';
      },
      party_schere:     () => {
        if (S.p.karton_offen) return 'Schon offen.';
        S.p.karton_offen = true;
        return 'Sie schneiden den Karton auf. Und finden: Styropor. Und leere Flaschen.';
      },
    },
  },

  getr_besen: {
    name: 'Besen',
    room: 'getraenkeladen',
    verbs: {
      look: 'Ein ganz normaler Besen.',
      take: 'Warum?',
    },
    useWith: {
      getr_schloss: () => 'Der Besen tut nichts.',
    },
  },

  getr_schaufenster: {
    name: 'Schaufenster',
    room: 'getraenkeladen',
    verbs: {
      look: 'Sie wagen einen Blick nach draußen. Das Service-Center ist von hier sichtbar.',
    },
  },

  getr_person: {
    name: 'Person mit Einkaufszettel',
    npc: true,
    room: 'getraenkeladen',
    verbs: {
      look: 'Die Person hält einen Zettel und schaut ratlos auf die Regale.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('getr_person'),
    },
    giveTo: {
      brotmesser:    () => 'Sie schaut auf das Messer, dann auf ihren Zettel. »Steht nicht drauf.«',
      luftballon:    () => 'Sie schaut den Ballon an. Dann auf ihren Zettel. »Steht nicht drauf.« Sie schaut aber kurz erfreut.',
      blumenstrauss: () => '»Das ist nett von Ihnen.« Sie schaut auf den Zettel. »Da steht nur Sekt. Und bitte.«',
    },
  },

  getr_wasserhahn: {
    name: 'Wasserhahn',
    room: 'getraenkeladen',
    verbs: {
      look: 'Da kommt Wasser heraus.',
      open: 'Sie drehen ihn auf. Wasser läuft.',
    },
    useWith: {
      eiskuebel: () => {
        if (S.p.eiskuebel_voll) return 'Der Eiskübel ist schon voll.';
        S.p.eiskuebel_voll = true;
        renderInventory();
        return 'Sie halten den Eiskübel unter den Hahn. Er füllt sich mit Wasser.';
      },
      getr_eiskuebel: () => {
        if (S.p.eiskuebel_voll) return 'Der Eiskübel ist schon voll.';
        S.p.eiskuebel_voll = true;
        renderInventory();
        return 'Sie halten den Eiskübel unter den Hahn. Er füllt sich mit Wasser.';
      },
    },
  },

  // ═══════════════════════════════════════════════════════════
  // PARTYAUSSTATTER
  // ═══════════════════════════════════════════════════════════
  party_schere: {
    name: 'Schere',
    room: 'partyausstatter',
    visible: () => !hasItem('schere'),
    verbs: {
      look: 'Groß, scharf, liegt offen auf dem Tresen.',
      take: () => { addItem('schere'); return 'Sie nehmen die Schere. Die Verkäuferin schaut nicht auf – sie wartet auf ihre Lieferung.'; },
    },
  },

  party_lagertuer: {
    name: 'Lagertür',
    room: 'partyausstatter',
    verbs: {
      look: () => S.p.ballon_gefunden ? 'Das Lager ist durchsucht. Den Ballon haben Sie.' : 'Als Sie die Tür öffnen, ist dahinter alles dunkel. Gruselig. Schnell machen Sie die Tür wieder zu.',
      open: () => {
        if (S.p.ballon_gefunden) return 'Das Lager ist bereits durchsucht. Den Ballon haben Sie schon.';
        if (hasItem('taschenlampe')) {
          S.p.ballon_gefunden = true;
          addItem('luftballon');
          return 'Sie leuchten ins Lager. Zwischen Kartons und Konfettivorräten: ein goldener Ballon mit der Aufschrift 19. Sie nehmen ihn.';
        }
        if (!S.p.kanone3) {
          S.p.kanone3 = true;
          return 'Sie sehen nichts. Es ist sehr dunkel. Sie stoßen gegen etwas. Es fühlt sich nach einer weiteren Konfetti-Kanone an. BUMM. Sie stehen jetzt in einem Konfetti-Sturm.';
        }
        return 'Sie sehen nichts. Es ist zu dunkel. Sie brauchen eine Taschenlampe.';
      },
    },
    useWith: {
      taschenlampe: () => {
        if (S.p.ballon_gefunden) return 'Das Lager ist bereits durchsucht.';
        S.p.ballon_gefunden = true;
        addItem('luftballon');
        return 'Sie leuchten ins Lager. Der Lichtstrahl fällt direkt auf einen goldenen Ballon mit einer 19 darauf. Den nehmen Sie an sich.';
      },
    },
  },

  party_kanone1: {
    name: 'Konfetti-Kanone 1',
    room: 'partyausstatter',
    verbs: {
      look:  'Bereits gezündet. Leer.',
      take:  'Schwer und leer.',
      push:  'Nichts mehr drin.',
    },
  },

  party_kanone2: {
    name: 'Konfetti-Kanone 2',
    room: 'partyausstatter',
    verbs: {
      look:  () => S.p.kanone2_gezuendet ? 'Bereits gezündet. Leer.' : 'Noch geladen. Und zeigt in Ihre Richtung.',
      take:  () => {
        if (S.p.kanone2_gezuendet) return 'Schwer und leer.';
        S.p.kanone2_gezuendet = true;
        return 'BUMM. Mehr Konfetti. Konfetti ist jetzt überall in Ihrem Haar.';
      },
      push:  () => S.p.kanone2_gezuendet ? 'Nichts mehr drin.' : 'Vielleicht lieber nicht.',
    },
  },

  party_verkaeuferin: {
    name: 'Verkäuferin',
    npc: true,
    room: 'partyausstatter',
    verbs: {
      look: 'Sie steht am Tresen und wartet auf Lieferung.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('party_verkaeuferin'),
    },
    giveTo: {
      taschenlampe: () => {
        if (S.p.ballon_gefunden) return '»Den Ballon haben Sie doch schon.« Sie blinzelt Konfetti aus den Augen.';
        S.p.ballon_gefunden = true;
        addItem('luftballon');
        return 'Sie leuchtet ins Lager, findet den Ballon, gibt ihn Ihnen. »Schöne Zahl, 19.«';
      },
      kerze:         () => '»Die gehört ins Service-Center, glaube ich.« Sie gibt sie zurück. »Ich warte hier.«',
      blumenstrauss: () => '»Schön.« Sie schaut zur Tür. »Aber ich warte immer noch auf die Lieferung.«',
    },
  },

  party_geschenk: {
    name: 'Geschenkbänder',
    room: 'partyausstatter',
    verbs: {
      look: 'Dutzende Farben.',
      take: 'Sie ziehen ein rotes Band heraus. Dann legen Sie es wieder hin.',
    },
    useWith: {
      schere:       () => 'Sie schneiden ein Band ordentlich ab. Ohne Zweck. Aber sehr ordentlich.',
      party_schere: () => 'Sie schneiden ein Band ordentlich ab. Ohne Zweck. Aber sehr ordentlich.',
    },
  },

  party_masken: {
    name: 'Partymasken',
    room: 'partyausstatter',
    verbs: {
      look: () => S.p.papst_maske ? 'Einhorn, ein unbekanntes Tier. Die Papst-Maske haben Sie schon. Und eine Maske reicht.' : 'Einhorn, Papst, ein unbekanntes Tier.',
      take: () => {
        if (S.p.papst_maske) return 'Die Papst-Maske haben Sie schon.';
        S.p.papst_maske = true;
        addItem('papst_maske');
        return 'Sie nehmen die Papst-Maske. Die Verkäuferin hat es gesehen und ignoriert es.';
      },
      use: () => {
        if (S.p.papst_maske) return 'Sie tragen bereits eine Papst-Maske. Oder haben sie eingesteckt. Jedenfalls: Papst.';
        S.p.papst_maske = true;
        addItem('papst_maske');
        return 'Sie setzen die Papst-Maske auf. Die Verkäuferin reagiert nicht.';
      },
    },
    giveTo: {
      party_philosophin: () => 'Sie hält die Papst-Maske vors Gesicht. »Identität als Oberfläche.« Eine Pause. »Oder Oberfläche als Identität?« Sie gibt sie zurück.',
    },
  },

  party_deko: {
    name: 'Tischdekokerzen',
    room: 'partyausstatter',
    verbs: {
      look: 'Klein, für Tische. Andere Kerzen als die gesuchte.',
    },
  },


  party_pinata: {
    name: 'Piñata',
    room: 'partyausstatter',
    verbs: {
      look:  'Sie hängt oben von der Decke und hat eine gewisse Ähnlichkeit mit einem Esel.',
      take:  'Sie kommen nicht ran. Sie hängt zu hoch.',
    },
    useWith: {
      schere:           () => 'Sie wollen die Piñata zerschneiden. Das wäre Sachbeschädigung!',
      party_schere:     () => 'Sie wollen die Piñata zerschneiden. Das wäre Sachbeschädigung!',
      brotmesser:       () => 'Sie hauen mit dem Brotmessergriff auf die Piñata. Sie schaukelt, geht kaputt und ist leer. Und Sie haben sich in die Hand geschnitten.',
      baeck_brotmesser: () => 'Sie hauen mit dem Brotmessergriff auf die Piñata. Sie schaukelt, geht kaputt und ist leer. Und Sie haben sich in die Hand geschnitten.',
    },
    giveTo: {
      party_philosophin: () => 'Sie hält die Piñata. Lange. »Ein Objekt, das seinen Inhalt erst durch Zerstörung freigibt.« Pause. »Das hat was.« Sie gibt sie zurück.',
    },
  },

  party_magnet: {
    name: 'Magnet',
    room: 'partyausstatter',
    verbs: {
      look: 'Kleiner Werbemagnet des Sachsenotto-Centers. Praktisch.',
      take: 'Er klebt sofort an Ihrer Uhr. Sie lösen ihn wieder ab.',
    },
    useWith: {
      party_lagertuer: () => 'Der Magnet klebt an der Tür. Das war kein Rätsel.',
    },
  },

  party_lichtschalter: {
    name: 'Lichtschalter',
    room: 'partyausstatter',
    verbs: {
      look:  'Der Schalter ist an der Wand neben der Lagertür.',
      open:  'Kein Licht. Die Birne ist kaputt.',
      close: 'Kein Licht. Die Birne ist kaputt.',
    },
    useWith: {
      party_lagertuer: () => 'Sie betätigen den Schalter. Kein Licht im Lagerraum. Die Birne scheint kaputt zu sein.',
      taschenlampe:    () => 'Die Taschenlampe hat schon einen Schalter.',
    },
  },

  party_philosophin: {
    name: 'Luftballon-Philosophin',
    npc: true,
    room: 'partyausstatter',
    verbs: {
      look: 'Sie hält einen leeren Luftballon in der linken Hand und schaut nachdenklich ins Leere.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('party_philosophin'),
    },
    giveTo: {
      luftballon:    () => 'Sie hält ihn kurz. »Voller Luft.« Gibt ihn zurück. »Gehört niemandem.«',
      kerze:         () => '»Licht ohne Luft. Oder Luft ohne Licht. Was ist nützlicher?« Pause. Sie gibt sie zurück.',
      stimmgabel:    () => 'Sie schlägt sie an. Hört zu. »Ein perfekter Ton. Anders als alles andere hier.« Sie gibt sie zurück.',
      eiskuebel:     () => '»Leer oder voll – das ist immer die Frage.« Sie gibt ihn zurück.',
      papst_maske:   () => 'Sie hält die Papst-Maske vors Gesicht. »Identität als Oberfläche.« Eine Pause. »Oder Oberfläche als Identität?« Sie gibt sie zurück.',
    },
  },

  // ═══════════════════════════════════════════════════════════
  // BLUMENLADEN
  // ═══════════════════════════════════════════════════════════
  blum_oel: {
    name: 'Öl',
    room: 'blumenladen',
    visible: () => !hasItem('oel'),
    verbs: {
      look: 'Kleines Fläschchen. Beschriftet: Schmiermittel – nicht für Salat. Wofür die das hier brauchen?',
      take: () => { addItem('oel'); return 'Sie nehmen das Öl. Der Blumenhändler winkt ab – er braucht es gerade nicht.'; },
    },
  },

  blum_schluessel: {
    name: 'Schlüssel',
    room: 'blumenladen',
    visible: () => !S.p.schluessel_befreit,
    verbs: {
      look: 'Ein Schlüssel liegt zwischen dem Regal und der Wand. Sichtbar, aber unerreichbar. Da ist maximal ein Zentimeter Luft.',
      take: 'Die Lücke ist zu eng für Ihre Hand.',
    },
    useWith: {
      brotmesser: () => {
        S.p.schluessel_befreit = true;
        return 'Das Brotmesser ist lang und schmal genug. Sie hebeln den Schlüssel heraus.';
      },
      baeck_brotmesser: () => {
        S.p.schluessel_befreit = true;
        return 'Das Brotmesser ist lang und schmal genug. Sie hebeln den Schlüssel heraus.';
      },
      blum_lineal: () => 'Das Lineal ist dafür zu kurz.',
    },
  },

  blum_schluessel_frei: {
    name: 'Schlüssel',
    room: 'blumenladen',
    visible: () => S.p.schluessel_befreit && !S.p.blumen_befreit && !hasItem('blum_vitrineschluessel'),
    verbs: {
      look: 'Der Schlüssel liegt jetzt auf dem Boden.',
      take: () => { addItem('blum_vitrineschluessel'); return 'Als Sie den Schlüssel aufheben, ruft der Blumenhändler begeistert: »Super! Wissen Sie was, öffnen Sie mit dem Schlüssel doch das Schloss an der Vitrine und nehmen Sie zum Dank den Blumenstrauß! Aber lassen Sie den Schlüssel dann stecken.«'; },
    },
  },

  blum_vitrine: {
    name: 'Kühlvitrine',
    room: 'blumenladen',
    verbs: {
      look:  () => S.p.blumen_befreit ? 'Die Vitrine steht offen. Der Strauß ist weg.' : 'Die Vitrine ist verschlossen. Darin: der einzige frische Strauß im ganzen Laden.',
      open: () => {
        if (S.p.blumen_befreit) return 'Die Vitrine ist schon offen.';
        if (hasItem('blum_vitrineschluessel')) {
          S.p.blumen_befreit = true;
          removeItem('blum_vitrineschluessel');
          addItem('blumenstrauss');
          return 'Der Schlüssel passt. Die Vitrine öffnet sich. Sie nehmen den Strauß – frisch, kühl, perfekt. Der Blumenhändler lächelt kurz.';
        }
        return 'Abgeschlossen.';
      },
    },
    useWith: {
      brotmesser:       () => 'Ein Brotmesser ist kein Schlüssel.',
      baeck_brotmesser: () => 'Ein Brotmesser ist kein Schlüssel.',
      schere:       () => 'Die Schere öffnet keine Kühlvitrine.',
      party_schere: () => 'Die Schere öffnet keine Kühlvitrine.',
      blum_vitrineschluessel: () => {
        if (S.p.blumen_befreit) return 'Die Vitrine ist schon offen.';
        S.p.blumen_befreit = true;
        removeItem('blum_vitrineschluessel');
        addItem('blumenstrauss');
        return 'Es war wirklich der Vitrinenschlüssel. Sie öffnen das Schloss, öffnen die Vitrine und nehmen den Strauß.';
      },
    },
  },

  blum_regal: {
    name: 'Regal',
    room: 'blumenladen',
    verbs: {
      look: 'Es ist voller Vasen und deshalb sehr schwer.',
      take: 'Das Regal bewegt sich keinen Millimeter.',
    },
  },

  blum_heizung: {
    name: 'Heizungsregler',
    room: 'blumenladen',
    verbs: {
      look:  () => S.p.heizung_aus ? 'Er zeigt auf Minimum. Der Laden wird angenehm kühl.' : 'Zeigt auf Maximum. Der Regler klemmt.',
      open:  () => S.p.heizung_aus ? 'Die Heizung ist schon aus.' : 'Klemmt. Bewegt sich nicht.',
    },
    useWith: {
      oel: () => {
        if (S.p.heizung_aus) return 'Die Heizung ist schon aus.';
        S.p.heizung_aus = true;
        return 'Der Regler lässt sich jetzt drehen. Die Heizung geht aus. Ahhh, angenehmer.';
      },
      blum_oel: () => {
        if (S.p.heizung_aus) return 'Die Heizung ist schon aus.';
        S.p.heizung_aus = true;
        return 'Der Regler lässt sich jetzt drehen. Die Heizung geht aus. Ahhh, angenehmer.';
      },
    },
  },

  blum_verkaeuf: {
    name: 'Verkäufer',
    npc: true,
    room: 'blumenladen',
    verbs: {
      look: 'Er schwitzt und fächert sich mit einer Preisliste Luft zu.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('blum_verkaeuf'),
    },
    giveTo: {
      kerze:         () => '»Eine Kerze.« Er fächert sich damit kurz Luft zu. »Das ist tatsächlich etwas besser. Danke.« Gibt sie zurück.',
      stimmgabel:    () => 'Er schlägt sie an. Hält inne. »Schöner Ton.« Pause. »Ich weiß nicht warum, aber das hilft.« Er gibt sie zurück.',
      eiskuebel:     () => 'Er schaut auf den Eiskübel. Lange. »Das wäre eigentlich perfekt gewesen.« Er gibt ihn zurück. »Zu spät für die Blumen, aber trotzdem.«',
      brotmesser: () => {
        if (S.p.blumen_befreit) return 'Er fächert sich weiter Luft zu. »Das Messer brauche ich nicht mehr.«';
        S.p.schluessel_befreit = true;
        S.p.blumen_befreit = true;
        addItem('blumenstrauss');
        return 'Er hebelt den Schlüssel heraus, öffnet die Vitrine, gibt Ihnen den Strauß. »Frische Luft würde dem Laden guttun.« Das Brotmesser gibt er zurück.';
      },
    },
  },

  blum_welke: {
    name: 'Welke Blumen',
    room: 'blumenladen',
    verbs: {
      look: 'Schade. Und traurig anzuschauen.',
      take: 'Sie heben eine welke Blume an. Sie fällt fast auseinander. Sie legen sie wieder hin.',
    },
    useWith: {
      blum_spray: () => 'Hilft nichts mehr.',
    },
    giveTo: {
      blum_influencerin: () => '»Oh! Vergänglichkeit pur!« Sie fotografiert. »Memento mori. Danke.« Sie gibt sie zurück.',
      blum_allergiker:   () => 'Er niest sofort. »Bitte nicht in meine Richtung. Nicht mal die welken.«',
    },
  },

  blum_spray: {
    name: 'Blumenspray',
    room: 'blumenladen',
    verbs: {
      look: 'Für die Blumen. Hat hier wohl noch nie jemand benutzt.',
      take: 'Hier lassen Sie es besser.',
      use:  'Sie sprühen kurz in die Luft. Erfrischt.',
    },
    useWith: {
      blum_schaufenster: () => 'Sie sprühen die Scheibe ein. Die Beschlagenheit löst sich kurz. Aber kommt sofort wieder.',
    },
  },

  blum_lineal: {
    name: 'Lineal',
    room: 'blumenladen',
    verbs: {
      look: '15 cm. Aus Plastik.',
      take: 'Sie nehmen es in die Hand und spielen eine lustige Melodie mit dem Lineal auf dem Tresen. Beeindruckend. Dann legen Sie es wieder hin.',
    },
    useWith: {
      blum_schluessel: () => 'Zu kurz. Und die Lücke ist zu schmal.',
    },
  },

  blum_arnomakerze: {
    name: 'Aromakerze',
    room: 'blumenladen',
    verbs: {
      look: 'Sie brennt. Mmmmh, Lavendelduft!',
      take: 'Sie ist heiß.',
    },
    useWith: {
      oel:          () => 'Das wäre gefährlich. Das machen Sie natürlich nicht.',
      blum_oel:     () => 'Das wäre gefährlich. Das machen Sie natürlich nicht.',
      blumenstrauss: () => 'Sie halten den Strauß über die Flamme. Und dann ziehen Sie ihn schnell zurück. Dumme Idee.',
    },
  },

  blum_giesskanne: {
    name: 'Gießkanne',
    room: 'blumenladen',
    verbs: {
      look: 'Sie ist voller Wasser.',
      take: 'Zu schwer und zu voll.',
    },
    useWith: {
      blum_regal:    () => 'Das Regal ist jetzt nass. Wow.',
      blum_schluessel: () => 'Der Schlüssel ist jetzt nass. Aber er liegt noch im Spalt.',
      blum_heizung:  () => 'Die wird nicht größer, wenn Sie sie gießen. Deshalb lassen Sie es.',
    },
    giveTo: {
      blum_verkaeuf: () => '»Die hab ich schon.« Er schaut auf den Eiskübel. Dann auf die Heizung. »Aber kein Wasser mehr.«',
    },
  },

  blum_schaufenster: {
    name: 'Schaufenster',
    room: 'blumenladen',
    verbs: {
      look: 'Es ist sehr beschlagen, denn es ist warm hier.',
      use:  'Sie schreiben »Hilfe« ins Beschlagene. Von draußen kaum lesbar.',
    },
  },

  blum_influencerin: {
    name: 'Floristik-Influencerin',
    npc: true,
    room: 'blumenladen',
    verbs: {
      look: 'Sie hält ihr Telefon hoch und fotografiert ... die welken Blumen.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('blum_influencerin'),
    },
    giveTo: {
      blumenstrauss: () => '»Oh warte!« Sie fotografiert ihn aus drei Winkeln. »Danke. Perfect lighting.« Gibt ihn zurück.',
      kerze:         () => 'Sie fotografiert die Kerze neben den welken Blumen. »Licht und Verfall. Ich poste das.« Gibt sie zurück.',
      luftballon:    () => '»Der Ballon und die welken Blumen. Zu viel Kontrast.« Pause. »Oder genau richtig.« Gibt ihn zurück.',
      stimmgabel:    () => 'Sie schlägt sie an und hält ihr Telefon daneben. »Ambient sound. Danke.« Gibt sie zurück.',
    },
  },

  blum_allergiker: {
    name: 'Allergiker',
    npc: true,
    room: 'blumenladen',
    verbs: {
      look: 'Er steht an der Wand, niest gelegentlich, aber hält trotzdem durch.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('blum_allergiker'),
    },
    giveTo: {
      blumenstrauss: () => 'Er niest sofort. Weicht einen Schritt zurück. »Bitte nicht in meine Richtung.«',
      kerze:         () => 'Er niest. »Danke. Aber Kerzen helfen nicht gegen Allergien.« Gibt sie zurück.',
      stimmgabel:    () => 'Er schlägt sie an. »Ein schöner Ton.« *niest* »Trotzdem nicht heilend.«',
      eiskuebel:     () => '»Kaltes Wasser!« Er schaut hoffnungsvoll. »Hilft leider auch nicht.« *niest*',
    },
  },

  // ═══════════════════════════════════════════════════════════
  // MUSIKGESCHÄFT
  // ═══════════════════════════════════════════════════════════
  musik_tasch: {
    name: 'Taschenlampe',
    room: 'musikgeschaeft',
    visible: () => !hasItem('taschenlampe'),
    verbs: {
      look: 'Sie hängt am Notenständer. Komisch. Aber sie funktioniert.',
      take: () => { addItem('taschenlampe'); return 'Sie nehmen die Taschenlampe. Der Verkäufer schaut kurz rüber. Dann wieder zu seinen Noten. Ihm scheint nichts aufzufallen, was falsch sein könnte.'; },
    },
  },

  musik_stimmgabel: {
    name: 'Stimmgabel',
    room: 'musikgeschaeft',
    visible: () => !hasItem('stimmgabel') && !S.stamps[4] && S.p.klavier_gesehen,
    verbs: {
      look: () => S.p.klavier_offen
        ? 'Liegt im nun geöffneten Klavier. Jetzt erreichbar.'
        : 'Liegt im Inneren des Klaviers. Durch den Glaskorpus gut sichtbar. Der Deckel ist gesperrt.',
      take: () => {
        if (!S.p.klavier_offen) return 'Der Deckel ist zu.';
        addItem('stimmgabel');
        return 'Sie nehmen die Stimmgabel. Der Klavierstimmer beobachtet Sie schweigend. Sie glauben, dass Sie ihn leise schluchzen hören. Aber warum hat er keine eigene Stimmgabel mitgebracht?';
      },
    },
  },

  musik_schloss: {
    name: 'Zahlenschloss',
    room: 'musikgeschaeft',
    visible: () => !S.p.klavier_offen,
    verbs: {
      look: () => {
        if (S.p.klavier_offen) return 'Das Schloss ist geöffnet. Der Klavierdeckel auch.';
        if (S.p.kombi_bekannt) {
          openComboModal();
          return null;
        }
        return 'Vierstellig. Die Kombination steht auf einem Aufkleber unten am Klavier – aber der ist komplett verdreckt.';
      },
      open: () => {
        if (!S.p.kombi_bekannt) return 'Sie brauchen die Kombination. Der Aufkleber ist noch unleserlich.';
        openComboModal();
        return null;
      },
    },
  },

  musik_aufkleber: {
    name: 'Aufkleber',
    room: 'musikgeschaeft',
    verbs: {
      look: () => S.p.aufkleber_lesbar
        ? 'Der Aufkleber zeigt jetzt eine vierstellige Zahl: 1907.'
        : 'Unter dem Klavier. Komplett verdreckt. Nichts lesbar.',
    },
    useWith: {
      taschenlampe: () => S.p.aufkleber_lesbar
        ? 'Sie sehen die Zahl: 1907. Hell erleuchtet vom Spot der Taschenlampe.'
        : 'Sie beleuchten den Dreck, aber die Zahl können Sie trotzdem nicht lesen.',
      musik_tasch: () => S.p.aufkleber_lesbar
        ? 'Sie sehen die Zahl: 1907. Hell erleuchtet vom Spot der Taschenlampe.'
        : 'Sie beleuchten den Dreck, aber die Zahl können Sie trotzdem nicht lesen.',
      brotmesser:       () => S.p.aufkleber_lesbar ? 'Die Zahl ist schon sichtbar: 1907.' : 'Sie kratzen. Der Dreck gibt nicht nach.',
      baeck_brotmesser: () => S.p.aufkleber_lesbar ? 'Die Zahl ist schon sichtbar: 1907.' : 'Sie kratzen. Der Dreck gibt nicht nach.',
      eiskuebel: () => {
        if (S.p.aufkleber_lesbar) return 'Der Aufkleber ist schon sauber. Die Zahl: 1907.';
        if (!S.p.eiskuebel_voll) return 'Der Eiskübel ist leer. So geht das nicht.';
        S.p.aufkleber_lesbar = true;
        S.p.kombi_bekannt = true;
        return 'Das Wasser löst den Dreck. Eine vierstellige Zahl wird sichtbar: 1907.';
      },
      getr_eiskuebel: () => {
        if (S.p.aufkleber_lesbar) return 'Der Aufkleber ist schon sauber. Die Zahl: 1907.';
        if (!S.p.eiskuebel_voll) return 'Der Eiskübel ist leer. So geht das nicht.';
        S.p.aufkleber_lesbar = true;
        S.p.kombi_bekannt = true;
        return 'Das Wasser löst den Dreck. Eine vierstellige Zahl wird sichtbar: 1907.';
      },
      musik_mopp: () => 'Der Mopp ist zu grob, um hier etwas zu erreichen. Der Aufkleber wäre fast gerissen.',
    },
  },

  musik_klavier: {
    name: 'Klavier',
    room: 'musikgeschaeft',
    verbs: {
      look: () => {
        S.p.klavier_gesehen = true;
        if (S.p.klavier_offen) return 'Ein transparentes Klavier. Der Deckel steht offen. Die Stimmgabel liegt griffbereit darin.';
        return 'Ein transparentes Klavier. Durch den Glaskorpus sieht man im Inneren eine Stimmgabel. Der Deckel ist mit einem Zahlenschloss gesperrt.';
      },
      open:  'Sie spielen C-Dur. Verstimmt.',
    },
    useWith: {
      stimmgabel:       () => 'Sie schlagen die Stimmgabel an und spielen nach. Eindeutig verstimmt.',
      musik_stimmgabel: () => 'Sie schlagen die Stimmgabel an und spielen nach. Eindeutig verstimmt.',
      musik_mopp:       () => 'Die Tasten bleiben lieber trocken.',
    },
  },

  musik_gitarre: {
    name: 'Gitarre',
    room: 'musikgeschaeft',
    verbs: {
      look: 'Eine wunderschöne Akustikgitarre.',
      take: '»Die ist nicht zum Anfassen.« – Der Verkäufer.',
    },
    useWith: {
      schere:           () => 'Das können Sie gerne mit Ihrer eigenen Gitarre ausprobieren.',
      party_schere:     () => 'Das können Sie gerne mit Ihrer eigenen Gitarre ausprobieren.',
      stimmgabel:       () => 'Sie halten die Stimmgabel an die Gitarre. Der Verkäufer zuckt kurz zusammen, aber sagt nichts.',
      musik_stimmgabel: () => 'Sie halten die Stimmgabel an die Gitarre. Der Verkäufer zuckt kurz zusammen, aber sagt nichts.',
    },
  },

  musik_noten: {
    name: 'Noten',
    room: 'musikgeschaeft',
    verbs: {
      look: 'Verschiedene Stücke. Darunter: »Happy Birthday« in sieben verschiedenen Versionen.',
      take: 'Sie blättern durch. Happy Birthday in sieben Variationen. Sie legen es zurück.',
    },
    useWith: {
      musik_klavier: () => 'Sie spielen Happy Birthday. Verstimmt. Es klingt traurig und schön zugleich.',
    },
    giveTo: {
      musik_stimmer: () => '»Happy Birthday.« Er schaut. »Ich bin zum Stimmen hier, nicht zum Spielen.« Er gibt sie zurück.',
    },
  },

  musik_akkordeon: {
    name: 'Akkordeon',
    room: 'musikgeschaeft',
    verbs: {
      look:  'Es sieht aus wie ein Akkordeon. Erstaunlich.',
      open:  'Es macht ein lautes Geräusch. Der Verkäufer schaut kurz auf.',
    },
  },

  musik_verkaeufer: {
    name: 'Verkäufer',
    npc: true,
    room: 'musikgeschaeft',
    verbs: {
      look: 'Stimmt eine Ukulele. Falsch.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('musik_verkaeufer'),
    },
    giveTo: {
      stimmgabel:    () => 'Er schlägt sie an. Lauscht. »Genau das A.« Er gibt sie zurück. »Ich brauch ein Klavier dafür.«',
      kerze:         () => '»Das Klavier hätte eine Feier verdient.« Er gibt sie zurück. »Aber noch nicht.«',
      blumenstrauss: () => '»Schön. Aber ich stimme gerade eine Ukulele.« Er gibt ihn zurück. »Falsch, aber immerhin.«',
      eiskuebel: () => {
        if (S.p.klavier_offen) return '»Das Klavier ist schon offen.« Er stimmt weiter. Immer noch falsch.';
        S.p.aufkleber_lesbar = true;
        S.p.kombi_bekannt = true;
        S.p.klavier_offen = true;
        return 'Er wischt den Aufkleber ab. »1907. Das Gründungsjahr von Sachsenotto.« Er öffnet das Schloss. »Bitte sehr.« Die Stimmgabel liegt jetzt auf dem offenen Deckel.';
      },
    },
  },


  musik_mopp: {
    name: 'Wischmopp',
    room: 'musikgeschaeft',
    verbs: {
      look: 'Der ist ... feucht. Und dreckig.',
      take: 'Schwer und nass.',
    },
    useWith: {
      musik_aufkleber: () => 'Der Mopp ist zu grob, um hier etwas zu erreichen. Der Aufkleber wäre fast gerissen.',
    },
  },

  musik_notenstaender: {
    name: 'Notenständer',
    room: 'musikgeschaeft',
    verbs: {
      look: 'Aus Metall. Klappbar. Wie früher. Manche Dinge ändern sich nie.',
    },
    useWith: {
      musik_noten: () => 'Sie legen die Noten auf den Ständer. Das sieht sehr professionell aus.',
    },
  },

  musik_stimmer: {
    name: 'Klavierstimmer',
    npc: true,
    room: 'musikgeschaeft',
    verbs: {
      look: 'Er sitzt auf einem Stuhl vor dem Klavier. Und wartet offenbar seit Stunden.',
      take: 'Das ist ein Mensch.',
      talk: () => showDialog('musik_stimmer'),
    },
    giveTo: {
      kerze:         () => '»Danke. Das Licht ist tatsächlich schlecht.« Er stellt sie auf den Boden vor das Klavier. »Stimmt aber immer noch nicht.«',
      blumenstrauss: () => '»Das ist nett.« Er schaut kurz auf. »Mein Problem ist musikalisch, nicht botanisch.« Er gibt ihn zurück.',
      luftballon:    () => 'Er schaut den Ballon an. »19.« Pause. »Ich sitze seit drei Stunden hier. Das ist keine gute Zahl.«',
    },
  },

  // ═══════════════════════════════════════════════════════════
  // SERVICECENTER
  // ═══════════════════════════════════════════════════════════
  serv_mitarb: {
    name: 'Mitarbeiterin',
    npc: true,
    room: 'servicecenter',
    verbs: {
      look:  'Sie steht hinter dem Tresen in leuchtender Sachsenotto-Center-Weste. Sehr akkurat.',
      take:  'Das ist ein Mensch.',
      talk:  () => showDialog('serv_mitarb'),
    },
    giveTo: {
      kerze: () => {
        if (!hasItem('stempelkarte')) return 'Sie schaut auf die Kerze. »Haben Sie eine Stempelkarte?« Sie haben keine.';
        if (S.stamps[0]) return '»Den Stempel haben Sie schon.« Sie deutet auf Ihre Karte.';
        S.stamps[0] = true;
        removeItem('kerze');
        renderStamps();
        const n = S.stamps.filter(Boolean).length;
        return 'Sie legen die Kerze auf den Tresen. Die Mitarbeiterin nickt, greift zum Kerzen-Stempel und drückt ihn auf Ihre Karte. »Hier haben Sie den Kerzen-Stempel. Damit haben Sie jetzt ' + STAMP_WORDS[n - 1] + ' von fünf Stempeln.' + (n === 5 ? ' Herzlichen Glückwunsch! Ihre Karte ist voll.« Die Mitarbeiterin deutet Richtung Passage. »Dann mal los, was?«' : '«');
      },
      sektflasche: () => {
        if (!hasItem('stempelkarte')) return 'Sie schaut auf die Flasche. »Haben Sie eine Stempelkarte?« Sie haben keine.';
        if (S.stamps[1]) return '»Den Stempel haben Sie schon.«';
        S.stamps[1] = true;
        removeItem('sektflasche');
        renderStamps();
        const n = S.stamps.filter(Boolean).length;
        return 'Sie stellen die Flasche auf den Tresen. Die Mitarbeiterin liest das Etikett. »Jahrgang 2007. Ein besonderer Jahrgang!« Sie stempelt. »Hier haben Sie den Sekt-Stempel. Damit haben Sie jetzt ' + STAMP_WORDS[n - 1] + ' von fünf Stempeln.' + (n === 5 ? ' Herzlichen Glückwunsch! Ihre Karte ist voll.« Die Mitarbeiterin deutet Richtung Passage. »Dann mal los, was?«' : '«');
      },
      luftballon: () => {
        if (!hasItem('stempelkarte')) return 'Sie schaut auf den Ballon. »Haben Sie eine Stempelkarte?« Sie haben keine.';
        if (S.stamps[2]) return '»Den Stempel haben Sie schon.«';
        S.stamps[2] = true;
        removeItem('luftballon');
        renderStamps();
        const n = S.stamps.filter(Boolean).length;
        return 'Sie halten den Ballon über den Tresen. Er streift kurz die Deckenverkleidung. Die Mitarbeiterin stempelt, ohne aufzuschauen. »19? Das waren noch Zeiten! Na ja, hier haben Sie den Ballon-Stempel. Damit haben Sie jetzt ' + STAMP_WORDS[n - 1] + ' von fünf Stempeln.' + (n === 5 ? ' Herzlichen Glückwunsch! Ihre Karte ist voll.« Die Mitarbeiterin deutet Richtung Passage. »Dann mal los, was?«' : '«');
      },
      blumenstrauss: () => {
        if (!hasItem('stempelkarte')) return 'Sie schaut auf den Strauß. »Haben Sie eine Stempelkarte?« Sie haben keine.';
        if (S.stamps[3]) return '»Den Stempel haben Sie schon.«';
        S.stamps[3] = true;
        removeItem('blumenstrauss');
        renderStamps();
        const n = S.stamps.filter(Boolean).length;
        return 'Sie legen den Strauß auf den Tresen. Die Mitarbeiterin hält kurz inne. »Die sind wirklich frisch. Wie schön!« Sie stempelt. »Hier haben Sie den Blumen-Stempel. Damit haben Sie jetzt ' + STAMP_WORDS[n - 1] + ' von fünf Stempeln.' + (n === 5 ? ' Herzlichen Glückwunsch! Ihre Karte ist voll.« Die Mitarbeiterin deutet Richtung Passage. »Dann mal los, was?«' : '«');
      },
      stimmgabel: () => {
        if (!hasItem('stempelkarte')) return 'Sie schaut auf die Stimmgabel. »Haben Sie eine Stempelkarte?« Sie haben keine.';
        if (S.stamps[4]) return '»Den Stempel haben Sie schon.«';
        S.stamps[4] = true;
        removeItem('stimmgabel');
        renderStamps();
        const n = S.stamps.filter(Boolean).length;
        return 'Sie legen die Stimmgabel auf den Tresen. Die Mitarbeiterin schlägt sie kurz an. Ein Ton. Sie horcht. Und nickt. »Aaaaaaaah, wie schön!« Stimmt. Sie stempelt. »Hier haben Sie den Noten-Stempel. Damit haben Sie jetzt ' + STAMP_WORDS[n - 1] + ' von fünf Stempeln.' + (n === 5 ? ' Herzlichen Glückwunsch! Ihre Karte ist voll.« Die Mitarbeiterin deutet Richtung Passage. »Dann mal los, was?«' : '«');
      },
    },
  },

  serv_stempelset: {
    name: 'Stempelset',
    room: 'servicecenter',
    verbs: {
      look: 'Es gibt fünf Stempel: Kerze, Sekt, Ballon, Blume und Note.',
    },
  },

  serv_poster: {
    name: 'Poster',
    room: 'servicecenter',
    verbs: {
      look: 'Der Slogan: Fünf für Fün! Wer Stempel sammelt, kann füntastisch feiern! Darunter ein KI-generiertes Bild von einem Party-Bären. Ach herrje.',
    },
  },

};

// Dummy-Item für Vitrinenschlüssel (kein Icon nötig, kurze Anzeige)
ITEMS.blum_vitrineschluessel = { name: 'Schlüssel', icon: '🗝️', desc: 'Passt zur Kühlvitrine.' };

// ── Räume ───────────────────────────────────────────────────
const ROOMS = {
  passage: {
    name: 'Passage',
    firstDesc: 'Herzlich willkommen in Sachsenotto! Sie stehen in der Hauptpassage des neuen Sachsenotto-Centers. Es riecht nach frischer Farbe und Eröffnungsballons. Links und rechts: fünf Läden, alle geöffnet. Am Ende der Passage, hinter einer Glasfront: der Weg zur Dachterrasse.',
    returnDesc: 'Sie sind wieder in der Passage.',
    objects: [],
    exits: [
      { label: 'Bäckerei',              room: 'baeckerei' },
      { label: 'Getränkeladen',         room: 'getraenkeladen' },
      { label: 'Partyzubehör',          room: 'partyausstatter' },
      { label: 'Service-Center',        room: 'servicecenter' },
      { label: 'Blumenladen',           room: 'blumenladen' },
      { label: 'Musikgeschäft',         room: 'musikgeschaeft' },
      { label: 'Weg zur Dachterrasse',  room: 'glasfront' },
    ],
  },
  baeckerei: {
    name: 'Bäckerei',
    firstDesc: 'Der Bäcker schaut auf, als die Tür aufgeht. Er wirkt erleichtert. Es riecht nach Vanille. Hinter ihm ist eine Theke mit einer wunderschön verzierten Torte. Auf der Arbeitsfläche: Chaos in Mehl. Und ein eingeschweißter Gegenstand. An der Theke steht eine Kundin – schon etwas länger, dem Anschein nach. Seitlich steht jemand mit einem Notizbuch und verschränkten Armen. Er schaut auf die Torte.',
    returnDesc: 'Sie betreten die Bäckerei wieder. Es riecht immer noch nach Vanille.',
    objects: ['baeck_torte','baeck_kerzen','baeck_kerze_frei','baeck_brotmesser','baeck_baecker','baeck_kuehlschrank','baeck_kassenschublade','baeck_mehlsack','baeck_schuerze','baeck_telefon','baeck_fenster','baeck_brotlaib','baeck_kundin','baeck_kritiker'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
  getraenkeladen: {
    name: 'Getränkeladen',
    firstDesc: 'Flaschen vom Boden bis zur Decke, alphabetisch sortiert. Hinter einem vergitterten Tresen sehen Sie eine Sektflasche in goldener Folie. Das Vorhängeschloss am Gitter ist orangebraun vor Rost. Außerdem steht hinter dem Tresen der Verkäufer. Professionell, leicht resigniert. Mit Ihnen im Raum ist eine Person, die ratlos wirkt.',
    returnDesc: 'Sie betreten den Getränkeladen wieder. So viele Flaschen!',
    objects: ['getr_sektflasche','getr_sektflasche_frei','getr_schloss','getr_eiskuebel','getr_flaschen','getr_verkaeufer','getr_preisschild','getr_schluesselb','getr_karton','getr_besen','getr_schaufenster','getr_wasserhahn','getr_person'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
  partyausstatter: {
    name: 'Partyzubehör',
    firstDesc: 'Sofort beim Eintreten macht es: BUMM. Konfetti überall. Eine Kanone hat selbstständig gezündet. Die Verkäuferin schaut nicht mal auf – das ist offenbar nicht das erste Mal. In der Ecke hält jemand einen leeren Luftballon und schaut nachdenklich ins Leere. Im hinteren Teil des Ladens sehen Sie eine Lagertür, dahinter Dunkelheit. So will da niemand hinein.',
    returnDesc: 'Sie sind wieder im Laden für Partyzubehör. Auf dem Boden liegt noch mehr Konfetti als beim letzten Mal.',
    objects: ['party_schere','party_lagertuer','party_kanone1','party_kanone2','party_verkaeuferin','party_geschenk','party_masken','party_deko','party_pinata','party_magnet','party_lichtschalter','party_philosophin'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
  blumenladen: {
    name: 'Blumenladen',
    firstDesc: 'Hier ist es warm. Sehr warm. Die Heizung brummt im Hintergrund wie ein kleines Triebwerk. Die meisten Blumen hängen welk in ihren Vasen. Der Verkäufer wirkt völlig überfordert. Jemand hält sein Mobiltelefon hoch und fotografiert die welken Blumen. An der Wand steht eine weitere Person. Hinten links sehen Sie eine verglaste Kühlvitrine mit einem perfekten Blumenstrauß darin. Davor steht ein schweres Regal.',
    returnDesc: 'Sie betreten den Blumenladen wieder. Spannendes Klima hier.',
    objects: ['blum_oel','blum_schluessel','blum_schluessel_frei','blum_vitrine','blum_regal','blum_heizung','blum_verkaeuf','blum_welke','blum_spray','blum_lineal','blum_arnomakerze','blum_giesskanne','blum_schaufenster','blum_influencerin','blum_allergiker'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
  musikgeschaeft: {
    name: 'Musikgeschäft',
    firstDesc: 'Ein transparentes Klavier steht mittig im Raum, leicht schief. Noten liegen überall, weitere Instrumente stehen in Regalen an den Wänden. Der Verkäufer stimmt gerade eine Ukulele. Leider falsch. Auf einem Stuhl vor dem Klavier sitzt ein Mann und wartet.',
    returnDesc: 'Sie betreten das Musikgeschäft wieder. Die Ukulele klingt immer noch falsch.',
    objects: ['musik_tasch','musik_stimmgabel','musik_schloss','musik_aufkleber','musik_klavier','musik_gitarre','musik_noten','musik_akkordeon','musik_verkaeufer','musik_mopp','musik_notenstaender','musik_stimmer'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
  servicecenter: {
    name: 'Service-Center',
    firstDesc: 'Ein kleiner Schalter mit einem Tresen aus hellem Holz. Dahinter steht eine Mitarbeiterin. Auf dem Tresen steht ein Stempelset mit fünf Stempeln. An der Wand hängt ein Poster. Alles wirkt sehr neu, ordentlich und aufgeräumt. Hier wird einem geholfen.',
    returnDesc: 'Sie sind wieder im Service-Center.',
    objects: ['serv_mitarb', 'serv_stempelset', 'serv_poster'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
  glasfront: {
    name: 'Glasfront',
    firstDesc: 'Sie stehen vor einer Glasfront. Hier geht es offensichtlich zur Dachterrasse des Sachsenotto-Centers. Aber wie man durch die Glastür kommt, das erschließt sich nicht direkt.',
    returnDesc: 'Sie stehen wieder vor der Glasfront.',
    objects: ['passage_tuer', 'passage_schild', 'passage_centerplan', 'passage_ballons', 'passage_glasfront'],
    exits: [{ label: 'Zurück zur Passage', room: 'passage' }],
  },
};

// ── Dialog-Definitionen ─────────────────────────────────────
const DIALOGS = {

  // ─── BÄCKEREI ──────────────────────────────────────────────
  baecker: { nodes: {
    start: {
      lines: ['Ich hab meine Schere irgendwo hingelegt.', 'Die Kerze muss noch auf die Torte.'],
      choices: () => S.p.kerze_befreit ? [] : [
        { text: 'Wo haben Sie sie zuletzt gesehen?', condition: () => !S.p.dlg_baeck_wo,  goto: 'kein_plan' },
        { text: 'Kann ich helfen?', goto: 'hilfe_anbieten' },
        { text: 'Für wen ist die Torte?', condition: () => !S.p.dlg_baeck_wen, goto: 'fuer_wen' },
        { text: 'Schönen Geburtstag jedenfalls.', goto: 'END' },
      ],
    },
    kein_plan: {
      actions: [{ flag: 'dlg_baeck_wo' }],
      lines: ['Im Nebenraum. Oder draußen. Ich weiß es ehrlich gesagt nicht mehr.', 'Falls Sie eine Schere sehen – bringen Sie sie mir.'],
      choices: [
        { text: 'Was passiert, wenn die Kerzen nicht rechtzeitig drauf sind?', goto: 'zu_spaet' },
        { text: 'Mache ich.', goto: 'END' },
      ],
    },
    zu_spaet: {
      lines: ['Dann kommt der Kunde und die Torte hat keine Kerzen.', 'Das ist unprofessionell.', 'Ich bin seit 22 Jahren Bäcker. Das ist noch nie passiert.', 'Heute passiert es vielleicht.'],
      choices: [
        { text: 'Wann kommt der Kunde?', goto: 'wann_kunde' },
        { text: 'Ich finde die Schere.', goto: 'END' },
      ],
    },
    wann_kunde: {
      lines: ['Um 16 Uhr.', 'Es ist ... ich schau nicht auf die Uhr.'],
      choices: [{ text: 'Das ist klug.', goto: 'END' }],
    },
    fuer_wen: {
      actions: [{ flag: 'dlg_baeck_wen' }],
      lines: ['Ein Podcast. Anscheinend.', '19 Jahre. Der Kunde hat das sehr präzise bestellt.', '19 Kerzen, einzeln eingeschweißt. – Warum eingeschweißt, hab ich gefragt.', 'Für die Haltbarkeit, hat er gesagt.'],
      choices: [
        { text: 'Ergibt das einen Sinn?', goto: 'sinn' },
        { text: 'Der Kunde klingt organisiert.', goto: 'organisiert' },
        { text: 'War der Kunde klein?', goto: 'aussehen' },
      ],
    },
    sinn: {
      lines: ['Ich bin Bäcker. Ich frage nicht nach dem Sinn.', 'Ich backe und schweiße ein.', 'Heute auch ohne Schere, offenbar.'],
      choices: [{ text: 'Kann ich helfen?', goto: 'hilfe_anbieten' }],
    },
    organisiert: {
      lines: ['Sehr. Er hat die Bestellung per Fax aufgegeben.', 'Wir haben seit 2019 kein Fax mehr.', 'Er hat trotzdem ein Fax geschickt.', 'Ich hab es ausgedruckt und beachtet. Aus Respekt.'],
      choices: [{ text: 'Das ist schön.', goto: 'END' }],
    },
    aussehen: {
      lines: ['Eher klein. Freundlich. Hat zweimal danke gesagt.', 'Und sich dann noch einmal beim Rausgehen bedankt.'],
      choices: [
        { text: 'Klingt nach Teddy.', goto: 'klingt_nach_teddy' },
        { text: 'Ich kenne ihn.', goto: 'END' },
      ],
    },
    klingt_nach_teddy: {
      lines: ['Teddy?', 'Er hat sich nicht vorgestellt.', 'Er hat sich nur bedankt. Mehrfach.'],
      choices: [{ text: 'Das klingt nach ihm.', goto: 'END' }],
    },
    hilfe_anbieten: {
      lines: ['Wenn Sie eine Schere hätten, das wäre ideal.'],
      choices: () => [
        { text: 'Ich habe eine.', condition: () => hasItem('schere'), goto: 'schere_geben' },
        { text: 'Leider nicht.', goto: 'kein_plan' },
        { text: 'Was machen Sie mit dem Brotmesser dort?', condition: () => !hasItem('brotmesser'), goto: 'brotmesser_frage' },
      ],
    },
    brotmesser_frage: {
      lines: ['Das liegt da seit heute Morgen. Ich brauche es gerade nicht.', 'Nehmen Sie es, wenn Sie wollen.'],
      actions: [{ give: 'brotmesser' }],
      choices: [{ text: 'Danke.', goto: 'hilfe_anbieten' }],
    },
    schere_geben: {
      lines: ['Wunderbar. Einen Moment.', '…', 'Da. 19 Kerzen. Alle frei.', 'Nehmen Sie eine. Der Kunde hat gesagt, eine reicht.'],
      actions: [{ give: 'kerze' }, { take: 'schere' }, { flag: 'kerze_befreit' }],
      choices: [
        { text: 'Danke.', goto: 'nach_loesung' },
        { text: 'Wissen Sie, wofür die Kerze ist?', goto: 'wozu_kerze' },
      ],
    },
    wozu_kerze: {
      lines: ['Für das Service-Center, glaube ich.', 'Der Kunde hat was von einer Stempelaktion erzählt.', 'Ich hab nicht alles verstanden.'],
      choices: [{ text: 'Ich verstehe es auch nicht ganz.', goto: 'END' }],
    },
    nach_loesung: {
      lines: ['Gern. Und ... schönen Geburtstag, wem auch immer.'],
      choices: [{ text: 'Danke.', goto: 'END' }],
    },
  }},

  // ─── WARTENDE KUNDIN ───────────────────────────────────────
  baeck_kundin: { nodes: {
    start: {
      lines: ['Ich warte jetzt seit 40 Minuten.', 'Ich hab eine Bestellung aufgegeben. Irgendwas mit Mohn.'],
      choices: () => [
        { text: 'Was genau haben Sie bestellt?', condition: () => !S.p.dlg_kund_best,  goto: 'was_bestellt' },
        { text: 'Hat der Bäcker etwas gesagt?', condition: () => !S.p.dlg_kund_baeck, goto: 'baecker_gesagt' },
        { text: 'Das tut mir leid.',            condition: () => !S.p.dlg_kund_leid,  goto: 'tut_leid' },
        { text: 'Viel Geduld noch.', goto: 'END' },
      ],
    },
    was_bestellt: {
      actions: [{ flag: 'dlg_kund_best' }],
      lines: ['Mohntorte, glaube ich. Oder Mohnkuchen.', 'Oder war das Mohnbrötchen? Es war jedenfalls Mohn.'],
      choices: [
        { text: 'Vielleicht sollten Sie nochmal nachfragen.', goto: 'nachfragen' },
        { text: 'Mohn ist gut.', goto: 'mohn_gut' },
      ],
    },
    nachfragen: {
      lines: ['Das habe ich. Dreimal.', 'Beim dritten Mal hat er genickt. Ich weiß nicht, was das bedeutet.'],
      choices: [
        { text: 'Wahrscheinlich, dass er es weiß.', goto: 'wahrscheinlich' },
        { text: 'Vielleicht ein allgemeines Nicken.', goto: 'allgemeines_nicken' },
      ],
    },
    allgemeines_nicken: {
      lines: ['Ein allgemeines Nicken. Nach 40 Minuten.', 'Das ist keine Antwort.'],
      choices: [{ text: 'Nein.', goto: 'END' }],
    },
    wahrscheinlich: {
      lines: ['Hoffentlich.', 'Ich stehe hier seit 40 Minuten für ein Hoffentlich.'],
      choices: [{ text: 'Das klingt nach einem langen Tag.', goto: 'END' }],
    },
    mohn_gut: {
      lines: ['Ja.', 'Das ist das Einzige, worüber ich mir sicher bin.'],
      choices: [{ text: 'Eine solide Grundlage.', goto: 'END' }],
    },
    baecker_gesagt: {
      actions: [{ flag: 'dlg_kund_baeck' }],
      lines: ['Er hat gesagt: Einen Moment.', 'Das war vor 38 Minuten.'],
      choices: [
        { text: 'Vielleicht ein langer Moment.', goto: 'langer_moment' },
        { text: 'Momente können relativ sein.', goto: 'relativ' },
      ],
    },
    langer_moment: {
      lines: ['38 Minuten ist kein Moment.', 'Das ist eine Mittagspause.'],
      choices: [{ text: 'Da haben Sie recht.', goto: 'END' }],
    },
    relativ: {
      lines: ['Das hat mir auch schon mein Ex gesagt.', 'Über andere Dinge. Aber das Prinzip war dasselbe.'],
      choices: [{ text: '...', goto: 'END' }],
    },
    tut_leid: {
      actions: [{ flag: 'dlg_kund_leid' }],
      lines: ['Nicht so leid wie mir.', 'Ich hab um 12 Uhr einen Termin.'],
      choices: [
        { text: 'Wie spät ist es?', goto: 'uhrzeit' },
        { text: 'Das wird knapp.', goto: 'END' },
      ],
    },
    uhrzeit: {
      lines: ['12:04.'],
      choices: [{ text: '...', goto: 'END' }],
    },
  }},

  // ─── TORTENKRITIKER ────────────────────────────────────────
  baeck_kritiker: { nodes: {
    start: {
      lines: ['Entschuldigung – sind Sie auch wegen der Torte hier?', 'Ich schreibe ein Blog. Geburtstagstorten, konzeptuell betrachtet.'],
      choices: () => [
        { text: 'Was meinen Sie mit konzeptuell?', condition: () => !S.p.dlg_krit_konz,  goto: 'konzeptuell' },
        { text: 'Ich bin wegen etwas anderem hier.', condition: () => !S.p.dlg_krit_and, goto: 'was_anderes' },
        { text: 'Gibt es einen Markt für sowas?', condition: () => !S.p.dlg_krit_markt,  goto: 'markt' },
        { text: 'Viel Erfolg mit dem Blog.', goto: 'END' },
      ],
    },
    konzeptuell: {
      actions: [{ flag: 'dlg_krit_konz' }],
      lines: ['Die Frage ist doch: Was sagt die Torte über den Jubilar?', '19 Kerzen. Eingeschweißt. Das ist eine Aussage.'],
      choices: [
        { text: 'Welche Aussage?', goto: 'aussage' },
        { text: 'Die Kerzen sind eingeschweißt weil die Schere fehlt.', goto: 'schere_erklaerung' },
      ],
    },
    aussage: {
      lines: ['Unerreichbarkeit. Versprechen hinter Folie.', 'Das Licht, das nicht brennen darf. Das Fest, das noch nicht beginnen kann.'],
      choices: [
        { text: 'Oder die Schere fehlt.', goto: 'schere_erklaerung' },
        { text: 'Das ist ... eine Interpretation.', goto: 'interpretation' },
      ],
    },
    interpretation: {
      lines: ['Alle Kunst ist Interpretation.', 'Ich gebe ihr 7 von 10. Punktabzug gibt es für die fehlende Sensorik.'],
      choices: [
        { text: 'Was ist die Sensorik?', goto: 'sensorik' },
        { text: '7 von 10 klingt gut.', goto: 'END' },
      ],
    },
    sensorik: {
      lines: ['Der Geruch. Der Klang beim Anschneiden. Das taktile Erlebnis.', 'Eine Torte muss auch gehört werden wollen.'],
      choices: [{ text: 'Ich gehe jetzt.', goto: 'END' }],
    },
    schere_erklaerung: {
      lines: ['...', 'Das wäre natürlich auch möglich.', 'Ich behalte dennoch die 7.'],
      choices: [{ text: 'Fair.', goto: 'END' }],
    },
    was_anderes: {
      actions: [{ flag: 'dlg_krit_and' }],
      lines: ['Schade. Ich hätte gerne ein Zitat gehabt.', 'Für das Blog. Zufälliger Passant findet Torte konzeptuell stark.'],
      choices: [
        { text: 'Das kann ich sagen.', goto: 'zitat_ja' },
        { text: 'Lieber nicht.', goto: 'END' },
      ],
    },
    zitat_ja: {
      lines: ['Wunderbar. Und Ihr Name?'],
      choices: [
        { text: 'Esel.', goto: 'name_esel' },
        { text: 'Herr Müller.', goto: 'name_mueller' },
      ],
    },
    name_esel: {
      lines: ['... Esel.', 'Das schreibe ich so.'],
      choices: [{ text: 'Bitte.', goto: 'END' }],
    },
    name_mueller: {
      lines: ['Herr Müller. Gut.', 'Herr Müller findet die Torte konzeptuell stark. Danke.'],
      choices: [{ text: 'Gern.', goto: 'END' }],
    },
    markt: {
      actions: [{ flag: 'dlg_krit_markt' }],
      lines: ['Meine Mutter fragt das auch.', 'Die Antwort ist: noch nicht. Aber ich bin optimistisch.'],
      choices: [{ text: 'Viel Erfolg.', goto: 'END' }],
    },
  }},

  // ─── GETRÄNKELADEN-VERKÄUFER ───────────────────────────────
  getr_verkaeufer: { nodes: {
    start: {
      lines: ['Das Schloss klemmt seit der Eröffnung.', 'Ich komme nicht ran.'],
      choices: () => S.p.sekt_befreit ? [] : [
        { text: 'Wie lange schon?',           condition: () => !S.p.dlg_getr_lang, goto: 'wie_lange' },
        { text: 'Was ist hinter dem Gitter?', condition: () => !S.p.dlg_getr_gitt, goto: 'was_dahinter' },
        { text: 'Haben Sie Öl?', goto: 'hat_oel' },
        { text: 'Ich helfe Ihnen.', goto: 'hilfe_anbieten' },
      ],
    },
    wie_lange: {
      actions: [{ flag: 'dlg_getr_lang' }],
      lines: ['Seit dem ersten Tag.', 'Ich hab dem Center-Management Bescheid gegeben.', 'Die haben gesagt: wird erledigt.', 'Das war vor drei Wochen.'],
      choices: [
        { text: 'Und seitdem?', goto: 'seitdem' },
        { text: 'Wird erledigt ist kein Zeitplan.', goto: 'kein_zeitplan' },
      ],
    },
    seitdem: {
      lines: ['Nichts.', 'Ich hab nochmal angerufen.', 'Ist in Bearbeitung, haben sie gesagt.', 'Das klingt besser als wird erledigt.', 'Ich glaube aber, es ist dasselbe.'],
      choices: [
        { text: 'Haben Sie Öl probiert?', goto: 'hat_oel' },
        { text: 'Das verstehe ich.', goto: 'END' },
      ],
    },
    kein_zeitplan: {
      lines: ['Nein.', 'Aber ich hab gelernt, dass wird erledigt und ist in Bearbeitung auf dasselbe hinauslaufen.', 'Nämlich: nichts.'],
      choices: [{ text: 'Haben Sie Öl probiert?', goto: 'hat_oel' }],
    },
    was_dahinter: {
      actions: [{ flag: 'dlg_getr_gitt' }],
      lines: ['Mein bestes Sortiment.', 'Und ganz vorne: die 2007er Sektflasche.', 'Die liegt da seit der Eröffnung.', 'Jemand hat sie bestellt. Für heute anscheinend.'],
      choices: [
        { text: 'Wer hat sie bestellt?', goto: 'wer_bestellt' },
        { text: '2007 ist ein guter Jahrgang.', goto: 'guter_jahrgang' },
      ],
    },
    wer_bestellt: {
      lines: ['Ein freundlicher Mann.', 'Kleiner Mann. Hat sich mehrfach bedankt.', 'Er meinte, er kommt sie heute abholen.', 'Aber ich komme ja nicht ran.'],
      choices: [{ text: 'Ich kümmere mich darum.', goto: 'hilfe_anbieten' }],
    },
    guter_jahrgang: {
      lines: ['So hab ich das auch dem Center-Management gesagt.', 'Die waren unbeeindruckt.'],
      choices: [
        { text: 'Menschen ohne Gespür für Wein.', goto: 'kein_gespuer' },
        { text: 'Ich helfe Ihnen.', goto: 'hilfe_anbieten' },
      ],
    },
    kein_gespuer: {
      lines: ['Genau das.', '2007 war ein außergewöhnliches Jahr.', 'Für Sekt jedenfalls.', 'Und, soweit ich weiß, auch für Podcasts.'],
      choices: [
        { text: 'Woher wissen Sie das?', goto: 'woher_podcast' },
        { text: 'Das stimmt.', goto: 'END' },
      ],
    },
    woher_podcast: {
      lines: ['Der kleine Mann hat es erwähnt.', 'Er wirkte stolz.'],
      choices: [
        { text: 'Das war Teddy.', goto: 'das_war_teddy' },
        { text: 'Das klingt nach jemandem, den ich kenne.', goto: 'END' },
      ],
    },
    das_war_teddy: {
      lines: ['Teddy.', 'Er hat sich nicht vorgestellt, aber Teddy klingt richtig.'],
      choices: [{ text: 'Ich hole die Flasche für ihn.', goto: 'hilfe_anbieten' }],
    },
    hat_oel: {
      lines: ['Nein. Haben Sie welches?'],
      choices: () => [
        { text: 'Ja.', condition: () => hasItem('oel'), goto: 'oel_geben' },
        { text: 'Noch nicht.', goto: 'noch_nicht_oel' },
      ],
    },
    noch_nicht_oel: {
      lines: ['Im Blumenladen gibt es manchmal Schmiermittel.', 'Für die Pflanzenscheren.', 'Das könnte helfen.'],
      choices: [{ text: 'Ich schaue nach.', goto: 'END' }],
    },
    hilfe_anbieten: {
      lines: ['Wenn Sie Öl auftreiben – sehr gerne.', 'Das Schloss ist verrostet. Das müsste reichen.'],
      choices: () => [
        { text: 'Ich versuche es.', goto: 'END' },
        { text: 'Haben Sie sonst noch etwas, das ich mitnehmen kann?', condition: () => !hasItem('eiskuebel'), goto: 'sonst_noch' },
      ],
    },
    sonst_noch: {
      lines: ['Den Eiskübel dort. Den brauche ich gerade nicht.', 'Steht seit drei Wochen rum. Nehmen Sie ihn.'],
      actions: [{ give: 'eiskuebel' }],
      choices: [{ text: 'Danke.', goto: 'END' }],
    },
    oel_geben: {
      lines: ['Ausgezeichnet.', '...', 'Da. Das Schloss gibt nach.', 'Bitte sehr. Die 2007er.'],
      actions: [{ give: 'sektflasche' }, { take: 'oel' }, { flag: 'sekt_befreit' }],
      choices: [
        { text: 'Danke.', goto: 'nach_loesung' },
        { text: 'Wissen Sie, wofür die Flasche ist?', goto: 'wozu_flasche' },
      ],
    },
    wozu_flasche: {
      lines: ['Für die Stempelaktion, nehme ich an.', 'Der Bestellende hat etwas davon erzählt.', 'Fünf Gegenstände, eine Dachterrasse.', 'Klingt nach einem guten Abend.'],
      choices: [{ text: 'Hoffentlich.', goto: 'END' }],
    },
    nach_loesung: {
      lines: ['Gern. Und – zum Wohl.'],
      choices: [{ text: 'Danke.', goto: 'END' }],
    },
  }},

  // ─── PERSON MIT EINKAUFSZETTEL ─────────────────────────────
  getr_person: { nodes: {
    start: {
      lines: ['Entschuldigung – Sie kennen sich hier aus?', 'Ich suche Sekt. Trocken. Günstig. Meine Frau hat Sekt auf den Zettel geschrieben.', 'Mehr steht da nicht.'],
      choices: () => [
        { text: 'Der Jahrgang 2007 ist empfehlenswert.', condition: () => !S.p.dlg_gper_j2007, goto: 'j2007' },
        { text: 'Was ist der Anlass?',                  condition: () => !S.p.dlg_gper_anl,   goto: 'anlass' },
        { text: 'Ich kenne mich hier nicht aus.',       condition: () => !S.p.dlg_gper_nicht, goto: 'nicht_auskennen' },
        { text: 'Viel Erfolg.', goto: 'END' },
      ],
    },
    anlass: {
      actions: [{ flag: 'dlg_gper_anl' }],
      lines: ['Geburtstag. Glaube ich.', 'Oder Jubiläum. Sie hat Sekt geschrieben und dann bitte.', 'Das bitte macht mich nervös.'],
      choices: [
        { text: 'Warum nervös?', goto: 'nervoes' },
        { text: 'Ein höflicher Zettel ist doch gut.', goto: 'hoeflich' },
      ],
    },
    nervoes: {
      lines: ['Wenn sie bitte schreibt, meint sie: vergiss das nicht.', 'Und wenn sie vergiss das nicht meint, meint sie eigentlich noch etwas anderes.', 'Was genau, weiß ich nach 14 Jahren noch nicht.'],
      choices: [
        { text: 'Der Jahrgang 2007 wäre symbolisch passend.', goto: 'j2007' },
        { text: 'Viel Erfolg.', goto: 'END' },
      ],
    },
    hoeflich: {
      lines: ['Bei ihr schon.', 'Bei ihr bedeutet bitte immer eine zweite Botschaft.'],
      choices: [
        { text: 'Was könnte die zweite Botschaft sein?', goto: 'zweite_botschaft' },
        { text: 'Dann nehmen Sie einfach irgendeinen.', goto: 'irgendeinen' },
      ],
    },
    zweite_botschaft: {
      lines: ['Das versuche ich seit 14 Jahren herauszufinden.'],
      choices: [{ text: 'Viel Erfolg.', goto: 'END' }],
    },
    j2007: {
      actions: [{ flag: 'dlg_gper_j2007' }],
      lines: ['2007. Ist das ein gutes Jahr?'],
      choices: [
        { text: '2007 war ein gutes Jahr.', goto: 'gut_bestaetigt' },
        { text: 'Ich habe keine Ahnung.', goto: 'keine_ahnung' },
      ],
    },
    gut_bestaetigt: {
      lines: ['Woher wissen Sie das?'],
      choices: [
        { text: 'Das hat mir jemand gesagt.', goto: 'jemand_gesagt' },
        { text: 'Intuitiv.', goto: 'intuitiv' },
      ],
    },
    jemand_gesagt: {
      lines: ['Gut genug.', 'Ich nehme den 2007er.', 'Falls das Gitter nochmal aufgeht.'],
      choices: [{ text: 'Da arbeite ich dran.', goto: 'END' }],
    },
    intuitiv: {
      lines: ['Intuitiv.', 'Meine Frau sagt, ich hab keine Intuition.', 'Vielleicht für Wein schon.'],
      choices: [{ text: 'Vielleicht.', goto: 'END' }],
    },
    keine_ahnung: {
      lines: ['Das ist ehrlich. Ich schätze das.', 'Ich nehme trotzdem den 2007er. Der Verkäufer hat auch genickt.'],
      choices: [{ text: 'Ein allgemeines Nicken.', goto: 'END' }],
    },
    irgendeinen: {
      lines: ['Irgendeinen.', 'Das ist riskant.', 'Das letzte Mal hab ich irgendeinen Käse mitgebracht.', 'Das war 2019. Wir reden noch darüber.'],
      choices: [{ text: 'Dann lieber doch den 2007er.', goto: 'j2007' }],
    },
    nicht_auskennen: {
      actions: [{ flag: 'dlg_gper_nicht' }],
      lines: ['Oh.', 'Sie stehen aber sehr selbstsicher da für jemanden, der sich nicht auskennt.'],
      choices: [
        { text: 'Das täuscht.', goto: 'END' },
        { text: 'Ich übe.', goto: 'END' },
      ],
    },
  }},

  // ─── PARTYAUSSTATTER-VERKÄUFERIN ───────────────────────────
  party_verkaeuferin: { nodes: {
    start: {
      lines: ['Entschuldigung wegen des Konfettis.', 'Die Kanone ist beim zweiten Kunden heute schon losgegangen.', 'Ich warte auf eine Lieferung. Ich kann den Tresen nicht verlassen.'],
      choices: () => S.p.ballon_gefunden ? [] : [
        { text: 'Wann kommt die Lieferung?',                    condition: () => !S.p.dlg_parv_lief, goto: 'lieferung' },
        { text: 'Was ist im Lager hinten?',                     condition: () => !S.p.dlg_parv_lag,  goto: 'was_im_lager' },
        { text: 'Ich helfe gerne.', goto: 'hilfe_anbieten' },
        { text: 'Die zweite Konfettikanone zeigt auf mich.', condition: () => !S.p.dlg_parv_kan, goto: 'zweite_kanone' },
      ],
    },
    lieferung: {
      actions: [{ flag: 'dlg_parv_lief' }],
      lines: ['Laut System: zwischen 14 und 18 Uhr.', 'Es ist kurz nach 15 Uhr.', 'Das heißt: irgendwann.'],
      choices: [
        { text: 'Das ist ein großes Zeitfenster.', goto: 'zeitfenster' },
        { text: 'Was ist im Lager hinten?', goto: 'was_im_lager' },
      ],
    },
    zeitfenster: {
      lines: ['Ja.', 'Ich hab heute Morgen auch irgendwann zwischen 7 und 9 gefrühstückt.', 'Das war um 8:47.', 'Ich bin vorsichtig geworden mit Zeitfenstern.'],
      choices: [
        { text: 'Das klingt vernünftig.', goto: 'END' },
        { text: 'Was ist im Lager hinten?', goto: 'was_im_lager' },
      ],
    },
    zweite_kanone: {
      actions: [{ flag: 'dlg_parv_kan' }],
      lines: ['Ja. Tut mir leid.', 'Ich hab sie noch nicht umgestellt.', 'Sie können sich dahinter stellen, wenn Sie möchten.'],
      choices: [
        { text: 'Lieber nicht.', goto: 'END' },
        { text: 'Was ist im Lager hinten?', goto: 'was_im_lager' },
      ],
    },
    was_im_lager: {
      actions: [{ flag: 'dlg_parv_lag' }],
      lines: ['Die goldenen 19er-Ballons. Die wurden heute extra bestellt.', 'Aber die Birne ist kaputt. Ich sehe da nichts ohne Licht.'],
      choices: [
        { text: 'Haben Sie eine Taschenlampe?', goto: 'hat_taschenlampe' },
        { text: 'Wer hat sie bestellt?', goto: 'wer_bestellt' },
        { text: 'Im Musikgeschäft hängt eine Taschenlampe.', goto: 'hinweis_taschenlampe' },
      ],
    },
    wer_bestellt: {
      lines: ['Ein freundlicher Herr. Kleiner Herr. Aber attraktiv.', 'Er hat alles sehr präzise beschrieben.', 'Gold, Aufschrift 19, nicht zu groß, nicht zu klein.', 'Und dann: bitte.'],
      choices: [
        { text: 'Das klingt nach jemandem, den ich kenne.', goto: 'jemand_kennen' },
        { text: 'Haben Sie eine Taschenlampe?', goto: 'hat_taschenlampe' },
      ],
    },
    jemand_kennen: {
      lines: ['Er saß nachher noch auf der Dachterrasse, glaube ich.', 'Mit einem Kaffee. Sehr ruhig.'],
      choices: [
        { text: 'Da sitzt er immer noch.', goto: 'immer_noch' },
        { text: 'Ich hole den Ballon für ihn.', goto: 'hilfe_anbieten' },
      ],
    },
    immer_noch: {
      lines: ['Oh. Wartet er auf jemanden?'],
      choices: [
        { text: 'Ja. Auf mich.', goto: 'auf_mich' },
        { text: 'Auf eine Stempelkarte.', goto: 'END' },
      ],
    },
    auf_mich: {
      lines: ['Dann sollten Sie sich beeilen.', 'Aber zuerst: der Ballon.'],
      choices: [{ text: 'Richtig.', goto: 'hilfe_anbieten' }],
    },
    hinweis_taschenlampe: {
      lines: ['Im Musikgeschäft? Das ist eine gute Idee.', 'Ich habe selbst keine.', 'Ich habe eine bestellt. Die kommt mit der Lieferung.', 'Zwischen 14 und 18 Uhr.'],
      choices: [{ text: 'Ich hole die aus dem Musikgeschäft.', goto: 'END' }],
    },
    hat_taschenlampe: {
      lines: ['Ich habe keine. Falls Sie eine finden – bringen Sie sie.'],
      choices: () => [
        { text: 'Ich habe eine.', condition: () => hasItem('taschenlampe'), goto: 'taschenlampe_geben' },
        { text: 'Ich schaue mich um.', goto: 'END' },
      ],
    },
    hilfe_anbieten: {
      lines: ['Wenn Sie eine Taschenlampe haben, leuchten Sie ins Lager.', 'Ich kann den Tresen nicht verlassen.'],
      choices: () => [
        { text: 'Ich habe eine.', condition: () => hasItem('taschenlampe'), goto: 'taschenlampe_geben' },
        { text: 'Ich besorge eine.', goto: 'END' },
      ],
    },
    taschenlampe_geben: {
      lines: ['Wunderbar. Gehen Sie rein und leuchten Sie nach links.', 'Die Ballons müssten in einer Kiste sein. Gold, Aufschrift 19.'],
      actions: [{ give: 'luftballon' }, { take: 'taschenlampe' }, { flag: 'ballon_gefunden' }],
      choices: [
        { text: 'Gefunden. Danke.', goto: 'nach_loesung' },
        { text: 'Wissen Sie, wofür der Ballon ist?', goto: 'wozu_ballon' },
      ],
    },
    wozu_ballon: {
      lines: ['Stempelaktion. Service-Center.', 'Der Besteller hat das erklärt.', 'Er war sehr gründlich.'],
      choices: [{ text: 'Das klingt nach ihm.', goto: 'END' }],
    },
    nach_loesung: {
      lines: ['Gern. Und – schöne Zahl, 19.'],
      choices: [{ text: 'Finde ich auch.', goto: 'END' }],
    },
  }},

  // ─── LUFTBALLON-PHILOSOPHIN ────────────────────────────────
  party_philosophin: { nodes: {
    start: {
      lines: ['Entschuldigung.', 'Ist ein Luftballon ohne Luft noch ein Luftballon?', 'Ich frage das jeden hier. Der Verkäufer hat aufgehört, zu antworten.'],
      choices: () => [
        { text: 'Ja. Form definiert das Objekt.',     condition: () => !S.p.dlg_phil_form, goto: 'form_definiert' },
        { text: 'Nein. Funktion definiert das Objekt.', condition: () => !S.p.dlg_phil_funk, goto: 'funktion_definiert' },
        { text: 'Das kommt drauf an.',               condition: () => !S.p.dlg_phil_drau, goto: 'kommt_drauf_an' },
        { text: 'Warum fragen Sie das?',             condition: () => !S.p.dlg_phil_war,  goto: 'warum' },
        { text: 'Gute Frage.', goto: 'END' },
      ],
    },
    form_definiert: {
      actions: [{ flag: 'dlg_phil_form' }],
      lines: ['Interessant. Dann wäre auch ein leeres Glas noch ein Glas.'],
      choices: [
        { text: 'Ja, natürlich.', goto: 'glas_ja' },
        { text: 'Ein leeres Glas ist ein trauriges Glas.', goto: 'trauriges_glas' },
      ],
    },
    glas_ja: {
      lines: ['Und ein Mensch ohne Inhalt noch ein Mensch?'],
      choices: [
        { text: 'Das ist eine andere Frage.', goto: 'andere_frage' },
        { text: 'Philosophisch gesehen: ja.', goto: 'philosophisch_ja' },
      ],
    },
    philosophisch_ja: {
      lines: ['Ich weiß nicht, ob mich das beruhigt oder beunruhigt.'],
      choices: [{ text: 'Beides ist erlaubt.', goto: 'END' }],
    },
    andere_frage: {
      lines: ['Ist sie das?', 'Ich finde, sie ist dieselbe Frage.'],
      choices: [{ text: 'Da haben Sie vielleicht recht.', goto: 'END' }],
    },
    trauriges_glas: {
      lines: ['Ein trauriges Glas.', 'Dann wäre auch der leere Ballon hier traurig.', 'Das fühlt sich richtig an.'],
      choices: [{ text: 'Freut mich.', goto: 'END' }],
    },
    funktion_definiert: {
      actions: [{ flag: 'dlg_phil_funk' }],
      lines: ['Dann ist ein kaputtes Fahrrad kein Fahrrad mehr.'],
      choices: [
        { text: 'Streng genommen ja.', goto: 'streng_genommen' },
        { text: 'Es ist ein ehemaliges Fahrrad.', goto: 'ehemaliges' },
      ],
    },
    streng_genommen: {
      lines: ['Mein Onkel hat ein kaputtes Fahrrad im Keller.', 'Er nennt es immer noch das Fahrrad.', 'Er wird das nicht gut aufnehmen.'],
      choices: [{ text: 'Das müssen Sie ihm ja nicht sagen.', goto: 'END' }],
    },
    ehemaliges: {
      lines: ['Ehemaliges Fahrrad.', 'Dann wäre das hier ein ehemaliger Luftballon.', 'Das klingt elegisch.'],
      choices: [{ text: 'Alles klingt elegisch, wenn man es so sagt.', goto: 'END' }],
    },
    kommt_drauf_an: {
      actions: [{ flag: 'dlg_phil_drau' }],
      lines: ['Worauf?'],
      choices: [
        { text: 'Auf die Definition von Luftballon.', goto: 'definition' },
        { text: 'Auf den Luftballon.', goto: 'auf_den_ballon' },
      ],
    },
    definition: {
      lines: ['Und wer definiert?'],
      choices: [
        { text: 'Der Hersteller.', goto: 'hersteller' },
        { text: 'Wir alle gemeinsam.', goto: 'wir_alle' },
      ],
    },
    hersteller: {
      lines: ['Dann ist ein Luftballon ohne Luft laut Hersteller ein Luftballon (unaufgeblasen).', 'Das steht so auf der Packung.', 'Die Frage stellt sich also gar nicht.', 'Ich bin jetzt traurig.'],
      choices: [{ text: 'Das tut mir leid.', goto: 'END' }],
    },
    wir_alle: {
      lines: ['Wir alle.', 'Und was sagen wir alle?'],
      choices: [{ text: 'Wir sind uns uneinig.', goto: 'END' }],
    },
    auf_den_ballon: {
      lines: ['Das ist keine Antwort.'],
      choices: [{ text: 'Ich weiß.', goto: 'END' }],
    },
    warum: {
      actions: [{ flag: 'dlg_phil_war' }],
      lines: ['Ich stehe hier seit einer halben Stunde und warte auf meinen Mann.', 'Er ist kurz in den anderen Laden gegangen.', 'Ich hab angefangen, nachzudenken.'],
      choices: [
        { text: 'Das passiert.', goto: 'passiert' },
        { text: 'Über Luftballons?', goto: 'ueber_luftballons' },
      ],
    },
    passiert: {
      lines: ['Beim Warten passiert viel.', 'Letzte Woche beim Zahnarzt hab ich die Kontinentalverschiebung neu durchdacht.'],
      choices: [{ text: 'Ergebnis?', goto: 'END' }],
    },
    ueber_luftballons: {
      lines: ['Man fängt klein an.'],
      choices: [{ text: 'Und dann?', goto: 'END' }],
    },
  }},

  // ─── BLUMENLADEN-VERKÄUFER ─────────────────────────────────
  blum_verkaeuf: { nodes: {
    start: {
      lines: ['Der Schlüssel zur Vitrine ist mir runtergefallen.', 'Zwischen Regal und Wand. Ich kriege ihn nicht raus.'],
      choices: () => S.p.blumen_befreit ? [] : [
        { text: 'Wie weit ist die Lücke?',     condition: () => !S.p.dlg_blum_lue, goto: 'wie_weit' },
        { text: 'Was ist in der Vitrine?',     condition: () => !S.p.dlg_blum_vit, goto: 'was_in_vitrine' },
        { text: 'Ich helfe Ihnen.', goto: 'hilfe_anbieten' },
        { text: 'Warum ist es hier so heiß?', condition: () => !S.p.dlg_blum_hei, goto: 'warum_heiss' },
      ],
    },
    wie_weit: {
      actions: [{ flag: 'dlg_blum_lue' }],
      lines: ['Drei Zentimeter. Vielleicht vier.', 'Meine Hand passt nicht rein.', 'Ich habe es mit einem Lineal versucht.', 'Zu breit.'],
      choices: [
        { text: 'Man bräuchte etwas Schmaleres.', goto: 'schmaleres' },
        { text: 'Was ist in der Vitrine?', goto: 'was_in_vitrine' },
      ],
    },
    schmaleres: {
      lines: ['Genau. Lang und schmal.', 'Ein Brotmesser zum Beispiel.', 'Ich bin Florist, ich hab kein Brotmesser.'],
      choices: () => [
        { text: 'Ich habe eines.', condition: () => hasItem('brotmesser'), goto: 'brotmesser_geben' },
        { text: 'Ich suche eines.', goto: 'END' },
      ],
    },
    was_in_vitrine: {
      actions: [{ flag: 'dlg_blum_vit' }],
      lines: ['Der einzige frische Strauß im Laden.', 'Die Heizung klemmt. Alles andere ist welk.', 'Nur da drin ist es kühl.'],
      choices: [
        { text: 'Wer hat den Strauß bestellt?', goto: 'wer_bestellt' },
        { text: 'Können Sie die Heizung nicht reparieren?', goto: 'heizung_reparieren' },
        { text: 'Ich helfe Ihnen.', goto: 'hilfe_anbieten' },
      ],
    },
    wer_bestellt: {
      lines: ['Ein kleiner, freundlicher Herr.', 'Er hat sehr genau beschrieben was er wollte.', 'Frisch, bunt, nicht zu groß, nicht zu förmlich.', 'Und dann: Es ist für einen besonderen Anlass.', 'Das sagen alle. Aber er hat es so gesagt, als ob er es wirklich meinte.'],
      choices: [
        { text: 'Was war der Anlass?', goto: 'anlass' },
        { text: 'Ich hole den Strauß für ihn.', goto: 'hilfe_anbieten' },
      ],
    },
    anlass: {
      lines: ['19-Jahre-etwas. Er war sehr stolz.', 'Ich hab nicht nachgefragt.', 'Manchmal ist das Wie wichtiger als das Was.'],
      choices: [
        { text: 'Das ist weise.', goto: 'END' },
        { text: 'Es war ein Podcast.', goto: 'es_war_podcast' },
      ],
    },
    es_war_podcast: {
      lines: ['19 Jahre Podcast.', 'Das ist… ungewöhnlich lang.', 'Für etwas ohne Bezahlung.', 'Er hat es trotzdem sehr freudig erzählt.'],
      choices: [
        { text: 'Es macht Spaß.', goto: 'macht_spass' },
        { text: 'Ich bin einer der beiden.', goto: 'ich_bin_dabei' },
      ],
    },
    macht_spass: {
      lines: ['Das sieht man manchmal.', 'Die Blumen, die am längsten frisch bleiben, stehen im richtigen Licht.', 'Vielleicht ist das eine Metapher.'],
      choices: [{ text: 'Vielleicht.', goto: 'END' }],
    },
    ich_bin_dabei: {
      lines: ['Ah.', 'Dann ist der Strauß für Sie.', 'Noch ein weiterer Grund, den Schlüssel zu finden.'],
      choices: [{ text: 'Richtig.', goto: 'hilfe_anbieten' }],
    },
    heizung_reparieren: {
      lines: ['Ich hab es versucht.', 'Der Regler klemmt.', 'Ich hab dem Center-Management Bescheid gegeben.'],
      choices: () => [
        { text: 'Und?', goto: 'centermanagement' },
        { text: 'Mit Öl ließe sich der Regler lösen.', condition: () => hasItem('oel'), goto: 'oel_heizung' },
      ],
    },
    centermanagement: {
      lines: ['Wird erledigt.', 'Das war vor zwei Wochen.'],
      choices: [{ text: 'Das höre ich heute zum zweiten Mal.', goto: 'END' }],
    },
    oel_heizung: {
      lines: ['Öl? Das könnte tatsächlich funktionieren.', 'Probieren Sie es am Regler dort hinten.'],
      choices: [{ text: 'Danke.', goto: 'hilfe_anbieten' }],
    },
    warum_heiss: {
      actions: [{ flag: 'dlg_blum_hei' }],
      lines: ['Die Heizung klemmt auf Maximum.', 'Ich habe heute Morgen 2 Liter Wasser getrunken.', 'Und ich schwitze trotzdem.'],
      choices: () => [
        { text: 'Das tut mir leid.', goto: 'tut_mir_leid_heiss' },
        { text: 'Mit Öl ließe sich der Regler lösen.', condition: () => hasItem('oel'), goto: 'oel_heizung' },
      ],
    },
    tut_mir_leid_heiss: {
      lines: ['Danke.', 'Ich hab wenigstens die Kühlvitrine.', 'Wenn ich den Schlüssel finden würde, könnte ich auch reingehen.'],
      choices: [{ text: 'Ich helfe Ihnen.', goto: 'hilfe_anbieten' }],
    },
    hilfe_anbieten: {
      lines: ['Etwas Schmales und Stabiles wäre ideal.', 'Ein Brotmesser zum Beispiel.'],
      choices: () => [
        { text: 'Ich habe eines.', condition: () => hasItem('brotmesser'), goto: 'brotmesser_geben' },
        { text: 'Ich suche eines.', goto: 'END' },
      ],
    },
    brotmesser_geben: {
      lines: ['Ausgezeichnet.', '...', 'Da. Der Schlüssel. Und damit –', 'Bitte sehr.'],
      actions: [{ give: 'blumenstrauss' }, { take: 'brotmesser' }, { flag: 'schluessel_befreit' }, { flag: 'blumen_befreit' }],
      choices: [
        { text: 'Danke.', goto: 'nach_loesung' },
        { text: 'Ich behalte das Brotmesser.', goto: 'brotmesser_behalten' },
      ],
    },
    brotmesser_behalten: {
      lines: ['Natürlich. Das gehört Ihnen ja.'],
      actions: [{ give: 'brotmesser' }],
      choices: [{ text: 'Danke.', goto: 'nach_loesung' }],
    },
    nach_loesung: {
      lines: ['Gern. Und – frische Luft würde dem Laden guttun.'],
      choices: [{ text: 'Da stimme ich zu.', goto: 'END' }],
    },
  }},

  // ─── FLORISTIK-INFLUENCERIN ────────────────────────────────
  blum_influencerin: { nodes: {
    start: {
      lines: ['Oh, warte – bleib kurz stehen. Das Licht hier ist perfekt.', 'Ich bin Sina. Ich mache Content über Floristik, Lifestyle und das Schöne im Alltag.'],
      choices: () => [
        { text: 'Was ist Content?',                    condition: () => !S.p.dlg_infl_con,  goto: 'was_content' },
        { text: 'Ich stehe lieber nicht im Bild.',    condition: () => !S.p.dlg_infl_bild, goto: 'nicht_im_bild' },
        { text: 'Was bedeutet das Schöne im Alltag?', condition: () => !S.p.dlg_infl_sch,  goto: 'schoenes' },
        { text: 'Schönen Tag noch.', goto: 'END' },
      ],
    },
    was_content: {
      actions: [{ flag: 'dlg_infl_con' }],
      lines: ['Content ist ... Inhalt. Aber auf Englisch klingt es professioneller.'],
      choices: [
        { text: 'Könnte man auch Inhalte sagen?', goto: 'inhalte' },
        { text: 'Verstehe.', goto: 'END' },
      ],
    },
    inhalte: {
      lines: ['Technisch gesehen ja.', 'Aber dann heißt mein Kanal: Sina macht Inhalte.', 'Das klingt nach einem Formular.'],
      choices: [
        { text: 'Sina macht Inhalte ... ist eigentlich gut.', goto: 'inhalte_gut' },
        { text: 'Da haben Sie recht.', goto: 'END' },
      ],
    },
    inhalte_gut: {
      lines: ['Ich denke darüber nach.', 'Nein, ich denke nicht darüber nach.'],
      choices: [{ text: 'Schade.', goto: 'END' }],
    },
    nicht_im_bild: {
      actions: [{ flag: 'dlg_infl_bild' }],
      lines: ['Kein Problem. Ich nehme die Blumen.', 'Obwohl – ein zufälliger Passant wäre authentischer.'],
      choices: [
        { text: 'Ich bin kein zufälliger Passant.', goto: 'kein_passant' },
        { text: 'Was ist authentischer Content?', goto: 'authentisch' },
      ],
    },
    kein_passant: {
      lines: ['Das sagen alle. Und dann sind sie trotzdem im Bild.'],
      choices: [{ text: '...', goto: 'END' }],
    },
    authentisch: {
      lines: ['Content, der sich nicht nach Content anfühlt.', 'Zum Beispiel jemand, der einfach so in einem Blumenladen steht.', 'So wie Sie.'],
      choices: [
        { text: 'Ich bin nicht einfach so hier.', goto: 'nicht_einfach_so' },
        { text: 'Ich stehe trotzdem nicht im Bild.', goto: 'END' },
      ],
    },
    nicht_einfach_so: {
      lines: ['Das sieht man Ihnen gar nicht an.', 'Das ist eigentlich das Beste, was ich über jemanden sagen kann.'],
      choices: [{ text: 'Danke, glaube ich.', goto: 'END' }],
    },
    schoenes: {
      actions: [{ flag: 'dlg_infl_sch' }],
      lines: ['Das Licht durch Blumenblätter. Ein frischer Strauß. Der Geruch.', 'Heute zum Beispiel: dieser Laden.'],
      choices: [
        { text: 'Es ist sehr heiß hier drin.', goto: 'sehr_heiss' },
        { text: 'Die meisten Blumen sind welk.', goto: 'welk' },
      ],
    },
    sehr_heiss: {
      lines: ['Das ist die goldene Stunde. Thermisch.'],
      choices: [
        { text: 'Das ist kein Begriff.', goto: 'kein_begriff' },
        { text: 'Interessante Perspektive.', goto: 'END' },
      ],
    },
    kein_begriff: {
      lines: ['Noch nicht.'],
      choices: [{ text: '...', goto: 'END' }],
    },
    welk: {
      lines: ['Das ist der Kontrast.', 'Vergänglichkeit trifft Frische. Die Vitrine dort hinten.', 'Ich poste das als Diptychon.'],
      choices: [
        { text: 'Was ist ein Diptychon?', goto: 'diptychon' },
        { text: 'Viel Erfolg.', goto: 'END' },
      ],
    },
    diptychon: {
      lines: ['Zwei Bilder nebeneinander. Gegensatz.', 'Links: welke Blumen, warmes Licht.', 'Rechts: frische Blumen, kühle Vitrine.', 'Caption: So ist das Leben.'],
      choices: [{ text: 'So ist das Leben ... ist immer eine gute Caption.', goto: 'END' }],
    },
  }},

  // ─── ALLERGIKER ────────────────────────────────────────────
  blum_allergiker: { nodes: {
    start: {
      lines: ['*niest*', 'Entschuldigung.', 'Haben Sie eine Frage zu Pfingstrosen?'],
      choices: () => [
        { text: 'Ich habe keine Frage zu Pfingstrosen.',                          condition: () => !S.p.dlg_all_kein, goto: 'keine_frage' },
        { text: 'Warum sind Sie in einem Blumenladen, wenn Sie allergisch sind?', condition: () => !S.p.dlg_all_war,  goto: 'warum_hier' },
        { text: 'Ich habe jetzt eine Frage zu Pfingstrosen.',                    condition: () => !S.p.dlg_all_frag, goto: 'frage_pfingstrose' },
        { text: 'Gute Besserung.', goto: 'END' },
      ],
    },
    keine_frage: {
      actions: [{ flag: 'dlg_all_kein' }],
      lines: ['*niest*', 'Ich schon. Mehrere.', 'Zum Beispiel: Blühen sie länger, wenn man sie ins kalte Wasser stellt?'],
      choices: [
        { text: 'Ja, glaube ich.', goto: 'kalt_ja' },
        { text: 'Keine Ahnung.', goto: 'keine_ahnung_blumen' },
      ],
    },
    kalt_ja: {
      lines: ['Das habe ich auch gelesen.', '*niest*', 'Und wenn man eine Aspirintablette ins Wasser gibt?'],
      choices: [
        { text: 'Auch gut, glaube ich.', goto: 'aspirin' },
        { text: 'Das klingt nach einem Experiment.', goto: 'experiment' },
      ],
    },
    aspirin: {
      lines: ['Ich hab das versucht.', 'Die Blumen haben es nicht überlebt.', '*niest*', 'Ich glaube, ich hab die falsche Dosis genommen.'],
      choices: [{ text: 'Für Blumen gibt es vermutlich keine Dosierungsanleitung.', goto: 'END' }],
    },
    experiment: {
      lines: ['Es war ein Experiment.', '*niest*', 'Negatives Ergebnis ist auch ein Ergebnis.'],
      choices: [{ text: 'Das stimmt.', goto: 'END' }],
    },
    keine_ahnung_blumen: {
      lines: ['Ich auch nicht wirklich.', '*niest*', 'Ich lese viel darüber. Das hilft trotzdem nicht.'],
      choices: [{ text: 'Warum sind Sie dann hier?', goto: 'warum_hier' }],
    },
    warum_hier: {
      actions: [{ flag: 'dlg_all_war' }],
      lines: ['Meine Frau liebt Pfingstrosen.', '*niest*', 'Ich kaufe sie trotzdem jedes Jahr.'],
      choices: [
        { text: 'Das ist sehr romantisch.', goto: 'romantisch' },
        { text: 'Haben Sie Antihistaminika dabei?', goto: 'antihistaminika' },
      ],
    },
    romantisch: {
      lines: ['*niest*', 'Sie findet das auch romantisch.', 'Sie hat mir eine Nasenklammer geschenkt.', 'Als Zeichen der Zuneigung.'],
      choices: [
        { text: 'Trägt man die beim Blumenkauf?', goto: 'nasenklammer' },
        { text: 'Das ist eine schöne Geschichte.', goto: 'END' },
      ],
    },
    nasenklammer: {
      lines: ['Theoretisch.', '*niest*', 'Ich vergesse sie immer.'],
      choices: [{ text: 'Jedes Jahr?', goto: 'END' }],
    },
    antihistaminika: {
      lines: ['Ja.', '*niest*', 'Sie helfen nicht besonders.', 'Ich nehme sie trotzdem. Aus Prinzip.'],
      choices: [{ text: 'Welches Prinzip?', goto: 'prinzip' }],
    },
    prinzip: {
      lines: ['*niest*', 'Das weiß ich ehrlich gesagt nicht mehr.'],
      choices: [{ text: 'Viel Erfolg heute.', goto: 'END' }],
    },
    frage_pfingstrose: {
      actions: [{ flag: 'dlg_all_frag' }],
      lines: ['Oh! Bitte.', '*niest*'],
      choices: [
        { text: 'Blühen Pfingstrosen länger im kalten Wasser?', goto: 'kalt_ja' },
        { text: 'Warum heißen sie Pfingstrosen?', goto: 'warum_name' },
      ],
    },
    warum_name: {
      lines: ['*niest*', 'Weil sie um Pfingsten blühen.', 'Das ist das erste Mal, dass ich das jemandem erklären kann.', '*niest*', 'Das war schön.'],
      choices: [{ text: 'Gern geschehen.', goto: 'END' }],
    },
  }},

  // ─── MUSIKGESCHÄFT-VERKÄUFER ───────────────────────────────
  musik_verkaeufer: { nodes: {
    start: {
      lines: ['Das Klavier ist neu reingekommen.', 'Jemand hat ein Schloss drangemacht.', 'Die Kombination steht unten drauf. Ich lese sie nicht mehr.'],
      choices: () => S.p.klavier_offen ? [] : [
        { text: 'Warum hat das Klavier ein Schloss?', condition: () => !S.p.dlg_musk_schl, goto: 'warum_schloss' },
        { text: 'Was ist die Kombination?', goto: 'was_kombi' },
        { text: 'Ich helfe Ihnen.', goto: 'hilfe_anbieten' },
        { text: 'Wer hat das Klavier gebracht?', condition: () => !S.p.dlg_musk_wer, goto: 'wer_gebracht' },
      ],
    },
    warum_schloss: {
      actions: [{ flag: 'dlg_musk_schl' }],
      lines: ['Das frage ich mich auch.', 'In 23 Jahren im Musikgeschäft war das das erste Klavier mit Schloss.', 'Ich hab nicht nachgefragt. Ich hätte nachfragen sollen.'],
      choices: [
        { text: 'Wer hat es gebracht?', goto: 'wer_gebracht' },
        { text: 'Was ist die Kombination?', goto: 'was_kombi' },
      ],
    },
    wer_gebracht: {
      actions: [{ flag: 'dlg_musk_wer' }],
      lines: ['Ein freundlicher Herr. Kleiner Herr, rosa Sakko.', 'Er hat das Klavier persönlich begleitet.', 'Als wäre es ein Tier.'],
      choices: [
        { text: 'Hat er etwas gesagt?', goto: 'was_gesagt' },
        { text: 'Das klingt nach jemandem, den ich kenne.', goto: 'jemand_kennen' },
      ],
    },
    was_gesagt: {
      lines: ['Er hat gesagt, das Klavier ist für heute.', 'Und die Stimmgabel darin auch.', 'Und dann: Bitte nicht anfassen, bis jemand die Kombination herausfindet.', 'Ich hab genickt. Ich weiß nicht, warum.'],
      choices: [
        { text: 'Was ist die Kombination?', goto: 'was_kombi' },
        { text: 'Das klingt nach Teddy.', goto: 'klingt_nach_teddy' },
      ],
    },
    klingt_nach_teddy: {
      lines: ['Teddy.', 'Er hat sich nicht vorgestellt.', 'Aber er hat sich zweimal bedankt.', 'Beim Rausgehen noch einmal.'],
      choices: [
        { text: 'Das ist typisch.', goto: 'END' },
        { text: 'Ich öffne das Schloss für ihn.', goto: 'hilfe_anbieten' },
      ],
    },
    jemand_kennen: {
      lines: ['Er war sehr organisiert.', 'Hat eine Liste gehabt.', 'Auf der Liste stand: Klavier, Schloss, Stimmgabel, Kombination aufschreiben.', 'Das hat er alles erledigt.', 'Bis auf den lesbaren Aufkleber.'],
      choices: [{ text: 'Was ist die Kombination?', goto: 'was_kombi' }],
    },
    was_kombi: {
      lines: ['Der Aufkleber ist unleserlich.', 'Komplett verdreckt. Ich hab es mit dem Ärmel versucht.', 'Schmutziger Ärmel. Unlesbarer Aufkleber.'],
      choices: () => [
        { text: 'Haben Sie etwas Feuchtes?', goto: 'feuchtes' },
        { text: 'Ich habe einen Eiskübel.', condition: () => hasItem('eiskuebel'), goto: 'eiskuebel_geben' },
        { text: 'Was könnte die Kombination sein?', goto: 'raten' },
      ],
    },
    raten: {
      lines: ['Ich hab 1234 probiert.', 'Und 0000.', 'Und 1907. Das ist das Gründungsjahr von Sachsenotto.', 'Steht am Eingang des Centers.', 'Hat nicht funktioniert. Ich hab vermutlich einen Tippfehler gemacht.'],
      choices: () => [
        { text: '1907 klingt richtig.', goto: 'r1907_richtig' },
        { text: 'Ich mache den Aufkleber lesbar.', goto: 'hilfe_anbieten' },
        { text: 'Und die Taschenlampe dort – brauchen Sie die?', condition: () => !hasItem('taschenlampe'), goto: 'taschenlampe_frage' },
      ],
    },
    r1907_richtig: {
      lines: ['Wenn Sie es versuchen wollen – bitte.', 'Ich tippe nicht nochmal.', 'Ich hab gerade kein Vertrauen in meine Finger.'],
      choices: [{ text: 'Ich versuche es.', goto: 'END' }],
    },
    feuchtes: {
      lines: ['Der Klavierstimmer hat Tee getrunken.', 'Sonst: Wasserkocher dort drüben.', 'Aber ich hab kein Gefäß mehr.'],
      choices: () => [
        { text: 'Ich habe einen Eiskübel.', condition: () => hasItem('eiskuebel'), goto: 'eiskuebel_geben' },
        { text: 'Ich organisiere etwas.', goto: 'END' },
        { text: 'Und die Taschenlampe dort – brauchen Sie die?', condition: () => !hasItem('taschenlampe'), goto: 'taschenlampe_frage' },
      ],
    },
    hilfe_anbieten: {
      lines: ['Wasser wäre ideal. Irgendwas Flüssiges für den Aufkleber.'],
      choices: () => [
        { text: 'Ich habe einen Eiskübel.', condition: () => hasItem('eiskuebel'), goto: 'eiskuebel_geben' },
        { text: 'Ich schaue mich um.', goto: 'END' },
        { text: 'Und die Taschenlampe dort – brauchen Sie die?', condition: () => !hasItem('taschenlampe'), goto: 'taschenlampe_frage' },
      ],
    },
    taschenlampe_frage: {
      lines: ['Die? Nein.', 'Die hängt da seit dem Einzug.', 'Nehmen Sie sie gerne.'],
      actions: [{ give: 'taschenlampe' }],
      choices: [{ text: 'Danke.', goto: 'hilfe_anbieten' }],
    },
    eiskuebel_geben: {
      lines: ['Ausgezeichnet.', '...', 'Da. 1907.', 'Das Gründungsjahr von Sachsenotto.', 'Ich hab 1970 eingegeben. Kein Wunder.'],
      actions: [{ flag: 'kombi_bekannt' }, { flag: 'aufkleber_lesbar' }, { take: 'eiskuebel' }],
      choices: [
        { text: 'Und jetzt?', goto: 'und_jetzt' },
        { text: 'Ich gebe die Kombination ein.', goto: 'kombi_eingeben' },
      ],
    },
    und_jetzt: {
      lines: ['Geben Sie 1907 ein. Am Schloss.', 'Wenn es aufgeht – bitte die Stimmgabel mitnehmen.', 'Die ist für die Stempelaktion.'],
      choices: [{ text: 'Ich versuche es.', goto: 'kombi_eingeben' }],
    },
    kombi_eingeben: {
      lines: ['1-9-0-7.', '...', 'Da. Es geht auf.', '23 Jahre im Musikgeschäft. Noch nie ein Schloss am Klavier.'],
      actions: [{ give: 'stimmgabel' }, { flag: 'klavier_offen' }],
      choices: [
        { text: 'Danke.', goto: 'nach_loesung' },
        { text: 'Wissen Sie wofür die Stimmgabel ist?', goto: 'wozu_stimmgabel' },
      ],
    },
    wozu_stimmgabel: {
      lines: ['Service-Center. Stempelaktion.', 'Der freundliche Herr hat das erklärt.', 'Sehr gründlich.'],
      choices: [{ text: 'Das klingt nach ihm.', goto: 'END' }],
    },
    nach_loesung: {
      lines: ['Gern. Und – komisch, dass das nötig war.'],
      choices: [{ text: 'Ja.', goto: 'END' }],
    },
  }},

  // ─── KLAVIERSTIMMER ────────────────────────────────────────
  musik_stimmer: { nodes: {
    start: {
      lines: ['Ich war um 13 Uhr bestellt.', 'Es ist jetzt fast 16 Uhr.', 'Ich sitze seit drei Stunden hier wegen eines Schlosses.'],
      choices: () => [
        { text: 'Warum gehen Sie nicht einfach?', condition: () => !S.p.dlg_stim_weg,  goto: 'warum_nicht_weg' },
        { text: 'Das Schloss ist ein Problem.',   condition: () => !S.p.dlg_stim_schl, goto: 'schloss_problem' },
        { text: 'Haben Sie schon Tee bestellt?', condition: () => !S.p.dlg_stim_tee,  goto: 'tee' },
        { text: 'Ich arbeite an der Lösung.', goto: 'END' },
      ],
    },
    warum_nicht_weg: {
      actions: [{ flag: 'dlg_stim_weg' }],
      lines: ['Ich hab den Auftrag angenommen.', 'Ich habe ein Problem damit, Aufträge aufzugeben.', 'Das hat mein Therapeut als dysfunktionalen Perfektionismus bezeichnet.', 'Ich finde, dass das eine sehr genaue Beschreibung ist.'],
      choices: [
        { text: 'Seit wann ist das so?', goto: 'seit_wann' },
        { text: 'Das Klavier bleibt verstimmt.', goto: 'bleibt_verstimmt' },
      ],
    },
    seit_wann: {
      lines: ['Immer, glaube ich.', 'Ich habe mal drei Stunden auf einen Aufzug gewartet, weil ich den Knopf gedrückt hatte.', 'Der Aufzug war außer Betrieb.', 'Aber ich hatte den Knopf gedrückt.'],
      choices: [
        { text: 'Und dann?', goto: 'und_dann_aufzug' },
        { text: 'Das klingt anstrengend.', goto: 'anstrengend' },
      ],
    },
    und_dann_aufzug: {
      lines: ['Nach drei Stunden hat mir jemand gesagt, dass der Aufzug außer Betrieb ist.', 'Ich habe die Treppe genommen.', 'Es war der zweite Stock.'],
      choices: [{ text: '...', goto: 'END' }],
    },
    anstrengend: {
      lines: ['Ja.', 'Mein Therapeut sagt das auch.'],
      choices: [
        { text: 'Vielleicht heute ausnahmsweise gehen?', goto: 'ausnahmsweise' },
        { text: 'Ich arbeite daran, das Schloss zu öffnen.', goto: 'ich_arbeite_dran' },
      ],
    },
    ich_arbeite_dran: {
      lines: ['Das wäre außerordentlich.', 'Dann kann ich noch heute stimmen.', 'Ich habe den ganzen Nachmittag geblockt.'],
      choices: [{ text: 'Ich tue mein Bestes.', goto: 'END' }],
    },
    ausnahmsweise: {
      lines: ['Ausnahmsweise.', 'Das fühlt sich falsch an.'],
      choices: [
        { text: 'Manchmal ist das okay.', goto: 'manchmal_okay' },
        { text: 'Dann bleiben Sie.', goto: 'END' },
      ],
    },
    manchmal_okay: {
      lines: ['…', 'Das werde ich meinem Therapeuten weiterleiten.'],
      choices: [{ text: 'Viel Erfolg.', goto: 'END' }],
    },
    bleibt_verstimmt: {
      lines: ['Ja.', 'Das weiß ich.', 'Ich höre es ja.', '*jemand spielt eine Taste*', 'Da. Hören Sie das?', 'Das h ist einen Viertelton zu hoch.', 'Das macht mich wahnsinnig.'],
      choices: [
        { text: 'Ein Viertelton fällt doch kaum auf.', goto: 'viertelton' },
        { text: 'Das höre ich auch.', goto: 'auch_hoeren' },
      ],
    },
    viertelton: {
      lines: ['Mir schon.', 'Ich schlaf damit.', 'Nicht buchstäblich. Aber fast.'],
      choices: [{ text: 'Ich versuche, das Schloss zu öffnen.', goto: 'ich_arbeite_dran' }],
    },
    auch_hoeren: {
      lines: ['Wirklich?', 'Das sagen die wenigsten.', 'Entweder haben Sie ein gutes Gehör oder Sie sind höflich.'],
      choices: [{ text: 'Beides ein bisschen.', goto: 'END' }],
    },
    schloss_problem: {
      actions: [{ flag: 'dlg_stim_schl' }],
      lines: ['Ein Zahlenschloss. Vierstellig.', 'Ich bin Klavierstimmer. Ich bin nicht für Schlösser ausgebildet.'],
      choices: [
        { text: 'Die Kombination steht unten am Klavier.', goto: 'kombi_unten' },
        { text: 'Haben Sie versucht, es zu öffnen?', goto: 'versucht' },
      ],
    },
    kombi_unten: {
      lines: ['Ich weiß. Der Aufkleber.', 'Komplett verdreckt. Ich konnte ihn nicht lesen.', 'Ich habe es mit dem Ärmel versucht.', 'Das hat nichts gebracht ... außer einem schmutzigen Ärmel.'],
      choices: [{ text: 'Ich kümmer mich darum.', goto: 'ich_arbeite_dran' }],
    },
    versucht: {
      lines: ['Natürlich.', '1234. 0000. 1907.', 'Bei 1907 hab ich kurz gehofft.', 'Aber ich hab ihn falsch abgelesen.'],
      choices: () => [
        { text: '1907 ist tatsächlich die Kombination.', condition: () => S.p.kombi_bekannt, goto: 'stimmt_1907' },
        { text: 'Ich finde es heraus.', goto: 'ich_arbeite_dran' },
      ],
    },
    stimmt_1907: {
      lines: ['1907.', 'Ich hab 1970 eingegeben.', 'Drei Stunden.', 'Drei Stunden wegen eines Zahlendrehers.'],
      choices: [{ text: 'Das passiert.', goto: 'END' }],
    },
    tee: {
      actions: [{ flag: 'dlg_stim_tee' }],
      lines: ['Ja. Zweimal.', 'Der Verkäufer hat einen Wasserkocher.', 'Wir haben nicht viel gesprochen.', 'Aber der Tee war gut.'],
      choices: [{ text: 'Das ist immerhin etwas.', goto: 'END' }],
    },
  }},

  // ─── SERVICECENTER-MITARBEITERIN ───────────────────────────
  serv_mitarb: { nodes: {
    start: {
      lines: ['Haben Sie etwas für mich?'],
      choices: () => [
        { text: 'Ich brauche eine Stempelkarte.', condition: () => !hasItem('stempelkarte'), goto: 'karte_geben' },
        { text: 'Was nehmen Sie an?',              condition: () => !S.p.dlg_serv_was, goto: 'was_nehmen' },
        { text: 'Wer hat diese Aktion organisiert?', condition: () => !S.p.dlg_serv_wer, goto: 'wer_organisiert' },
        { text: 'Ja.', condition: () => hasItem('kerze') || hasItem('sektflasche') || hasItem('luftballon') || hasItem('blumenstrauss') || hasItem('stimmgabel'), goto: 'item_uebergeben' },
        { text: 'Noch nicht.', goto: 'noch_nicht' },
      ],
    },
    karte_geben: {
      lines: ['Natürlich.', 'Bitte sehr.'],
      actions: [{ fn: () => {
        addItem('stempelkarte');
        document.getElementById('stamp-panel').classList.remove('hidden');
        renderStamps();
      }}],
      choices: () => [
        { text: 'Was nehmen Sie an?', goto: 'was_nehmen' },
        { text: 'Danke.', goto: 'END' },
      ],
    },
    was_nehmen: {
      actions: [{ flag: 'dlg_serv_was' }],
      lines: ['Fünf Gegenstände aus den Partnergeschäften.', 'Kerze, Sektflasche, Luftballon, Blumenstrauß, Stimmgabel.', 'Pro Gegenstand ein Stempel. Bei fünf Stempeln: Dachterrasse.'],
      choices: [
        { text: 'Wer hat sich das ausgedacht?', goto: 'wer_organisiert' },
        { text: 'Das klingt aufwendig.', goto: 'aufwendig' },
      ],
    },
    aufwendig: {
      lines: ['Der Auftraggeber auch.', 'Er hatte eine sehr genaue Liste.', 'Und er hat sich für die Liste entschuldigt.', 'Das war ungewöhnlich.'],
      choices: () => [
        { text: 'Wer war das?', goto: 'wer_organisiert' },
        { text: 'Ich habe etwas für Sie.', condition: () => hasItem('kerze') || hasItem('sektflasche') || hasItem('luftballon') || hasItem('blumenstrauss') || hasItem('stimmgabel'), goto: 'item_uebergeben' },
      ],
    },
    wer_organisiert: {
      actions: [{ flag: 'dlg_serv_wer' }],
      lines: ['Ein freundlicher Herr. Klein, aber sehr attraktiv.', 'Er trug ein rosafarbenes Sakko.', 'Und er hat alles sehr präzise erklärt. Welcher Gegenstand welchen Stempel bekommt und so. Und dass die Reihenfolge egal ist.', 'Und er sagte: Wer die Gegenstände bringt, ist ein Freund von ihm. Das würde sowieso nur einer machen.'],
      choices: () => [
        { text: 'Das bin ich.', goto: 'das_bin_ich' },
        { text: 'Hat er sonst noch etwas gesagt?', goto: 'sonst_noch' },
      ],
    },
    das_bin_ich: {
      lines: ['Das dachte ich mir.', 'Er hat gesagt, sein Freund wirkt manchmal verloren, weiß aber immer was er tut.', 'Ich fand das eine schöne Beschreibung.'],
      choices: () => [
        { text: 'Das ist eine gute Beschreibung.', goto: 'END' },
        { text: 'Ich habe etwas für Sie.', condition: () => hasItem('kerze') || hasItem('sektflasche') || hasItem('luftballon') || hasItem('blumenstrauss') || hasItem('stimmgabel'), goto: 'item_uebergeben' },
      ],
    },
    sonst_noch: {
      lines: ['Er hat gesagt: Falls mein Freund fragt – es lohnt sich.', 'Das war alles.'],
      choices: () => [
        { text: 'Was lohnt sich?', goto: 'was_lohnt' },
        { text: 'Ich habe etwas für Sie.', condition: () => hasItem('kerze') || hasItem('sektflasche') || hasItem('luftballon') || hasItem('blumenstrauss') || hasItem('stimmgabel'), goto: 'item_uebergeben' },
      ],
    },
    was_lohnt: {
      lines: ['Das hat er nicht gesagt.', 'Ich nehme an: die Dachterrasse.'],
      choices: [{ text: 'Ich hoffe das auch.', goto: 'END' }],
    },
    noch_nicht: {
      lines: ['Die Partnergeschäfte sind alle geöffnet.', 'Kerze, Sektflasche, Luftballon, Blumenstrauß, Stimmgabel.', 'Ich bin hier.'],
      choices: [{ text: 'Danke.', goto: 'END' }],
    },
    item_uebergeben: {
      lines: ['Was haben Sie?'],
      choices: () => [
        { text: 'Die Kerze.',       condition: () => hasItem('kerze'),        goto: 'stempel_kerze' },
        { text: 'Die Sektflasche.', condition: () => hasItem('sektflasche'),  goto: 'stempel_sekt' },
        { text: 'Den Luftballon.',  condition: () => hasItem('luftballon'),   goto: 'stempel_ballon' },
        { text: 'Den Blumenstrauß.',condition: () => hasItem('blumenstrauss'),goto: 'stempel_blumen' },
        { text: 'Die Stimmgabel.',  condition: () => hasItem('stimmgabel'),   goto: 'stempel_stimmgabel' },
        { text: 'Doch nichts.', goto: 'END' },
      ],
    },
    stempel_kerze: {
      lines: ['Eine von neunzehn.', 'Schöne Zahl.'],
      actions: [{ take: 'kerze' }, { stamp: 0 }],
      choices: [
        { text: 'Noch vier.', goto: 'END' },
        { text: 'Ich habe noch mehr.', goto: 'item_uebergeben' },
      ],
    },
    stempel_sekt: {
      lines: ['Jahrgang 2007. Schöner Jahrgang.', 'Für Sekt. Und offenbar für anderes.'],
      actions: [{ take: 'sektflasche' }, { stamp: 1 }],
      choices: [
        { text: 'Noch drei.', goto: 'END' },
        { text: 'Ich habe noch mehr.', goto: 'item_uebergeben' },
      ],
    },
    stempel_ballon: {
      lines: ['Gold. Aufschrift 19.', 'Er streift die Decke.'],
      actions: [{ take: 'luftballon' }, { stamp: 2 }],
      choices: [
        { text: 'Weiter.', goto: 'END' },
        { text: 'Ich habe noch mehr.', goto: 'item_uebergeben' },
      ],
    },
    stempel_blumen: {
      lines: ['Die sind wirklich frisch.', 'Aus der Kühlvitrine, nehme ich an.'],
      actions: [{ take: 'blumenstrauss' }, { stamp: 3 }],
      choices: [
        { text: 'Noch einen.', goto: 'END' },
        { text: 'Ich habe noch mehr.', goto: 'item_uebergeben' },
      ],
    },
    stempel_stimmgabel: {
      lines: ['…', 'Darf ich?', '*schlägt Stimmgabel an*', 'Aaaaaahh. Genau.', 'Stimmt.'],
      actions: [{ take: 'stimmgabel' }, { stamp: 4 }],
      choices: [{ text: 'Und jetzt?', goto: 'alle_stempel' }],
    },
    alle_stempel: {
      lines: ['Ihre Karte ist voll.', 'Fünf von fünf.', 'Die Tür am Ende der Passage.', 'Da lang.', 'Er wartet.'],
      choices: [{ text: 'Danke.', goto: 'END' }],
    },
  }},
};

// ── Verb-Aktion ausführen ───────────────────────────────────
function executeAction(verb, objId, secondId = null) {
  // Inventar-Item: Schau-an gibt die Beschreibung
  if (ITEMS[objId] && !secondId) {
    if (verb === 'look') return ITEMS[objId].desc;
    // Inventar-Item als Ziel für use/give – handled below
  }

  const obj = OBJECTS[objId];

  if (verb === 'use' || verb === 'give') {
    if (!secondId) return defR(); // Sollte nicht passieren
    return handleTwoPart(verb, objId, secondId);
  }

  if (!obj) return defR();

  const handler = obj.verbs?.[verb];
  if (handler === undefined) return defR();
  if (typeof handler === 'function') {
    const result = handler();
    return result !== null ? result : undefined;
  }
  return handler;
}

function handleTwoPart(verb, aId, bId) {
  // Probiere: a.useWith/giveTo[b] und b.useWith/giveTo[a]
  const key = verb === 'use' ? 'useWith' : 'giveTo';

  const objA = OBJECTS[aId] || {};
  const objB = OBJECTS[bId] || {};

  if (objA[key]?.[bId]) {
    const h = objA[key][bId];
    return typeof h === 'function' ? h() : h;
  }
  if (objB[key]?.[aId]) {
    const h = objB[key][aId];
    return typeof h === 'function' ? h() : h;
  }

  // Sonderfälle: Inventar-Items die auf sich selbst angewendet werden
  if (aId === bId) return 'Das ergibt keinen Sinn.';

  // Generische Nicht-Schlüssel-Abgabe ans Service-Center
  if (bId === 'serv_mitarb' || aId === 'serv_mitarb') {
    return 'Das nehmen wir hier nicht an.';
  }

  return defR();
}

// ── Raum betreten ───────────────────────────────────────────
function enterRoom(roomId) {
  const room = ROOMS[roomId];
  if (!room) return;

  const isFirst = !S.visited.has(roomId);
  S.room = roomId;
  S.visited.add(roomId);

  // Verb-Modus zurücksetzen
  clearVerbMode();

  renderRoom();

  const desc = isFirst ? room.firstDesc : room.returnDesc;
  document.getElementById('room-description').textContent = desc;
  showReaction('');
  saveGame();
}

// ── Verb-Modus ──────────────────────────────────────────────
function setVerb(verb) {
  if (S.verb === verb) { clearVerbMode(); return; }
  clearVerbMode();
  S.verb = verb;
  S.verbStep = 1;
  S.firstObj = null;

  document.querySelectorAll('.verb-btn').forEach(b => b.classList.toggle('active', b.dataset.verb === verb));
  updateVerbStatus();
  highlightInteractables();
}

function clearVerbMode() {
  S.verb = null;
  S.verbStep = 1;
  S.firstObj = null;
  document.querySelectorAll('.verb-btn').forEach(b => b.classList.remove('active'));
  document.querySelectorAll('.obj-btn, .npc-btn, .inv-item').forEach(b => {
    b.classList.remove('highlighted', 'selected-first');
  });
  document.getElementById('verb-status-header').textContent = '';
}

function updateVerbStatus() {
  const bar = document.getElementById('verb-status-header');
  if (!S.verb) { bar.textContent = ''; return; }
  const verbNames = {
    take:'Nimm', open:'Öffne', close:'Schließe',
    use:'Benutze', give:'Gib', talk:'Rede mit', push:'Drücke', pull:'Ziehe', goto:'Gehe zu',
  };
  const vn = verbNames[S.verb] || S.verb;

  if (S.verbStep === 1) {
    if (S.verb === 'use') bar.textContent = 'Benutze … mit …';
    else if (S.verb === 'give') bar.textContent = 'Gib … an …';
    else bar.textContent = `${vn} …`;
  } else if (S.verbStep === 2 && S.firstObj) {
    const name = getObjName(S.firstObj.id);
    if (S.verb === 'use') bar.textContent = `Benutze ${name} mit …`;
    else if (S.verb === 'give') bar.textContent = `Gib ${name} an …`;
  }
}

function highlightInteractables() {
  if (!S.verb) return;
  if (S.verb === 'talk') {
    document.querySelectorAll('.npc-btn').forEach(b => b.classList.add('highlighted'));
  } else if (S.verb === 'use') {
    document.querySelectorAll('.obj-btn, .inv-item').forEach(b => b.classList.add('highlighted'));
  } else if (S.verb === 'give') {
    if (S.verbStep === 1) {
      document.querySelectorAll('.obj-btn, .inv-item').forEach(b => b.classList.add('highlighted'));
    } else {
      document.querySelectorAll('.npc-btn').forEach(b => b.classList.add('highlighted'));
    }
  } else {
    document.querySelectorAll('.obj-btn').forEach(b => b.classList.add('highlighted'));
  }
}

// ── Objekt-Klick ────────────────────────────────────────────
function handleObjClick(objId, kind) { // kind: 'room'|'inv'
  if (!S.verb) {
    // Kein Verb → automatisch »Schau an«
    const result = executeAction('look', objId);
    if (result !== undefined && result !== null) showReaction(result);
    renderRoom();
    return;
  }

  const isTwoPart = S.verb === 'use' || S.verb === 'give';

  if (isTwoPart) {
    if (S.verbStep === 1) {
      S.firstObj = { id: objId, kind };
      S.verbStep = 2;
      // Visuelles Feedback
      document.querySelectorAll('.obj-btn, .inv-item, .npc-btn').forEach(b => {
        b.classList.remove('selected-first', 'highlighted');
      });
      const el = document.querySelector(`[data-obj="${objId}"]`);
      if (el) el.classList.add('selected-first');
      highlightInteractables();
      updateVerbStatus();
    } else {
      // Zweites Objekt – Aktion ausführen
      const result = executeAction(S.verb, S.firstObj.id, objId);
      clearVerbMode();
      if (result !== undefined && result !== null) showReaction(result);
      renderRoom(); // Sichtbarkeit aktualisieren
    }
  } else {
    const result = executeAction(S.verb, objId);
    clearVerbMode();
    if (result !== undefined && result !== null) showReaction(result);
    renderRoom(); // Sichtbarkeit aktualisieren
  }
}

// ── Dialogfenster ───────────────────────────────────────────
function runDialogActions(actions) {
  (actions || []).forEach(a => {
    if (a.give  !== undefined) addItem(a.give);
    if (a.take  !== undefined) removeItem(a.take);
    if (a.flag  !== undefined) S.p[a.flag] = true;
    if (a.stamp !== undefined) { S.stamps[a.stamp] = true; renderStamps(); }
    if (a.fn) a.fn();
  });
  if ((actions || []).length > 0) saveGame();
}

function renderDialogNode(npcId, nodeId) {
  const modal = document.getElementById('dialog-modal');
  if (!nodeId || nodeId === 'END') {
    modal.classList.add('hidden');
    renderRoom();
    return;
  }
  const node = DIALOGS[npcId]?.nodes?.[nodeId];
  if (!node) { modal.classList.add('hidden'); renderRoom(); return; }

  runDialogActions(typeof node.actions === 'function' ? node.actions() : (node.actions || []));

  const lines = typeof node.lines === 'function' ? node.lines() : (node.lines || []);
  const textEl = document.getElementById('dialog-npc-text');
  textEl.innerHTML = '';
  const p = document.createElement('p');
  p.textContent = lines.join(' ');
  textEl.appendChild(p);

  const choicesDiv = document.getElementById('dialog-choices');
  choicesDiv.innerHTML = '';
  const choices = typeof node.choices === 'function' ? node.choices() : (node.choices || []);
  choices.filter(c => !c.condition || c.condition()).forEach(c => {
    const btn = document.createElement('button');
    btn.className = 'dialog-choice';
    btn.textContent = c.text;
    btn.addEventListener('click', () => {
      if (c.actions) runDialogActions(c.actions);
      renderDialogNode(npcId, c.goto || 'END');
    });
    choicesDiv.appendChild(btn);
  });

  if (choices.filter(c => !c.condition || c.condition()).length === 0) {
    modal.classList.add('hidden');
    renderRoom();
  }
}

function showDialog(npcId) {
  if (!DIALOGS[npcId]) return defR();
  document.getElementById('dialog-modal').classList.remove('hidden');
  renderDialogNode(npcId, 'start');
  return null;
}

document.getElementById('dialog-close').addEventListener('click', () => {
  document.getElementById('dialog-modal').classList.add('hidden');
  renderRoom();
});

// ── Kombinationsschloss ─────────────────────────────────────
function openComboModal() {
  const modal = document.getElementById('combo-modal');
  document.getElementById('combo-input').value = '';
  modal.classList.remove('hidden');
  document.getElementById('combo-input').focus();
}

document.getElementById('combo-ok').addEventListener('click', () => {
  const val = document.getElementById('combo-input').value.trim();
  document.getElementById('combo-modal').classList.add('hidden');
  if (val === '1907') {
    S.p.klavier_offen = true;
    showReaction('Das Schloss öffnet sich mit einem Klick. Der Klavierdeckel schwenkt auf. Die Stimmgabel liegt vor Ihnen.');
    renderRoom();
  } else {
    showReaction('Das ist nicht die richtige Kombination.');
  }
});

document.getElementById('combo-cancel').addEventListener('click', () => {
  document.getElementById('combo-modal').classList.add('hidden');
});

document.getElementById('combo-input').addEventListener('keydown', e => {
  if (e.key === 'Enter') document.getElementById('combo-ok').click();
  if (e.key === 'Escape') document.getElementById('combo-cancel').click();
});

// ── Reaktionstext anzeigen ──────────────────────────────────
function showReaction(text) {
  const el = document.getElementById('reaction-text');
  el.style.opacity = '0';
  setTimeout(() => {
    el.textContent = text;
    el.style.opacity = '1';
  }, 100);
  if (text) saveGame();
}

// ── Hilfsfunktionen ─────────────────────────────────────────
function getObjName(id) {
  if (ITEMS[id]) return ITEMS[id].name;
  if (OBJECTS[id]) return OBJECTS[id].name;
  return id;
}

function getVisibleObjects(roomId) {
  return Object.entries(OBJECTS)
    .filter(([id, o]) => {
      if (o.room !== roomId) return false;
      if (typeof o.visible === 'function') return o.visible();
      return true;
    })
    .map(([id, o]) => ({ id, ...o }));
}

// ── UI Rendering ────────────────────────────────────────────
function renderRoom() {
  const room = ROOMS[S.room];
  if (!room) return;

  document.getElementById('room-name').textContent = room.name;

  // Gegenstände und Personen trennen
  const allVisible = getVisibleObjects(S.room);
  const visibleObjs = allVisible.filter(o => !o.npc);
  const visibleNPCs = allVisible.filter(o => o.npc);

  const objsDiv = document.getElementById('room-objects');
  const objsSection = document.getElementById('objects-section');
  objsDiv.innerHTML = '';
  objsSection.style.display = visibleObjs.length ? '' : 'none';
  visibleObjs.forEach(obj => {
    const btn = document.createElement('button');
    btn.className = 'obj-btn';
    btn.textContent = obj.name;
    btn.dataset.obj = obj.id;
    btn.addEventListener('click', () => handleObjClick(obj.id, 'room'));
    btn.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') handleObjClick(obj.id, 'room'); });
    objsDiv.appendChild(btn);
  });

  // Personen
  const personsDiv = document.getElementById('room-persons');
  const personsSection = document.getElementById('persons-section');
  personsDiv.innerHTML = '';
  personsSection.style.display = visibleNPCs.length ? '' : 'none';
  visibleNPCs.forEach(obj => {
    const btn = document.createElement('button');
    btn.className = 'npc-btn';
    btn.textContent = obj.name;
    btn.dataset.obj = obj.id;
    btn.addEventListener('click', () => handleObjClick(obj.id, 'room'));
    btn.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') handleObjClick(obj.id, 'room'); });
    personsDiv.appendChild(btn);
  });

  // Ausgänge – in Passage im Hauptbereich, in Läden in der linken Spalte
  const exitsDiv = document.getElementById('room-exits');
  const exitsSection = document.getElementById('exits-section');
  const exitsLabel = document.getElementById('exits-label');
  exitsDiv.innerHTML = '';
  exitsSection.style.display = room.exits.length ? '' : 'none';
  const inPassage = S.room === 'passage';
  if (inPassage) {
    document.getElementById('main-area').appendChild(exitsSection);
    exitsLabel.className = 'section-label';
    exitsDiv.style.flexDirection = 'row';
  } else {
    document.getElementById('verb-panel').appendChild(exitsSection);
    exitsLabel.className = 'panel-label';
    exitsLabel.style.marginTop = '20px';
    exitsDiv.style.flexDirection = 'column';
  }
  exitsDiv.dataset.passage = inPassage ? '1' : '';
  room.exits.forEach(exit => {
    const btn = document.createElement('button');
    btn.className = 'exit-btn';
    btn.textContent = exit.label;
    btn.addEventListener('click', () => enterRoom(exit.room));
    exitsDiv.appendChild(btn);
  });
}

function renderInventory() {
  const slots = document.getElementById('inventory-slots');
  slots.innerHTML = '';
  S.inv.forEach(id => {
    const item = ITEMS[id];
    if (!item) return;
    const el = document.createElement('button');
    el.className = 'inv-item';
    el.dataset.obj = id;
    el.title = item.desc;
    el.innerHTML = `<span>${item.icon}</span><span>${item.name}</span>`;
    el.addEventListener('click', () => handleObjClick(id, 'inv'));
    slots.appendChild(el);
  });
}

function renderStamps() {
  const slots = document.getElementById('stamp-slots');
  slots.innerHTML = '';
  S.stamps.forEach((filled, i) => {
    const el = document.createElement('div');
    el.className = 'stamp-slot' + (filled ? ' filled' : '');
    el.title = STAMP_ORDER[i] ? getObjName(STAMP_ORDER[i]) : '';
    el.textContent = filled ? STAMP_ICONS[i] : '';
    slots.appendChild(el);
  });
  renderInventory();
}

// ── Outro ───────────────────────────────────────────────────
const OUTRO_LINES = [
  'Und dann geht die Tür auf.',
  'Esel steht auf der Dachterrasse des Einkaufszentrums Sachsenotto. Die Lichterketten leuchten. Sein Blick schweift über die ganze Stadt. Auch über den alten Zirkuswagen.',
  'Teddy sitzt auf seinem Stuhl, dreht sich zu Esel um und schaut ihn an. Dann sagt er: »Mensch, da bist du ja. Ich hab schon gedacht – na ja. Schau mal! Hier hätten wir feiern können! Wäre schön geworden, oder? Aber jetzt ist es ein bisschen spät geworden.« Er schaut kurz zur Tür. »Wie das mit dem Türgriff passieren konnte – ich versteh\'s selbst nicht. Die KI hat da irgendwas falsch halluziniert.« Kurze Pause. »Aber weißt du was? Dann feiern wir heute halt zu zweit. Und zum 20. Jubiläum, da machen wir das wieder richtig. Mit echten Menschen. Oder?«',
  'Esel schaut sich um. Sein Blick wandert über die Dachterrasse, dann zurück zu Teddy. Er sagt: »...«',
];

function showOutro() {
  document.getElementById('game').classList.add('hidden');
  const prologEl = document.getElementById('prolog');
  prologEl.classList.remove('hidden');
  document.getElementById('prolog-next').classList.add('hidden');

  const textEl = document.getElementById('prolog-text');
  textEl.innerHTML = '';

  // Restart-Button in den Prolog-Content einbauen
  const prologContent = document.getElementById('prolog-content');
  const restartBtn = document.createElement('button');
  restartBtn.className = 'btn-primary';
  restartBtn.textContent = 'Von vorne beginnen';
  restartBtn.style.position = 'absolute';
  restartBtn.style.right = '10%';
  restartBtn.style.top = '50%';
  restartBtn.style.transform = 'translateY(-50%)';
  restartBtn.style.display = 'none';
  restartBtn.addEventListener('click', () => {
    localStorage.removeItem(SAVE_KEY);
    localStorage.removeItem('eut_intro_seen');
    location.reload();
  });
  prologContent.appendChild(restartBtn);

  const cursor = document.createElement('span');
  cursor.id = 'prolog-cursor';

  let lineIdx = 0;
  let charIdx = 0;
  let currentP = null;
  let done = false;

  function finish() {
    if (done) return;
    done = true;
    document.removeEventListener('keydown', onSpaceKey);
    cursor.remove();
    textEl.innerHTML = '';
    OUTRO_LINES.forEach(line => {
      const p = document.createElement('p');
      p.textContent = line;
      textEl.appendChild(p);
    });
    restartBtn.style.display = '';
  }

  function onSpaceKey(e) {
    if (e.code === 'Space') { e.preventDefault(); finish(); }
  }
  document.addEventListener('keydown', onSpaceKey);

  function typeChar() {
    if (done) return;
    if (lineIdx >= OUTRO_LINES.length) { finish(); return; }
    if (charIdx === 0) {
      currentP = document.createElement('p');
      textEl.appendChild(currentP);
    }
    const line = OUTRO_LINES[lineIdx];
    if (charIdx < line.length) {
      currentP.textContent = line.slice(0, charIdx + 1);
      currentP.appendChild(cursor);
      charIdx++;
      setTimeout(typeChar, 28);
    } else {
      charIdx = 0;
      lineIdx++;
      setTimeout(typeChar, 600);
    }
  }
  typeChar();
}

document.getElementById('restart-btn').addEventListener('click', () => {
  localStorage.removeItem(SAVE_KEY);
  localStorage.removeItem('eut_intro_seen');
  location.reload();
});

// ── Prolog ──────────────────────────────────────────────────
const PROLOG_LINES = [
  'Es hätte eine weitere Jubiläumsfeier werden sollen.',
  'Denn Esel und Teddy wissen ja, wie das geht. Ihre Volljährigkeit haben sie letztes Jahr gefeiert – live, in Köln, zusammen mit sympathischen Leuts. Es war herrlich.',
  'Zum 19. Jubiläum wollte Teddy jetzt nachlegen. Digital. Die Dachterrasse des neuen Einkaufszentrums in Sachsenotto war gebucht. Eine grandiose Location mit einem Blick über die ganze Stadt. Auch auf den alten Zirkuswagen. Die Idee war gut. Das Wetter sollte auch mitspielen. Aber die Ausführung, die hat Teddy dummerweise der künstlichen Intelligenz überlassen.',
  'Jetzt sitzt er da. Alleine auf der Dachterrasse vom Einkaufscenter Sachsenotto. Die Tür nach draußen geht von innen nicht auf. Und von außen irgendwie auch nicht, weil die KI keinen Türgriff halluziniert hat.',
  'Aber Teddy konnte Esel noch einen Zettel hinterlassen.',
];

function showProlog() {
  const textEl = document.getElementById('prolog-text');
  const nextBtn = document.getElementById('prolog-next');
  textEl.innerHTML = '';
  nextBtn.classList.add('hidden');

  const cursor = document.createElement('span');
  cursor.id = 'prolog-cursor';

  let lineIdx = 0;
  let charIdx = 0;
  let currentP = null;
  let done = false;

  function finish() {
    if (done) return;
    done = true;
    document.removeEventListener('keydown', onSpaceKey);
    cursor.remove();
    textEl.innerHTML = '';
    PROLOG_LINES.forEach(line => {
      const p = document.createElement('p');
      p.textContent = line;
      textEl.appendChild(p);
    });
    nextBtn.classList.remove('hidden');
  }

  function onSpaceKey(e) {
    if (e.code === 'Space') {
      e.preventDefault();
      finish();
    }
  }

  document.addEventListener('keydown', onSpaceKey);

  function typeChar() {
    if (done) return;
    if (lineIdx >= PROLOG_LINES.length) {
      finish();
      return;
    }

    if (charIdx === 0) {
      currentP = document.createElement('p');
      textEl.appendChild(currentP);
    }

    const line = PROLOG_LINES[lineIdx];

    if (charIdx < line.length) {
      currentP.textContent = line.slice(0, charIdx + 1);
      currentP.appendChild(cursor);
      charIdx++;
      setTimeout(typeChar, 28);
    } else {
      charIdx = 0;
      lineIdx++;
      setTimeout(typeChar, 600);
    }
  }

  textEl.appendChild(cursor);
  typeChar();
}

document.getElementById('prolog-next').addEventListener('click', () => {
  document.getElementById('prolog').classList.add('hidden');
  document.getElementById('note-screen').classList.remove('hidden');
});

// ── Zettel ──────────────────────────────────────────────────
document.getElementById('btn-start').addEventListener('click', () => {
  localStorage.setItem('eut_intro_seen', '1');
  document.getElementById('note-screen').classList.add('hidden');
  document.getElementById('image-screen').classList.remove('hidden');

  function startGame() {
    document.getElementById('image-screen').classList.add('hidden');
    document.getElementById('game').classList.remove('hidden');
    enterRoom('passage');
    renderInventory();
    renderStamps();
  }

  const timer = setTimeout(startGame, 10000);

  document.getElementById('image-screen-img').addEventListener('click', () => {
    clearTimeout(timer);
    startGame();
  }, { once: true });
});

const PHONE_LINES = [
  'Oh boy, ich wusste, dass Sie das anklicken. Hilft aber nichts. Es geht hier nur mit den anderen Button weiter.',
];

document.getElementById('btn-nope').addEventListener('click', () => {
  const btnNope = document.getElementById('btn-nope');
  btnNope.disabled = true;
  btnNope.style.opacity = '0.3';

  const phoneDiv = document.getElementById('phone-dialog');
  phoneDiv.classList.remove('hidden');
  phoneDiv.innerHTML = '';

  let i = 0;
  function showPhoneLine() {
    if (i >= PHONE_LINES.length) {
      // Nur noch »Auf geht's« zeigen
      return;
    }
    const p = document.createElement('p');
    p.textContent = PHONE_LINES[i];
    p.style.animation = 'fadeIn 0.5s forwards';
    phoneDiv.appendChild(p);
    i++;
    setTimeout(showPhoneLine, 1400);
  }
  showPhoneLine();
});

// ── Verb-Buttons ────────────────────────────────────────────
document.querySelectorAll('.verb-btn').forEach(btn => {
  btn.addEventListener('click', () => setVerb(btn.dataset.verb));
});

// ESC bricht Verb-Modus ab
document.addEventListener('keydown', e => {
  if (e.key === 'Escape') clearVerbMode();
});

// ── Reset-Button ─────────────────────────────────────────────
document.getElementById('reset-btn').addEventListener('click', () => {
  localStorage.removeItem(SAVE_KEY);
  localStorage.removeItem('eut_intro_seen');
  location.reload();
});

// ── Start ───────────────────────────────────────────────────
const introSeen = localStorage.getItem('eut_intro_seen');
if (loadGame()) {
  // Gespeicherter Stand vorhanden – direkt ins Spiel
  document.getElementById('prolog').classList.add('hidden');
  document.getElementById('game').classList.remove('hidden');
  enterRoom(S.room);
  if (hasItem('stempelkarte')) {
    document.getElementById('stamp-panel').classList.remove('hidden');
  }
  renderInventory();
  renderStamps();
} else if (introSeen) {
  // Intro schon gesehen, kein gespeicherter Stand – direkt zur Zettel-Szene
  document.getElementById('prolog').classList.add('hidden');
  document.getElementById('note-screen').classList.remove('hidden');
} else {
  // Erstes Mal – Intro spielen
  showProlog();
}
// Stempelkarte anfangs ausgeblendet – wird beim ersten Besuch im Service-Center eingeblendet
