{"title":"Accesorios para heladería y repostería","description":"\u003cp\u003eContenedores de cartón para helado y postres, tapas de papel para contenedores y cajas de cartón para pastel, complementados con servilletas impresas 1 tinta. Todo lo que necesita una heladería, pastelería o repostería para presentar, transportar y servir sus productos con higiene, seguridad y una imagen profesional y personalizada.\u003c\/p\u003e","products":[{"product_id":"vaso-pet-12-14oz-bebidas-frias-lc14","title":"Vaso PET transparente para bebidas frías 12\/14oz (caja 1000 pzas)","description":"\u003cp\u003eVaso desechable \u003cstrong\u003ePET transparente\u003c\/strong\u003e para bebidas frías tamaño \u003cstrong\u003e12\/14 oz\u003c\/strong\u003e (aprox. 414–420 ml). Su acabado tipo \u003cstrong\u003e“cristal”\u003c\/strong\u003e realza la presentación de frappés, smoothies, cafés fríos, jugos y refrescos, permitiendo ver claramente el contenido.\u003c\/p\u003e\n\u003cp\u003eFabricado en \u003cstrong\u003ePET resistente y reciclable\u003c\/strong\u003e, ideal para negocios con alto volumen de servicio como \u003cstrong\u003ecafeterías, heladerías, barras de smoothies, food trucks y reposterías\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, perfecta para compra al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eLC14\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 12\/14 oz (≈414–420 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/B.F._12_14oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Vaso PET transparente para bebidas frías 12\/14oz\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-pet-12-14oz-bebidas-frias-lc14?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147566100730,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/58.jpg?v=1768504245"},{"product_id":"vaso-pet-16oz-bebidas-frias-lc16","title":"Vaso PET transparente para bebidas frías 16oz (caja 1000 pzas)","description":"\u003cp\u003eVaso desechable \u003cstrong\u003ePET transparente\u003c\/strong\u003e para bebidas frías tamaño \u003cstrong\u003e16 oz\u003c\/strong\u003e (≈473 ml), ideal para porciones generosas de frappés, smoothies, tés helados, limonadas y cafés fríos. Su presentación tipo \u003cstrong\u003ecristal\u003c\/strong\u003e resalta el color y la textura de la bebida.\u003c\/p\u003e\n\u003cp\u003eCompatible con \u003cstrong\u003etapas domo y tapas planas\u003c\/strong\u003e para vasos 16 oz (no incluidas), perfecto para servicio \u003cstrong\u003e“para llevar”\u003c\/strong\u003e y entregas a domicilio. Fabricado en \u003cstrong\u003ePET ligero, resistente y reciclable\u003c\/strong\u003e, diseñado para el uso diario en \u003cstrong\u003ecafeterías, heladerías, restaurantes y barras de bebidas\u003c\/strong\u003e.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, ideal para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eLC16\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 16 oz (≈473 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: tapas domo y planas para vaso 16 oz\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/B.F._16oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Vaso PET transparente para bebidas frías 16oz\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-pet-16oz-bebidas-frias-lc16?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147566133498,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/59.jpg?v=1768504245"},{"product_id":"vaso-pet-20oz-bebidas-frias-vpet-20","title":"Vaso PET transparente para bebidas frías 20oz (caja 1000 pzas)","description":"\u003cp\u003eVaso desechable \u003cstrong\u003ePET transparente\u003c\/strong\u003e para bebidas frías tamaño \u003cstrong\u003e20 oz\u003c\/strong\u003e (≈591 ml), ideal para porciones grandes de \u003cstrong\u003efrappés, smoothies, tés helados, malteadas y bebidas con toppings\u003c\/strong\u003e. El acabado tipo \u003cstrong\u003ecristal\u003c\/strong\u003e realza la presentación de tus bebidas y mejora la experiencia visual del cliente.\u003c\/p\u003e\n\u003cp\u003eFabricado con \u003cstrong\u003ePET (Polietileno Tereftalato)\u003c\/strong\u003e, un plástico transparente, ligero y resistente, diseñado especialmente para bebidas frías y uso intensivo en \u003cstrong\u003ecafeterías, heladerías, restaurantes, bares de jugos y food trucks\u003c\/strong\u003e.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, perfecta para negocios con alto consumo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eVPET-20\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 20 oz (≈591 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías de gran tamaño\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/B.F._20oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Vaso PET transparente para bebidas frías 20oz\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-pet-20oz-bebidas-frias-vpet-20?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147566330106,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/60.jpg?v=1768504246"},{"product_id":"tapa-plana-sin-orificio-vaso-pet-12-14oz-l92","title":"Tapa plana sin orificio para vaso PET 12\/14 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana sin orificio\u003c\/strong\u003e para vaso \u003cstrong\u003ePET 12\/14 oz\u003c\/strong\u003e, ideal para \u003cstrong\u003ebebidas frías sin popote\u003c\/strong\u003e. Ofrece una \u003cstrong\u003eentrega segura\u003c\/strong\u003e y una \u003cstrong\u003epresentación ordenada\u003c\/strong\u003e, ayudando a evitar derrames durante el servicio o traslado.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e, mantiene la apariencia “cristalina” del vaso y permite ver perfectamente el contenido. Recomendada para \u003cstrong\u003ecafeterías, heladerías, barras de smoothies, juguerías y negocios de bebidas para llevar\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, ideal para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eL92\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET 12\/14 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana sin orificio\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías sin popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147568820474,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/18.jpg?v=1768504543"},{"product_id":"tapa-plana-orificio-vaso-pet-12-14oz-pl92","title":"Tapa plana con orificio para vaso PET 12\/14 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana con orificio\u003c\/strong\u003e para vaso \u003cstrong\u003ePET 12\/14 oz\u003c\/strong\u003e, diseñada para usarse con \u003cstrong\u003epopote\u003c\/strong\u003e, ideal para bebidas frías como refrescos, jugos, cafés fríos, tés helados y smoothies. El orificio central permite colocar el popote cómodamente y beber sin necesidad de destapar.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e, mantiene una excelente visibilidad del contenido y una presentación limpia y profesional. Pensada para \u003cstrong\u003ecafeterías, heladerías, restaurantes, food trucks y barras de bebidas para llevar\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, práctica para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003ePL92\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET 12\/14 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías con popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147568886010,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/19.jpg?v=1768504543"},{"product_id":"tapa-domo-orificio-vaso-pet-12-14oz-dl92","title":"Tapa domo con orificio para vaso PET 12\/14 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003etipo domo con orificio\u003c\/strong\u003e para vaso \u003cstrong\u003ePET 12\/14 oz\u003c\/strong\u003e, ideal para bebidas frías con \u003cstrong\u003etopping, crema batida o espuma\u003c\/strong\u003e, como frappés, malteadas, smoothies y cafés fríos especiales. Su forma \u003cstrong\u003ecurvada hacia arriba\u003c\/strong\u003e ofrece espacio adicional para decoraciones o añadidos.\u003c\/p\u003e\n\u003cp\u003eIncluye \u003cstrong\u003eorificio para popote\u003c\/strong\u003e, lo que facilita el consumo sin retirar la tapa. Fabricada en \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e, brinda una excelente visibilidad del contenido y una presentación atractiva para tu negocio.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, perfecta para cafeterías y heladerías con alto volumen de servicio.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eDL92\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET 12\/14 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa domo con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: frappés, malteadas, smoothies y bebidas con topping\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147569606906,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/20.jpg?v=1768504593"},{"product_id":"tapa-plana-sin-orificio-vaso-pet-16-20oz-l98","title":"Tapa plana sin orificio para vaso PET 16\/20 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana sin orificio\u003c\/strong\u003e para vasos \u003cstrong\u003ePET 16 oz y 20 oz\u003c\/strong\u003e, ideal para \u003cstrong\u003ebebidas frías sin popote\u003c\/strong\u003e y preparaciones que requieren un cierre completo. Proporciona \u003cstrong\u003eentrega segura\u003c\/strong\u003e y \u003cstrong\u003epresentación ordenada\u003c\/strong\u003e, ayudando a minimizar derrames durante el transporte.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e, conserva el aspecto cristalino del vaso y permite apreciar el contenido. Recomendada para \u003cstrong\u003ecafeterías, heladerías, bares de jugos, restaurantes y negocios de bebidas para llevar\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, pensada para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eL98\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET 16 oz y 20 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana sin orificio\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías sin popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147569737978,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/21.jpg?v=1768504614"},{"product_id":"tapa-plana-orificio-vaso-pet-16-20oz-pl98","title":"Tapa plana con orificio para vaso PET 16\/20 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana con orificio\u003c\/strong\u003e para vasos \u003cstrong\u003ePET 16 oz y 20 oz\u003c\/strong\u003e, ideal para bebidas frías servidas con \u003cstrong\u003epopote\u003c\/strong\u003e: frappés, smoothies, tés helados, limonadas y refrescos. El orificio central permite colocar el popote de forma cómoda y segura.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e, ofrece una imagen limpia y profesional, manteniendo la visibilidad total del contenido. Perfecta para \u003cstrong\u003ecafeterías, heladerías, restaurantes, barras de bebidas y food trucks\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, adecuada para negocios con alto consumo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003ePL98\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET 16 oz y 20 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías con popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147570491642,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/22.jpg?v=1768504657"},{"product_id":"tapa-domo-orificio-vaso-pet-16-20oz-dl98","title":"Tapa domo con orificio para vaso PET 16\/20 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003etipo domo con orificio\u003c\/strong\u003e para vasos \u003cstrong\u003ePET 16 oz y 20 oz\u003c\/strong\u003e, diseñada para bebidas frías con \u003cstrong\u003etopping, crema batida, frutas o espumas\u003c\/strong\u003e. Su forma elevada permite agregar decoraciones sin que se derramen, ideal para \u003cstrong\u003efrappés, malteadas, smoothies y bebidas especiales\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eIncluye \u003cstrong\u003eorificio para popote\u003c\/strong\u003e, lo que facilita el consumo sin retirar la tapa. Elaborada en \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e, ofrece una excelente visibilidad y una presentación atractiva en barra o vitrina.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, ideal para cafeterías, heladerías y bares de bebidas con gran volumen.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eDL98\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET 16 oz y 20 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa domo con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: frappés, malteadas, smoothies y bebidas con topping\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147578290426,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/23.jpg?v=1768504697"},{"product_id":"tapa-boquilla-vaso-pet-sip-lid-petsp","title":"Tapa boquilla para vaso PET transparente “sip-lid” (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eboquilla tipo “sip-lid”\u003c\/strong\u003e para vasos \u003cstrong\u003ePET\u003c\/strong\u003e diseñada para \u003cstrong\u003ebeber directamente\u003c\/strong\u003e sin necesidad de popote. Su apertura ergonómica permite disfrutar bebidas frías de forma cómoda y segura, reduciendo el uso de popotes y mejorando la experiencia del cliente.\u003c\/p\u003e\n\u003cp\u003eProporciona un \u003cstrong\u003eacabado limpio y moderno\u003c\/strong\u003e, con excelente visibilidad del contenido gracias a su \u003cstrong\u003ePET transparente y reciclable\u003c\/strong\u003e. Ideal para \u003cstrong\u003ecafés fríos, tés helados, jugos, frappés y smoothies\u003c\/strong\u003e, especialmente en negocios que buscan una \u003cstrong\u003epresentación contemporánea y más sustentable\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, adecuada para operación diaria y compra al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003ePETSP\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PET (según diámetro correspondiente)\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa boquilla “sip-lid” (sin popote)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: cafés fríos, tés helados, jugos, frappés y smoothies\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PET\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147578585338,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/24.jpg?v=1768504724"},{"product_id":"vaso-biodegradable-pla-12-14oz-bebidas-frias","title":"Vaso biodegradable PLA transparente para bebidas frías 12\/14oz (caja 1000 pzas)","description":"\u003cp\u003eVaso \u003cstrong\u003ebiodegradable\u003c\/strong\u003e para bebidas frías tamaño \u003cstrong\u003e12\/14 oz\u003c\/strong\u003e (aprox. 414–420 ml), fabricado en \u003cstrong\u003ePLA transparente\u003c\/strong\u003e con acabado tipo \u003cstrong\u003e“cristal”\u003c\/strong\u003e que realza la presentación de tus bebidas. Ideal para \u003cstrong\u003efrappés, smoothies, cafés fríos, jugos y refrescos\u003c\/strong\u003e, permitiendo que el cliente aprecie el color y textura del producto.\u003c\/p\u003e\n\u003cp\u003eEl \u003cstrong\u003ePLA (ácido poliláctico)\u003c\/strong\u003e es un material de origen vegetal, diseñado para ser \u003cstrong\u003ebiodegradable\u003c\/strong\u003e, por lo que es una excelente opción para negocios que quieren reducir su impacto ambiental sin sacrificar imagen ni funcionalidad. Perfecto para \u003cstrong\u003ecafeterías, heladerías, barras de jugos, food trucks y negocios eco-friendly\u003c\/strong\u003e.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, ideal para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCapacidad: 12\/14 oz (≈414–420 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/B.F._12_14oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Vaso biodegradable PLA transparente para bebidas frías 12\/14oz\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-biodegradable-pla-12-14oz-bebidas-frias?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147581075706,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/15.jpg?v=1768504000"},{"product_id":"vaso-biodegradable-pla-16oz-bebidas-frias","title":"Vaso biodegradable PLA transparente para bebidas frías 16oz (caja 1000 pzas)","description":"\u003cp\u003eVaso \u003cstrong\u003ebiodegradable\u003c\/strong\u003e de \u003cstrong\u003ePLA transparente\u003c\/strong\u003e para bebidas frías tamaño \u003cstrong\u003e16 oz\u003c\/strong\u003e (≈473 ml), ideal para porciones generosas de \u003cstrong\u003efrappés, smoothies, limonadas, tés helados y cafés fríos\u003c\/strong\u003e. Su presentación tipo \u003cstrong\u003e“cristal”\u003c\/strong\u003e resalta la bebida y mejora la experiencia visual del cliente.\u003c\/p\u003e\n\u003cp\u003eEs \u003cstrong\u003ecompatible con tapas domo y tapas planas\u003c\/strong\u003e para vasos 16 oz (no incluidas), lo que lo convierte en una excelente opción para bebidas \u003cstrong\u003e“para llevar”\u003c\/strong\u003e y entregas a domicilio. El material \u003cstrong\u003ePLA\u003c\/strong\u003e es de origen vegetal y \u003cstrong\u003ebiodegradable\u003c\/strong\u003e, ideal para negocios que buscan \u003cstrong\u003eempaques ecológicos\u003c\/strong\u003e y una imagen sustentable.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, perfecta para cafeterías y restaurantes con alto consumo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCapacidad: 16 oz (≈473 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: tapas domo y planas para 16 oz\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/B.F._16oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Vaso biodegradable PLA transparente para bebidas frías 16oz\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-biodegradable-pla-16oz-bebidas-frias?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147581370618,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/16.jpg?v=1768504803"},{"product_id":"vaso-biodegradable-pla-20oz-bebidas-frias","title":"Vaso biodegradable PLA transparente para bebidas frías 20oz (caja 1000 pzas)","description":"\u003cp\u003eVaso \u003cstrong\u003ebiodegradable\u003c\/strong\u003e para bebidas frías tamaño \u003cstrong\u003e20 oz\u003c\/strong\u003e (≈591 ml), ideal para porciones grandes de \u003cstrong\u003efrappés, smoothies, tés helados, malteadas y bebidas con topping o crema batida\u003c\/strong\u003e. Su capacidad amplia lo hace perfecto para presentaciones “grandes” o “jumbo”.\u003c\/p\u003e\n\u003cp\u003eFabricado en \u003cstrong\u003ePLA transparente\u003c\/strong\u003e con acabado tipo \u003cstrong\u003ecristal\u003c\/strong\u003e, ofrece una presentación atractiva, permitiendo ver la bebida y sus toppings. El material PLA es de origen vegetal y \u003cstrong\u003ebiodegradable\u003c\/strong\u003e, ideal para negocios que desean \u003cstrong\u003ereducir el uso de plásticos tradicionales\u003c\/strong\u003e y ofrecer opciones más sustentables a sus clientes.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, pensada para cafeterías, heladerías, restaurantes y barras de bebidas con alto volumen de venta.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCapacidad: 20 oz (≈591 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías grandes con o sin topping\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/B.F._20oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Vaso biodegradable PLA transparente para bebidas frías 20oz\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-biodegradable-pla-20oz-bebidas-frias?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147582157050,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/17.jpg?v=1768504822"},{"product_id":"tapa-biodegradable-plana-sin-orificio-pla-12-14oz","title":"Tapa biodegradable plana sin orificio para vaso PLA 12\/14 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana sin orificio biodegradable\u003c\/strong\u003e para vasos \u003cstrong\u003ePLA 12\/14 oz\u003c\/strong\u003e, ideal para \u003cstrong\u003ebebidas frías sin popote\u003c\/strong\u003e. Proporciona una \u003cstrong\u003eentrega segura\u003c\/strong\u003e y una \u003cstrong\u003epresentación ordenada\u003c\/strong\u003e, ayudando a evitar derrames en mostrador o durante el transporte.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePLA transparente\u003c\/strong\u003e, con apariencia tipo \u003cstrong\u003e“cristal”\u003c\/strong\u003e, combina una excelente presentación con una opción más amigable con el ambiente. Pensada para \u003cstrong\u003ecafeterías, heladerías, barras de smoothies, juguerías y negocios eco-friendly de bebidas para llevar\u003c\/strong\u003e.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, ideal para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompatibilidad: vasos PLA 12\/14 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana sin orificio\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías sin popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147587006714,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/18.jpg?v=1768504543"},{"product_id":"tapa-biodegradable-plana-orificio-pla-12-14oz","title":"Tapa biodegradable plana con orificio para vaso PLA 12\/14 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana con orificio biodegradable\u003c\/strong\u003e diseñada para vasos \u003cstrong\u003ePLA 12\/14 oz\u003c\/strong\u003e, ideal para bebidas frías que se consumen con \u003cstrong\u003epopote\u003c\/strong\u003e: refrescos, jugos, tés helados, smoothies y cafés fríos. El orificio central permite colocar el popote fácilmente, manteniendo el vaso tapado y reduciendo derrames.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePLA transparente y biodegradable\u003c\/strong\u003e, ofrece una imagen moderna y sustentable para tu negocio, conservando la visibilidad del contenido. Perfecta para \u003cstrong\u003ecafeterías, heladerías, restaurantes, bares de jugos y food trucks\u003c\/strong\u003e que buscan una \u003cstrong\u003esolución ecológica\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompatibilidad: vasos PLA 12\/14 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías con popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147587105018,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/19.jpg?v=1768504543"},{"product_id":"tapa-biodegradable-domo-orificio-pla-12-14oz","title":"Tapa biodegradable domo con orificio para vaso PLA 12\/14 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003etipo domo biodegradable con orificio\u003c\/strong\u003e para vasos \u003cstrong\u003ePLA 12\/14 oz\u003c\/strong\u003e, ideal para bebidas frías con \u003cstrong\u003etopping, crema batida, frutas o espumas\u003c\/strong\u003e, como frappés, malteadas, smoothies y cafés fríos especiales. Su forma \u003cstrong\u003ecurvada hacia arriba\u003c\/strong\u003e ofrece espacio extra para decoraciones sin que se derramen.\u003c\/p\u003e\n\u003cp\u003eIncluye \u003cstrong\u003eperforación para popote\u003c\/strong\u003e, permitiendo disfrutar la bebida sin retirar la tapa. Elaborada en \u003cstrong\u003ePLA transparente y biodegradable\u003c\/strong\u003e, combina excelente presentación con una opción más responsable con el medio ambiente.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, recomendada para \u003cstrong\u003ecafeterías, heladerías y negocios de bebidas con enfoque ecofriendly\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompatibilidad: vasos PLA 12\/14 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa domo con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: frappés, malteadas, smoothies y bebidas con topping\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147588415738,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/20.jpg?v=1768504593"},{"product_id":"tapa-biodegradable-plana-sin-orificio-pla-16-20oz","title":"Tapa biodegradable plana sin orificio para vaso PLA 16\/20 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana sin orificio biodegradable\u003c\/strong\u003e para vasos \u003cstrong\u003ePLA 16 oz y 20 oz\u003c\/strong\u003e, ideal para \u003cstrong\u003ebebidas frías sin popote\u003c\/strong\u003e y presentaciones “para llevar” que requieren un cierre completo. Ayuda a brindar \u003cstrong\u003eentrega segura\u003c\/strong\u003e y \u003cstrong\u003epresentación ordenada\u003c\/strong\u003e, reduciendo el riesgo de derrames.\u003c\/p\u003e\n\u003cp\u003eFabricada en \u003cstrong\u003ePLA transparente y biodegradable\u003c\/strong\u003e, con aspecto tipo \u003cstrong\u003ecristal\u003c\/strong\u003e, ofrece una imagen moderna y sustentable para tu negocio. Recomendada para \u003cstrong\u003ecafeterías, heladerías, juguerías, restaurantes y food trucks\u003c\/strong\u003e que trabajan con vasos medianos y grandes.\u003cbr\u003eSe entrega en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, perfecta para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompatibilidad: vasos PLA 16 oz y 20 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana sin orificio\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías sin popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147591037178,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/21.jpg?v=1768504614"},{"product_id":"tapa-biodegradable-plana-orificio-pla-16-20oz","title":"Tapa biodegradable plana con orificio para vaso PLA 16\/20 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003eplana con orificio biodegradable\u003c\/strong\u003e para vasos \u003cstrong\u003ePLA 16 oz y 20 oz\u003c\/strong\u003e, pensada para bebidas frías con \u003cstrong\u003epopote\u003c\/strong\u003e, como \u003cstrong\u003efrappés, smoothies, limonadas, aguas frescas, tés helados y refrescos grandes\u003c\/strong\u003e. El orificio central permite insertar el popote sin destapar, lo que hace la bebida más segura para llevar.\u003c\/p\u003e\n\u003cp\u003eFabricada con \u003cstrong\u003ePLA transparente y biodegradable\u003c\/strong\u003e, ofrece una presentación limpia y moderna, alineada con negocios que buscan soluciones \u003cstrong\u003emás responsables con el medio ambiente\u003c\/strong\u003e. Ideal para \u003cstrong\u003ecafeterías, heladerías, restaurantes, bares de bebidas y food trucks\u003c\/strong\u003e.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003ePOR-DEFINIR\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PLA 16 oz y 20 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa plana con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías con popote\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147591659770,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}]},{"product_id":"tapa-biodegradable-domo-orificio-pla-16-20oz","title":"Tapa biodegradable domo con orificio para vaso PLA 16\/20 oz transparente (caja 1000 pzas)","description":"\u003cp\u003eTapa \u003cstrong\u003etipo domo biodegradable con orificio\u003c\/strong\u003e para vasos \u003cstrong\u003ePLA 16 oz y 20 oz\u003c\/strong\u003e, ideal para bebidas frías con \u003cstrong\u003etopping, crema batida, frutas, granola o espuma\u003c\/strong\u003e, como frappés grandes, smoothies especiales, malteadas y postres bebibles.\u003c\/p\u003e\n\u003cp\u003eSu diseño \u003cstrong\u003ecurvado hacia arriba\u003c\/strong\u003e da espacio adicional para decoraciones sin que se derramen, mientras que la \u003cstrong\u003eperforación para popote\u003c\/strong\u003e permite consumir la bebida sin retirar la tapa. Fabricada en \u003cstrong\u003ePLA transparente y biodegradable\u003c\/strong\u003e, ofrece una imagen atractiva y alineada con conceptos \u003cstrong\u003eeco-friendly\u003c\/strong\u003e.\u003cbr\u003eSe vende en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, adecuada para negocios con alto volumen de venta.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCompatibilidad: vasos PLA 16 oz y 20 oz\u003c\/li\u003e\n\u003cli\u003eEstilo: tapa domo con orificio para popote\u003c\/li\u003e\n\u003cli\u003eUso recomendado: frappés, malteadas, smoothies y bebidas con topping\u003c\/li\u003e\n\u003cli\u003eColor: transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: PLA\u003c\/li\u003e\n\u003cli\u003eProducto biodegradable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147592708346,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/23.jpg?v=1768504697"},{"product_id":"tapa-tpp8-vaso-pp-8-16-32oz","title":"Tapa lisa TPP8 para vaso PP 8, 16 y 32 oz polipropileno translúcida (caja 500 pzas)","description":"\u003cp\u003eLa \u003cstrong\u003etapa TPP8\u003c\/strong\u003e es una \u003cstrong\u003etapa lisa de polipropileno (PP)\u003c\/strong\u003e compatible con los \u003cstrong\u003evasos de 8, 16 y 32 oz\u003c\/strong\u003e de polipropileno. Ofrece un \u003cstrong\u003esellado seguro\u003c\/strong\u003e y una \u003cstrong\u003epresentación práctica\u003c\/strong\u003e, ideal para bebidas frías que requieren tapa para servicio en barra o para llevar.\u003c\/p\u003e\n\u003cp\u003eEs perfecta para \u003cstrong\u003ebebidas frías, smoothies, aguas frescas, jugos, mezclas y bebidas con hielo\u003c\/strong\u003e, ayudando a evitar derrames y mejorar la experiencia del cliente. Su acabado \u003cstrong\u003etranslúcido \/ transparente\u003c\/strong\u003e permite ver el contenido, aportando una imagen limpia y profesional.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 500 tapas\u003c\/strong\u003e, una opción \u003cstrong\u003erentable\u003c\/strong\u003e para negocios con consumo medio o alto.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTPP8\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: vasos PP de \u003cstrong\u003e8, 16 y 32 oz\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eTipo de tapa: lisa\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías, smoothies, aguas frescas, jugos, mezclas\u003c\/li\u003e\n\u003cli\u003eColor: translúcido \/ transparente\u003c\/li\u003e\n\u003cli\u003eMaterial: polipropileno (PP)\u003c\/li\u003e\n\u003cli\u003eProducto reciclable\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147605127418,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/33.jpg?v=1768505214"},{"product_id":"contenedor-helado-6oz-cph06-95","title":"Contenedor para helado 6oz CPH06-95 cartón alimenticio blanco (caja 1000 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003econtenedor 6oz CPH06-95\u003c\/strong\u003e en \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e es ideal para \u003cstrong\u003ehelado, nieve, gelato, postres y degustaciones generosas\u003c\/strong\u003e. Ofrece una porción media muy usada en \u003cstrong\u003eheladerías y cafeterías\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eSu \u003cstrong\u003ecartón resistente\u003c\/strong\u003e y \u003cstrong\u003epresentación limpia en color blanco\u003c\/strong\u003e lo convierten en una opción profesional para servir \u003cstrong\u003ehelado, postres fríos, toppings o porciones dobles\u003c\/strong\u003e.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 1000 piezas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eCPH06-95\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 6 oz (porción media)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: helado, nieve, gelato, postres, toppings, muestras\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C.H._6oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Contenedor para helado 6oz CPH06-95\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/contenedor-helado-6oz-cph06-95?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147610173690,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/39.jpg?v=1768505349"},{"product_id":"contenedor-helado-8oz-cph08-95","title":"Contenedor para helado 8oz CPH08-95 cartón alimenticio blanco (caja 1000 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003econtenedor 8oz CPH08-95\u003c\/strong\u003e es un envase de \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e pensado para \u003cstrong\u003ehelado, nieve, gelato, postres y porciones más abundantes\u003c\/strong\u003e. Es uno de los tamaños más populares en heladerías.\u003c\/p\u003e\n\u003cp\u003eSu \u003cstrong\u003ecartón resistente\u003c\/strong\u003e y \u003cstrong\u003epresentación en color blanco\u003c\/strong\u003e brindan una imagen higiénica y profesional. Ideal para \u003cstrong\u003eheladerías, gelaterías, cafeterías, reposterías y eventos\u003c\/strong\u003e que manejan porciones medianas\/grandes.\u003cbr\u003eSe vende en \u003cstrong\u003ecaja con 1000 piezas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eCPH08-95\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 8oz (porción mediana\/grande)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: helado, nieve, gelato, postres, toppings, muestras\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C.H._8oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Contenedor para helado 8oz CPH08-95\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/contenedor-helado-8oz-cph08-95?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147835912442,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/40.jpg?v=1768505432"},{"product_id":"contenedor-para-helado-8-oz-cph08-95-carton-alimenticio-blanco-caja-1000-pzas-copia","title":"Contenedor para helado 4oz CPH04-75 cartón alimenticio blanco (caja 1000 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003econtenedor 4oz \u003c\/strong\u003e\u003cspan lang=\"es\"\u003e\u003cstrong\u003eCPH04-75\u003c\/strong\u003e \u003c\/span\u003ees un envase de \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e pensado para \u003cstrong\u003ehelado, nieve, gelato, postres y porciones más abundantes\u003c\/strong\u003e. Es uno de los tamaños más populares en heladerías.\u003c\/p\u003e\n\u003cp\u003eSu \u003cstrong\u003ecartón resistente\u003c\/strong\u003e y \u003cstrong\u003epresentación en color blanco\u003c\/strong\u003e brindan una imagen higiénica y profesional. Ideal para \u003cstrong\u003eheladerías, gelaterías, cafeterías, reposterías y eventos\u003c\/strong\u003e que manejan porciones medianas\/grandes.\u003cbr\u003eSe vende en \u003cstrong\u003ecaja con 1000 piezas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cspan lang=\"es\"\u003e\u003cstrong\u003eCPH04-75\u003c\/strong\u003e\u003c\/span\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 4oz (porción mediana\/grande)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: helado, nieve, gelato, postres, toppings, muestras\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C.H._4oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 25%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Contenedor para helado 4oz CPH04-75\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/contenedor-para-helado-8-oz-cph08-95-carton-alimenticio-blanco-caja-1000-pzas-copia?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147857801466,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/38.jpg?v=1768505317"},{"product_id":"contenedor-helado-12oz-cph12-10","title":"Contenedor para helado 12oz CPH12-10 carton alimenticio blanco (caja 1000 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003econtenedor 12 oz CPH12-10\u003c\/strong\u003e de \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e es perfecto para \u003cstrong\u003eporciones grandes de helado, nieve, gelato o postres\u003c\/strong\u003e. Ofrece capacidad suficiente para varias bolas de helado o postres combinados.\u003c\/p\u003e\n\u003cp\u003eSu \u003cstrong\u003epresentación en blanco\u003c\/strong\u003e y el \u003cstrong\u003ecartón resistente\u003c\/strong\u003e proporcionan un empaque confiable y atractivo para \u003cstrong\u003eheladerías, reposterías y cafeterías\u003c\/strong\u003e con servicio en sitio o para llevar.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 1000 piezas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eCPH12-10\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 12 oz (porción grande)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: helado, nieve, gelato, postres, toppings\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C.H._12oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Contenedor para helado 12 oz CPH12-10\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/contenedor-helado-12oz-cph12-10?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148100251898,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/41.jpg?v=1768505700"},{"product_id":"contenedor-helado-16oz-dpc16","title":"Contenedor para helado 16oz DPC16 cartón alimenticio blanco (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003econtenedor 16 oz DPC16\u003c\/strong\u003e es un envase de \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e con capacidad ideal para \u003cstrong\u003eporciones extra grandes de helado, nieve, gelato y postres\u003c\/strong\u003e, o presentaciones familiares\/para compartir.\u003c\/p\u003e\n\u003cp\u003eSu \u003cstrong\u003ecartón resistente\u003c\/strong\u003e y su \u003cstrong\u003ecolor blanco\u003c\/strong\u003e ofrecen una \u003cstrong\u003epresentación limpia y profesional\u003c\/strong\u003e, pensada para \u003cstrong\u003eheladerías, reposterías, cafeterías y negocios de delivery\u003c\/strong\u003e que manejan tamaños grandes.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 500 piezas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eDPC16\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 16 oz (porción extra grande \/ para compartir)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: helado, nieve, gelato, postres, toppings\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C.H._16oz.png?v=1768508829\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 30%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Contenedor para helado 16oz DPC16\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/contenedor-helado-16oz-dpc16?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148106346746,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/42.jpg?v=1768505720"},{"product_id":"contenedor-helado-32oz-dpc32","title":"Contenedor para helado 32oz DPC32 cartón alimenticio blanco (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003econtenedor 32 oz DPC32\u003c\/strong\u003e es un empaque de \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e diseñado para \u003cstrong\u003epresentaciones familiares, medio litro o porciones muy grandes de helado, nieve, gelato o postres\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eSu tamaño lo hace ideal para \u003cstrong\u003eventa para llevar\u003c\/strong\u003e, combos de postres o presentaciones para compartir. El \u003cstrong\u003ecartón resistente\u003c\/strong\u003e y su \u003cstrong\u003ecolor blanco\u003c\/strong\u003e ofrecen una imagen limpia y profesional tanto en vitrina como en delivery.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 500 piezas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eDPC32\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 32 oz (presentación grande\/familiar)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: helado, nieve, gelato, postres, toppings\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C.H._32oz.png?v=1768508829\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 35%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Contenedor para helado 32oz DPC32\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/contenedor-helado-32oz-dpc32?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148108083450,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/43.jpg?v=1768505744"},{"product_id":"tapa-tdpc16-contenedor-16-32oz","title":"Tapa de papel TDPC16 para contenedor 16 oz y 32 oz cartón alimenticio blanco (500 pzas)","description":"\u003cp\u003eLa \u003cstrong\u003etapa de papel TDPC16\u003c\/strong\u003e está diseñada para ajustarse a los \u003cstrong\u003econtenedores de 16 oz y 32 oz\u003c\/strong\u003e (modelos DPC16 y DPC32). Fabricada en \u003cstrong\u003ecartón alimenticio\u003c\/strong\u003e, ofrece un \u003cstrong\u003eajuste seguro\u003c\/strong\u003e para mantener tu producto \u003cstrong\u003efresco, protegido y listo para transporte\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eEs ideal para \u003cstrong\u003eheladerías, reposterías y servicios de delivery\u003c\/strong\u003e que requieren un cierre confiable para sus contenedores de helado, gelato, postres o alimentos fríos. Su \u003cstrong\u003ecolor blanco\u003c\/strong\u003e combina con los vasos de cartón, brindando una \u003cstrong\u003epresentación limpia y uniforme\u003c\/strong\u003e.\u003cbr\u003eSe vende en \u003cstrong\u003epaquetes de 500 tapas\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTDPC16\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: contenedores de 16 oz y 32 oz (DPC16, DPC32)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: tapas para helado, gelato, postres, delivery\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón alimenticio\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/T.C.H._16_32oz.png?v=1768528015\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 40%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Tapa de papel para helado TDPC16\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/tapa-tdpc16-contenedor-16-32oz?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148129022202,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/44.jpg?v=1768505779"},{"product_id":"caja-pastel-28x28x6-cj28","title":"Caja para pastel 28x28x6 cm CJ28 cartón kraft blanco natural","description":"\u003cp\u003eLa \u003cstrong\u003ecaja para pastel CJ28 (28x28x6 cm)\u003c\/strong\u003e está fabricada en \u003cstrong\u003ecartón kraft de alta resistencia\u003c\/strong\u003e, diseñada para \u003cstrong\u003emantener tus postres seguros, firmes y bien presentados\u003c\/strong\u003e. Su altura de 6 cm la hace ideal para \u003cstrong\u003epasteles bajos, pays, tartas y repostería fina\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003ePermite \u003cstrong\u003etransportar pasteles y postres sin riesgo de deformación\u003c\/strong\u003e, ofreciendo un empaque \u003cstrong\u003econfiable, profesional y visualmente atractivo\u003c\/strong\u003e. El \u003cstrong\u003ecolor blanco natural\u003c\/strong\u003e brinda una estética \u003cstrong\u003eelegante y artesanal\u003c\/strong\u003e que realza cualquier creación repostera, ya sea para mostrador o para llevar.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eCJ28\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMedidas: \u003cstrong\u003e28 cm x 28 cm x 6 cm\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón kraft de alta resistencia\u003c\/li\u003e\n\u003cli\u003eUso recomendado: pasteles bajos, pays, tartas, repostería\u003c\/li\u003e\n\u003cli\u003eColor: blanco natural, estética elegante y artesanal\u003c\/li\u003e\n\u003cli\u003eBeneficios: transporte seguro, presentación profesional\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C._28X28X6.png?v=1768528015\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 40%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Caja para pastel 28x28x6 cm CJ28\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/caja-pastel-28x28x6-cj28?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148224180474,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/48.jpg?v=1768505958"},{"product_id":"caja-pastel-28x28x11-cj6","title":"Caja para pastel 28x28x11 cm CJ6 cartón kraft blanco natural","description":"\u003cp\u003eLa \u003cstrong\u003ecaja para pastel CJ6 (28x28x11 cm)\u003c\/strong\u003e está fabricada en \u003cstrong\u003ecartón kraft de alta resistencia\u003c\/strong\u003e, pensada para \u003cstrong\u003epasteles más altos, pays de varias capas y postres voluminosos\u003c\/strong\u003e. Su altura de 11 cm ofrece el espacio necesario para proteger tus creaciones.\u003c\/p\u003e\n\u003cp\u003eProporciona un \u003cstrong\u003etransporte seguro\u003c\/strong\u003e, evitando deformaciones y conservando la \u003cstrong\u003epresentación firme y profesional\u003c\/strong\u003e. El \u003cstrong\u003ecolor blanco natural\u003c\/strong\u003e aporta una imagen \u003cstrong\u003eelegante, limpia y artesanal\u003c\/strong\u003e, ideal para \u003cstrong\u003epastelerías, reposterías y negocios que cuidan su presentación al cliente\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eCJ6\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMedidas: \u003cstrong\u003e28 cm x 28 cm x 11 cm\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón kraft de alta resistencia\u003c\/li\u003e\n\u003cli\u003eUso recomendado: pasteles altos, pays por capas, postres voluminosos\u003c\/li\u003e\n\u003cli\u003eColor: blanco natural\u003c\/li\u003e\n\u003cli\u003eBeneficios: empaque confiable, profesional y atractivo\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C._28X28X11.png?v=1768528015\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 40%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Caja para pastel 28x28x11 cm CJ6\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/caja-pastel-28x28x11-cj6?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148242628858,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/49.jpg?v=1768505958"},{"product_id":"caja-pastel-30x30x11-cj30","title":"Caja para pastel 30x30x11 cm CJ30 cartón kraft blanco natural","description":"\u003cp\u003eLa \u003cstrong\u003ecaja para pastel CJ30 (30x30x11 cm)\u003c\/strong\u003e está elaborada en \u003cstrong\u003ecartón kraft de alta resistencia\u003c\/strong\u003e, ideal para \u003cstrong\u003epasteles medianos, pays grandes y repostería especial\u003c\/strong\u003e. Su tamaño de 30x30 cm y altura de 11 cm proporciona un espacio amplio y seguro para tus creaciones.\u003c\/p\u003e\n\u003cp\u003eAyuda a \u003cstrong\u003etransportar pasteles y postres sin riesgo de deformación\u003c\/strong\u003e, manteniéndolos firmes y bien presentados. El \u003cstrong\u003ecolor blanco natural\u003c\/strong\u003e ofrece una estética \u003cstrong\u003eelegante, artesanal y profesional\u003c\/strong\u003e, perfecta para \u003cstrong\u003epastelerías, reposterías y negocios que buscan un empaque de alta presentación\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eCJ30\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMedidas: \u003cstrong\u003e30 cm x 30 cm x 11 cm\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón kraft de alta resistencia\u003c\/li\u003e\n\u003cli\u003eUso recomendado: pasteles medianos, pays grandes, repostería especial\u003c\/li\u003e\n\u003cli\u003eColor: blanco natural\u003c\/li\u003e\n\u003cli\u003eBeneficios: transporte seguro, presentación premium\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003csection class=\"customize-order-section\"\u003e\n  \u003cdiv class=\"customize-order-inner\"\u003e\n    \u003ch2 class=\"customize-order-title\"\u003ePersonaliza tu pedido\u003c\/h2\u003e\n\n    \u003cdiv class=\"customize-order-grid\"\u003e\n      \u003c!-- Columna 1: Subir logo --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003clabel for=\"logo-upload-input\" class=\"customize-upload-box\" id=\"upload-box-label\"\u003e\n          \u003cdiv class=\"upload-plus-wrapper\" id=\"upload-plus-wrapper\"\u003e\n            \u003cspan class=\"upload-icon\"\u003e+\u003c\/span\u003e\n          \u003c\/div\u003e\n\n          \u003cdiv class=\"upload-preview-wrapper\"\u003e\n            \u003cimg id=\"upload-preview-img\" src=\"\" alt=\"Vista previa de tu logo\" class=\"upload-preview-img\" style=\"display:none;\"\u003e\n          \u003c\/div\u003e\n        \u003c\/label\u003e\n\n        \u003cinput id=\"logo-upload-input\" type=\"file\" accept=\"image\/png,image\/jpeg,image\/jpg\" class=\"upload-input\"\u003e\n\n        \u003cbutton type=\"button\" id=\"clear-logo-btn\" class=\"clear-logo-btn\" style=\"display:none;\"\u003e\n          Borrar imagen\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 2: Mockup --\u003e\n      \u003cdiv class=\"customize-step\"\u003e\n        \u003cdiv class=\"mockup-preview\"\u003e\n          \u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/C._30x30x11.png?v=1768528015\" alt=\"Vaso personalizado\" class=\"mockup-base\" width=\"800\" height=\"800\"\u003e\n\n          \u003cdiv class=\"mockup-logo-wrap\" id=\"mockup-logo-wrap\"\u003e\n            \u003cimg id=\"mockup-logo-img\" src=\"\" alt=\"Tu logotipo\" class=\"mockup-logo\" style=\"display:none;\" width=\"600\" height=\"600\"\u003e\n          \u003c\/div\u003e\n        \u003c\/div\u003e\n      \u003c\/div\u003e\n\n      \u003c!-- Columna 3: Cantidad + botón WhatsApp --\u003e\n      \u003cdiv class=\"customize-step customize-step--quantity\"\u003e\n        \u003ch3 class=\"step-title step-title-top\"\u003eCantidad de cajas para cotizar\u003c\/h3\u003e\n\n        \u003cdiv class=\"qty-block qty-block-top\"\u003e\n          \u003cdiv class=\"qty-control\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-minus\"\u003e−\u003c\/button\u003e\n            \u003cinput type=\"text\" id=\"quote-quantity\" class=\"qty-input\" value=\"1\" inputmode=\"numeric\" pattern=\"[0-9]*\"\u003e\n            \u003cbutton type=\"button\" class=\"qty-btn\" id=\"qty-plus\"\u003e+\u003c\/button\u003e\n          \u003c\/div\u003e\n          \u003cp class=\"qty-min-text\"\u003eTe cotizamos desde una caja\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Botón WhatsApp verde con icono (imagen) --\u003e\n        \u003cbutton type=\"button\" id=\"custom-whatsapp-btn\" class=\"whatsapp-quote-btn\"\u003e\n          \u003cspan class=\"wa-icon-circle\"\u003e\n            \u003cimg src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6b\/WhatsApp.svg\" alt=\"WhatsApp\" class=\"wa-icon-img\"\u003e\n          \u003c\/span\u003e\n          \u003cspan\u003eCotizar Producto\u003c\/span\u003e\n        \u003c\/button\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Fila inferior de pasos --\u003e\n    \u003cdiv class=\"customize-steps-row\"\u003e\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e1\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eAgrega tu logo\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Solo se admiten imágenes en formato .png con fondo transparente. Tamaño máximo: 20 KB.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e2\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eVisualiza cómo se ve\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Esta es una representación digital del producto final. El resultado puede variar ligeramente en color, tamaño o proporciones.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n\n      \u003cdiv class=\"customize-step-text\"\u003e\n        \u003cdiv class=\"step-circle\"\u003e3\u003c\/div\u003e\n        \u003ch3 class=\"step-title\"\u003eHaz tu pedido\u003c\/h3\u003e\n        \u003cp class=\"step-desc\"\u003e\n          Puedes pedir desde una caja para imprimir tu logo en tu artículo, así de fácil.\n        \u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003c!-- Campos ocultos --\u003e\n    \u003cinput type=\"hidden\" id=\"logo-data-input\" name=\"properties[Logo personalizado]\" value=\"\"\u003e\n    \u003cinput type=\"hidden\" id=\"quote-quantity-input\" name=\"properties[Cantidad para cotización]\" value=\"1\"\u003e\n  \u003c\/div\u003e\n\n  \u003cstyle\u003e\n    .customize-order-section {\n      padding: 2.5rem 1.25rem;\n      background-color: #ffffff;\n    }\n    .customize-order-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n    .customize-order-title {\n      font-size: 1.75rem;\n      font-weight: 700;\n      margin-bottom: 1.75rem;\n      text-align: left;\n      color: #2044A3;\n    }\n\n    .customize-order-grid {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 3rem;\n      align-items: flex-start;\n      margin-bottom: 3rem;\n      justify-content: center;\n    }\n    .customize-step {\n      width: 100%;\n      max-width: 300px;\n      margin: 0 auto;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .customize-upload-box {\n      border: 2px dashed #D4D4D8;\n      border-radius: 1.5rem;\n      padding: 1.5rem;\n      min-height: 220px;\n      width: 100%;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      position: relative;\n      cursor: pointer;\n      box-sizing: border-box;\n    }\n\n    .upload-plus-wrapper {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      pointer-events: none;\n    }\n\n    .upload-icon {\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 60px;\n      height: 60px;\n      border-radius: 9999px;\n      border: 2px solid #2044A3;\n      font-size: 1.85rem;\n      font-weight: 600;\n      color: #2044A3;\n      background: #ffffff;\n    }\n\n    .upload-input {\n      display: none;\n    }\n\n    .upload-preview-wrapper {\n      width: 100%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      min-height: 150px;\n    }\n    .upload-preview-img {\n      max-width: 100%;\n      max-height: 160px;\n      object-fit: contain;\n      display: block;\n    }\n\n    .clear-logo-btn {\n      margin-top: 0.75rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.6rem 1.6rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #FFC800;\n      color: #111111;\n      font-size: 0.9rem;\n      cursor: pointer;\n      white-space: nowrap;\n    }\n    .clear-logo-btn:hover {\n      background-color: #e0ae00;\n    }\n\n    .mockup-preview {\n      position: relative;\n      border-radius: 1.5rem;\n      background-color: #F5F5F7;\n      padding: 1.5rem;\n      min-height: 220px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n    }\n    .mockup-base {\n      max-width: 120%;\n      height: auto;\n      display: block;\n    }\n    .mockup-logo-wrap {\n      position: absolute;\n      top: 55%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 40%;\n      pointer-events: auto;\n      cursor: move;\n      border: 2px solid transparent;\n      border-radius: 4px;\n      box-sizing: border-box;\n    }\n    .mockup-logo-wrap.is-dragging {\n      border-color: #2044A3;\n    }\n    .mockup-logo {\n      width: 100%;\n      height: auto;\n      object-fit: contain;\n      display: block;\n      filter: drop-shadow(0 1px 2px rgba(0,0,0,0.18));\n    }\n\n    .customize-step--quantity {\n      text-align: center;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .step-title-top {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 1.5rem;\n    }\n\n    .qty-min-text {\n      font-size: 0.85rem;\n      color: #6B7280;\n      margin-top: 0.25rem;\n    }\n\n    \/* === FORZAR ALINEACIÓN PERFECTA DE LA PÍLDORA DE CANTIDAD === *\/\n    .customize-order-section .qty-control {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      border-radius: 9999px !important;\n      border: 1px solid #D4D4D8 !important;\n      overflow: hidden !important;\n      background-color: #ffffff !important;\n      padding: 0 !important;\n      line-height: 0 !important;\n    }\n\n    .customize-order-section .qty-btn {\n      display: inline-flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      width: 60px !important;\n      height: 46px !important;\n      background-color: #FFC800 !important;\n      border: none !important;\n      cursor: pointer !important;\n      color: #111111 !important;\n      font-size: 1.6rem !important;\n      line-height: 1 !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-shadow: none !important;\n    }\n\n    .customize-order-section .qty-input {\n      width: 80px !important;\n      height: 46px !important;\n      border: none !important;\n      outline: none !important;\n      text-align: center !important;\n      font-size: 1rem !important;\n      color: #111111 !important;\n      background-color: #ffffff !important;\n      display: flex !important;\n      align-items: center !important;\n      justify-content: center !important;\n      padding: 0 !important;\n      margin: 0 !important;\n      box-sizing: border-box !important;\n      line-height: 1 !important;\n    }\n\n    .customize-order-section .qty-btn span,\n    .customize-order-section .qty-btn,\n    .customize-order-section .qty-control * {\n      line-height: 1 !important;\n    }\n\n    \/* BOTÓN WHATSAPP VERDE *\/\n    .customize-order-section .whatsapp-quote-btn {\n      margin-top: 1.25rem;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      align-self: center;\n      padding: 0.9rem 2.5rem;\n      border-radius: 9999px;\n      border: none;\n      background-color: #25D366 !important; \/* Verde WhatsApp *\/\n      color: #ffffff !important;\n      font-size: 1rem;\n      font-weight: 600;\n      cursor: pointer;\n      white-space: nowrap;\n      box-shadow: 0 8px 20px rgba(0,0,0,0.12);\n      gap: 0.5rem; \/* separa icono y texto *\/\n    }\n    .customize-order-section .whatsapp-quote-btn:hover {\n      background-color: #1eb259 !important;\n    }\n\n    \/* Círculo blanco para el ícono *\/\n    .customize-order-section .wa-icon-circle {\n      width: 22px;\n      height: 22px;\n      border-radius: 9999px;\n      background-color: #ffffff;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      overflow: hidden;\n      flex-shrink: 0;\n    }\n\n    \/* Imagen del ícono de WhatsApp *\/\n    .customize-order-section .wa-icon-img {\n      width: 16px;\n      height: 16px;\n      display: block;\n    }\n\n    .customize-order-section .wa-icon-phone,\n    .customize-order-section .wa-icon-phone::after {\n      display: none !important;\n    }\n\n    .customize-steps-row {\n      display: grid;\n      grid-template-columns: repeat(3, minmax(0, 1fr));\n      gap: 2rem;\n      margin-top: 1rem;\n      max-width: 1100px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n    .customize-step-text {\n      text-align:center;\n      display:flex;\n      flex-direction:column;\n      align-items:center;\n    }\n    .step-circle {\n      width: 40px;\n      height: 40px;\n      border-radius: 9999px;\n      border: 2px solid #D4D4D8;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin: 0 auto 0.75rem auto;\n      font-weight: 600;\n      color: #111827;\n    }\n    .step-title {\n      font-size: 1rem;\n      font-weight: 700;\n      margin-bottom: 0.5rem;\n    }\n    .step-desc {\n      font-size: 0.875rem;\n      color: #6B7280;\n      line-height: 1.4;\n    }\n\n    @media (max-width: 900px) {\n      .customize-order-grid {\n        grid-template-columns: 1fr;\n      }\n      .customize-steps-row {\n        grid-template-columns: 1fr;\n      }\n      .customize-order-title {\n        text-align: center;\n      }\n      .customize-step--quantity {\n        text-align: center;\n        align-items: center;\n      }\n      .customize-order-section .whatsapp-quote-btn {\n        align-self: center;\n      }\n    }\n  \u003c\/style\u003e\n\n  \u003cscript\u003e\n    document.addEventListener('DOMContentLoaded', function() {\n      var fileInput       = document.getElementById('logo-upload-input');\n      var logoImg         = document.getElementById('mockup-logo-img');\n      var uploadPreview   = document.getElementById('upload-preview-img');\n      var clearBtn        = document.getElementById('clear-logo-btn');\n      var logoDataInput   = document.getElementById('logo-data-input');\n      var plusWrapper     = document.getElementById('upload-plus-wrapper');\n\n      var qtyInput  = document.getElementById('quote-quantity');\n      var qtyHidden = document.getElementById('quote-quantity-input');\n      var btnMinus  = document.getElementById('qty-minus');\n      var btnPlus   = document.getElementById('qty-plus');\n\n      var mockupPreview   = document.querySelector('.mockup-preview');\n      var mockupLogoWrap  = document.getElementById('mockup-logo-wrap');\n\n      if (fileInput \u0026\u0026 logoImg \u0026\u0026 logoDataInput) {\n        fileInput.addEventListener('change', function(event) {\n          var file = event.target.files[0];\n          if (!file) return;\n\n          var maxSizeMB = 2;\n          if (file.size \u003e maxSizeMB * 1024 * 1024) {\n            alert('La imagen es demasiado grande. Tamaño máximo: ' + maxSizeMB + ' MB');\n            fileInput.value = '';\n            return;\n          }\n\n          var reader = new FileReader();\n          reader.onload = function(e) {\n            var dataUrl = e.target.result;\n\n            logoImg.src = dataUrl;\n            logoImg.style.display = 'block';\n\n            if (uploadPreview) {\n              uploadPreview.src = dataUrl;\n              uploadPreview.style.display = 'block';\n            }\n\n            if (plusWrapper) plusWrapper.style.display = 'none';\n\n            logoDataInput.value = dataUrl;\n            clearBtn.style.display = 'inline-flex';\n\n            resetLogoPosition();\n          };\n          reader.readAsDataURL(file);\n        });\n\n        clearBtn.addEventListener('click', function() {\n          fileInput.value = '';\n\n          logoImg.src = '';\n          logoImg.style.display = 'none';\n\n          if (uploadPreview) {\n            uploadPreview.src = '';\n            uploadPreview.style.display = 'none';\n          }\n\n          if (plusWrapper) plusWrapper.style.display = 'flex';\n\n          logoDataInput.value = '';\n          clearBtn.style.display = 'none';\n\n          resetLogoPosition();\n        });\n      }\n\n      function resetLogoPosition() {\n        if (!mockupLogoWrap) return;\n        mockupLogoWrap.style.top = '55%';\n        mockupLogoWrap.style.left = '50%';\n        mockupLogoWrap.style.transform = 'translate(-50%, -50%)';\n        mockupLogoWrap.classList.remove('is-dragging');\n      }\n\n      if (mockupPreview \u0026\u0026 mockupLogoWrap) {\n        var isDragging = false;\n        var startX = 0;\n        var startY = 0;\n        var startLeft = 0;\n        var startTop = 0;\n\n        function getBounds() {\n          return mockupPreview.getBoundingClientRect();\n        }\n\n        function onPointerDown(e) {\n          if (!logoImg || logoImg.style.display === 'none') return;\n\n          isDragging = true;\n          mockupLogoWrap.classList.add('is-dragging');\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          startX = clientX;\n          startY = clientY;\n\n          var wrapRect = mockupLogoWrap.getBoundingClientRect();\n          startLeft = wrapRect.left - rect.left;\n          startTop  = wrapRect.top  - rect.top;\n\n          mockupLogoWrap.style.transform = 'none';\n\n          document.addEventListener('mousemove', onPointerMove);\n          document.addEventListener('mouseup', onPointerUp);\n          document.addEventListener('touchmove', onPointerMove, { passive: false });\n          document.addEventListener('touchend', onPointerUp);\n        }\n\n        function onPointerMove(e) {\n          if (!isDragging) return;\n          e.preventDefault();\n\n          var rect = getBounds();\n          var clientX = e.touches ? e.touches[0].clientX : e.clientX;\n          var clientY = e.touches ? e.touches[0].clientY : e.clientY;\n\n          var deltaX = clientX - startX;\n          var deltaY = clientY - startY;\n\n          var newLeft = startLeft + deltaX;\n          var newTop  = startTop + deltaY;\n\n          var wrapRect  = mockupLogoWrap.getBoundingClientRect();\n          var wrapWidth = wrapRect.width;\n          var wrapHeight = wrapRect.height;\n\n          var minLeft = 0;\n          var minTop  = 0;\n          var maxLeft = rect.width  - wrapWidth;\n          var maxTop  = rect.height - wrapHeight;\n\n          if (newLeft \u003c minLeft) newLeft = minLeft;\n          if (newTop  \u003c minTop)  newTop  = minTop;\n          if (newLeft \u003e maxLeft) newLeft = maxLeft;\n          if (newTop  \u003e maxTop)  newTop  = maxTop;\n\n          mockupLogoWrap.style.left = newLeft + 'px';\n          mockupLogoWrap.style.top  = newTop  + 'px';\n        }\n\n        function onPointerUp() {\n          if (!isDragging) return;\n          isDragging = false;\n          mockupLogoWrap.classList.remove('is-dragging');\n\n          document.removeEventListener('mousemove', onPointerMove);\n          document.removeEventListener('mouseup', onPointerUp);\n          document.removeEventListener('touchmove', onPointerMove);\n          document.removeEventListener('touchend', onPointerUp);\n        }\n\n        mockupLogoWrap.addEventListener('mousedown', onPointerDown);\n        mockupLogoWrap.addEventListener('touchstart', onPointerDown, { passive: true });\n      }\n\n      function sanitizeQty() {\n        if (!qtyInput || !qtyHidden) return;\n\n        var value = qtyInput.value.replace(\/[^0-9]\/g, '');\n        if (!value || Number(value) \u003c 1) {\n          value = '1';\n        }\n        qtyInput.value = value;\n        qtyHidden.value = value;\n      }\n\n      if (qtyInput \u0026\u0026 qtyHidden) {\n        qtyInput.addEventListener('change', sanitizeQty);\n        qtyInput.addEventListener('blur', sanitizeQty);\n      }\n\n      if (btnMinus \u0026\u0026 qtyInput) {\n        btnMinus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          if (current \u003e 1) {\n            qtyInput.value = String(current - 1);\n            sanitizeQty();\n          }\n        });\n      }\n\n      if (btnPlus \u0026\u0026 qtyInput) {\n        btnPlus.addEventListener('click', function() {\n          var current = Number(qtyInput.value || 1);\n          qtyInput.value = String(current + 1);\n          sanitizeQty();\n        });\n      }\n\n      sanitizeQty();\n\n      \/* --- BOTÓN WHATSAPP --- *\/\n      var whatsappBtn    = document.getElementById('custom-whatsapp-btn');\n      var whatsappNumber = '525536684089'; \/\/ tu número sin + ni espacios\n\n      \/\/ EDITA ESTAS DOS LÍNEAS EN CADA PRODUCTO:\n      var productTitle   = \"Caja para pastel 30x30x11 cm CJ30 \";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/caja-pastel-30x30x11-cj30?utm_source=copyToPasteBoard\u0026utm_medium=product-links\u0026utm_content=web\";\n\n      if (whatsappBtn \u0026\u0026 qtyHidden) {\n        whatsappBtn.addEventListener('click', function() {\n          var qty = parseInt(qtyHidden.value || '1', 10);\n          if (isNaN(qty) || qty \u003c 1) qty = 1;\n\n          var message =\n            \"Hola, quiero cotizar este producto personalizado con mi marca.%0A%0A\" +\n            \"Producto: \" + encodeURIComponent(productTitle) + \"%0A\" +\n            \"Cantidad: \" + encodeURIComponent(qty + \" cajas\") + \"%0A\" +\n            \"URL del producto: \" + encodeURIComponent(productUrl) + \"%0A%0A\" +\n            \"Por favor, confírmenme tiempos de producción, precios y opciones de personalización.\";\n\n          var waUrl = \"https:\/\/wa.me\/\" + whatsappNumber + \"?text=\" + message;\n          window.open(waUrl, \"_blank\");\n        });\n      }\n    });\n  \u003c\/script\u003e\n\u003c\/section\u003e\n","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48148254654714,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/50.jpg?v=1768505958"}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/collections\/Coleccion_Accesorios_para_cafeterias_Accesa_Interabasto_59ca85f8-e21c-48b7-8317-98394c3894c5.jpg?v=1766167465","url":"https:\/\/acesainter.com\/collections\/accesorios-heladeria-reposteria.oembed?page=4","provider":"ACESA INTERABASTO S. A. de C.V.","version":"1.0","type":"link"}