{"title":"Vorbestellen","description":"\u003cstyle\u003e\n  @font-face {\n    font-family: 'P-L Grotesque 001';\n    src: url('https:\/\/snnjky-1d.myshopify.com\/cdn\/shop\/t\/8\/assets\/pl-grotesque-001.otf') format('opentype');\n    font-weight: 400;\n    font-style: normal;\n    font-display: swap;\n  }\n  #bb-preorder, #bb-preorder * {\n    font-family: 'P-L Grotesque 001', sans-serif;\n  }\n\u003c\/style\u003e\n\u003cdiv id=\"bb-preorder\" style=\"max-width:560px;margin:0 auto;padding:24px 16px;\"\u003e\n  \u003ch1 style=\"margin-bottom:4px;\"\u003eVorbestellen\u003c\/h1\u003e\n  \u003cp style=\"margin-top:0;color:#555;\"\u003eWähle, was du vorbestellen möchtest.\u003c\/p\u003e\n\n  \u003cdiv id=\"bb-choice-group\" style=\"display:flex;flex-direction:column;gap:10px;margin:24px 0;\"\u003e\n    \u003cbutton type=\"button\" id=\"bb-choose-dinner\" class=\"bb-choice-btn\" style=\"text-align:left;border:1px solid #a80404;border-radius:8px;padding:14px;background:#D20505;color:#000;cursor:pointer;font-size:16px;font-weight:600;\"\u003e\n      BussiBar Dinner-Event\n      \u003cdiv style=\"font-weight:400;font-size:13px;color:#2a0000;margin-top:4px;\"\u003ePannierstraße 57, 12047 Berlin-Neukölln · 14.\/15. August 2026, 17:00–21:00 Uhr\u003c\/div\u003e\n    \u003c\/button\u003e\n    \u003cbutton type=\"button\" id=\"bb-choose-oysters\" class=\"bb-choice-btn\" style=\"text-align:left;border:1px solid #a80404;border-radius:8px;padding:14px;background:#D20505;color:#000;cursor:pointer;font-size:16px;font-weight:600;\"\u003e\n      Austern Abholung\n      \u003cdiv style=\"font-weight:400;font-size:13px;color:#2a0000;margin-top:4px;\"\u003eZähringerstr. 26, 10707 Berlin · Mi–Sa, 17:00–20:00 Uhr\u003c\/div\u003e\n    \u003c\/button\u003e\n    \u003cbutton type=\"button\" id=\"bb-choose-merch\" class=\"bb-choice-btn\" style=\"text-align:left;border:1px solid #a80404;border-radius:8px;padding:14px;background:#D20505;color:#000;cursor:pointer;font-size:16px;font-weight:600;\"\u003e\n      Merch\n      \u003cdiv style=\"font-weight:400;font-size:13px;color:#2a0000;margin-top:4px;\"\u003eAbholung bei Viktor und Luise, Welserstraße 10-12, Schöneberg, 10777 Berlin\u003c\/div\u003e\n    \u003c\/button\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv id=\"bb-dinner-section\" style=\"display:none;\"\u003e\n    \u003cbutton type=\"button\" class=\"bb-back\" data-target=\"bb-dinner-section\" style=\"background:none;border:none;color:#555;cursor:pointer;padding:0;margin-bottom:16px;font-size:14px;\"\u003e← Zurück zur Auswahl\u003c\/button\u003e\n    \u003cp style=\"margin-top:0;color:#555;\"\u003eBussiBar · Pannierstraße 57, 12047 Berlin-Neukölln · 17:00–21:00 Uhr\u003c\/p\u003e\n\n    \u003cdiv id=\"bb-preorder-form\" style=\"display:flex;flex-direction:column;gap:20px;margin-top:16px;\"\u003e\n\n      \u003cdiv\u003e\n        \u003clabel style=\"font-weight:600;display:block;margin-bottom:8px;\"\u003e1. Datum wählen\u003c\/label\u003e\n        \u003cdiv style=\"display:flex;flex-direction:column;gap:10px;\"\u003e\n          \u003clabel class=\"bb-date-option\" data-variant-id=\"64122851623289\" style=\"border:1px solid #ccc;border-radius:8px;padding:12px 14px;display:flex;align-items:center;justify-content:space-between;gap:10px;cursor:pointer;\"\u003e\n            \u003cspan\u003e\u003cinput type=\"radio\" name=\"bb-date\" value=\"64122851623289\" style=\"margin-right:8px;\"\u003eFreitag, 14. August 2026\u003c\/span\u003e\n            \u003cspan class=\"bb-availability\" data-variant=\"64122851623289\" style=\"font-size:13px;color:#777;\"\u003e\u003c\/span\u003e\n          \u003c\/label\u003e\n          \u003clabel class=\"bb-date-option\" data-variant-id=\"64122851656057\" style=\"border:1px solid #ccc;border-radius:8px;padding:12px 14px;display:flex;align-items:center;justify-content:space-between;gap:10px;cursor:pointer;\"\u003e\n            \u003cspan\u003e\u003cinput type=\"radio\" name=\"bb-date\" value=\"64122851656057\" style=\"margin-right:8px;\"\u003eSamstag, 15. August 2026\u003c\/span\u003e\n            \u003cspan class=\"bb-availability\" data-variant=\"64122851656057\" style=\"font-size:13px;color:#777;\"\u003e\u003c\/span\u003e\n          \u003c\/label\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv\u003e\n        \u003clabel for=\"bb-persons\" style=\"font-weight:600;display:block;margin-bottom:8px;\"\u003e2. Anzahl Personen\u003c\/label\u003e\n        \u003cinput type=\"number\" id=\"bb-persons\" name=\"bb-persons\" min=\"1\" max=\"20\" value=\"2\" style=\"width:100px;padding:10px;border:1px solid #ccc;border-radius:8px;\"\u003e\n      \u003c\/div\u003e\n\n      \u003cbutton type=\"button\" id=\"bb-submit\" style=\"background:#D20505;color:#000;border:1px solid #a80404;border-radius:8px;padding:14px 20px;font-size:16px;font-weight:600;cursor:pointer;\"\u003e\n        Weiter zu den Gerichten\n      \u003c\/button\u003e\n\n      \u003cp id=\"bb-error\" style=\"color:#c0392b;display:none;margin:0;\"\u003e\u003c\/p\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv id=\"bb-oyster-section\" style=\"display:none;\"\u003e\n    \u003cbutton type=\"button\" class=\"bb-back\" data-target=\"bb-oyster-section\" style=\"background:none;border:none;color:#555;cursor:pointer;padding:0;margin-bottom:16px;font-size:14px;\"\u003e← Zurück zur Auswahl\u003c\/button\u003e\n    \u003cp style=\"margin-top:0;color:#555;\"\u003eAustern zum Vorbestellen · Abholung Mi–Sa, 17:00–20:00 Uhr · bitte mindestens 3 Tage vor dem Wunschtermin bestellen.\u003c\/p\u003e\n\n    \u003cdiv style=\"display:flex;flex-direction:column;gap:20px;margin-top:16px;\"\u003e\n\n      \u003cdiv\u003e\n        \u003clabel style=\"font-weight:600;display:block;margin-bottom:8px;\"\u003e1. Standort wählen\u003c\/label\u003e\n        \u003cdiv style=\"display:flex;flex-direction:column;gap:10px;\"\u003e\n          \u003clabel class=\"bb-oyster-location\" data-location=\"Zähringerstr. 26, 10707 Berlin\" style=\"border:1px solid #ccc;border-radius:8px;padding:12px 14px;display:flex;align-items:center;justify-content:space-between;gap:10px;cursor:pointer;\"\u003e\n            \u003cspan\u003e\u003cinput type=\"radio\" name=\"bb-oyster-location\" value=\"Zähringerstr. 26, 10707 Berlin\" style=\"margin-right:8px;\"\u003eBerlin – Zähringerstr. 26, 10707 Berlin\u003c\/span\u003e\n          \u003c\/label\u003e\n          \u003clabel class=\"bb-oyster-location\" style=\"border:1px solid #ccc;border-radius:8px;padding:12px 14px;display:flex;align-items:center;justify-content:space-between;gap:10px;opacity:0.5;cursor:not-allowed;\"\u003e\n            \u003cspan\u003e\u003cinput type=\"radio\" name=\"bb-oyster-location\" value=\"hamburg\" disabled style=\"margin-right:8px;\"\u003eHamburg\u003c\/span\u003e\n            \u003cspan style=\"font-size:12px;color:#777;\"\u003eBald verfügbar\u003c\/span\u003e\n          \u003c\/label\u003e\n          \u003clabel class=\"bb-oyster-location\" style=\"border:1px solid #ccc;border-radius:8px;padding:12px 14px;display:flex;align-items:center;justify-content:space-between;gap:10px;opacity:0.5;cursor:not-allowed;\"\u003e\n            \u003cspan\u003e\u003cinput type=\"radio\" name=\"bb-oyster-location\" value=\"muenchen\" disabled style=\"margin-right:8px;\"\u003eMünchen\u003c\/span\u003e\n            \u003cspan style=\"font-size:12px;color:#777;\"\u003eBald verfügbar\u003c\/span\u003e\n          \u003c\/label\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv\u003e\n        \u003clabel style=\"font-weight:600;display:block;margin-bottom:8px;\"\u003e2. Abholtermin wählen\u003c\/label\u003e\n        \u003cdiv id=\"bb-oyster-dates\" style=\"display:flex;flex-direction:column;gap:10px;\"\u003e\n          \u003cspan style=\"font-size:13px;color:#777;\"\u003eTermine werden geladen …\u003c\/span\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003cbutton type=\"button\" id=\"bb-oyster-submit\" style=\"background:#D20505;color:#000;border:1px solid #a80404;border-radius:8px;padding:14px 20px;font-size:16px;font-weight:600;cursor:pointer;\"\u003e\n        Weiter zu den Austern\n      \u003c\/button\u003e\n\n      \u003cp id=\"bb-oyster-error\" style=\"color:#c0392b;display:none;margin:0;\"\u003e\u003c\/p\u003e\n    \u003c\/div\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv id=\"bb-merch-section\" style=\"display:none;\"\u003e\n    \u003cbutton type=\"button\" class=\"bb-back\" data-target=\"bb-merch-section\" style=\"background:none;border:none;color:#555;cursor:pointer;padding:0;margin-bottom:16px;font-size:14px;\"\u003e← Zurück zur Auswahl\u003c\/button\u003e\n    \u003cp style=\"margin-top:0;color:#555;\"\u003eAbholung bei Viktor und Luise, Welserstraße 10-12, Schöneberg, 10777 Berlin.\u003c\/p\u003e\n    \u003cbutton type=\"button\" id=\"bb-merch-continue\" style=\"background:#D20505;color:#000;border:1px solid #a80404;border-radius:8px;padding:14px 20px;font-size:16px;font-weight:600;cursor:pointer;\"\u003e\n      Weiter zum Merch\n    \u003c\/button\u003e\n  \u003c\/div\u003e\n\u003c\/div\u003e\n\n\u003cscript\u003e\n(function () {\n  var RESERVATION_HANDLE = 'bussibar-dinner-reservierung';\n  var DISHES_COLLECTION_URL = '\/collections\/bussibar-dinner-menu';\n  var MERCH_COLLECTION_URL = '\/collections\/merch-abholung';\n  var OYSTER_COLLECTION_URL = '\/collections\/austern-abholung';\n  var FETCH_TIMEOUT_MS = 15000;\n  var OYSTER_PICKUP_WEEKDAYS = [3, 4, 5, 6]; \/\/ Mi, Do, Fr, Sa (Date.getDay(): So=0 … Sa=6)\n  var OYSTER_MIN_LEAD_DAYS = 3;\n  var OYSTER_DATE_COUNT = 8;\n\n  var choiceGroup = document.getElementById('bb-choice-group');\n  var dinnerSection = document.getElementById('bb-dinner-section');\n  var oysterSection = document.getElementById('bb-oyster-section');\n  var merchSection = document.getElementById('bb-merch-section');\n\n  document.getElementById('bb-choose-dinner').addEventListener('click', function () {\n    choiceGroup.style.display = 'none';\n    dinnerSection.style.display = 'block';\n  });\n\n  document.getElementById('bb-choose-oysters').addEventListener('click', function () {\n    choiceGroup.style.display = 'none';\n    oysterSection.style.display = 'block';\n  });\n\n  document.getElementById('bb-choose-merch').addEventListener('click', function () {\n    choiceGroup.style.display = 'none';\n    merchSection.style.display = 'block';\n  });\n\n  Array.prototype.forEach.call(document.querySelectorAll('.bb-back'), function (btn) {\n    btn.addEventListener('click', function () {\n      document.getElementById(btn.getAttribute('data-target')).style.display = 'none';\n      choiceGroup.style.display = 'flex';\n    });\n  });\n\n  document.getElementById('bb-merch-continue').addEventListener('click', function () {\n    window.location.href = MERCH_COLLECTION_URL;\n  });\n\n  \/\/ Timeout wrapper: if a fetch (or anything downstream, e.g. another app's\n  \/\/ script intercepting window.fetch) stalls, don't leave a button stuck\n  \/\/ forever — surface an error after FETCH_TIMEOUT_MS instead.\n  function withTimeout(promise, ms) {\n    return new Promise(function (resolve, reject) {\n      var timer = setTimeout(function () {\n        reject(new Error('Zeitüberschreitung. Bitte versuche es erneut.'));\n      }, ms);\n      promise.then(\n        function (value) { clearTimeout(timer); resolve(value); },\n        function (err) { clearTimeout(timer); reject(err); }\n      );\n    });\n  }\n\n  \/* ---------------- BussiBar Dinner ---------------- *\/\n\n  var errorBox = document.getElementById('bb-error');\n  var submitBtn = document.getElementById('bb-submit');\n\n  function showError(msg) {\n    errorBox.textContent = msg;\n    errorBox.style.display = 'block';\n  }\n\n  function dateLabelForVariant(id) {\n    return id === '64122851623289' ? '14. August 2026' : '15. August 2026';\n  }\n\n  fetch('\/products\/' + RESERVATION_HANDLE + '.js')\n    .then(function (r) { return r.json(); })\n    .then(function (product) {\n      product.variants.forEach(function (variant) {\n        var el = document.querySelector('.bb-availability[data-variant=\"' + variant.id + '\"]');\n        var wrapper = document.querySelector('.bb-date-option[data-variant-id=\"' + variant.id + '\"]');\n        var radio = wrapper ? wrapper.querySelector('input[type=radio]') : null;\n        if (!el) { return; }\n        if (variant.available === false) {\n          el.textContent = 'ausgebucht';\n          el.style.color = '#c0392b';\n          if (radio) { radio.disabled = true; }\n          if (wrapper) { wrapper.style.opacity = '0.5'; wrapper.style.cursor = 'not-allowed'; }\n        }\n      });\n    })\n    .catch(function () { });\n\n  \/\/ Bound directly to the button's click event (button is type=\"button\",\n  \/\/ not type=\"submit\", and this is not inside a \u003cform\u003e) so no other script\n  \/\/ on the page that listens for native form \"submit\" events can ever\n  \/\/ intercept or short-circuit this before it runs.\n  submitBtn.addEventListener('click', function (e) {\n    e.preventDefault();\n    errorBox.style.display = 'none';\n\n    var selected = document.querySelector('input[name=\"bb-date\"]:checked');\n    var persons = parseInt(document.getElementById('bb-persons').value, 10);\n\n    if (!selected) {\n      showError('Bitte wähle ein Datum aus.');\n      return;\n    }\n    if (!persons || persons \u003c 1) {\n      showError('Bitte gib eine gültige Personenzahl an.');\n      return;\n    }\n\n    var variantId = parseInt(selected.value, 10);\n    var dateLabel = dateLabelForVariant(selected.value);\n\n    submitBtn.disabled = true;\n    submitBtn.textContent = 'Wird reserviert …';\n\n    function resetButton() {\n      submitBtn.disabled = false;\n      submitBtn.textContent = 'Weiter zu den Gerichten';\n    }\n\n    withTimeout(\n      fetch('\/cart\/add.js', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application\/json', Accept: 'application\/json' },\n        body: JSON.stringify({\n          items: [{\n            id: variantId,\n            quantity: persons,\n            properties: {\n              'Datum': dateLabel,\n              'Personen': String(persons)\n            }\n          }]\n        })\n      }).then(function (res) {\n        return res.json().then(function (data) {\n          if (!res.ok) { throw new Error(data.description || 'Für dieses Datum sind nicht mehr genug Plätze frei.'); }\n          return data;\n        });\n      }).then(function () {\n        return fetch('\/cart\/update.js', {\n          method: 'POST',\n          headers: { 'Content-Type': 'application\/json', Accept: 'application\/json' },\n          body: JSON.stringify({\n            attributes: {\n              'Veranstaltungsdatum': dateLabel,\n              'Personenanzahl': String(persons),\n              'Venue': 'BussiBar, Pannierstraße 57, 12047 Berlin'\n            }\n          })\n        });\n      }),\n      FETCH_TIMEOUT_MS\n    )\n      .then(function () {\n        window.location.href = DISHES_COLLECTION_URL;\n      })\n      .catch(function (err) {\n        resetButton();\n        showError(err.message || 'Etwas ist schiefgelaufen. Bitte versuche es erneut.');\n      });\n  });\n\n  \/* ---------------- Austern Abholung ---------------- *\/\n\n  var oysterDatesContainer = document.getElementById('bb-oyster-dates');\n  var oysterErrorBox = document.getElementById('bb-oyster-error');\n  var oysterSubmitBtn = document.getElementById('bb-oyster-submit');\n\n  function showOysterError(msg) {\n    oysterErrorBox.textContent = msg;\n    oysterErrorBox.style.display = 'block';\n  }\n\n  function pad(n) { return n \u003c 10 ? '0' + n : String(n); }\n\n  function isoDate(d) {\n    return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());\n  }\n\n  function germanLabel(d) {\n    try {\n      return d.toLocaleDateString('de-DE', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });\n    } catch (e) {\n      return isoDate(d);\n    }\n  }\n\n  function buildOysterDateList() {\n    var dates = [];\n    var d = new Date();\n    d.setHours(0, 0, 0, 0);\n    d.setDate(d.getDate() + OYSTER_MIN_LEAD_DAYS);\n\n    var guard = 0;\n    while (dates.length \u003c OYSTER_DATE_COUNT \u0026\u0026 guard \u003c 60) {\n      if (OYSTER_PICKUP_WEEKDAYS.indexOf(d.getDay()) !== -1) {\n        dates.push(new Date(d.getTime()));\n      }\n      d.setDate(d.getDate() + 1);\n      guard++;\n    }\n\n    oysterDatesContainer.innerHTML = '';\n    dates.forEach(function (date, idx) {\n      var label = document.createElement('label');\n      label.className = 'bb-oyster-date-option';\n      label.style.cssText = 'border:1px solid #ccc;border-radius:8px;padding:12px 14px;display:flex;align-items:center;gap:10px;cursor:pointer;';\n\n      var input = document.createElement('input');\n      input.type = 'radio';\n      input.name = 'bb-oyster-date';\n      input.value = isoDate(date);\n      input.setAttribute('data-label', germanLabel(date));\n      input.style.marginRight = '8px';\n\n      label.appendChild(input);\n      label.appendChild(document.createTextNode(germanLabel(date)));\n      oysterDatesContainer.appendChild(label);\n    });\n  }\n\n  buildOysterDateList();\n\n  oysterSubmitBtn.addEventListener('click', function (e) {\n    e.preventDefault();\n    oysterErrorBox.style.display = 'none';\n\n    var selectedLocation = document.querySelector('input[name=\"bb-oyster-location\"]:checked');\n    var selectedDate = document.querySelector('input[name=\"bb-oyster-date\"]:checked');\n\n    if (!selectedLocation) {\n      showOysterError('Bitte wähle einen Standort aus.');\n      return;\n    }\n    if (!selectedDate) {\n      showOysterError('Bitte wähle einen Abholtermin aus.');\n      return;\n    }\n\n    var locationLabel = selectedLocation.value;\n    var dateLabel = selectedDate.getAttribute('data-label') || selectedDate.value;\n\n    oysterSubmitBtn.disabled = true;\n    oysterSubmitBtn.textContent = 'Wird gespeichert …';\n\n    function resetButton() {\n      oysterSubmitBtn.disabled = false;\n      oysterSubmitBtn.textContent = 'Weiter zu den Austern';\n    }\n\n    withTimeout(\n      fetch('\/cart\/update.js', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application\/json', Accept: 'application\/json' },\n        body: JSON.stringify({\n          attributes: {\n            'Austern Standort': locationLabel,\n            'Austern Abholdatum': dateLabel,\n            'Austern Abholzeit': '17:00–20:00 Uhr'\n          }\n        })\n      }),\n      FETCH_TIMEOUT_MS\n    )\n      .then(function () {\n        window.location.href = OYSTER_COLLECTION_URL;\n      })\n      .catch(function (err) {\n        resetButton();\n        showOysterError(err.message || 'Etwas ist schiefgelaufen. Bitte versuche es erneut.');\n      });\n  });\n})();\n\u003c\/script\u003e\n","products":[],"url":"https:\/\/oystore.de\/collections\/vorbestellen.oembed","provider":"OYSTORE","version":"1.0","type":"link"}