
- Base líquida
Base Matte de Alta Cobertura Payot
- R$ 69,90
- Este produto tem várias variantes. As opções podem ser escolhidas na página do produto
FavoritarFavoritar
(function () { 'use strict'; const LIST_SELECTORS = [ '.woocommerce ul.products', '.related.products ul.products', '.upsells.products ul.products', '.cross-sells ul.products' ]; function $all(root, sel) { try { return Array.from((root || document).querySelectorAll(sel)); } catch(e){ return []; } } // Espera todas as imagens de um container decodificarem (medição correta) function waitImages(container) { const imgs = $all(container, 'img'); const ps = imgs.map(img => { if (img.complete && img.naturalWidth > 0) return Promise.resolve(); if (img.decode) return img.decode().catch(()=>{}); return new Promise(res => { img.addEventListener('load', res, {once:true}); img.addEventListener('error', res, {once:true}); }); }); return Promise.all(ps); } function findLists(root) { if (root && root.matches && root.matches('ul.products')) return [root]; const lists = []; LIST_SELECTORS.forEach(sel => { $all(document, sel).forEach(ul => lists.push(ul)); }); return lists; } function resetItem(li) { li.style.display = ''; li.style.flexDirection = ''; const wrap = li.querySelector('.woocommerce-LoopProduct-link'); if (wrap) { wrap.style.display = ''; wrap.style.flexDirection = ''; wrap.style.flex = ''; } const title = li.querySelector('.woocommerce-loop-product__title'); const price = li.querySelector('.price'); if (title) title.style.minHeight = ''; if (price) price.style.minHeight = ''; const btn = li.querySelector('a.button, .added_to_cart'); if (btn) btn.style.marginTop = ''; } // Define variáveis CSS por lista e usa min-height via CSS nos cards async function equalizeList(ul) { const items = $all(ul, 'li.product'); if (!items.length) return; // Aguarda imagens para medir de forma confiável await waitImages(ul); items.forEach(li => { resetItem(li); li.style.display = 'flex'; li.style.flexDirection = 'column'; const wrap = li.querySelector('.woocommerce-LoopProduct-link'); if (wrap) { wrap.style.display = 'flex'; wrap.style.flexDirection = 'column'; wrap.style.flex = '1 1 auto'; } const btn = li.querySelector('a.button, .added_to_cart'); if (btn) btn.style.marginTop = 'auto'; }); let titleMax = 0; let priceMax = 0; items.forEach(li => { const title = li.querySelector('.woocommerce-loop-product__title'); const price = li.querySelector('.price'); if (title) { const h = title.getBoundingClientRect().height; if (h > titleMax) titleMax = h; } if (price) { const h = price.getBoundingClientRect().height; if (h > priceMax) priceMax = h; } }); // Variáveis por UL – cada grade pode ter alturas próprias ul.style.setProperty('--sv-title-min', titleMax ? `${titleMax}px` : 'auto'); ul.style.setProperty('--sv-price-min', priceMax ? `${priceMax}px` : 'auto'); } function equalizeAll(root) { const lists = findLists(root); if (!lists.length) return; lists.forEach(equalizeList); } // Agenda com RAF (evita rodar 100x durante mudanças) let rafId; function schedule(root) { if (rafId) cancelAnimationFrame(rafId); rafId = requestAnimationFrame(() => equalizeAll(root)); } // Observa novas entradas no DOM (Carregar mais, Ajax, Relacionados, etc.) const mo = new MutationObserver(muts => { let touch = false; for (const m of muts) { if (touch) break; m.addedNodes.forEach(n => { if (n.nodeType !== 1) return; if (n.matches && (n.matches('li.product') || n.matches('ul.products'))) touch = true; else if (n.querySelector && n.querySelector('li.product, ul.products')) touch = true; }); } if (touch) schedule(); }); mo.observe(document.body, { childList: true, subtree: true }); // Gancho em frameworks comuns (YITH, Jet, etc.) document.addEventListener('yith_infs_adding_elem', () => schedule()); document.addEventListener('yith_infs_loaded', () => schedule()); document.addEventListener('jet-filter-content-rendered', () => schedule()); document.addEventListener('jet-plugins/frontend/elementor/ajaxloaded', () => schedule()); document.addEventListener('woo_loadmore_success', () => schedule()); // Patch fetch / XHR pra agendar após qualquer Ajax const _fetch = window.fetch; window.fetch = function(){ return _fetch.apply(this, arguments).then(res=>{ try { res.clone().text().finally(schedule); } catch(e){} schedule(); return res; }); }; const _send = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(){ this.addEventListener('loadend', () => schedule(), {once:true}); _send.apply(this, arguments); }; // ResizeObserver: se as alturas mudarem depois (ex: fontes web), recalcula const ro = new ResizeObserver(() => schedule()); window.addEventListener('load', () => { findLists().forEach(ul => ro.observe(ul)); schedule(); }); window.addEventListener('resize', schedule); document.addEventListener('DOMContentLoaded', schedule); })();