Search for products, concerns and keywords.


Your Brand Consultant Agreement has been successfully renewed.
There was a problem processing your Brand Consultant Agreement renewal. Please try again.
There was a system error. Please try again.
There was an issue adding this product. Please refresh the page and try again
You're saving 10% on your entire order, including subscription orders and one-time purchases!

Be a product of the product! Schedule convenient, monthly deliveries of your favorite R+F products at the discounted Consultant price.

Join PC Perks for Free
  • Free gift ($50+ value) with 2nd qualifying order + exclusive offers
  • Fully flexible subscription: Choose delivery frequency and delay or cancel anytime before shipment
Item has been added to your bag.
This field is required.
Home | ESSENTIALS Instant Makeup Remover Wipes
  • ESMRW01_1168x1168_MOBILE.jpg

ESSENTIALS Instant Makeup Remover Wipes

$31.00

60 Day Money Back Guarantee

Don't love it? It's on us. Learn More

60 Day Money Back Guarantee

Don't love it? It's on us. Learn More

Wipe the day away. Super-soft cloths gently and effectively dissolve long-wearing makeup, dirt + oil in just a few swipes with no residue or need to rinse.

Size: 2-pack, 30 towelettes each

DETAILS

What it is: A pack of 2 of our ultra-soft cloths that gently and effectively dissolve makeup, including long-wearing lipstick and foundation. This powerful makeup remover is specifically formulated to prepare skin for your R+F Regimen in just a few swipes.

Why you need it: Wearing makeup or other products to bed can cause buildup of dirt and oil. These ultra-soft cloths are non-irritating and let you get the most out of your regimen, even on the go.

ITEM NUMBER: ESMRW01

SKIN TYPE

Suitable for all skin types, even most sensitive

KEY BENEFITS

Ultra-soft and non-irritating cloths to dissolve dirt and impurities

INGREDIENTS

View All Ingredients
You May Also Like

ESSENTIALS Complete Eye Makeup Remover
Dual-phase formula easily erases eye makeup including waterproof mascara.

Defend Against Sun Exposure

ESSENTIALS Face + Body Sunscreen Broad Spectrum SPF 50
Defend against UV rays with broad spectrum protection for your entire face + body.

HOW TO USE

Use by gently wiping face to remove makeup. Do not use around the eyes and no need to rinse. Dispose of cloth in trash receptacle.
 

HOW TO USE

Use by gently wiping face to remove makeup. Do not use around the eyes and no need to rinse. Dispose of cloth in trash receptacle.
 

View Less View More

You May Also Like

ESSENTIALS Complete Eye Makeup Remover
Dual-phase formula easily erases eye makeup including waterproof mascara.

Defend Against Sun Exposure

ESSENTIALS Face + Body Sunscreen Broad Spectrum SPF 50
Defend against UV rays with broad spectrum protection for your entire face + body.

Reviews

(function() { 'use strict'; // ============================================ // CONFIGURATION - EDIT THESE VALUES // ============================================ const marketingCards = [ // ============================================ // MARKETING CARDS - EVERGREEN - "Lash Day Offer" // ============================================ { // URLS to match for immediate render urlMatches: ['beauty-enhancements','lash-serum-and-eyebrow-tint'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'YOUR LASHES.
BUT BETTER.
', bodyText: 'Celebrate National Lash Day with a boost. Get 20% off Lash Boost + a FREE Mini Eye Cream, for a limited time.', ctaText: 'USE CODE LASHDAY', ctaHref: '/shop/r-f-lash-boost/p/ENHLSH01', cardHref: '/shop/r-f-lash-boost/p/ENHLSH01', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/LASH-DAY-marketing-module-horizontal-image.jpg?context=bWFzdGVyfGltYWdlc3wxMTMwOTh8aW1hZ2UvanBlZ3xhRGczTDJneFppOHlPRFExTVRReE1UY3lNakkzTUM5TVFWTklMVVJCV1MxdFlYSnJaWFJwYm1jdGJXOWtkV3hsWDJodmNtbDZiMjUwWVd4ZmFXMWhaMlV1YW5CbnxhNTZkMTEyODgxNzdhM2NkNGQxODNkYmRjNWRkNGUyZDVjYjNmYjRlYWQxZjc0NjRhMGJjMjZjZjI5N2Y2YTI0', backgroundColor: '#FFFFFF', // Used only if backgroundImage is null copyBackgroundColor: '#FFFFFF', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Pure C Promo MC" // ============================================ { // URLS to match for immediate render urlMatches: ['best-sellers','redefine','skin-care-regimens'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'LIMITED-TIME: PURE C EXCLUSIVE OFFERS', bodyText: 'Pair with Active Hydration Serum and save $45 or buy Pure C, get a complimentary Hydra Mask ($54 Value)', ctaText: 'Shop Now', ctaHref: '/category/face-serums', cardHref: '/category/face-serums', disclaimerText: 'Valid thru 2/28/26. See Terms & Conditions', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Pure-C-Promo-Marketing-Module.jpg?context=bWFzdGVyfGltYWdlc3w2NTk0MHxpbWFnZS9qcGVnfGFESXdMMmhoWmk4eU9ETTVOems1TnpjeE9UVTRNaTlRZFhKbExVTXRVSEp2Ylc4dFRXRnlhMlYwYVc1bkxVMXZaSFZzWlM1cWNHY3xhNmFmZWY2YjU3MzM5ZWY2NWNlN2Q5Njk1MWFjYTY1MzE0MWI4NzQ3OWY1YWUyNTM0NDY4YzUwMzcyYzcwY2Mz', backgroundColor: '#FFFFFF', // Used only if backgroundImage is null copyBackgroundColor: '#FFFFFF', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Pure C Evergreen MC" // ============================================ { // URLS to match for immediate render urlMatches: ['face-serums','anti-aging-skin-care'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'NEW PURE C SERUM', bodyText: 'Activate your skin’s longevity for firmer, smoother, brighter skin...now and for years to come', ctaText: 'Learn More', ctaHref: '/discover/purec', cardHref: '/discover/purec', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Pure-C-Evergreen-Marketing-Module.jpg?context=bWFzdGVyfGltYWdlc3w5MjQxOXxpbWFnZS9qcGVnfGFEVXhMMmhoTlM4eU9ETTVOems1TnpRMU56UXpPQzlRZFhKbExVTXRSWFpsY21keVpXVnVMVTFoY210bGRHbHVaeTFOYjJSMWJHVXVhbkJufDNkZTgzNTUzYTFjY2QwMjY2OWVlZjljODYwZmNjYWY5YzRmNGFjNWE2Y2I3YjM4YjczNTdjODhmOTQzZDcwMDY', backgroundColor: '#FFFFFF', // Used only if backgroundImage is null copyBackgroundColor: '#FFFFFF', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Money Back Guarantee" // ============================================ { // URLS to match for immediate render urlMatches: ['exfoliants','eye-creams-and-treatments','neck-and-decollete','reverse','soothe','unblemish'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'Love it or get your money back.', bodyText: 'We stand behind our science, formulas + results with a 60-Day Money Back Guarantee.', ctaText: 'Learn More', ctaHref: '/satisfaction-guarantee', cardHref: '/satisfaction-guarantee', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/60-day-Guarantee.jpg?context=bWFzdGVyfGltYWdlc3wyNDc0OTd8aW1hZ2UvanBlZ3xhREppTDJnek1TOHlPRE01TnprNU5qRTBOamN4T0M4Mk1DMWtZWGt0UjNWaGNtRnVkR1ZsTG1wd1p3fDM1ZDU3NGEwZDllNWMxZDUwYzk1NDJhZjMwNGZkM2Y5NGEwMmM3NTQ2MzhjYTI0ZDk2NWQ4ZjJlOTY2NTJmYWE', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "#1 Female Dermatologist Founded Skincare Brand" // ============================================= { // URLS to match for immediate render urlMatches: ['acne-pores-blackheads-skin-care','dry-skin-care','skin-care-essentials','face-moisturizers','lip-care-and-color','sensitive-skin-care','sun-protection','toners','uneven-skin-tone-and-dark-marks-skin-care'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: '#1 Female Dermatologist Founded Skincare Brand in the U.S.*', bodyText: '', ctaText: 'Learn More', ctaHref: '/nx/our-story', cardHref: '/nx/our-story', disclaimerText: '*Source Euromonitor Int’l Ltd. 2024; See rodanandfields.com for details.', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Female-Derm.jpg?context=bWFzdGVyfGltYWdlc3wyNDQ2MTR8aW1hZ2UvanBlZ3xhR1k1TDJnellTOHlPRE01TnprNU5qUXdPRGcyTWk5R1pXMWhiR1V0UkdWeWJTNXFjR2N8NDc0NTdhYzliNzNhMTA3ZGJkYzc5NzVmNjMzNzcyMGUwYzE5OGQzMDk3MDE3ZWRhNTk2NTM3ZjZlZGZhNjdjMQ', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Rodan + Fields is the #1 Premium Lash Serum" // ============================================= { // URLS to match for immediate render urlMatches: [], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'Rodan + Fields is the #1 Premium Lash Serum Brand in the US in 2024*', bodyText: '', ctaText: '', ctaHref: '', cardHref: '', disclaimerText: '*Source Euromonitor International Limited; Custom research conducted June-Aug 2025, retail value RSP terms; all channels; Lash Serum including Lash Serum products sold as part of Sets and Kits', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Lash-Boost-MC-Image.jpg?context=bWFzdGVyfGltYWdlc3wyMDE1Mjd8aW1hZ2UvanBlZ3xhRFJsTDJneU1DOHlPRE01TnprNU5UZzRORFUzTkM5TVlYTm9MVUp2YjNOMExVMURMVWx0WVdkbExtcHdad3w2MTVjMTdmN2Q2MDJlYmIzMzhmOWQ2OTg0MmRlNTFiODg5N2Q5OTBhNDFlODQwMmNjODliMzM3Yjk3NGJiNjIz', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' }, // ============================================ // MARKETING CARDS - EVERGREEN - "Klarna" // ============================================= { // URLS to match for immediate render urlMatches: ['regimen-sets','rf-paired-multi-action-regimens','skin-care-tools-and-accessories'], // PLACEMENT: Choose ONE method (comment out the others) insertAtPosition: 3, // Insert AFTER this position in the grid // insertAfterProductCode: 'HRVRGG01', // Insert AFTER this CAT ID // insertBeforeProductCode: 'HAAGR', // OR insert BEFORE this CAT ID // POSITION: 'Start' or 'End' (if not set, uses insertAtPosition. If insertAtPosition exceeds product count, defaults to 'End') // placement: 'End', // 'Start' or 'End' titleText: 'Buy now. Pay later.', bodyText: 'Select Klarna at checkout to split your purchase into 4 interest-free payments.', ctaText: '', ctaHref: '', cardHref: '', disclaimerText: '', textShadowEnabled: false, // BACKGROUND: Image URL or null for solid color backgroundImage: 'https://www.rodanandfields.com/en-us/medias/Klarna.jpg?context=bWFzdGVyfGltYWdlc3wzMTE3NnxpbWFnZS9qcGVnfGFETmlMMmc1TVM4eU9ETTVOems1T1RFMk1UTTNOQzlMYkdGeWJtRXVhbkJufDUwMzJkNzBjNzRjZmMxYzc2MjE5NWEyNjIwOTJmYzg5ZDE1NjQ1Y2U4MDQ3ZTg2OTI3ZjIxMzE1OGU3OGE2NWI', backgroundColor: '#F5F4F2', // Used only if backgroundImage is null copyBackgroundColor: '#F5F4F2', splitImageHalf: true, // LAYOUT copyAlign: 'left' } ]; // ============================================ // MODULE HTML GENERATOR // ============================================ function generateModuleHTML(cfg) { const alignMap = { left: 'flex-start', center: 'center', right: 'flex-end' }; const safeAlign = ['left','center','right'].includes(cfg.copyAlign) ? cfg.copyAlign : 'center'; const bgStyle = cfg.backgroundImage ? `background: url('${cfg.backgroundImage}') center/cover no-repeat;` : `background: ${cfg.backgroundColor}`; const shadowStyle = cfg.textShadowEnabled ? 'text-shadow: 0 1px 2px rgba(0,0,0,0.6);' : ''; // Split Image Half Layout if (cfg.splitImageHalf) { const splitImageStyle = `${cfg.backgroundImage ? `--split-image-url: url('${cfg.backgroundImage}');` : ''}`; const cardAttr = cfg.cardHref ? `data-card-href="${cfg.cardHref}"` : ''; const cardClass = cfg.cardHref ? ' rf-card-clickable' : ''; return `

${cfg.titleText.replace(/\n/g, '
')}

${cfg.bodyText ? `

${cfg.bodyText}

` : ''} ${cfg.ctaText && cfg.ctaText.trim() ? `${cfg.ctaText}` : ''} ${cfg.disclaimerText ? `
${cfg.disclaimerText}
` : ''}
`; } // Default horizontal layout const cardAttr = cfg.cardHref ? `data-card-href="${cfg.cardHref}"` : ''; const cardClass = cfg.cardHref ? ' rf-card-clickable' : ''; return `

${cfg.titleText.replace(/\n/g, '
')}

${cfg.bodyText ? `

${cfg.bodyText}

` : ''} ${cfg.ctaText && cfg.ctaText.trim() ? `${cfg.ctaText}` : ''} ${cfg.disclaimerText ? `
${cfg.disclaimerText}
` : ''}
`; } // PDP detection helper function isPDP() { try { const path = (window.location && window.location.pathname) || ''; // PDP URLs include "/p/" followed by a code return path.includes('/p/'); } catch (e) { return false; } } // Return cards whose urlMatches match a full path segment (not substring) function getActiveCards() { const href = (window.location && window.location.href || '').toLowerCase(); const path = (window.location && window.location.pathname || '').toLowerCase(); const segments = path.split('/').filter(Boolean); // path parts without empty strings const matchesSegment = (needle) => { if (!needle) return false; const n = String(needle).toLowerCase(); // exact segment match, or common category patterns return segments.includes(n) || path.endsWith('/' + n) || path.includes('/shop/' + n + '/') || href.includes('cgid=' + encodeURIComponent(n)); }; return marketingCards.filter(card => Array.isArray(card.urlMatches) && card.urlMatches.some(matchesSegment)); } // ============================================ // PRODUCT DETECTION // ============================================ let injected = false; function filterProductElements(elements) { return elements.filter(el => { const tag = el.tagName ? el.tagName.toLowerCase() : ''; if (tag === 'button' || tag === 'a') return false; const role = (el.getAttribute && el.getAttribute('role')) || ''; if (role === 'button' || role === 'link') return false; if (el.hasAttribute && el.hasAttribute('data-copilot-module')) return false; if (el.closest && el.closest('.add-to-cart, .product-cta, .product-actions, .pdp-add-to-cart, .quickbuy')) return false; return true; }); } function findProducts() { const selectors = [ '[data-product-code]', '[data-product-id]', '.product-item', '.product-card', '.product-tile', '.product', '.js-product', 'article.product', '.product-grid-item', '.product-list-item' ]; for (let selector of selectors) { const elements = document.querySelectorAll(selector); if (elements.length > 0) { console.log(`Found ${elements.length} products using: ${selector}`); return filterProductElements(Array.from(elements)); } } console.warn('No products found'); return []; } function getProductCode(el) { return el.getAttribute('data-product-code') || el.getAttribute('data-product-id') || el.getAttribute('data-sku') || el.querySelector('[data-product-code]')?.getAttribute('data-product-code') || el.querySelector('[data-product-id]')?.getAttribute('data-product-id') || el.querySelector('a[href*="/shop/"]')?.href.split('/p/')[1]?.split('?')[0] || null; } // ============================================ // INJECTION LOGIC // ============================================ function injectModule() { if (injected) return; // Guard: never inject on PDPs if (isPDP()) { console.warn('PDP detected; skipping marketing card injection.'); return; } const cards = getActiveCards(); if (!cards || cards.length === 0) { console.warn('No marketing card configured for this URL'); return; } // Only consider products inside .mdc-layout-grid__inner if present let products = []; const gridInner = document.querySelector('.mdc-layout-grid__inner'); if (gridInner) { // Find all product elements inside the grid products = filterProductElements(Array.from(gridInner.querySelectorAll('[data-product-code], [data-product-id], .product-item, .product-card, .product-tile, .product, .js-product, article.product, .product-grid-item, .product-list-item'))); } else { products = findProducts(); } if (products.length === 0) return; console.log(`${cards.length} marketing card(s) matched this URL`); // Log all found product codes and positions for debugging console.log('Product codes and positions found:'); products.forEach((p, i) => { const pos = p.getAttribute('data-position'); const code = getProductCode(p); console.log(` Index ${i + 1} | Position: ${pos} | Code: ${code || 'N/A'}`); }); // Try to inject each matching card let anyInjected = false; cards.forEach(card => { let placed = false; // Placement logic if (!placed && card.placement) { if (card.placement.toLowerCase() === 'start' && products.length > 0) { console.log('Inserting module at START (before first product)'); insertModule(products[0], 'before', card); placed = true; } else if (card.placement.toLowerCase() === 'end' && products.length > 0) { console.log('Inserting module at END (after last product)'); insertModule(products[products.length - 1], 'after', card); placed = true; } } // Fallbacks: by product code or position if (!placed) { for (let i = 0; i < products.length; i++) { const code = getProductCode(products[i]); if (card.insertAfterProductCode && code === card.insertAfterProductCode) { console.log(`Inserting module AFTER product code: ${code}`); insertModule(products[i], 'after', card); placed = true; break; } if (card.insertBeforeProductCode && code === card.insertBeforeProductCode) { console.log(`Inserting module BEFORE product code: ${code}`); insertModule(products[i], 'before', card); placed = true; break; } } } if (!placed && card.insertAtPosition) { let targetProduct = null; // Try to find by data-position attribute first targetProduct = Array.from(products).find(p => parseInt(p.getAttribute('data-position')) === card.insertAtPosition ); // If not found, fallback to Nth product in the array (1-based) if (!targetProduct && products.length >= card.insertAtPosition) { targetProduct = products[card.insertAtPosition - 1]; } // If still not found, fallback to last product in gridInner if (!targetProduct && products.length > 0) { targetProduct = products[products.length - 1]; } if (targetProduct) { console.log(`Inserting module after product (insertAtPosition=${card.insertAtPosition})`); insertModule(targetProduct, 'after', card); placed = true; } } if (!placed) { console.warn(`Target not found for card. Check insertAfterProductCode, insertBeforeProductCode, or insertAtPosition configuration.`); } else { anyInjected = true; } }); if (anyInjected) { injected = true; // Ensure any end-placed cards are positioned after the latest product set repositionEndCards(); } } function insertModule(target, position, cardConfig) { const wrapper = document.createElement('div'); wrapper.innerHTML = generateModuleHTML(cardConfig).trim(); const base = target.closest && target.closest('[data-product-code], [data-product-id], .product-item, .product-card, .product-tile, .product, .js-product, article.product, .product-grid-item, .product-list-item') || target; const baseTag = (base.tagName || '').toLowerCase(); const safeTag = (baseTag === 'button' || baseTag === 'a') ? 'div' : (baseTag || 'div'); const classList = (base.className || '') .split(/\s+/) .filter(Boolean) .filter(c => !/(^|-)btn($|-)|button|cta|add-to-cart|purchase|subscribe|link/i.test(c)) .join(' '); const container = document.createElement(safeTag); if (classList) container.className = classList; container.setAttribute('data-copilot-module', 'true'); if (cardConfig && cardConfig.placement) { container.setAttribute('data-copilot-placement', String(cardConfig.placement).toLowerCase()); } container.appendChild(wrapper.firstElementChild); if (position === 'after') { base.parentNode.insertBefore(container, base.nextSibling); } else { base.parentNode.insertBefore(container, base); } // Make entire card clickable if data-card-href is present const clickable = container.querySelector('.rf-card-clickable[data-card-href]'); if (clickable) { const href = clickable.getAttribute('data-card-href'); clickable.setAttribute('role', 'link'); clickable.setAttribute('tabindex', '0'); const navigate = () => { try { window.location.assign(href); } catch(e) { window.location.href = href; } }; clickable.addEventListener('click', (e) => { const insideAnchor = e.target.closest('a'); if (insideAnchor) return; // allow inner links like CTA/disclaimer navigate(); }); clickable.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); navigate(); } }); } console.log('Marketing module injected successfully!'); } // Reposition any cards configured with placement: 'End' after dynamic loads function repositionEndCards() { const endCards = Array.from(document.querySelectorAll('[data-copilot-module="true"][data-copilot-placement="end"]')); if (endCards.length === 0) return; // Determine current product list inside grid const gridInner = document.querySelector('.mdc-layout-grid__inner'); const productSelector = '[data-product-code], [data-product-id], .product-item, .product-card, .product-tile, .product, .js-product, article.product, .product-grid-item, .product-list-item'; let products = []; if (gridInner) { products = Array.from(gridInner.querySelectorAll(productSelector)); } else { products = Array.from(document.querySelectorAll(productSelector)); } products = products.filter(el => !el.hasAttribute('data-copilot-module')); if (products.length === 0) return; const lastProduct = products[products.length - 1]; endCards.forEach(card => { if (lastProduct.nextSibling !== card) { try { lastProduct.parentNode.insertBefore(card, lastProduct.nextSibling); } catch (e) {} } }); } function isModulePresent() { return document.querySelector('[data-copilot-module="true"]') !== null; } // ============================================ // INITIALIZATION - IMMEDIATE LOAD // ============================================ function init() { injectModule(); // Quick retries for fast page load if (!injected) { setTimeout(injectModule, 100); setTimeout(injectModule, 300); setTimeout(injectModule, 500); setTimeout(injectModule, 1000); } } // Run immediately init(); // Also run on DOMContentLoaded as backup if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } // Watch for dynamically loaded products const observer = new MutationObserver(() => { clearTimeout(window.moduleInjectionTimeout); window.moduleInjectionTimeout = setTimeout(() => { if (!isModulePresent()) { injected = false; injectModule(); } repositionEndCards(); }, 120); }); // Start observing immediately const startObserver = () => { const container = document.querySelector('.product-grid, .product-list, .products, main, body'); if (container) { observer.observe(container, { childList: true, subtree: true }); } }; startObserver(); setTimeout(startObserver, 500); })();