{"title":"Accesorios para cafeterías","description":"\u003cp\u003eAccesorios esenciales para cafeterías y coffee shops: fajillas microcorrugadas para vasos de papel y servilletas impresas a 1 tinta. Mejora la experiencia del cliente con protección térmica, mejor agarre y presentación premium, mientras refuerzas tu marca con servilletas personalizadas para cada café, bebida caliente o snack.\u003c\/p\u003e","products":[{"product_id":"tapa-viajera-negra-8oz-tl38rn","title":"Tapa viajera negra para vaso 8 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera color \u003cstrong\u003enegro\u003c\/strong\u003e para vasos de \u003cstrong\u003e8 oz\u003c\/strong\u003e de bebidas calientes como café, té o chocolate. Diseñada para ofrecer un \u003cstrong\u003ecierre hermético\u003c\/strong\u003e, evitar derrames y soportar el calor. Fabricada en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, ideal para \u003cstrong\u003ecafeterías, panaderías, food trucks, restaurantes y servicio para llevar\u003c\/strong\u003e.\u003cbr\u003eCaja con \u003cstrong\u003e1000 tapas\u003c\/strong\u003e, práctica para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTL38RN\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 8 oz para bebidas calientes\u003c\/li\u003e\n\u003cli\u003eColor: negro\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147536445690,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/7.jpg?v=1768503791"},{"product_id":"tapa-viajera-blanca-8oz-tl38b","title":"Tapa viajera blanca para vaso 8 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera color \u003cstrong\u003eblanco\u003c\/strong\u003e para vasos de \u003cstrong\u003e8 oz\u003c\/strong\u003e de bebidas calientes. Diseñada para \u003cstrong\u003eresistir el calor\u003c\/strong\u003e y ofrecer un \u003cstrong\u003ecierre hermético\u003c\/strong\u003e, evitando goteos y derrames durante el consumo o el traslado. Elaborada en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, perfecta para \u003cstrong\u003ecafeterías, coffee shops, panaderías y oficinas\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e para uso intensivo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTL38B\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 8 oz para bebidas calientes\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147539722490,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/8.jpg?v=1768503826"},{"product_id":"tapa-viajera-negra-10oz-tl31rn","title":"Tapa viajera negra para vaso 10 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003enegra\u003c\/strong\u003e para vasos de \u003cstrong\u003e10 oz\u003c\/strong\u003e de bebidas calientes, ideal para café mediano, té y chocolate caliente para llevar. Diseñada para ofrecer \u003cstrong\u003ecierre hermético\u003c\/strong\u003e y \u003cstrong\u003esoportar el calor\u003c\/strong\u003e sin deformarse. Hecha de \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, recomendada para \u003cstrong\u003ecafeterías, panaderías, restaurantes y food trucks\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e para operación diaria al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTL31RN\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 10 oz para bebidas calientes\u003c\/li\u003e\n\u003cli\u003eColor: negro\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147543294202,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/7.jpg?v=1768503791"},{"product_id":"tapa-viajera-blanca-10oz-tlr31rb","title":"Tapa viajera blanca para vaso 10 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003eblanca\u003c\/strong\u003e para vasos de \u003cstrong\u003e10 oz\u003c\/strong\u003e de bebidas calientes. Diseñada para \u003cstrong\u003eresistir el calor\u003c\/strong\u003e y proporcionar un \u003cstrong\u003ecierre hermético\u003c\/strong\u003e, ideal para café mediano, té y chocolate caliente para llevar. Fabricada en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, pensada para \u003cstrong\u003ecafeterías, panaderías, restaurantes y oficinas\u003c\/strong\u003e.\u003cbr\u003eIncluye \u003cstrong\u003e1000 tapas por caja\u003c\/strong\u003e, óptimo para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTLR31RB\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 10 oz para bebidas calientes\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147544244474,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/8.jpg?v=1768503826"},{"product_id":"tapa-viajera-negra-12-16-20oz-tlp316n","title":"Tapa viajera negra para vasos 12, 16 y 20 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003enegra\u003c\/strong\u003e compatible con vasos de \u003cstrong\u003e12 oz, 16 oz y 20 oz\u003c\/strong\u003e para bebidas calientes. Diseñada para brindar \u003cstrong\u003ecierre hermético\u003c\/strong\u003e y \u003cstrong\u003eresistencia al calor\u003c\/strong\u003e, evitando derrames durante el traslado. Producida en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, ideal para \u003cstrong\u003ecafeterías, cadenas de café, panaderías, restaurantes y servicio para llevar\u003c\/strong\u003e.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e, adecuada para consumo intensivo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTLP316N\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 12 oz \/ 16 oz \/ 20 oz\u003c\/li\u003e\n\u003cli\u003eColor: negro\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147545620730,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/9.jpg?v=1768503902"},{"product_id":"tapa-viajera-blanca-12-16-20oz-tlp316b","title":"Tapa viajera blanca para vasos 12, 16 y 20 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003eblanca\u003c\/strong\u003e compatible con vasos de \u003cstrong\u003e12 oz, 16 oz y 20 oz\u003c\/strong\u003e de bebidas calientes. Ofrece \u003cstrong\u003ecierre hermético\u003c\/strong\u003e y \u003cstrong\u003eresistencia al calor\u003c\/strong\u003e, ideal para café grande, lattes y chocolate caliente para llevar. Fabricada en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, recomendada para \u003cstrong\u003ecafeterías, panaderías y negocios de bebidas\u003c\/strong\u003e.\u003cbr\u003eLa presentación en \u003cstrong\u003ecaja con 1000 tapas\u003c\/strong\u003e facilita la compra al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eTLP316B\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 12 oz \/ 16 oz \/ 20 oz\u003c\/li\u003e\n\u003cli\u003eColor: blanco\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147546734842,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/10.jpg?v=1768503902"},{"product_id":"tapa-viajera-gris-12-16-20oz-lhrdsc-16g","title":"Tapa viajera gris para vasos 12, 16 y 20 oz bebidas calientes (caja 1000 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003egris\u003c\/strong\u003e para vasos de \u003cstrong\u003e12 oz, 16 oz y 20 oz\u003c\/strong\u003e de bebidas calientes. Diseñada para ofrecer \u003cstrong\u003ecierre hermético\u003c\/strong\u003e y evitar derrames, con \u003cstrong\u003eplástico duradero\u003c\/strong\u003e que resiste el calor. Su color gris agrega un toque distintivo a la presentación de tus bebidas. Fabricada en \u003cstrong\u003eplástico reciclable\u003c\/strong\u003e, ideal para \u003cstrong\u003ecafeterías, panaderías, coffee shops y cadenas de café\u003c\/strong\u003e.\u003cbr\u003eIncluye \u003cstrong\u003e1000 tapas por caja\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eLHRDSC-16G\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 12 oz \/ 16 oz \/ 20 oz\u003c\/li\u003e\n\u003cli\u003eColor: gris\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147561545978,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/11.jpg?v=1768503902"},{"product_id":"tapa-viajera-rosa-12-16-20oz-lhrdsp-16","title":"Tapa viajera rosa para vasos 12, 16 y 20 oz bebidas calientes (caja 1200 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003erosa\u003c\/strong\u003e compatible con vasos de \u003cstrong\u003e12 oz, 16 oz y 20 oz\u003c\/strong\u003e de bebidas calientes. Aporta un \u003cstrong\u003etoque de color y diferenciación\u003c\/strong\u003e a tus bebidas, manteniendo un \u003cstrong\u003ecierre hermético\u003c\/strong\u003e y buena \u003cstrong\u003eresistencia al calor\u003c\/strong\u003e. Elaborada en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, perfecta para \u003cstrong\u003ecafeterías, conceptos temáticos, pastelerías y negocios que buscan destacar su marca\u003c\/strong\u003e.\u003cbr\u003eCaja con \u003cstrong\u003e1200 tapas\u003c\/strong\u003e, ideal para alto volumen.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eLHRDSP-16\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 12 oz \/ 16 oz \/ 20 oz\u003c\/li\u003e\n\u003cli\u003eColor: rosa\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147561709818,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/12.jpg?v=1768503902"},{"product_id":"tapa-viajera-roja-12-16-20oz-lhrdsc-16r","title":"Tapa viajera roja para vasos 12, 16 y 20 oz bebidas calientes (caja 1200 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003eroja\u003c\/strong\u003e para vasos de \u003cstrong\u003e12 oz, 16 oz y 20 oz\u003c\/strong\u003e de bebidas calientes. Ofrece \u003cstrong\u003ecierre hermético\u003c\/strong\u003e y \u003cstrong\u003eplástico duradero\u003c\/strong\u003e para soportar el calor, agregando un \u003cstrong\u003ecolor llamativo\u003c\/strong\u003e a la presentación de tus bebidas. Fabricada en \u003cstrong\u003eplástico reciclable\u003c\/strong\u003e, ideal para \u003cstrong\u003ecafeterías, cadenas de café, food trucks y eventos especiales\u003c\/strong\u003e.\u003cbr\u003ePresentación en \u003cstrong\u003ecaja con 1200 tapas\u003c\/strong\u003e para consumo de alto volumen.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eLHRDSC-16R\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 12 oz \/ 16 oz \/ 20 oz\u003c\/li\u003e\n\u003cli\u003eColor: rojo\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147562037498,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/13.jpg?v=1768503902"},{"product_id":"tapa-viajera-cafe-12-16-20oz-lhrdsn-16c","title":"Tapa viajera color café para vasos 12, 16 y 20 oz bebidas calientes (caja 1200 pzas)","description":"\u003cp\u003eTapa viajera \u003cstrong\u003ecolor café\u003c\/strong\u003e compatible con vasos de \u003cstrong\u003e12 oz, 16 oz y 20 oz\u003c\/strong\u003e para bebidas calientes. Diseñada para ofrecer \u003cstrong\u003ecierre hermético\u003c\/strong\u003e, evitar derrames y resistir el calor, además de complementar estéticamente los vasos de café. Fabricada en \u003cstrong\u003eplástico duradero y reciclable\u003c\/strong\u003e, ideal para \u003cstrong\u003ecafeterías, panaderías y negocios de café de especialidad\u003c\/strong\u003e.\u003cbr\u003eIncluye \u003cstrong\u003e1200 tapas por caja\u003c\/strong\u003e, pensada para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eLHRDSN-16C\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad compatible: vasos 12 oz \/ 16 oz \/ 20 oz\u003c\/li\u003e\n\u003cli\u003eColor: café\u003c\/li\u003e\n\u003cli\u003eMaterial: plástico\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":48147562692858,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/14.jpg?v=1768503902"},{"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":"vaso-reyma-16eu-16oz","title":"Vaso Reyma 16 EU 16oz para bebidas frías opaco (caja 1000 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso Reyma 16 EU\u003c\/strong\u003e es un vaso desechable de plástico con capacidad de \u003cstrong\u003e16 oz (473 ml)\u003c\/strong\u003e, ideal para servir \u003cstrong\u003ebebidas frías\u003c\/strong\u003e en \u003cstrong\u003ecafeterías, reposterías, restaurantes, eventos o negocios de bebidas en México\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eFabricado en \u003cstrong\u003epolipropileno (PP)\u003c\/strong\u003e, ofrece buena resistencia y practicidad en el servicio diario. Su \u003cstrong\u003ecolor opaco\u003c\/strong\u003e ayuda a diferenciarlo de los vasos transparentes y a mantener una imagen uniforme en tu negocio. Es una excelente opción para \u003cstrong\u003erefrescos, aguas frescas, jugos, tés helados y bebidas con hielo\u003c\/strong\u003e.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, ideal para consumo al mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e16EU\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\u003eColor: opaco\u003c\/li\u003e\n\u003cli\u003eMaterial: polipropileno (PP)\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\/V.R._16EU.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 Reyma 16 EU 16oz para bebidas frías\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-reyma-16eu-16oz?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":48147595821306,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/25.jpg?v=1768505019"},{"product_id":"vaso-reyma-24eu-24oz","title":"Vaso Reyma 24 EU 24oz para bebidas frías opaco (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso Reyma 24 EU\u003c\/strong\u003e es un vaso desechable de plástico con capacidad de \u003cstrong\u003e24 oz\u003c\/strong\u003e (ideal para bebidas frías de tamaño grande). Es perfecto para \u003cstrong\u003efrappés, malteadas, smoothies, aguas frescas, batidos o bebidas frías con hielo\u003c\/strong\u003e que requieren mayor volumen.\u003c\/p\u003e\n\u003cp\u003eSu fabricación en \u003cstrong\u003epolipropileno (PP) opaco\u003c\/strong\u003e le da buena resistencia y una apariencia uniforme. Es \u003cstrong\u003ecompatible con tapas para venta “para llevar”\u003c\/strong\u003e (según modelo de tapa correspondiente), lo que lo hace ideal para \u003cstrong\u003ecafeterías, heladerías, reposterías, negocios de bebidas y eventos\u003c\/strong\u003e que manejan servicio para consumo en sitio o para llevar.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 500 vasos\u003c\/strong\u003e, adecuada para negocios con consumo medio o alto.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e24EU\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 24 oz (tamaño grande)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: frappés, malteadas, smoothies, aguas frescas y bebidas frías con hielo\u003c\/li\u003e\n\u003cli\u003eColor: opaco\u003c\/li\u003e\n\u003cli\u003eMaterial: polipropileno (PP)\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\/V.R._24EU.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 Reyma 24 EU 24oz para bebidas frías\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-reyma-24eu-24oz?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":48147596017914,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/26.jpg?v=1768505043"},{"product_id":"vaso-reyma-32eu-32oz","title":"Vaso Reyma 32 EU 32oz extra grande para bebidas frías opaco (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso Reyma 32 EU\u003c\/strong\u003e es un vaso desechable de plástico de \u003cstrong\u003e32 oz (946 ml)\u003c\/strong\u003e, el \u003cstrong\u003eformato extra-grande\u003c\/strong\u003e ideal para \u003cstrong\u003efrappés, malteadas, smoothies, licuados, aguas frescas o bebidas frías con mucho hielo\u003c\/strong\u003e. Diseñado para porciones tipo “jumbo”, perfecto para clientes que buscan tamaños grandes.\u003c\/p\u003e\n\u003cp\u003eEstá fabricado en \u003cstrong\u003epolipropileno (PP) opaco\u003c\/strong\u003e, un plástico resistente que soporta el manejo intensivo en \u003cstrong\u003ecafeterías, heladerías, food trucks, locales de aguas frescas y negocios de bebidas\u003c\/strong\u003e. Su presentación en \u003cstrong\u003ecaja con 500 vasos\u003c\/strong\u003e lo hace práctico para operaciones con alto volumen.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e32EU\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 32 oz (≈946 ml)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: frappés, malteadas, smoothies, aguas frescas grandes y bebidas frías extra-grandes\u003c\/li\u003e\n\u003cli\u003eColor: opaco\u003c\/li\u003e\n\u003cli\u003eMaterial: polipropileno (PP)\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\/V.R._32EU.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 Reyma 32 EU 32oz extra grande\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-reyma-32eu-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","brand":"ACESA INTERABASTO S. A. de C.V.","offers":[{"title":"Default Title","offer_id":48147596476666,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/27.jpg?v=1768505062"},{"product_id":"vaso-reyma-16l-linea-l-530ml","title":"Vaso Reyma 16 L línea L para bebidas frías 530 ml opaco (caja 1000 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso Reyma 16 L\u003c\/strong\u003e de la \u003cstrong\u003elínea L\u003c\/strong\u003e es un vaso desechable de plástico con capacidad aproximada de \u003cstrong\u003e530 ml\u003c\/strong\u003e, ideal para una gran variedad de \u003cstrong\u003ebebidas frías\u003c\/strong\u003e. Su tamaño es perfecto para \u003cstrong\u003emalteadas, frappés, smoothies, tés helados, aguas frescas, jugos y bebidas con hielo\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eEstá fabricado en \u003cstrong\u003epolipropileno (PP) opaco\u003c\/strong\u003e, un plástico \u003cstrong\u003eresistente\u003c\/strong\u003e, adecuado para el uso intensivo en negocios de bebidas. Es \u003cstrong\u003ecompatible con tapas y selladora\u003c\/strong\u003e (según el modelo de tu equipo y tapa), lo que lo convierte en una excelente opción para \u003cstrong\u003eservicio para llevar, entregas a domicilio y consumo en barra\u003c\/strong\u003e.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 1000 vasos\u003c\/strong\u003e, ideal para negocios con alto consumo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e16L\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 530 ml (equivalente aprox. a 18 oz)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: bebidas frías, malteadas, frappés, smoothies, tés helados, aguas frescas\u003c\/li\u003e\n\u003cli\u003eCompatibilidad: tapas y selladora (según modelo)\u003c\/li\u003e\n\u003cli\u003eColor: opaco\u003c\/li\u003e\n\u003cli\u003eMaterial: polipropileno (PP)\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\/V.L._16L.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 Reyma 16 L línea L para bebidas frías 530 ml\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-reyma-16l-linea-l-530ml?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":48147598278906,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/28.jpg?v=1768505084"},{"product_id":"vaso-8pp-237ml-pp","title":"Vaso 8 PP 237 ml polipropileno para bebidas frías translúcido (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso 8 PP (237 ml)\u003c\/strong\u003e es un vaso desechable de \u003cstrong\u003epolipropileno (PP)\u003c\/strong\u003e, \u003cstrong\u003epráctico y funcional\u003c\/strong\u003e para servir \u003cstrong\u003erefrescos, aguas frescas, jugos, bebidas individuales o porciones pequeñas\u003c\/strong\u003e. Es una excelente opción cuando se busca \u003cstrong\u003econtrolar porciones\u003c\/strong\u003e y optimizar costos en el servicio diario.\u003c\/p\u003e\n\u003cp\u003eSu material de \u003cstrong\u003epolipropileno translúcido \/ transparente\u003c\/strong\u003e lo hace \u003cstrong\u003eligero, resistente y fácil de almacenar\u003c\/strong\u003e, ideal para uso intensivo en negocios de bebidas. Perfecto para \u003cstrong\u003ecafeterías, juguerías, fondas, puestos de comida, eventos y servicios de banquetes\u003c\/strong\u003e.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 500 vasos\u003c\/strong\u003e, ideal para consumo medio o mayoreo.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e8PP\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 237 ml (≈8 oz)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: refrescos, aguas frescas, jugos, porciones pequeñas de bebida\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\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\/V.P.P._8PP.png?v=1768508828\" 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 8 PP 237 ml polipropileno para bebidas frías\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-8pp-237ml-pp?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":48147599556858,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/30.jpg?v=1768505140"},{"product_id":"vaso-16pp-500ml-pp","title":"Vaso 16 PP 500 ml polipropileno para bebidas frías transparente (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso 16 PP (500 ml)\u003c\/strong\u003e es una opción \u003cstrong\u003eideal y económica\u003c\/strong\u003e para servir \u003cstrong\u003ebebidas frías\u003c\/strong\u003e como \u003cstrong\u003eaguas frescas, jugos, malteadas, frappés o cafés fríos\u003c\/strong\u003e. Su capacidad de medio litro lo hace muy versátil para distintos tipos de negocios.\u003c\/p\u003e\n\u003cp\u003eFabricado en \u003cstrong\u003epolipropileno (PP) translúcido \/ transparente\u003c\/strong\u003e, es un vaso \u003cstrong\u003eligero, resistente y práctico\u003c\/strong\u003e, diseñado para el uso diario en \u003cstrong\u003enegocios de bebidas, cafeterías, food trucks, puestos ambulantes y eventos\u003c\/strong\u003e. Gracias a su resistencia, soporta bien bebidas con hielo y un manejo frecuente.\u003cbr\u003eSe presenta en \u003cstrong\u003ecaja con 500 vasos\u003c\/strong\u003e, ideal para consumo recurrente.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e16PP\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 500 ml (≈16–17 oz)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: aguas frescas, jugos, malteadas, frappés, cafés fríos\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\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\/V.P.P._16PP.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 16 PP 500 ml polipropileno para bebidas frías\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-16pp-500ml-pp?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":48147599687930,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/31.jpg?v=1768505166"},{"product_id":"vaso-32pp-946ml-pp","title":"Vaso 32 PP 946 ml polipropileno grande para bebidas frías transparente (caja 500 pzas)","description":"\u003cp\u003eEl \u003cstrong\u003evaso 32 PP (946 ml)\u003c\/strong\u003e es el \u003cstrong\u003eformato grande\u003c\/strong\u003e para quienes buscan \u003cstrong\u003eporciones generosas\u003c\/strong\u003e de bebida. Resulta ideal para \u003cstrong\u003esmoothies, malteadas, frappés, aguas frescas, jugos con hielo y bebidas frías tamaño jumbo\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eFabricado en \u003cstrong\u003epolipropileno (PP) translúcido \/ transparente\u003c\/strong\u003e, combina \u003cstrong\u003eresistencia, ligereza y buena presentación\u003c\/strong\u003e, soportando sin problema bebidas con bastante hielo y uso continuo. Es perfecto para \u003cstrong\u003enegocios de bebidas, food trucks, puestos de aguas frescas, eventos y ferias\u003c\/strong\u003e que requieren vasos de gran capacidad.\u003cbr\u003eSe comercializa en \u003cstrong\u003ecaja con 500 vasos\u003c\/strong\u003e, ideal para operaciones de alto volumen.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003e32PP\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eCapacidad: 946 ml (≈32 oz)\u003c\/li\u003e\n\u003cli\u003eUso recomendado: smoothies, malteadas, frappés, aguas frescas grandes, jugos con hielo\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\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\/V.P.P._32PP.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 32 PP 946 ml polipropileno grande para bebidas frías\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/vaso-32pp-946ml-pp?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":48147600998650,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/32.jpg?v=1768505186"},{"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":"fajilla-microcorrugada-faj-1","title":"Fajilla microcorrugada FAJ-1 para vaso de papel café caliente color kraft","description":"\u003cp\u003eLa \u003cstrong\u003efajilla microcorrugada FAJ-1\u003c\/strong\u003e es el complemento ideal para \u003cstrong\u003evasos de papel para café y bebidas calientes\u003c\/strong\u003e. Proporciona \u003cstrong\u003eprotección térmica\u003c\/strong\u003e, mejorando el agarre y evitando que el calor moleste a tus clientes al sostener el vaso.\u003c\/p\u003e\n\u003cp\u003eAdemás de su función de \u003cstrong\u003eaislamiento térmico\u003c\/strong\u003e, aporta una \u003cstrong\u003epresentación premium\u003c\/strong\u003e a tus bebidas y es una excelente opción para \u003cstrong\u003epersonalizar con tu marca\u003c\/strong\u003e mediante impresión o sello. Fabricada en \u003cstrong\u003ecartón microcorrugado resistente\u003c\/strong\u003e, en color \u003cstrong\u003ekraft natural\u003c\/strong\u003e, combina estética y funcionalidad en cafeterías y negocios de bebidas calientes.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eFAJ-1\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eUso: aislamiento térmico para vasos de papel con bebidas calientes\u003c\/li\u003e\n\u003cli\u003eBeneficios: protección térmica, mejor agarre, presentación premium\u003c\/li\u003e\n\u003cli\u003ePersonalización: opción de personalizar con tu marca\u003c\/li\u003e\n\u003cli\u003eColor: kraft natural\u003c\/li\u003e\n\u003cli\u003eMaterial: cartón microcorrugado resistente\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\/FAJILLAS.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: 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   = \"Fajilla microcorrugada FAJ-1\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/fajilla-microcorrugada-faj-1?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":48147605225722,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/34.jpg?v=1768505242"},{"product_id":"servilletas-impresas-1-tinta-ser-eco-im","title":"Servilletas impresas 1 tinta SER-ECO-IM 12 x 12.5 cm papel tissue blanco","description":"\u003cp\u003eLas \u003cstrong\u003eservilletas impresas SER-ECO-IM\u003c\/strong\u003e están elaboradas en \u003cstrong\u003epapel tissue de alta calidad\u003c\/strong\u003e, suave, absorbente y pensado para el \u003cstrong\u003euso diario en negocios de alimentos\u003c\/strong\u003e. Sus medidas de \u003cstrong\u003e12 x 12.5 cm\u003c\/strong\u003e las hacen prácticas para \u003cstrong\u003ecafeterías, restaurantes, food trucks y servicios para llevar\u003c\/strong\u003e.\u003c\/p\u003e\n\u003cp\u003eSu \u003cstrong\u003ecolor blanco natural\u003c\/strong\u003e permite que la \u003cstrong\u003eimpresión en una sola tinta\u003c\/strong\u003e destaque de manera \u003cstrong\u003elimpia, nítida y profesional\u003c\/strong\u003e, ideal para \u003cstrong\u003ereforzar la identidad de tu marca\u003c\/strong\u003e en cada mesa o pedido.\u003c\/p\u003e\n\u003cp\u003eSon una \u003cstrong\u003eopción práctica y personalizada\u003c\/strong\u003e que \u003cstrong\u003eeleva la presentación de tu negocio\u003c\/strong\u003e sin perder funcionalidad, generando una experiencia más cuidada para tus clientes.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLAVE: \u003cstrong\u003eSER-ECO-IM\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMedidas: \u003cstrong\u003e12 cm x 12.5 cm\u003c\/strong\u003e\n\u003c\/li\u003e\n\u003cli\u003eMaterial: papel tissue de alta calidad\u003c\/li\u003e\n\u003cli\u003eCaracterísticas: suave, absorbente, ideal para uso diario\u003c\/li\u003e\n\u003cli\u003eColor de servilleta: blanco natural\u003c\/li\u003e\n\u003cli\u003eImpresión: 1 tinta, acabado nítido y elegante\u003c\/li\u003e\n\u003cli\u003eUso recomendado: cafeterías, restaurantes, bares, food trucks, delivery\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\/SERVILLETAS_IMPRESAS.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: 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   = \"Servilletas impresas 1 tinta SER-ECO-IM\";\n      var productUrl     = \"https:\/\/acesainter.com\/products\/servilletas-impresas-1-tinta-ser-eco-im?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":48148342571258,"sku":null,"price":10.0,"currency_code":"MXN","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/files\/57.jpg?v=1768506134"}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0794\/9883\/8266\/collections\/Coleccion_Accesorios_para_cafeterias_Accesa_Interabasto.jpg?v=1766167387","url":"https:\/\/acesainter.com\/collections\/accesorios-para-cafeterias.oembed?page=7","provider":"ACESA INTERABASTO S. A. de C.V.","version":"1.0","type":"link"}