Carrinho de compras
Seu carrinho está vazio

Atendimento

Frete Grátis

Compras Acima de 1200

Pague com Pix e Ganhe

10% de Desconto

Pague com cartão

em até 12x s/ juros

Tire suas dúvidas

por Whatsapp

Frete e Entrega

ÚLTIMA ATUALIZAÇÃO: 12 de Fevereiro de 2024

 Esta política de frete visa esclarecer nossas políticas e procedimentos relacionados ao método de envio, frete e responsabilidades da transportadora, foi criada com base no código de defesa do consumidor, com o objetivo de garantir paridade entre nós e nossos clientes.

Prazo de Recebimento

O prazo para o recebimento do seu pedido é composto por dois prazos, o prazo de envio que é o tempo que precisamos para processar o seu pedido e o prazo de transporte que é o prazo da transportadora efetuar a coleta, trafegar até o seu endereço e realizar a entrega.

Você pode verificar o nosso prazo de recebimento diretamente em nossa loja após informar seus dados de envio como o CEP por exemplo.

Prazo de Envio

Sempre que você faz uma compra e ela tem seu pagamento confirmado, nós precisamos de pelo menos 2 dias úteis para processar o seu pedido, precisamos fazer a parte de separação do estoque, embalagem, impressão de etiquetas, nota fiscal e por fim aguardar a coleta da transportadora.

Pedidos realizados até às 10h possuem grande chance de serem enviados no mesmo dia, caso contrário enviamos em até 2 dias úteis.

Prazo de Transporte

O prazo de Transporte é responsabilidade da transportadora, uma vez que a transportadora fez a coleta em nossa loja, nós não temos como interferir no processo de transporte da transportadora.

Constantemente estamos vigiando os envios para nos antecipar aos problemas, porém, caso identifique um atraso no seu pedido, pedimos que entre em contato através do nosso formulário de contato localizado em nosso site.

O prazo de transporte está sujeito a eventuais atrasos em função das condições climáticas, tráfego de aeroportos, greve de profissionais envolvidos, datas festivas, condições das rodovias e outros motivos de força maior.

O cumprimento do prazo de entrega é de inteira responsabilidade da transportadora e não nos responsabilizamos por atrasos de entrega, porém em caso de problemas comunique conosco pois sempre estamos dispostos a ajudar e conseguimos verificar informações mais rapidamente com a transportadora.

Modalidades de Entrega

Atualmente, trabalhamos com as seguintes empresas de transporte.

  • Correios
    • MINI ENVIOS (Encomenda Normal com preço menor) O Mini Envios é um método de envio bom para envio de pequenos objetos, tem um prazo de envio maior, porém o preço é bem acessível.
    • PAC (Encomenda Normal) O PAC é o envio de menor custo dos Correios, porém, costuma ter um prazo de envio mais demorado.
    • SEDEX (Encomenda Expressa) Sedex é o envio com custo maior, porém, o prazo é menor.

Código de Rastreamento

Quando você opta por frete por meio de uma empresa transportadora, ao efetuarmos o envio do produto é gerado um código de rastreamento, esse código é enviado para o seu e-mail e através desse código você pode acompanhar a chegada do seu pedido pelo site da empresa transportadora. Se você não recebeu o e-mail, verifique na caixa de SPAM do seu provedor de e-mails.

Proteção e Segurança

Nem sempre a gente consegue ficar tranquilo em 100% das encomendas e eventualmente ocorrem alguns problemas no processo de entrega. Caso você tenha algum problema com sua entrega fique tranquilo, pois em casos mais sérios como o de extravio ou roubo da sua encomenda, você não sofrerá nenhum tipo de prejuízo, pois assumimos toda a responsabilidade. Infelizmente quando isso ocorre você terá que esperar um tempo maior pelo recebimento e/ou reenvio.

Atrasos

Qualquer encomenda pode sofrer atrasos na entrega. Por vezes atrasam por motivo de chuvas, problemas climáticos em geral, outras vezes atrasam devido a falhas no serviço da empresa transportadora, excesso de encomendas para entregar, falta de pessoal, área com muito risco de assaltos, greve e etc.

Infelizmente nem todas as empresas de transporte oferecem formas de interferir no fluxo postal para retirar uma encomenda, cancelar a entrega ou acelerá-la. Nestes casos é preciso aguardar um pouco até a encomenda seguir seu trajeto novamente.

Caso sua encomenda sofra algum atraso, entre em contato conosco que iremos prontamente abrir um protocolo junto a empresa transportadora, informando do atraso e solicitando a urgência no encaminhamento.

Dica: Encomendas via SEDEX raramente sofrem atrasos. Opte por ela sempre que possível!

Extravio ou roubo de mercadoria

Se a encomenda está atrasando muito pode ser que tenha ocorrido um problema mais grave. A encomenda pode ter sido extraviada, perdida, desaparecida no fluxo postal. Ou então no trajeto/caminho da entrega, o carteiro pode ser assaltado. Nestes casos, tão logo a informação constar no rastreio do objeto, serão tomadas providências para o re-envio do seu pedido ou a realização da devolução do pagamento, conforme for do seu interesse ou conforme a disponibilidade do nosso estoque.

Avaria

Jamais receba um produto com sinais de violação ou avaria, recuse o recebimento e entre em contato conosco para informar. Assim que a caixa voltar para nosso estoque, verificaremos o ocorrido e também daremos prosseguimento ao reenvio do pedido ou caso desejar a devolução do valor. Caso tenha dúvidas sobre a devolução, consulte nossa política de cancelamento e devolução.

Notificação para retirar seu pedido nos Correios

Todas as encomendas são endereçadas para chegarem diretamente no endereço fornecido. Todavia em alguns casos você terá que retirar a encomenda na agência mais próxima do endereço fornecido. Isso pode ocorrer por 2 motivos básicos:

Motivo: O carteiro faz 3 tentativas de entrega, caso não tenha sucesso é deixado um protocolo no endereço indicado, informando que o produto está à disposição do cliente na agência de origem. Caso o cliente não retire a mercadoria no prazo informado no protocolo, a mercadoria retornará para o nosso estoque e você precisará arcar com o pagamento de um novo frete, caso não tenha interesse em continuar com o seu pedido, leia nossa política de devolução.

Motivo: Infelizmente devido a violência, algumas regiões são consideradas pelos Correios como Áreas de Restrição Temporária. Nessas áreas, muitas vezes a encomenda não é entregue diretamente no endereço fornecido por questões de segurança, o objetivo é proteger a encomenda por se tratar de região com altos índices de assaltos aos carteiros e carros dos Correios. Como essas áreas variam muito, só ficamos sabendo do ocorrido no mesmo momento que o nosso cliente, quando recebemos a informação pelo rastreamento de seu pedido. Por motivo de segurança você terá que retirar seu pedido na agência indicada. Caso a retirada não seja realizada, a mercadoria retornará para o nosso estoque e você precisará arcar com o pagamento de um novo frete de preferência escolhendo um novo endereço de entrega, caso não tenha interesse em continuar com o seu pedido, leia nossa política de devolução.

Nestes casos o valor do frete não é devolvido, pois este repasse também não é realizado pelos Correios.

Pedido consta como entregue mas não recebi

Já ocorreram alguns casos de clientes que receberam a informação que o pedido foi entregue mas eles não o receberam. O primeiro passo é verificar se o endereço fornecido no momento da compra estava correto. Em 100% dos casos a mercadoria havia sido entregue para o porteiro ou para um vizinho próximo que recebeu o pacote, porém por algum motivo não o entregou para o cliente no mesmo dia. Sendo assim, aconselhamos verificar com as pessoas de seu prédio e com os vizinhos, se alguém recebeu a encomenda por você. Se em até 1 dia você não achar sua encomenda, entre em contato conosco para que possamos abrir um chamado junto a empresa transportadora, onde será investigado a pessoa que assinou o documento no momento da entrega. Com o nome da pessoa em mãos teremos como saber quem está com sua mercadoria. Se você preencheu o endereço errado no momento da sua compra, leia o tópico seguinte.

Pedido pedido não foi entregue e está voltando

É de total responsabilidade do cliente o fornecimento do endereço correto e completo para envio dos produtos no ato da finalização do seu pedido. Caso a transportadora tenha algum problema para efetuar a entrega do seu pedido e o mesmo esteja voltando para nossa loja, colocamos a disposição as seguintes possibilidades:

A realização de um novo envio, o cliente será solicitado a realizar o pagamento de um novo frete para o reenvio dos produtos.

Cancelamento do pedido com reembolso parcial, poderá receber a devolução dos valores pagos referente apenas aos produtos, excetuando-se o montante referente ao valor do frete.

Não temos responsabilidade de realizar a verificação dos endereços e em caso de qualquer problema relacionado ao endereçamento, seja no erro do preenchimento dos campos, seja na informação dos endereços distintos, ou horário de atendimento para entrega, a responsabilidade em caso da não-entrega ou entrega em outro endereço é inteiramente do comprador.

 

';anchor.parentNode.insertBefore(bar,anchor);} var pct=Math.min(100,Math.round(val/FREE_SHIP*100)),rem=Math.max(0,FREE_SHIP-val); var html=(rem<=0)?(String.fromCodePoint(0x1F389)+' Você ganhou frete grátis!'):('Faltam '+brl(rem)+' para o frete grátis '+String.fromCodePoint(0x1F69A)); var key=html+'|'+pct+'|on'; if(bar.getAttribute('data-st')===key)return; /* nada mudou: não reescreve (evita re-disparar o observer) */ bar.setAttribute('data-st',key); bar.style.display=''; bar.classList.toggle('is-free',rem<=0); bar.querySelector('.ab-freeship__msg').innerHTML=html; bar.querySelector('.ab-freeship__fill').style.width=pct+'%'; } if(window.__abCart)return; window.__abCart=true; /* Frete grátis: acha a linha grátis na tabela de estimativa, realça, vira badge e move pro TOPO (a mais barata é grátis mas some no meio -> pessoa não vê). */ /* IMPORTANTE: regex 100% ASCII. O inline script e servido em iso-8859-1 e acentos viram mojibake (o [aa] com acento quebrava). "gr.tis" casa "gratis"/"gratis-com-acento" pois o "." casa o caractere do meio. */ function highlightFreeShipping(){ var tables=document.querySelectorAll('.shipping-rates-table'); var reFree=/gr.tis/i; for(var i=0;i✓ $1'); } } } } if(free && firstData && free!==firstData){ tbody.insertBefore(free, firstData); } /* Clarity: captura CEP (prefixo 5) + prazo do frete gratis, 1x por calculo, pra entender se prazo longo e distancia (CEP) ou transportadora lenta. */ if(window.clarity && free && !tables[i].__abTracked){ tables[i].__abTracked=true; try{ var cepEl=document.querySelector('#zip'); var cepv=cepEl?String(cepEl.value||'').replace(/\D/g,''):''; if(cepv.length>=8) window.clarity('set','frete_cep', cepv.slice(0,5)+'-'+cepv.slice(5,8)); var dm=(free.textContent||'').match(/(\d{2})\/(\d{2})\/(\d{4})/g); if(dm && dm.length){ var pp=dm[dm.length-1].split('/'); var days=Math.round((new Date(+pp[2],+pp[1]-1,+pp[0]) - new Date())/86400000); window.clarity('set','frete_prazo_dias', String(days)); window.clarity('set','frete_prazo', days<=3?'1-3 dias':days<=7?'4-7 dias':days<=14?'8-14 dias':'15+ dias'); } }catch(_){} } } } function run(){ /* realce do frete grátis na tabela de estimativa (produto) */ try{ highlightFreeShipping(); }catch(e){} /* nome do produto abreviado + "ler mais" no modal do carrinho */ try{ abTruncateNames(); }catch(e){} /* precos do order bump com centavos (BRL) */ try{ abFixRecPrices(); }catch(e){} /* "Finalizar compra" + "Limpar carrinho" no modal */ try{ abEnhanceCartModal(); }catch(e){} /* carrinho vazio: renomeia "Fechar carrinho" -> "Continuar comprando" (o texto vem do JS nativo do tema; so trocamos o texto, o handler de fechar continua o mesmo) */ try{ var rc=document.querySelector('.plugoo-cart-preview-sidebar .pg-return-nocart'); if(rc && /fechar/i.test(rc.textContent||'')) rc.textContent='Continuar comprando'; }catch(e){} /* acessibilidade: cards de noticia (blog) sao injetados por JS e o link da imagem (#noticia_imagem a) fica sem texto/alt -> leitor de tela nao entende. Aplicamos o titulo da noticia como aria-label do link + alt da imagem. Puramente aditivo. */ try{ abFixNewsA11y(); }catch(e){} /* modal nativo (popup de adicionar) */ var body=document.querySelector('.cart-preview-body'); if(body){ wire(body); update(body); var modal=(body.closest&&body.closest('.modal-content'))||body.parentElement; var msub=modal&&modal.querySelector('.cart-preview-subtotal'); if(msub) applyBar(modal, msub.textContent, body); } /* sidebar do tema (ícone do carrinho) */ var sb=document.querySelector('.plugoo-cart-preview-sidebar'); if(sb){ var sval=sb.querySelector('.cart-preview-footer .total .value'), content=sb.querySelector('.cart-preview-content'); if(sval&&content) applyBar(sb, sval.textContent, content); } } /* Acessibilidade dos cards de noticia do blog (injetados por JS): o link da imagem (#noticia_imagem a) envolve so a imagem, sem texto -> "link sem nome". Pegamos o titulo da noticia no card e usamos como aria-label do link + alt da imagem. So adiciona atributo quando falta; nunca sobrescreve nem remove nada. */ function abFixNewsA11y(){ var boxes=document.querySelectorAll('.box-noticia'); for(var i=0;i apos clicar comprar, re-buscamos e reinjetamos no modal. Tudo ASCII (mojibake). */ function refreshCartModalWithGifts(tries){ tries=tries||1; var cur=document.querySelector('.cart-preview-body'); if(!cur || /brinde/i.test(cur.textContent||'')) return; /* sem modal ou ja tem brinde */ var url=(typeof window.mountCartUrl==='function')?window.mountCartUrl():'/mvc/store/element/snippets/cart_preview/'; fetch(url,{headers:{'X-Requested-With':'XMLHttpRequest'}}).then(function(r){return r.arrayBuffer();}).then(function(buf){ var html; try{ html=new TextDecoder('iso-8859-1').decode(buf); }catch(_){ html=new TextDecoder().decode(buf); } var fresh=new DOMParser().parseFromString(html,'text/html').querySelector('.cart-preview-body'); var c=document.querySelector('.cart-preview-body'); if(!fresh||!c) return; if(/brinde/i.test(fresh.textContent||'')){ if(!/brinde/i.test(c.textContent||'')) c.innerHTML=fresh.innerHTML; } else if(tries<3){ setTimeout(function(){ refreshCartModalWithGifts(tries+1); }, 800); } }).catch(function(){}); } document.addEventListener('click', function(e){ var b=e.target && e.target.closest && e.target.closest('#button-buy, .botao-comprar'); if(b){ [700,1500,2600].forEach(function(ms){ setTimeout(function(){ try{refreshCartModalWithGifts(1);}catch(_){} }, ms); }); } }, true); /* Abre o MODAL NATIVO da Tray (.modal.cart-preview) com o order bump "Recomendamos para voce" -- o mesmo que aparece na pagina do produto. Passos: (1) re-busca o partial do carrinho (mountCartUrl) que ja traz item novo + brinde + order bump + recomendacoes, e reinjeta o MODAL INTEIRO (o order bump fica FORA do .cart-preview-body, entao trocar so o body nao bastava); (2) abre via Bootstrap modal('show'). Fallback: showCart (sidebar). Os handlers de remover ([data-cart-preview-del]) e checkout sao delegados no document -> sobrevivem a troca de innerHTML. Ja os forms do order bump (.related-product-buy-form) tem submit ligado DIRETO -> quebram; por isso ha um interceptor de submit mais abaixo que manda pro data-fallback (pagina do produto). Tudo ASCII por causa do mojibake iso-8859-1. */ function abOpenNativeCartModal(tries){ tries=tries||1; var showIt=function(){ try{ var lb=document.querySelector('.ab-buy-black.loading'); if(lb) lb.classList.remove('loading'); }catch(_){} try{ abTruncateNames(); }catch(_){} try{ abFixRecPrices(); }catch(_){} try{ abEnhanceCartModal(); }catch(_){} try{ if(window.jQuery && jQuery.fn && jQuery.fn.modal){ jQuery('.modal.cart-preview').modal('show'); return; } }catch(_){} try{ if(window.cart && cart.showCart){ cart.showCart(); } }catch(_){} }; /* mountCartUrl e definido por um script nativo que as vezes ainda nao carregou no clique (fica undefined) -> por isso usamos o path fixo do partial como fallback (a sessao vai pelo cookie, nao pela URL). */ var url=(typeof window.mountCartUrl==='function')?window.mountCartUrl():'/mvc/store/element/snippets/cart_preview/'; fetch(url,{headers:{'X-Requested-With':'XMLHttpRequest'}}).then(function(r){return r.arrayBuffer();}).then(function(buf){ var html; try{ html=new TextDecoder('iso-8859-1').decode(buf); }catch(_){ html=new TextDecoder().decode(buf); } var fresh=new DOMParser().parseFromString(html,'text/html').querySelector('.modal.cart-preview'); /* se o add ainda nao propagou (partial vazio), re-tenta antes de mostrar */ if(fresh){ var freshEmpty = /vazio/i.test(fresh.textContent||'') || fresh.querySelectorAll('.cart-preview-item').length===0; if(freshEmpty && tries<=6){ setTimeout(function(){ abOpenNativeCartModal(tries+1); }, 300); return; } } var live=document.querySelector('.modal.cart-preview'); if(fresh && live){ live.innerHTML=fresh.innerHTML; } showIt(); }).catch(function(){ showIt(); }); } /* Order bump reinjetado: o submit nativo do .related-product-buy-form fica ligado direto no form, entao ao trocar o innerHTML ele quebra e faria um POST bruto (pagina de erro). Interceptamos aqui (delegado no document -> sobrevive): - SEM variacao obrigatoria (data-required-variant vazio) -> adiciona DIRETO no carrinho via /web_api/cart e recarrega o modal (nao sai da pagina); - COM variacao (data-required-variant="1") -> vai pro data-fallback (pagina do produto), pois nao da pra adivinhar qual variacao adicionar. */ document.addEventListener('submit', function(e){ var f=e.target && e.target.closest && e.target.closest('.modal.cart-preview .related-product-buy-form'); if(!f) return; e.preventDefault(); if(f.getAttribute('data-busy')) return; var reqVar=f.getAttribute('data-required-variant'); var fallback=f.getAttribute('data-fallback'); if(reqVar==='1'){ if(fallback) window.location.href=fallback; return; } var pidEl=f.querySelector('input[name="product_id"]'); var pid=pidEl?pidEl.value:''; if(!pid){ if(fallback) window.location.href=fallback; return; } var qtyEl=f.querySelector('input[name="quant"], input[name="quantity"]'); var qty=(qtyEl && qtyEl.value)?qtyEl.value:'1'; var session=document.querySelector('html').getAttribute('data-session'); f.setAttribute('data-busy','1'); setTimeout(function(){ f.removeAttribute('data-busy'); }, 2500); var buyBtn=f.querySelector('.buy-link, button[type="submit"]'); if(buyBtn) buyBtn.classList.add('loading'); fetch('/web_api/cart/',{method:'POST',headers:{'Content-Type':'application/json; charset=utf-8'},body:JSON.stringify({Cart:{session_id:session,product_id:pid,quantity:qty}})}) .then(function(r){ return r.json(); }) .then(function(){ abOpenNativeCartModal(); }) .catch(function(){ if(buyBtn) buyBtn.classList.remove('loading'); if(fallback) window.location.href=fallback; }); }, true); /* Setas do order bump reinjetado: sem slick, as setas nativas (.related-product-custom-*) ficam mortas. Ligamos aqui (rola o trilho em 1 "pagina" = clientWidth). So atua quando o slick nao inicializou -> na pagina do produto o slick nativo cuida das setas. */ document.addEventListener('click', function(e){ var pv=e.target.closest && e.target.closest('.modal.cart-preview .related-products-wrapper:not(.slick-initialized) .related-product-custom-prev'); var nx=e.target.closest && e.target.closest('.modal.cart-preview .related-products-wrapper:not(.slick-initialized) .related-product-custom-next'); if(!pv && !nx) return; e.preventDefault(); var wrap=(pv||nx).closest('.related-products-wrapper'); var track=wrap && wrap.querySelector('.related-product-slide-content'); if(!track) return; var step=track.clientWidth || 300; var max=track.scrollWidth - track.clientWidth; var target=track.scrollLeft + (nx ? step : -step); target=Math.max(0, Math.min(target, max)); /* smooth nao funciona neste elemento (snap); animamos manualmente via rAF */ var start=track.scrollLeft, dist=target-start, t0=null, dur=280; function anim(ts){ if(!t0) t0=ts; var p=Math.min((ts-t0)/dur,1); track.scrollLeft=start+dist*(0.5-Math.cos(p*Math.PI)/2); if(p<1) requestAnimationFrame(anim); } requestAnimationFrame(anim); }, true); /* Nome do produto no carrinho: os nomes sao longos (6+ linhas). Trunca em 30 chars por padrao e injeta um "ler mais"/"ler menos". Usa … (…) em ASCII pra evitar mojibake iso-8859-1. Roda no modal nativo (produto e vitrine) -> igual nos dois. */ var AB_NAME_LIMIT=25; var AB_TRASH_SVG=''; function abTruncateNames(){ var items=document.querySelectorAll('.modal.cart-preview .cart-preview-item'); for(var i=0;iAB_NAME_LIMIT){ el.setAttribute('data-full', full); el.textContent=full.slice(0,AB_NAME_LIMIT).trim()+'\u2026'; var btn=document.createElement('span'); btn.className='ab-ler-mais'; btn.textContent='ler mais'; btn.setAttribute('data-exp','0'); /* logo depois do nome -> "nome… ler mais" na 1a linha; a cor (small block) cai na linha de baixo naturalmente */ el.insertAdjacentElement('afterend', btn); } } var del=item.querySelector('.cart-preview-item-delete'); if(del && !del.__abTrash){ del.__abTrash=1; del.classList.add('ab-trash'); del.setAttribute('title','Remover'); del.innerHTML=AB_TRASH_SVG; } } } /* Precos do order bump ("Recomendamos") vem crus do partial: principal em [data-reference^="price-"] (ex "219") e original em .related-product-original-price span (ex "299.99") -- sem centavos e com ponto. Reformata pra BRL (219,00 / 299,99). */ function abFixRecPrices(){ var modal=document.querySelector('.modal.cart-preview'); if(!modal) return; var sps=modal.querySelectorAll('.related-product-principal-price [data-reference^="price-"], .related-product-principal-price span, .related-product-original-price span'); for(var i=0;i ignora */ sp.__abPrice=1; var n=parseFloat(raw); if(isNaN(n)) continue; sp.textContent=n.toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2}); } } /* Modal do carrinho: (1) "Avancar" -> "Finalizar compra" (consistente com o carrinho lateral); (2) injeta "Limpar carrinho" no fim do rodape (igual o lateral tem). */ function abEnhanceCartModal(){ var modal=document.querySelector('.modal.cart-preview'); if(!modal) return; var av=modal.querySelector('.botao-prosseguir-compra .botao-commerce-img'); if(av && /avan/i.test(av.textContent||'')) av.textContent='Finalizar compra'; /* "Limpar carrinho" a esquerda do Subtotal (o CSS poe a linha em flex) */ var subt=modal.querySelector('.cart-preview-subtotal'); if(subt && !subt.querySelector('.ab-limpar-modal')){ var btn=document.createElement('button'); btn.type='button'; btn.className='ab-limpar-modal'; btn.textContent='Limpar carrinho'; subt.insertBefore(btn, subt.firstChild); } /* order bump: itens COM variacao (data-required-variant=1) nao podem ser adicionados direto (nao da pra saber a cor), entao o botao vai pra pagina do produto -> deixamos o texto "Escolher cor" (igual a vitrine), mais claro que "Adicionar"/"Comprar". */ modal.querySelectorAll('.related-product-buy-form[data-required-variant="1"] .buy-link, .related-product-buy-form[data-required-variant="1"] button[type="submit"]').forEach(function(bb){ if(bb.__abRelabel) return; bb.__abRelabel=1; var t=(bb.textContent||'').trim(); if(t && !/escolher/i.test(t)) bb.textContent='Escolher cor'; }); } /* Limpar carrinho (modal): usa o clearProduct nativo e fecha o modal (o clearProduct atualiza o lateral, nao o modal -> fechamos pra nao ficar conteudo velho). */ document.addEventListener('click', function(e){ var t=e.target && e.target.closest && e.target.closest('.ab-limpar-modal'); if(!t) return; e.preventDefault(); try{ if(window.cart && cart.clearProduct) cart.clearProduct(); }catch(_){} try{ if(window.jQuery && jQuery.fn && jQuery.fn.modal) jQuery('.modal.cart-preview').modal('hide'); }catch(_){} }, true); document.addEventListener('click', function(e){ var t=e.target && e.target.closest && e.target.closest('.ab-ler-mais'); if(!t) return; e.preventDefault(); e.stopPropagation(); var box=t.closest('.cart-preview-item-name-box')||t.parentElement; var el=box && box.querySelector('.cart-preview-item-name'); if(!el) return; var full=el.getAttribute('data-full')||''; if(t.getAttribute('data-exp')==='1'){ el.textContent=full.slice(0,AB_NAME_LIMIT).trim()+'\u2026'; t.textContent='ler mais'; t.setAttribute('data-exp','0'); } else { el.textContent=full; t.textContent='ler menos'; t.setAttribute('data-exp','1'); } }, true); /* Vitrine: "Comprar (Preta)" no produto SOLO com variacao -> adiciona a variante preta via /web_api/cart (o quick-buy nativo nao passa variacao) e abre o carrinho. variant_id vem do data-variant (a preta = reference == SKU do produto). Tudo ASCII. */ document.addEventListener('click', function(e){ var b = e.target && e.target.closest && e.target.closest('.ab-buy-black'); if(!b) return; e.preventDefault(); if(b.getAttribute('data-busy')) return; b.setAttribute('data-busy','1'); setTimeout(function(){ b.removeAttribute('data-busy'); }, 2500); /* feedback igual ao botao nativo do kit: classe 'loading' esconde o texto e mostra o spinner (.botao.loading::after). Removida quando o modal abre (dentro do showIt). */ b.classList.add('loading'); var pid=b.getAttribute('data-product'), vid=b.getAttribute('data-variant'); var box=b.closest('.actions')||b.closest('.flex')||b.parentElement; var qtyEl=box?box.querySelector('input[name="qty"]'):null; var qty=(qtyEl && qtyEl.value)?qtyEl.value:'1'; var session=document.querySelector('html').getAttribute('data-session'); fetch('/web_api/cart/',{method:'POST',headers:{'Content-Type':'application/json; charset=utf-8'},body:JSON.stringify({Cart:{session_id:session,product_id:pid,quantity:qty,variant_id:vid}})}) /* Guarda o STATUS HTTP junto do corpo. ⚠️ ARMADILHA: no SUCESSO a Tray devolve 201 {message:'Created', id, code:201}. O `code` no sucesso é 201 (nao é erro!) — por isso NAO da pra usar `j.code` como sinal de erro (dava falso "Indisponivel" mesmo adicionando). Sinal de erro correto = HTTP >=400 OU corpo com Bad Request/causes. Erro de estoque = HTTP 400 {code:400,name:'Bad Request',causes:[...]}. */ .then(function(r){ return r.json().then(function(j){ return {ok:r.ok, status:r.status, j:j}; }, function(){ return {ok:r.ok, status:r.status, j:null}; }); }) .then(function(res){ var j = res.j || {}; var failed = !res.ok || j.name === 'Bad Request' || (j.causes && j.causes.length); if(failed){ b.classList.remove('loading'); var cz = (j.causes && j.causes.join ? j.causes.join(' ') : '') || ''; var esgot = /estoque|esgot|indispon/i.test(cz); b.textContent = esgot ? 'Preta esgotada' : 'Indisponivel'; b.style.opacity = '.55'; b.style.pointerEvents = 'none'; /* volta ao normal depois de alguns segundos (cliente pode usar "Escolher cor" ao lado) */ setTimeout(function(){ b.textContent = 'Comprar (Preta)'; b.style.opacity = ''; b.style.pointerEvents = ''; }, 4000); return; } b.textContent='Adicionado'; b.classList.add('ab-added'); abOpenNativeCartModal(); }) .catch(function(){ b.classList.remove('loading'); }); }, true); /* Vitrine: abrir o carrinho tambem no fastBuy (Comprar / Comprar (Preta) do kit), pra ficar consistente com o botao do solo. Delay pequeno pro add completar. Mira so os forms de compra-rapida da vitrine (nao o #button-buy da pagina do produto). */ document.addEventListener('click', function(e){ var f=e.target && e.target.closest && e.target.closest('form.add-to-cart[data-app="product.buy-button"]'); if(!f) return; setTimeout(abOpenNativeCartModal, 1600); }, true); /* Carrinho sidebar: "Continuar comprando" fecha o carrinho e volta a comprar. Tenta store.continueShopping(); fallback: clica a seta de voltar ou o overlay. */ document.addEventListener('click', function(e){ var b=e.target && e.target.closest && e.target.closest('.ab-continuar-comprando'); if(!b) return; e.preventDefault(); try{ if(window.store && typeof store.continueShopping==='function'){ store.continueShopping(); return; } }catch(_){} var back=document.querySelector('.plugoo-cart-preview-sidebar .pg-return-cart'); if(back){ back.click(); return; } var shadow=document.querySelector('.shadow-cart'); if(shadow){ shadow.click(); } }, true); if(document.body){boot();}else{document.addEventListener('DOMContentLoaded',boot);} })();