{"title":"Specialty Coffee Discovery","description":null,"products":[{"product_id":"aeropress-bundle-1","title":"Kit Inicial AeroPress","description":null,"brand":"Fábrica Coffee Roasters","offers":[{"title":"Default Title","offer_id":52083511296347,"sku":null,"price":54.9,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/aeropress-starter-kit-specialty-coffee-fabrica.webp?v=1769107760"},{"product_id":"v60-bundle","title":"Kit V60 de Iniciação","description":"\u003cp\u003e\u003cspan class=\"\"\u003eTudo o que precisa para dominar a arte do método \"pour-over\" está aqui.\u003c\/span\u003e\u003cspan class=\"\"\u003e Este conjunto cuidadosamente selecionado combina o icónico \u003c\/span\u003e\u003cb data-path-to-node=\"3\" data-index-in-node=\"107\" class=\"\"\u003eHario V60 Craft Coffee Maker\u003c\/b\u003e\u003cspan class=\"\"\u003e – conhecido pela sua capacidade de realçar as notas delicadas e limpas de grãos de alta qualidade – com um saco do nosso \u003c\/span\u003e\u003cb data-path-to-node=\"3\" data-index-in-node=\"240\" class=\"\"\u003eCafé de Filtro de Especialidade Premium\u003c\/b\u003e\u003cspan class=\"\"\u003e.\u003c\/span\u003e\u003cspan class=\"\"\u003e Quer seja um principiante ou um barista experiente,\u003c\/span\u003e\u003cspan class=\"\"\u003e esta combinação garante uma chávena brilhante,\u003c\/span\u003e\u003cspan class=\"\"\u003e aromática\u003c\/span\u003e\u003cspan class=\"\"\u003e e equilibrada todas as manhãs.\u003c\/span\u003e\u003cspan class=\"\"\u003e Basta indicar-nos o seu método de preparação preferido\u003c\/span\u003e\u003cspan class=\"\"\u003e e moeremos o seu café na perfeição.\u003c\/span\u003e\u003c\/p\u003e","brand":"Fábrica Coffee Roasters","offers":[{"title":"Default Title","offer_id":52083527549275,"sku":null,"price":41.9,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/v60-starter-kit-specialty-coffee-fabrica.webp?v=1769107222"},{"product_id":"specialty-coffee-discovery-pack","title":"Specialty Coffee Discovery Pack","description":"\u003cp\u003eDescubra o mundo do café de especialidade — caraterizado pela presença distinta de perfis sensoriais: frutados, achocolatados, florais, doces, especiados e muitos outros. Explore uma seleção de origens únicas dos melhores terroirs do mundo.\u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003cp\u003eEste pack de descoberta contém 6 sacos de 35 g de café de especialidade. Um saco de 35 g rende cerca de 2 cafés de filtro de 250 ml ou 4 espressos simples — a dose perfeita para provar sabores fora do comum.\u003c\/p\u003e","brand":"Fábrica Coffee Roasters","offers":[{"title":"Default Title","offer_id":52846216839515,"sku":null,"price":14.9,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/discovery-pack-specialty-coffee-fabrica-front.webp?v=1776868467"},{"product_id":"fabrica-coffee-subscription-exotics","title":"Fábrica's Coffee Subscription - Exotics","description":"\u003cp\u003ePerfis experimentais e especiais - frutados, florais, surpreendentes. Embalado do nosso lote mais fresco e enviado em 24-48h.\u003c\/p\u003e\n\u003cdiv id=\"fspdp-exotics\" class=\"fspdp-exotics-scope\" style=\"display:none\"\u003e\n  \u003ch3 class=\"fspdp-exotics-title\"\u003eNa seleção desta semana\u003c\/h3\u003e\n  \u003cdiv class=\"fspdp-exotics-grid\"\u003e\n    \u003cdiv class=\"fspdp-exotics-coffee\" data-c=\"xEsp1\"\u003e\n      \u003cdiv class=\"fspdp-exotics-img\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/cyeza-250g-fabrica-specialty-coffee-bag.webp?v=1785771983\u0026amp;width=420\" alt=\"Cyeza - Rwanda\" loading=\"lazy\"\u003e\u003c\/div\u003e\n      \u003cspan class=\"fspdp-exotics-tag\"\u003eExotics\u003c\/span\u003e\n      \u003ch4\u003eCyeza - Rwanda\u003c\/h4\u003e\n      \u003cdiv class=\"fspdp-exotics-notes\"\u003eRed berries, cola, dark chocolate\u003c\/div\u003e\n      \u003cdiv class=\"fspdp-exotics-colr\"\u003e\n\u003cspan class=\"fspdp-exotics-role\"\u003eEspresso\u003c\/span\u003e\u003cspan class=\"fspdp-exotics-cnt\"\u003e\u003c\/span\u003e\n\u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"fspdp-exotics-coffee\" data-c=\"xEsp2\"\u003e\n      \u003cdiv class=\"fspdp-exotics-img\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/las-amapolas-250g-fabrica-specialty-coffee-bag.webp?v=1785771788\u0026amp;width=420\" alt=\"Las Amapolas - Guatemala\" loading=\"lazy\"\u003e\u003c\/div\u003e\n      \u003cspan class=\"fspdp-exotics-tag\"\u003eExotics\u003c\/span\u003e\n      \u003ch4\u003eLas Amapolas - Guatemala\u003c\/h4\u003e\n      \u003cdiv class=\"fspdp-exotics-notes\"\u003eChocolate, orange, plum\u003c\/div\u003e\n      \u003cdiv class=\"fspdp-exotics-colr\"\u003e\n\u003cspan class=\"fspdp-exotics-role\"\u003eEspresso\u003c\/span\u003e\u003cspan class=\"fspdp-exotics-cnt\"\u003e\u003c\/span\u003e\n\u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"fspdp-exotics-coffee\" data-c=\"xFil1\"\u003e\n      \u003cdiv class=\"fspdp-exotics-img\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/sholi-250g-fabrica-specialty-coffee-bag.webp?v=1785771945\u0026amp;width=420\" alt=\"Sholi - Rwanda\" loading=\"lazy\"\u003e\u003c\/div\u003e\n      \u003cspan class=\"fspdp-exotics-tag\"\u003eExotics\u003c\/span\u003e\n      \u003ch4\u003eSholi - Rwanda\u003c\/h4\u003e\n      \u003cdiv class=\"fspdp-exotics-notes\"\u003eFlorals, citrus, black tea\u003c\/div\u003e\n      \u003cdiv class=\"fspdp-exotics-colr\"\u003e\n\u003cspan class=\"fspdp-exotics-role\"\u003eFilter\u003c\/span\u003e\u003cspan class=\"fspdp-exotics-cnt\"\u003e\u003c\/span\u003e\n\u003c\/div\u003e\n    \u003c\/div\u003e\n    \u003cdiv class=\"fspdp-exotics-coffee\" data-c=\"xFil2\"\u003e\n      \u003cdiv class=\"fspdp-exotics-img\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0953\/5553\/5707\/files\/nahuatl-250g-fabrica-specialty-coffee-bag.webp?v=1785771836\u0026amp;width=420\" alt=\"Nahuatl - Guatemala\" loading=\"lazy\"\u003e\u003c\/div\u003e\n      \u003cspan class=\"fspdp-exotics-tag\"\u003eExotics\u003c\/span\u003e\n      \u003ch4\u003eNahuatl - Guatemala\u003c\/h4\u003e\n      \u003cdiv class=\"fspdp-exotics-notes\"\u003eStone fruit, honey, toffee\u003c\/div\u003e\n      \u003cdiv class=\"fspdp-exotics-colr\"\u003e\n\u003cspan class=\"fspdp-exotics-role\"\u003eFilter\u003c\/span\u003e\u003cspan class=\"fspdp-exotics-cnt\"\u003e\u003c\/span\u003e\n\u003c\/div\u003e\n    \u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv id=\"fspdp-exotics-extra\" class=\"fspdp-exotics-scope\" style=\"display:none\"\u003e\n  \u003cdiv class=\"fspdp-exotics-how\"\u003e\n    \u003ch3 class=\"fspdp-exotics-title\" style=\"margin-top:20px;\"\u003eComo funciona\u003c\/h3\u003e\n    \u003cdiv class=\"fspdp-exotics-step\"\u003e\n\u003cspan class=\"fspdp-exotics-dot\"\u003e\u003c\/span\u003e\u003cdiv\u003e\n\u003cb\u003eHoje\u003c\/b\u003e\u003cspan\u003eFaz a sua subscrição\u003c\/span\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"fspdp-exotics-step\"\u003e\n\u003cspan class=\"fspdp-exotics-dot\"\u003e\u003c\/span\u003e\u003cdiv\u003e\n\u003cb\u003eEm 24-48h\u003c\/b\u003e\u003cspan\u003eEmbalado do lote mais fresco e enviado\u003c\/span\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n    \u003cdiv class=\"fspdp-exotics-step\"\u003e\n\u003cspan class=\"fspdp-exotics-dot g\"\u003e\u003c\/span\u003e\u003cdiv\u003e\n\u003cb\u003e1-2 dias úteis\u003c\/b\u003e\u003cspan\u003eÀ sua porta\u003c\/span\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n  \u003c\/div\u003e\n  \u003cdiv class=\"fspdp-exotics-pills\"\u003e\n    \u003cspan class=\"fspdp-exotics-pill\"\u003eEnvio em 24-48h\u003c\/span\u003e\n    \u003cspan class=\"fspdp-exotics-pill\"\u003ePortes grátis\u003c\/span\u003e\n    \u003cspan class=\"fspdp-exotics-pill\"\u003eFeito à sua medida\u003c\/span\u003e\n    \u003cspan class=\"fspdp-exotics-pill\"\u003ePause, salte ou cancele quando quiser\u003c\/span\u003e\n  \u003c\/div\u003e\n\u003c\/div\u003e\n\u003cstyle\u003e\n  .fspdp-exotics-scope { display: block; width: 100%; padding: 8px 0; }\n  .fspdp-exotics-scope .fspdp-exotics-title { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: #191919; margin: 0 0 12px; }\n  .fspdp-exotics-scope .fspdp-exotics-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }\n  .fspdp-exotics-scope .fspdp-exotics-coffee { display: flex; flex-direction: column; padding: 18px 18px 16px; border-radius: 16px; background: rgba(237, 231, 248, 0.75); transition: opacity 0.25s ease; }\n  .fspdp-exotics-scope .fspdp-exotics-coffee.dim { opacity: 0.35; }\n  .fspdp-exotics-scope .fspdp-exotics-img { width: 100%; height: 200px; display: flex; align-items: center; justify-content: center; margin-bottom: 12px; }\n  .fspdp-exotics-scope .fspdp-exotics-img img { width: auto; height: 100%; }\n  .fspdp-exotics-scope .fspdp-exotics-img img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; mix-blend-mode: multiply; border: none !important; box-shadow: none !important; }\n  .fspdp-exotics-scope h4 { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.25; color: #191919; margin: 0 0 2px; }\n  .fspdp-exotics-scope .fspdp-exotics-tag { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.8px; font-weight: 800; color: #534AB7; margin-bottom: 3px; }\n  .fspdp-exotics-scope .fspdp-exotics-notes { font-size: 13px; color: #6f6a62; }\n  .fspdp-exotics-scope .fspdp-exotics-colr { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-top: auto; padding-top: 14px; flex-wrap: wrap; }\n  .fspdp-exotics-scope .fspdp-exotics-role { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 700; border: 1px solid rgba(25, 25, 25, 0.35); border-radius: 90px; padding: 4px 12px; white-space: nowrap; color: #191919; }\n  .fspdp-exotics-scope .fspdp-exotics-cnt { display: none; font-size: 12px; font-weight: 800; background: #191919; color: #FFFEFA; border-radius: 90px; padding: 3px 12px; white-space: nowrap; }\n  .fspdp-exotics-scope .fspdp-exotics-coffee.on .fspdp-exotics-cnt { display: inline-block; }\n  .fspdp-exotics-scope .fspdp-exotics-note { font-size: 12px; color: #6f6a62; margin: 12px 0 0; }\n  .fspdp-exotics-scope .fspdp-exotics-how { margin-top: 4px; }\n  .fspdp-exotics-scope .fspdp-exotics-step { display: flex; gap: 14px; align-items: flex-start; padding: 10px 4px; border-bottom: 1px solid rgba(25, 25, 25, 0.08); }\n  .fspdp-exotics-scope .fspdp-exotics-step:last-child { border-bottom: none; }\n  .fspdp-exotics-scope .fspdp-exotics-dot { display: inline-block !important; width: 10px; height: 10px; border-radius: 50%; background: #191919; margin-top: 7px; flex-shrink: 0; }\n  .fspdp-exotics-scope .fspdp-exotics-dot.g { background: #2FAC66; }\n  .fspdp-exotics-scope .fspdp-exotics-step b { display: block; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; color: #6f6a62; font-weight: 700; }\n  .fspdp-exotics-scope .fspdp-exotics-step span:not(.fspdp-exotics-dot) { font-size: 15px; font-weight: 600; color: #191919; }\n  .fspdp-exotics-scope .fspdp-exotics-pills { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }\n  .fspdp-exotics-scope .fspdp-exotics-pill { font-size: 14px; font-weight: 400; color: #191919; padding: 9px 18px; border-radius: 90px; border: 1px solid #191919; background: transparent; white-space: nowrap; }\n\u003c\/style\u003e\n\u003cscript\u003e\n(function () {\n  var TIER = \"exotics\";\n  var HANDLE = 'fabrica-coffee-subscription-' + TIER;\n  if (window.location.pathname.indexOf(HANDLE) === -1) return; \/\/ not this product's page - do nothing\n  var panel = document.getElementById(\"fspdp-exotics\");\n  if (!panel) return;\n  var WASH = \"#F2EDFB\", ACCENT = \"#534AB7\", TILE = \"#EDE7F8\", STROKE = \"#CFC5EE\";\n  \/\/ The JS-written strings can't go through Shopify's translate app (it only\n  \/\/ sees static content), so they localize off the storefront locale directly.\n  var IS_PT = (((window.Shopify \u0026\u0026 window.Shopify.locale) || document.documentElement.lang || '') + '').toLowerCase().indexOf('pt') === 0;\n  var L = IS_PT\n    ? { youPay: 'Total', perDelivery: 'por entrega', perBag: '\/ bag', bag: 'bag', bags: 'bags' }\n    : { youPay: 'You pay', perDelivery: 'per delivery', perBag: '\/ bag', bag: 'bag', bags: 'bags' };\n  var BAGS = { '1 bag': 1, '2 bags': 2, '4 bags': 4, '6 bags': 6 };\n  var BREW = { 'Espresso': 'esp', 'Filter': 'fil', 'Half \u0026 half': 'mix' };\n  function sel() {\n    var q = 1, b = 'esp';\n    Array.prototype.forEach.call(document.querySelectorAll('input[type=radio]'), function (r) {\n      if (r.checked) {\n        if (BAGS[r.value]) q = BAGS[r.value];\n        if (BREW[r.value]) b = BREW[r.value];\n      }\n    });\n    return { q: q, b: b };\n  }\n  function half(m) { return [Math.ceil(m \/ 2), Math.floor(m \/ 2)]; }\n  function allocation(q, b) {\n    var c = {}, s, e, f;\n    if (TIER === 'decaf') { c.decaf = q; return c; }\n    if (TIER === 'classics') {\n      if (b === 'esp') c.cEsp = q;\n      else if (b === 'fil') c.cFil = q;\n      else { s = half(q); c.cEsp = s[0]; if (s[1]) c.cFil = s[1]; }\n      return c;\n    }\n    if (b === 'esp') { s = half(q); c.xEsp1 = s[0]; if (s[1]) c.xEsp2 = s[1]; }\n    else if (b === 'fil') { s = half(q); c.xFil1 = s[0]; if (s[1]) c.xFil2 = s[1]; }\n    else {\n      s = half(q); e = half(s[0]); f = half(s[1]);\n      c.xEsp1 = e[0]; if (e[1]) c.xEsp2 = e[1];\n      if (f[0]) c.xFil1 = f[0]; if (f[1]) c.xFil2 = f[1];\n    }\n    return c;\n  }\n  function update() {\n    var s = sel();\n    var alloc = allocation(s.q, s.b);\n    Array.prototype.forEach.call(panel.querySelectorAll('[data-c]'), function (el) {\n      var n = alloc[el.getAttribute('data-c')];\n      var cnt = el.querySelector('.' + \"fspdp-exotics\" + '-cnt');\n      if (n) { el.classList.add('on'); el.classList.remove('dim'); cnt.textContent = '\\u00d7 ' + n + ' ' + (n === 1 ? L.bag : L.bags); }\n      else { el.classList.remove('on'); el.classList.add('dim'); }\n    });\n  }\n  \/\/ \"You pay\" summary above the subscribe button. Reads the widget's server-\n  \/\/ rendered variant-\u003eplan price map, so it never depends on the widget JS's\n  \/\/ own rebase timing. Prices are flat across frequencies, but we still honour\n  \/\/ the selected plan id in case that ever changes.\n  function money(c) {\n    try { if (window.Shopify \u0026\u0026 Shopify.formatMoney \u0026\u0026 Shopify.money_format) return Shopify.formatMoney(Math.round(c), Shopify.money_format); } catch (e) { \/* fall through *\/ }\n    return (Math.round(c) \/ 100).toFixed(2).replace('.', ',') + '\\u20ac';\n  }\n  \/\/ The info container holds several cart forms (sample add-on etc.) - anchor\n  \/\/ on the buy buttons and walk up to THEIR form, which carries the variant id.\n  function buyButtons() {\n    return document.querySelector('.product__info-container .product-form__buttons');\n  }\n  function payData() {\n    var mapEl = document.querySelector('.js-variant-plans-data');\n    var btns = buyButtons();\n    var form = btns \u0026\u0026 btns.closest('form');\n    if (!mapEl || !form) return null;\n    var data; try { data = JSON.parse(mapEl.textContent); } catch (e) { return null; }\n    var vid = form.querySelector('input[name=\"id\"]');\n    var v = vid \u0026\u0026 data[String(vid.value)];\n    if (!v) return null;\n    var planInp = document.querySelector('input[name=\"selling_plan_id\"]:checked');\n    var hidden = form.querySelector('input[name=\"selling_plan\"]');\n    var planId = planInp ? String(planInp.value) : String((hidden \u0026\u0026 hidden.value) || '');\n    var total = planId \u0026\u0026 v.plans \u0026\u0026 v.plans[planId] != null ? v.plans[planId] : v.base;\n    var bags = parseInt(v.bags, 10) || 1;\n    return { total: total, bags: bags };\n  }\n  function updatePay() {\n    var el = document.getElementById(\"fspdp-exotics\" + '-pay');\n    if (!el) return;\n    var d = payData();\n    if (!d || !d.total) { el.style.display = 'none'; return; }\n    el.style.display = '';\n    el.querySelector('.js-pay-total').textContent = money(d.total);\n    el.querySelector('.js-pay-per').textContent = money(Math.round(d.total \/ d.bags)) + ' ' + L.perBag + (d.bags \u003e 1 ? ' \\u00b7 ' + d.bags + ' ' + L.bags : '');\n  }\n  function mountPay() {\n    if (document.getElementById(\"fspdp-exotics\" + '-pay')) { updatePay(); return; }\n    var btns = buyButtons();\n    if (!btns) return;\n    var el = document.createElement('div');\n    el.id = \"fspdp-exotics\" + '-pay';\n    el.className = \"fspdp-exotics\" + '-pay';\n    el.innerHTML = '\u003cdiv\u003e\u003cspan class=\"' + \"fspdp-exotics\" + '-pay-label\"\u003e' + L.youPay + '\u003c\/span\u003e'\n      + '\u003cspan class=\"' + \"fspdp-exotics\" + '-pay-total js-pay-total\"\u003e\u003c\/span\u003e'\n      + '\u003cspan class=\"' + \"fspdp-exotics\" + '-pay-freq\"\u003e' + L.perDelivery + '\u003c\/span\u003e\u003c\/div\u003e'\n      + '\u003cdiv class=\"' + \"fspdp-exotics\" + '-pay-per js-pay-per\"\u003e\u003c\/div\u003e';\n    btns.parentNode.insertBefore(el, btns);\n    updatePay();\n  }\n  function mount() {\n    document.body.style.setProperty('background', WASH, 'important');\n    var title = document.querySelector('.product__title h1') || document.querySelector('h1.product__title') || document.querySelector('.product__title');\n    if (title) title.style.setProperty('color', ACCENT);\n    var css = document.createElement('style');\n    css.textContent = [\n      '.product__info-container .text-brown1 { color: ' + ACCENT + ' !important; }',\n      '.product__price .text-brown1, .custom-subscription-block .text-brown1, .sticky-bar .text-brown1 { color: ' + ACCENT + ' !important; }',\n      '.' + \"fspdp-exotics\" + '-pay { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; margin: 26px 0 20px; }',\n      '.product__info-container .product-form__buttons .product-form__submit, .sticky-bar .product-form__submit { background-color: ' + ACCENT + ' !important; border-color: ' + ACCENT + ' !important; color: #FFFEFA !important; }',\n      '.' + \"fspdp-exotics\" + '-pay-label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px; font-weight: 800; color: #6f6a62; margin-bottom: 4px; }',\n      '.' + \"fspdp-exotics\" + '-pay-total { font-size: 32px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; color: ' + ACCENT + '; }',\n      '.' + \"fspdp-exotics\" + '-pay-freq { font-size: 14px; font-weight: 500; color: #6f6a62; margin-left: 6px; }',\n      '.' + \"fspdp-exotics\" + '-pay-per { font-size: 15px; font-weight: 600; color: #6f6a62; padding-bottom: 3px; }',\n      '.product__info-container [class*=\"bg-brown\"], .product__info-container [class*=\"bg-tan\"] { background-color: ' + TILE + ' !important; }',\n      '.product__info-container [class*=\"border-brown\"] { border-color: ' + ACCENT + ' !important; }',\n      '.product__info-container label:has(input:checked) { background-color: ' + TILE + ' !important; border-color: ' + ACCENT + ' !important; }',\n      '.product__info-container input:checked + label { background-color: ' + TILE + ' !important; border-color: ' + ACCENT + ' !important; }',\n      '.grind-note-wrapper input:checked + label { background-color: ' + TILE + ' !important; border-color: ' + ACCENT + ' !important; }',\n      '.product__info-container input:not(:checked) + label { border-color: ' + STROKE + ' !important; }',\n      '.grind-note-wrapper input:not(:checked) + label { border-color: ' + STROKE + ' !important; }',\n      'label.subscription-plan-row:not(:has(input:checked)) { border-color: ' + STROKE + ' !important; }',\n      'quantity-input.quantity { border-color: ' + STROKE + ' !important; }',\n      '.grind-note .custom-select-trigger { border-color: ' + STROKE + ' !important; }',\n      '.grind-note.has-selection .custom-select-trigger, .grind-note.is-open .custom-select-trigger { background-color: ' + TILE + ' !important; border-color: ' + ACCENT + ' !important; }',\n      '.grind-note .custom-select-option::before { border-color: ' + STROKE + ' !important; }',\n      '.grind-note .custom-select-option.selected::before { background-color: ' + ACCENT + ' !important; border-color: ' + ACCENT + ' !important; }',\n      '.quantity__input { background: transparent !important; -webkit-appearance: none !important; appearance: textfield !important; -moz-appearance: textfield !important; }',\n      '.quantity__input::-webkit-inner-spin-button, .quantity__input::-webkit-outer-spin-button { -webkit-appearance: none !important; display: none !important; margin: 0 !important; }',\n      'label.subscription-plan-row:has(input:checked) { background-color: ' + TILE + ' !important; border-color: ' + ACCENT + ' !important; }'\n    ].join('\\n');\n    document.head.appendChild(css);\n    var host = document.querySelector('.product__media-wrapper') || document.querySelector('media-gallery') || document.querySelector('.product__media-gallery') || document.querySelector('.product__media-list');\n    if (host) {\n      Array.prototype.forEach.call(host.children, function (ch) { ch.style.display = 'none'; });\n      host.appendChild(panel);\n    }\n    panel.style.display = 'block';\n    var extra = document.getElementById(\"fspdp-exotics\" + '-extra');\n    var mq = window.matchMedia('(max-width: 749px)');\n    function placeExtra() {\n      if (!extra) return;\n      if (mq.matches) {\n        var info = document.querySelector('.product__info-wrapper') || document.querySelector('.product__info-container');\n        if (info) info.appendChild(extra);\n      } else if (host) {\n        host.appendChild(extra);\n      }\n      extra.style.display = 'block';\n    }\n    placeExtra();\n    if (mq.addEventListener) mq.addEventListener('change', placeExtra);\n    update();\n    mountPay();\n    \/\/ Widget builds its rows async - retry so the panel lands even on slow loads.\n    setTimeout(mountPay, 600);\n    setTimeout(mountPay, 2000);\n  }\n  document.addEventListener('change', function (e) {\n    if (e.target \u0026\u0026 e.target.type === 'radio') update();\n    \/\/ After the widget's own 80ms rebase, refresh the pay panel too.\n    setTimeout(updatePay, 160);\n  });\n  \/\/ Live lineup from the roastery app: replace this tier's fallback cards when\n  \/\/ the feed has coffees for it. Same slot-\u003ecard mapping as the landing page.\n  var SLOT_KEY = { exoticEsp1: 'xEsp1', exoticEsp2: 'xEsp2', exoticFil1: 'xFil1', exoticFil2: 'xFil2', classicEsp: 'cEsp', classicFil: 'cFil', decaf: 'decaf' };\n  function escHtml(s) { return String(s).replace(\/\u0026\/g, '\u0026amp;').replace(\/\u003c\/g, '\u0026lt;').replace(\/\u003e\/g, '\u0026gt;').replace(\/\"\/g, '\u0026quot;'); }\n  function liveCards() {\n    fetch('https:\/\/fabrica-roastery.vercel.app\/api\/public\/lineup').then(function (r) { return r.json(); }).then(function (d) {\n      if (!d || !d.slots) return;\n      var mine = d.slots.filter(function (s) { return s.tier === TIER \u0026\u0026 SLOT_KEY[s.slot]; });\n      if (!mine.length) return;\n      var html = mine.map(function (s) {\n        var img = s.imageUrl ? s.imageUrl + (s.imageUrl.indexOf('?') === -1 ? '?' : '\u0026') + 'width=420' : null;\n        var blend = img \u0026\u0026 img.toLowerCase().split('?')[0].slice(-4) === '.png' ? ' style=\"mix-blend-mode:normal\"' : '';\n        var name = s.name + (s.origin ? ' - ' + s.origin : '');\n        return '\u003cdiv class=\"' + \"fspdp-exotics\" + '-coffee\" data-c=\"' + SLOT_KEY[s.slot] + '\"\u003e'\n          + '\u003cdiv class=\"' + \"fspdp-exotics\" + '-img\"\u003e' + (img ? '\u003cimg src=\"' + escHtml(img) + '\" alt=\"' + escHtml(name) + '\"' + blend + '\u003e' : '') + '\u003c\/div\u003e'\n          + '\u003cspan class=\"' + \"fspdp-exotics\" + '-tag\"\u003e' + \"Exotics\" + '\u003c\/span\u003e'\n          + '\u003ch4\u003e' + escHtml(name) + '\u003c\/h4\u003e'\n          + '\u003cdiv class=\"' + \"fspdp-exotics\" + '-notes\"\u003e' + escHtml(s.notes || '') + '\u003c\/div\u003e'\n          + '\u003cdiv class=\"' + \"fspdp-exotics\" + '-colr\"\u003e\u003cspan class=\"' + \"fspdp-exotics\" + '-role\"\u003e' + escHtml(s.role) + '\u003c\/span\u003e\u003cspan class=\"' + \"fspdp-exotics\" + '-cnt\"\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e';\n      }).join('');\n      var grid = panel.querySelector('[class$=\"-grid\"]');\n      if (grid \u0026\u0026 html) { grid.innerHTML = html; update(); }\n    }).catch(function () {});\n  }\n  liveCards();\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount);\n  else mount();\n})();\n\u003c\/script\u003e","brand":"Fábrica Coffee Roasters","offers":[{"title":"1 saco \/ Espresso","offer_id":53834159718747,"sku":"SUB-EXO-1-ESP","price":16.0,"currency_code":"EUR","in_stock":true},{"title":"1 saco \/ Filtro","offer_id":53834159915355,"sku":"SUB-EXO-1-FIL","price":16.0,"currency_code":"EUR","in_stock":true},{"title":"2 sacos \/ Espresso","offer_id":53834160111963,"sku":"SUB-EXO-2-ESP","price":25.0,"currency_code":"EUR","in_stock":true},{"title":"2 sacos \/ Filtro","offer_id":53834160308571,"sku":"SUB-EXO-2-FIL","price":25.0,"currency_code":"EUR","in_stock":true},{"title":"2 sacos \/ Meio a meio","offer_id":53834160505179,"sku":"SUB-EXO-2-MIX","price":25.0,"currency_code":"EUR","in_stock":true},{"title":"4 sacos \/ Espresso","offer_id":53834160701787,"sku":"SUB-EXO-4-ESP","price":48.0,"currency_code":"EUR","in_stock":true},{"title":"4 sacos \/ Filtro","offer_id":53834160898395,"sku":"SUB-EXO-4-FIL","price":48.0,"currency_code":"EUR","in_stock":true},{"title":"4 sacos \/ Meio a meio","offer_id":53834161095003,"sku":"SUB-EXO-4-MIX","price":48.0,"currency_code":"EUR","in_stock":true},{"title":"6 sacos \/ Espresso","offer_id":53834161291611,"sku":"SUB-EXO-6-ESP","price":60.0,"currency_code":"EUR","in_stock":true},{"title":"6 sacos \/ Filtro","offer_id":53834161488219,"sku":"SUB-EXO-6-FIL","price":60.0,"currency_code":"EUR","in_stock":true},{"title":"6 sacos \/ Meio a meio","offer_id":53834161684827,"sku":"SUB-EXO-6-MIX","price":60.0,"currency_code":"EUR","in_stock":true}]}],"url":"https:\/\/fabricacoffeeroasters.com\/pt\/collections\/specialty-coffee-discovery.oembed","provider":"Fábrica Coffee Roasters","version":"1.0","type":"link"}