Decants de perfumesNICHO

Descubre entre la mejor selección de perfumes nicho

Oud Wood

Desde 9,99 €

Wild Python

Desde 5,99 €

Fleur de Peau

Desde 5,99 €

Ganymede

Desde 7,99 €

More Than Words

Desde 7,99 €

40 Knots

Desde 7,99 €

Haltane

Desde 8,99 €

Hibiscus Mahajád

Desde 12,99 €

Bibliothèque

Desde 6,99 €

Pegasus

Desde 7,99 €

Wood Sage & Sea Salt

Desde 6,99 €

Black Phantom

Desde 11,99 €

Delina

Desde 9,99 €

Baccarat Rouge 540 Extrait

Desde 9,99 €

Valero Extrait

Desde 9,99 €

Pacific Chill

Desde 9,99 €

Ombre Nomade

Desde 12,99 €

Bois Impérial

Desde 4,99 €

Oud Maracujá

Desde 12,99 €

Van Py Rhum

Desde 9,99 €

Bal d’Afrique Absolu

Desde 8,99 €

Mojave Ghost Absolu

Desde 8,99 €

Summer Hammer

Desde 9,99 €

Angel’s Share

Desde 8,99 €

Megamare

Desde 9,99 €

Bianco Latte

Desde 5,99 €

Más populares

Búsquedas populares

'; } function highlight(text, q) { var i = q ? text.toLowerCase().indexOf(q.toLowerCase()) : -1; if (i < 0) return esc(text); return esc(text.slice(0, i)) + '' + esc(text.slice(i, i + q.length)) + '' + esc(text.slice(i + q.length)); } function setupWrap(w) { if (w.__lsReady) return; w.__lsReady = true; q$(w, '.ls-popular').innerHTML = POPULAR.map(function (t) { return ''; }).join(''); if ('IntersectionObserver' in window) { new IntersectionObserver(function (en) { en.forEach(function (e) { if (e.isIntersecting) onOpen(w); else onClose(w); }); }).observe(w); } } function allWraps() { return Array.prototype.slice.call(document.querySelectorAll('.ls-wrap')); } allWraps().forEach(setupWrap); /* ---------- Más populares ---------- */ var popularData = null, popularReq = null, popularErr = ''; function renderPopular(w) { var row = q$(w, '.ls-row'); if (popularErr) { row.innerHTML = '
No se pudieron cargar los populares (' + esc(popularErr) + ').
'; return; } if (!popularData) { var sk = '
'; row.innerHTML = sk + sk + sk + sk; return; } if (!popularData.length) { row.innerHTML = '
La API devolvió 0 productos populares.
'; return; } row.innerHTML = popularData.map(function (p) { return '' + tile(p) + (p.brand ? '
' + esc(p.brand) + '
' : '') + '
' + esc(p.name) + '
' + (p.price ? '
' + (p.from ? 'Desde ' : '') + esc(p.price) + '
' : '') + '
'; }).join(''); setTimeout(function () { updateArrows(row); }, 50); } /* ---------- Fila horizontal en escritorio: flechas, arrastre y rueda ---------- */ function updateArrows(row) { var wrap = row.closest('.ls-rowwrap'); if (!wrap) return; var canScroll = row.scrollWidth > row.clientWidth + 4; wrap.classList.toggle('is-scrollable', canScroll); var prev = wrap.querySelector('.ls-arrow[data-dir="prev"]'), next = wrap.querySelector('.ls-arrow[data-dir="next"]'); if (prev) prev.disabled = row.scrollLeft <= 2; if (next) next.disabled = row.scrollLeft + row.clientWidth >= row.scrollWidth - 2; } document.addEventListener('scroll', function (e) { if (e.target && e.target.classList && e.target.classList.contains('ls-row')) updateArrows(e.target); }, true); window.addEventListener('resize', function () { allWraps().forEach(function (w) { updateArrows(q$(w, '.ls-row')); }); }); var drag = null; document.addEventListener('pointerdown', function (e) { if (e.pointerType !== 'mouse' || e.button !== 0) return; var row = e.target.closest ? e.target.closest('.ls-row') : null; if (!row) return; drag = { row: row, x: e.clientX, left: row.scrollLeft, moved: false }; }); document.addEventListener('pointermove', function (e) { if (!drag) return; var dx = e.clientX - drag.x; if (!drag.moved && Math.abs(dx) < 4) return; drag.moved = true; drag.row.classList.add('is-dragging'); drag.row.scrollLeft = drag.left - dx; e.preventDefault(); }); function endDrag() { if (!drag) return; var row = drag.row; setTimeout(function () { row.classList.remove('is-dragging'); }, 0); drag = null; } document.addEventListener('pointerup', endDrag); document.addEventListener('pointercancel', endDrag); document.addEventListener('wheel', function (e) { var row = e.target.closest ? e.target.closest('.ls-row') : null; if (!row || row.scrollWidth <= row.clientWidth) return; if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return; e.preventDefault(); row.scrollLeft += e.deltaY; }, { passive: false }); function loadPopular() { if (popularData || popularReq) return popularReq; var hit = cacheGet('popular'); if (hit && hit.length) { popularData = hit; allWraps().forEach(renderPopular); return null; } popularReq = getJSON(API + '?popular=1') .then(function (d) { popularData = (d && d.products) || []; popularErr = ''; cacheSet('popular', popularData); }) .catch(function (err) { popularData = null; popularErr = err.message || 'error'; console.error('[buscador] populares:', err); }) .then(function () { popularReq = null; allWraps().forEach(renderPopular); }); return popularReq; } /* ---------- Búsqueda en vivo ---------- */ function searchUrl(q) { return ORIGIN + '/?s=' + encodeURIComponent(q) + '&post_type=product'; } function chipsHTML(list) { return '
' + list.map(function (t) { return ''; }).join('') + '
'; } function productCardHTML(p) { return '' + tile(p) + (p.brand ? '
' + esc(p.brand) + '
' : '') + '
' + esc(p.name) + '
' + (p.price ? '
' + (p.from ? 'Desde ' : '') + esc(p.price) + '
' : '') + '
'; } function brandCardHTML(b) { var n = b.count || 0; return '' + '' + '' + esc(b.name) + '' + '' + n + (n === 1 ? ' perfume' : ' perfumes') + '' + ''; } function renderResults(w, q, d) { var res = q$(w, '.ls-results'); var products = (d && d.products) || [], brands = (d && d.brands) || []; var corrected = (d && d.corrected) || '', suggestions = (d && d.suggestions) || []; if (!products.length && !brands.length) { res.innerHTML = '
No tenemos nada con «' + esc(q) + '»' + (suggestions.length ? '
¿Buscabas…?
' + chipsHTML(suggestions) : '') + 'Pídenos este decant' + '
'; return; } var html = ''; if (corrected) { html += '
Resultados para ' + esc(corrected) + '' + (suggestions.length ? ' · ¿o buscabas ' + suggestions.map(function (t) { return ''; }).join(', ') + '?' : '') + '
'; } /* Pestaña por defecto: Perfumes; si no hay perfumes pero sí marcas, Marcas. Se recuerda la última elegida. */ var tab = w.__lsTab || 'products'; if (tab === 'products' && !products.length) tab = 'brands'; if (tab === 'brands' && !brands.length) tab = 'products'; html += '
' + '' + '' + '
'; html += '
' + '
' + products.map(productCardHTML).join('') + '
' + '
'; html += '
' + '
' + brands.map(brandCardHTML).join('') + '
'; res.innerHTML = html; res.scrollTop = 0; } function onType(w) { var input = q$(w, '.ls-input'); var q = input.value.trim(); q$(w, '.ls-clear').style.display = q ? 'block' : 'none'; clearTimeout(w.__lsTimer); if (w.__lsCtrl) { try { w.__lsCtrl.abort(); } catch (e) {} } if (q.length < 2) { w.__lsQ = ''; w.classList.remove('is-loading'); q$(w, '.ls-home').style.display = ''; q$(w, '.ls-results').innerHTML = ''; return; } w.__lsQ = q; q$(w, '.ls-home').style.display = 'none'; var key = 'q:' + q.toLowerCase(); var hit = cacheGet(key); if (hit) { w.classList.remove('is-loading'); renderResults(w, q, hit); return; } w.classList.add('is-loading'); w.__lsTimer = setTimeout(function () { var c = window.AbortController ? new AbortController() : null; w.__lsCtrl = c; getJSON(API + '?q=' + encodeURIComponent(q), c && c.signal) .then(function (d) { cacheSet(key, d); if (w.__lsQ !== q) return; w.classList.remove('is-loading'); renderResults(w, q, d); }) .catch(function (err) { if (err && err.name === 'AbortError') return; if (w.__lsQ !== q) return; w.classList.remove('is-loading'); console.error('[buscador] búsqueda:', err); q$(w, '.ls-results').innerHTML = '
No se ha podido buscar (' + esc(err.message || 'error') + ').
'; }); }, 200); } document.addEventListener('input', function (e) { var inp = e.target && e.target.closest ? e.target.closest('.ls-input') : null; if (inp) onType(inp.closest('.ls-wrap')); }); /* Enter: no navega a la página de resultados de WooCommerce. Los resultados en vivo son la búsqueda. En móvil cierra el teclado para que se vean; si hay una sola coincidencia exacta, va a ella. */ document.addEventListener('keydown', function (e) { if (e.key !== 'Enter') return; var inp = e.target && e.target.closest ? e.target.closest('.ls-input') : null; if (!inp) return; e.preventDefault(); var w = inp.closest('.ls-wrap'); var cards = w.querySelectorAll('.ls-pane.is-active .ls-card, .ls-pane.is-active .ls-bcard'); if (cards.length === 1) { window.location.href = cards[0].getAttribute('href'); return; } inp.blur(); }); document.addEventListener('click', function (e) { var t = e.target && e.target.closest ? e.target : null; if (!t) return; var w = t.closest('.ls-wrap'); if (!w) return; var arrow = t.closest('.ls-arrow[data-dir]'); if (arrow) { var row = arrow.closest('.ls-rowwrap').querySelector('.ls-row'); var step = Math.round(row.clientWidth * 0.8) * (arrow.getAttribute('data-dir') === 'next' ? 1 : -1); row.scrollBy({ left: step, behavior: 'smooth' }); return; } var tabBtn = t.closest('.ls-tab[data-tab]'); if (tabBtn && !tabBtn.disabled) { var name = tabBtn.getAttribute('data-tab'); w.__lsTab = name; Array.prototype.forEach.call(w.querySelectorAll('.ls-tab'), function (b) { b.classList.toggle('is-active', b === tabBtn); }); Array.prototype.forEach.call(w.querySelectorAll('.ls-pane'), function (p) { p.classList.toggle('is-active', p.getAttribute('data-pane') === name); }); q$(w, '.ls-results').scrollTop = 0; return; } var chip = t.closest('.ls-chip[data-q], .ls-link[data-q]'); if (chip) { var inp = q$(w, '.ls-input'); inp.value = chip.getAttribute('data-q'); onType(w); inp.focus(); return; } if (t.closest('.ls-clear')) { var inp2 = q$(w, '.ls-input'); inp2.value = ''; onType(w); inp2.focus(); return; } if (t.closest('.ls-close')) { closeSearch(w, e); } }); /* ---------- Cierre robusto: botón de Elementor → API de Elementor → cierre manual ---------- */ function closeSearch(w, e) { var modal = w.closest('.elementor-popup-modal'); var done = false; try { var x = modal && modal.querySelector('.dialog-close-button'); if (x) { x.click(); done = true; } } catch (err) {} if (!done) { try { window.elementorProFrontend.modules.popup.closePopup({}, e || {}); done = true; } catch (err2) {} } /* Si a los 150 ms sigue visible, cierre manual */ setTimeout(function () { if (modal && getComputedStyle(modal).display !== 'none') { modal.style.display = 'none'; try { document.body.classList.remove('elementor-popup-modal-open'); } catch (err3) {} } onClose(w); unlockScroll(); }, 150); } document.addEventListener('keydown', function (e) { if (e.key !== 'Escape') return; allWraps().forEach(function (w) { if (w.__lsOpen) closeSearch(w, e); }); }); /* ---------- Apertura / cierre ---------- */ var lockedY = null; function lockScroll() { if (lockedY !== null) return; lockedY = window.scrollY || 0; var b = document.body.style; b.overflow = 'hidden'; b.position = 'fixed'; b.top = '-' + lockedY + 'px'; b.width = '100%'; } function unlockScroll() { if (lockedY === null) return; var y = lockedY; lockedY = null; var b = document.body.style; b.overflow = ''; b.position = ''; b.top = ''; b.width = ''; window.scrollTo(0, y); } var openCount = 0; function onOpen(w) { if (w.__lsOpen) return; w.__lsOpen = true; openCount++; lockScroll(); renderPopular(w); loadPopular(); var inp = q$(w, '.ls-input'); setTimeout(function () { try { inp.focus({ preventScroll: true }); } catch (e) { inp.focus(); } }, 120); } function onClose(w) { if (!w.__lsOpen) return; w.__lsOpen = false; openCount = Math.max(0, openCount - 1); if (!openCount) unlockScroll(); } if (window.jQuery) { window.jQuery(document).on('elementor/popup/show', function () { allWraps().forEach(function (w) { setupWrap(w); if (w.offsetParent !== null) onOpen(w); }); }); } /* Precarga de los populares al primer toque en la web */ document.addEventListener('pointerdown', function pre() { document.removeEventListener('pointerdown', pre, true); setTimeout(loadPopular, 300); }, true); })();