PageSourceSearch

https://www.mueblesbonitos.com/salon

html mueblesbonitos.com collected 2026-10-08 07:24:58 UTC 797,780 bytes, 15,291 lines download raw bytes

1<!doctype html>
2<html lang="es">
3<head prefix="og: http://ogp.me/ns# category: http://ogp.me/ns/category#">
4    <meta charset="utf-8"/>
5<meta name="title" content="Comprar Salones Modernos y de Diseño | Muebles Bonitos"/>
6<meta name="description" content="Muebles de salón modernos: aparadores, muebles TV, vitrinas, armarios y más. +365 modelos con envío gratuito y 3 años de garantía."/>
7<meta name="robots" content="INDEX,FOLLOW"/>
8<meta name="viewport" content="width=device-width, initial-scale=1"/>
9<title>Comprar Salones Modernos y de Diseño | Muebles Bonitos</title>
10        <link rel="stylesheet" type="text/css" media="all" href="https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES/css/styles.css" />
11<link rel="stylesheet" type="text/css" media="all" href="https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES/css/custom_overrides.css" />
12<link rel="stylesheet" type="text/css" media="all" href="https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES/Amasty_ShopbyBase/css/chosen/chosen.css" />
13<script type="text/javascript" src="https://s.kk-resources.com/leadtag.js"></script>
13
14<link rel="canonical" href="https://www.mueblesbonitos.com/salon" />
15<link rel="icon" type="image/x-icon" href="https://www.mueblesbonitos.com/media/favicon/stores/2/favicon.png" />
16<link rel="shortcut icon" type="image/x-icon" href="https://www.mueblesbonitos.com/media/favicon/stores/2/favicon.png" />
17    
18<script>
19    // 1. Definimos el flag en el objeto window para que sea persistente a re-inyecciones de Hyvä
20    window.gtmIsInitialized = window.gtmIsInitialized || false;
21
22    (function() {
23        // 2. Si ya se marcó como inicializado, abortamos ejecución de este bloque inmediatamente
24        if (window.gtmIsInitialized) {
25            return;
26        }
27
28        var gtmLoaded = false;
29
30        var loadGTM = function() {
31            if (gtmLoaded) return;
32            gtmLoaded = true;
33            window.gtmIsInitialized = true; // Marcamos el flag global
34
35            (function(w,d,s,l,i){
36                w[l]=w[l]||[];
37                w[l].push({'gtm.start': new Date().getTime(), event:'gtm.js'});
38                var f=d.getElementsByTagName(s)[0],
39                    j=d.createElement(s),
40                    dl=l!='dataLayer'?'&l='+l:'';
41                var script=d.createElement(s);
42                script.async=true;
43                script.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
44                f.parentNode.insertBefore(script,f);
45            })(window,document,'script','dataLayer','GTM-TR9K4DK');
46
47            // 3. Limpiamos todos los listeners para liberar memoria
48            ['scroll', 'mousemove', 'touchstart', 'click'].forEach(function(evt) {
49                window.removeEventListener(evt, loadGTM);
50            });
51        };
52
53        // 4. Escuchamos interacciones reales del usuario
54        ['scroll', 'mousemove', 'touchstart', 'click'].forEach(function(evt) {
55            window.addEventListener(evt, loadGTM, {passive: true});
56        });
57
58        // 5. Carga de seguridad: si no hay interacción, cargamos a los 6 segundos para no perder analítica
59        setTimeout(loadGTM, 3000);
60    })();
61</script>
61
62
63        
63<script>
64        window.motive = {"initParams":{"xEngineId":"9a837fe9-f00c-4c01-baff-02f7b44d45f9","lang":"es-ES","currency":"EUR","triggerSelector":"#site-search,#search_mini_form","isolated":true,"cartUrl":"https:\/\/www.mueblesbonitos.com\/checkout\/cart\/"},"options":{"shopperPrices":true,"priceRates":{"min":1,"max":1,"static":1}},"endpoints":{"shopperPrices":"https:\/\/www.mueblesbonitos.com\/motive\/results\/resultsenrichment\/?___store=mueblesbonitos_com_es"},"motive_x_url":"https:\/\/assets.motive.co\/motive-x\/v2\/app.js"};
65    </script>
65
66    
66<script id="motive-front-loader" async src="https://assets.motive.co/front-loader/magento/v1.js"></script>
vendor: 1 bytes, line 66
66
67<script>
68    var BASE_URL = 'https://www.mueblesbonitos.com/';
69    var THEME_PATH = 'https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES';
70    var COOKIE_CONFIG = {
71        "expires": null,
72        "path": "\u002F",
73        "domain": ".www.mueblesbonitos.com",
74        "secure": true,
75        "lifetime": "3600",
76        "cookie_restriction_enabled": false    };
77    var CURRENT_STORE_CODE = 'mueblesbonitos_com_es';
78    var CURRENT_WEBSITE_ID = '2';
79
80    window.hyva = window.hyva || {}
81
82    window.cookie_consent_groups = window.cookie_consent_groups || {}
83    window.cookie_consent_groups['necessary'] = true;
84
85    window.cookie_consent_config = window.cookie_consent_config || {};
86    window.cookie_consent_config['necessary'] = [].concat(
87        window.cookie_consent_config['necessary'] || [],
88        [
89            'user_allowed_save_cookie',
90            'form_key',
91            'mage-messages',
92            'private_content_version',
93            'mage-cache-sessid',
94            'last_visited_store',
95            'section_data_ids'
96        ]
97    );
98    //# sourceURL=hyva-variables.js
99</script>
vendor: 1 bytes, line 99
99
100<script>
101    (function( hyva, undefined ) {
102
103        function lifetimeToExpires(options, defaults) {
104
105            const lifetime = options.lifetime || defaults.lifetime;
106
107            if (lifetime) {
108                const date = new Date;
109                date.setTime(date.getTime() + lifetime * 1000);
110                return date;
111            }
112
113            return null;
114        }
115
116        function generateRandomString() {
117
118            const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
119                length = 16;
120
121            let formKey = '',
122                charactersLength = allowedCharacters.length;
123
124            for (let i = 0; i < length; i++) {
125                formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))]
126            }
127
128            return formKey;
129        }
130
131        const sessionCookieMarker = {noLifetime: true}
132
133        const cookieTempStorage = {};
134
135        const internalCookie = {
136            get(name) {
137                const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
138                return v ? v[2] : null;
139            },
140            set(name, value, days, skipSetDomain) {
141                let expires,
142                    path,
143                    domain,
144                    secure,
145                    samesite;
146
147                const defaultCookieConfig = {
148                    expires: null,
149                    path: '/',
150                    domain: null,
151                    secure: false,
152                    lifetime: null,
153                    samesite: 'lax'
154                };
155
156                const cookieConfig = window.COOKIE_CONFIG || {};
157
158                expires = days && days !== sessionCookieMarker
159                    ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig)
160                    : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires;
161
162                path = cookieConfig.path || defaultCookieConfig.path;
163                domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain);
164                secure = cookieConfig.secure || defaultCookieConfig.secure;
165                samesite = cookieConfig.samesite || defaultCookieConfig.samesite;
166
167                document.cookie = name + "=" + encodeURIComponent(value) +
168                    (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') +
169                    (path ? '; path=' + path : '') +
170                    (domain ? '; domain=' + domain : '') +
171                    (secure ? '; secure' : '') +
172                    (samesite ? '; samesite=' + samesite : 'lax');
173            },
174            isWebsiteAllowedToSaveCookie() {
175                const allowedCookies = this.get('user_allowed_save_cookie');
176                if (allowedCookies) {
177                    const allowedWebsites = JSON.parse(unescape(allowedCookies));
178
179                    return allowedWebsites[CURRENT_WEBSITE_ID] === 1;
180                }
181                return false;
182            },
183            getGroupByCookieName(name) {
184                const cookieConsentConfig = window.cookie_consent_config || {};
185                let group = null;
186                for (let prop in cookieConsentConfig) {
187                    if (!cookieConsentConfig.hasOwnProperty(prop)) continue;
188                    if (cookieConsentConfig[prop].includes(name)) {
189                        group = prop;
190                        break;
191                    }
192                }
193                return group;
194            },
195            isCookieAllowed(name) {
196                const cookieGroup = this.getGroupByCookieName(name);
197                return cookieGroup
198                    ? window.cookie_consent_groups[cookieGroup]
199                    : this.isWebsiteAllowedToSaveCookie();
200            },
201            saveTempStorageCookies() {
202                for (const [name, data] of Object.entries(cookieTempStorage)) {
203                    if (this.isCookieAllowed(name)) {
204                        this.set(name, data['value'], data['days'], data['skipSetDomain']);
205                        delete cookieTempStorage[name];
206                    }
207                }
208            }
209        };
210
211        hyva.getCookie = (name) => {
212            const cookieConfig = window.COOKIE_CONFIG || {};
213
214            if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
215                return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null;
216            }
217
218            return internalCookie.get(name);
219        }
220
221        hyva.setCookie = (name, value, days, skipSetDomain) => {
222            const cookieConfig = window.COOKIE_CONFIG || {};
223
224            if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
225                cookieTempStorage[name] = {value, days, skipSetDomain};
226                return;
227            }
228            return internalCookie.set(name, value, days, skipSetDomain);
229        }
230
231
232        hyva.setSessionCookie = (name, value, skipSetDomain) => {
233            return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain)
234        }
235
236        hyva.getBrowserStorage = () => {
237            const browserStorage = window.localStorage || window.sessionStorage;
238            if (!browserStorage) {
239                console.warn('Browser Storage is unavailable');
240                return false;
241            }
242            try {
243                browserStorage.setItem('storage_test', '1');
244                browserStorage.removeItem('storage_test');
245            } catch (error) {
246                console.warn('Browser Storage is not accessible', error);
247                return false;
248            }
249            return browserStorage;
250        }
251
252        hyva.postForm = (postParams) => {
253            const form = document.createElement("form");
254
255            let data = postParams.data;
256
257            if (! postParams.skipUenc && ! data.uenc) {
258                data.uenc = btoa(window.location.href);
259            }
260            form.method = "POST";
261            form.action = postParams.action;
262
263            Object.keys(postParams.data).map(key => {
264                const field = document.createElement("input");
265                field.type = 'hidden'
266                field.value = postParams.data[key];
267                field.name = key;
268                form.appendChild(field);
269            });
270
271            const form_key = document.createElement("input");
272            form_key.type = 'hidden';
273            form_key.value = hyva.getFormKey();
274            form_key.name="form_key";
275            form.appendChild(form_key);
276
277            document.body.appendChild(form);
278
279            form.submit();
280        }
281
282        hyva.getFormKey = function () {
283            let formKey = hyva.getCookie('form_key');
284
285            if (!formKey) {
286                formKey = generateRandomString();
287                hyva.setCookie('form_key', formKey);
288            }
289
290            return formKey;
291        }
292
293        hyva.formatPrice = (value, showSign, options = {}) => {
294            const groupSeparator = options.groupSeparator;
295            const decimalSeparator = options.decimalSeparator
296            delete options.groupSeparator;
297            delete options.decimalSeparator;
298            const formatter = new Intl.NumberFormat(
299                'es\u002DES',
300                Object.assign({
301                    style: 'currency',
302                    currency: 'EUR',
303                    signDisplay: showSign ? 'always' : 'auto'
304                }, options)
305            );
306            return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ?
307                formatter.formatToParts(value).map(({type, value}) => {
308                    switch (type) {
309                        case 'currency':
310                            return '\u20AC' || value;
311                        case 'minusSign':
312                            return '- ';
313                        case 'plusSign':
314                            return '+ ';
315                        case 'group':
316                            return groupSeparator !== undefined ? groupSeparator : value;
317                        case 'decimal':
318                            return decimalSeparator !== undefined ? decimalSeparator : value;
319                        default :
320                            return value;
321                    }
322                }).reduce((string, part) => string + part) :
323                formatter.format(value);
324        }
325
326        const formatStr = function (str, nStart) {
327            const args = Array.from(arguments).slice(2);
328
329            return str.replace(/(%+)([0-9]+)/g, (m, p, n) => {
330                const idx = parseInt(n) - nStart;
331
332                if (args[idx] === null || args[idx] === void 0) {
333                    return m;
334                }
335                return p.length % 2
336                    ? p.slice(0, -1).replace('%%', '%') + args[idx]
337                    : p.replace('%%', '%') + n;
338            })
339        }
340
341        hyva.str = function (string) {
342            const args = Array.from(arguments);
343            args.splice(1, 0, 1);
344
345            return formatStr.apply(undefined, args);
346        }
347
348        hyva.strf = function () {
349            const args = Array.from(arguments);
350            args.splice(1, 0, 0);
351
352            return formatStr.apply(undefined, args);
353        }
354
355        /**
356         * Take a html string as `content` parameter and
357         * extract an element from the DOM to replace in
358         * the current page under the same selector,
359         * defined by `targetSelector`
360         */
361        hyva.replaceDomElement = (targetSelector, content) => {
362            // Parse the content and extract the DOM node using the `targetSelector`
363            const parser = new DOMParser();
364            const doc = parser.parseFromString(content, 'text/html');
365            const contentNode = doc.querySelector(targetSelector);
366
367            // Bail if content or target can't be found
368            if (!contentNode || !document.querySelector(targetSelector)) {
369                return;
370            }
371
372                        hyva.activateScripts(contentNode);
373            
374            // Replace the old DOM node with the new content
375            document.querySelector(targetSelector).replaceWith(contentNode);
376
377            // Reload customerSectionData and display cookie-messages if present
378            window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
379            hyva.initMessages();
380        }
381
382        hyva.removeScripts = (contentNode) => {
383            const scripts = contentNode.getElementsByTagName('script');
384            for (let i = 0; i < scripts.length; i++) {
385                scripts[i].parentNode.removeChild(scripts[i]);
386            }
387            const templates = contentNode.getElementsByTagName('template');
388            for (let i = 0; i < templates.length; i++) {
389                const container = document.createElement('div');
390                container.innerHTML = templates[i].innerHTML;
391                hyva.removeScripts(container);
392                templates[i].innerHTML = container.innerHTML;
393            }
394        }
395
396        hyva.activateScripts = (contentNode) => {
397            // Create new array from HTMLCollection to avoid mutation of collection while manipulating the DOM.
398            const scripts = Array.from(contentNode.getElementsByTagName('script'));
399
400            // Iterate over all script tags to duplicate+inject each into the head
401            for (const original of scripts) {
402                const script = document.createElement('script');
403                original.type && (script.type = original.type);
404                script.innerHTML = original.innerHTML;
405
406                // Remove the original (non-executing) script from the contentNode
407                original.parentNode.removeChild(original)
408
409                // Add script to head
410                document.head.appendChild(script);
411            }
412
413            return contentNode;
414        }
415
416        const replace = {['+']: '-', ['/']: '_', ['=']: ','};
417        hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]);
418
419        let currentTrap;
420
421        const focusableElements = (rootElement) => {
422            const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]';
423            return Array.from(rootElement.querySelectorAll(selector))
424                .filter(el => {
425                    return el.style.display !== 'none'
426                        && !el.disabled
427                        && el.tabIndex !== -1
428                        && (el.offsetWidth || el.offsetHeight || el.getClientRects().length)
429                })
430        }
431
432        const focusTrap = (e) => {
433            const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
434            if (!isTabPressed) return;
435
436            const focusable = focusableElements(currentTrap)
437            const firstFocusableElement = focusable[0]
438            const lastFocusableElement = focusable[focusable.length - 1]
439
440            e.shiftKey
441                ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault())
442                : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault())
443        };
444
445        hyva.releaseFocus = (rootElement) => {
446            if (currentTrap && (!rootElement || rootElement === currentTrap)) {
447                currentTrap.removeEventListener('keydown', focusTrap)
448                currentTrap = null
449            }
450        }
451        hyva.trapFocus = (rootElement) => {
452            if (!rootElement) return;
453            hyva.releaseFocus()
454            currentTrap = rootElement
455            rootElement.addEventListener('keydown', focusTrap)
456            const firstElement = focusableElements(rootElement)[0]
457            firstElement && firstElement.focus()
458        }
459
460        hyva.safeParseNumber = (rawValue) => {
461            const number = rawValue ? parseFloat(rawValue) : null;
462
463            return Array.isArray(number) || isNaN(number) ? rawValue : number;
464        }
465
466        const toCamelCase = s => s.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
467        hyva.createBooleanObject = (name, value = false, additionalMethods = {}) => {
468
469            const camelCase = toCamelCase(name);
470            const key = '__hyva_bool_' + name
471
472            return new Proxy(Object.assign(
473                additionalMethods,
474                {
475                    [key]: !!value,
476                    [name]() {return !!this[key]},
477                    ['!' + name]() {return !this[key]}, // @deprecated This does not work with non-CSP Alpine
478                    ['not' + camelCase]() {return !this[key]},
479                    ['toggle' + camelCase]() {this[key] = !this[key]},
480                    [`set${camelCase}True`]() {this[key] = true},
481                    [`set${camelCase}False`]() {this[key] = false},
482                }
483            ), {
484                set(target, prop, value) {
485                    return prop === name
486                        ? (target[key] = !!value)
487                        : Reflect.set(...arguments);
488                }
489            })
490        }
491
492                hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true})
493        window.addEventListener('alpine:init', () => Alpine.data('{}', () => ({})), {once: true});
494                window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies())
495
496    }( window.hyva = window.hyva || {} ));
497    //# sourceURL=hyva.js
498</script>
vendor: 1 bytes, line 498
498
499<script type="speculationrules">
500{
501    "tag": "Hyva Theme",
502    "prefetch": [{
503        "source": "document",
504        "where": {
505            "and": [
506                { "href_matches": "/*" },
507                { "not": {
508                    "href_matches": ["/customer/*","/search/*","/sales/*","/wishlist/*","/checkout/*","/paypal/*","/newsletter/*","/stores/store/redirect/*"]                }},
509                { "not": {
510                    "selector_matches": [".no-preload", ".do-not-prerender", "[download]", "[rel~=nofollow]", "[target]"]
511                }}
512            ]
513        },
514        "eagerness": "moderate"
515    }]
516}
517</script>
517
518
519<meta property="og:type" content="category"/>
520
521    <meta property="og:title" content="Comprar Salones Modernos y de Diseño | Muebles Bonitos"/>
522
523    <meta property="og:description" content="Muebles de salón modernos: aparadores, muebles TV, vitrinas, armarios y más. +365 modelos con envío gratuito y 3 años de garantía."/>
524
525<meta property="og:url" content="https://www.mueblesbonitos.com/salon"/>
526
527
528<meta property="og:site_name" content="mueblesbonitos.com"/>
529<script>
530    (function () {
531        let amSplideProcessed = false;
532
533        window.addEventListener('load-amsplide', () => {
534            if (amSplideProcessed) {
535                window?.Splide && window.dispatchEvent(new CustomEvent('amsplide-loaded', {}));
536                return;
537            }
538
539            const script = document.createElement('script');
540            script.src = 'https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES/Amasty_LibSplideJs/4.1.3/js/splide/splide.min.js';
541            script.async = true;
542            document.body.appendChild(script);
543
544            amSplideProcessed = true;
545
546            script.onload = () => {
547                window.dispatchEvent(new CustomEvent('amsplide-loaded', {}));
548            }
549
550            const stylesHref = 'https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES/Amasty_LibSplideJs/4.1.3/css/splide/splide.min.css';
551
552            if (document.querySelector(`link[href="${stylesHref}"]`)) {
553                return;
554            }
555
556            const styles = document.createElement('link');
557            styles.rel = 'stylesheet';
558            styles.type = 'text/css';
559            styles.href = stylesHref;
560
561            document.head.appendChild(styles);
562        });
563    }());
564</script>
564
565<link rel="next" href="https://www.mueblesbonitos.com/salon?p=2" />
566</head>
567<body id="html-body" class="page-with-filter page-products categorypath-salon category-salon catalog-category-view page-layout-1column">
568
569
570    <!-- RESTO DEL SITIO: versión original con Alpine y carrusel -->
571    <div id="site-notice" class="notice-fixed">
572        <div class="text-white text-sm leading-5 font-semibold" style="background-color:#34515E;">
573            <div
574                class="max-w-7xl mx-auto flex justify-center items-center"
575                x-data='{ activeIndex: 0, messages: ["<span class=\"flex items-center space-x-2 font-light\"> <a href=\"https:\/\/www.mueblesbonitos.com\/reviews_mb\" class=\"flex items-center space-x-1 hover:underline\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-4 w-4 fill-current text-white\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n              <path d=\"M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2 9.19 8.62 2 9.24l5.46 4.73L5.82 21z\"\/>\n            <\/svg><span>4,6<\/span><span class=\"ml-1 inline-flex items-center gap-1 rounded-full bg-white\/10 px-2 py-0.5 text-[11px] font-medium text-white\/90 ring-1 ring-white\/20\">Google<\/span><\/a><span class=\"ml-2\"><a href=\"tel: +34 965 104 517\"> Tel:   +34 965 104 517<a href= \"https:\/\/api.whatsapp.com\/send?phone=34697303158&amp;text=Hola\" target=\"_blank\" rel=\"noindex,nofollow\"> Whatsapp<i class=\"fa fa-whatsapp\" aria-hidden=\"true\" style=\"font-size: 20px;\"><\/i><\/a> <\/span><\/span>","<span class=\"font-light\">Viernes 9 cerrado por festivo<\/span>"] }'
576                x-init="setInterval(() => { activeIndex = (activeIndex + 1) % messages.length }, 5000);">
577                <div class="transition-opacity duration-500 ease-in-out text-center px-3">
578                    <span x-html="messages[activeIndex]"></span>
579                </div>
580            </div>
581        </div>
582    </div>
583
584<!-- Google Tag Manager (noscript) -->
vendor: 73 bytes, lines 584-586
584
585<noscript>
586    <iframe src="https://www.googletagmanager.com/ns.html?id=
586GTM-TR9K4DK
vendor: 96 bytes, lines 586-588
586"
587            height="0" width="0" style="display:none;visibility:hidden"></iframe>
588</noscript>
589<!-- End Google Tag Manager (noscript) -->
590<input name="form_key" type="hidden" value="GoQ6wnK4Gflfjncs" />
591    <noscript>
592        <section class="message global noscript border-b-2 border-blue-500 bg-blue-50 shadow-none m-0 px-0 rounded-none font-normal">
593            <div class="container text-center">
594                <p>
595                    <strong>JavaScript seems to be disabled in your browser.</strong>
596                    <span>
597                        For the best experience on our site, be sure to turn on Javascript in your browser.                    </span>
598                </p>
599            </div>
600        </section>
601    </noscript>
602
603
604<script>
605    document.body.addEventListener('touchstart', () => {}, {passive: true})
606</script>
vendor: 1 bytes, line 606
606
607<script>
608    (function(hyva) {
609                const formValidationRules = {
610            required(value, options, field, context) {
611                const el = field.element.type === 'hidden' ? createTextInputFrom(field.element) : field.element,
612                    fieldName = getFieldName(field),
613                    msg = fieldName
614                        ? hyva.str('El\u0020campo\u0020\u00251\u0020es\u0020obligatorio.', fieldName)
615                        : 'Este\u0020es\u0020un\u0020campo\u0020obligatorio.';
616
617                if (el.type === 'radio' || el.type === 'checkbox') {
618                    return (value === undefined || value.length === 0) ? msg : true;
619                }
620
621                el.setAttribute('required', '');
622                el.checkValidity();
623
624                return el.validity.valueMissing ? msg : true;
625            },
626            maxlength(value, options, field, context) {
627                const n = Number(options)
628                if (value.length > n) {
629                    const fieldName = getFieldName(field);
630                    return fieldName
631                        ? n === 1
632                            ? hyva.str('El\u0020campo\u0020\u00251\u0020no\u0020puede\u0020tener\u0020m\u00E1s\u0020de\u00201\u0020car\u00E1cter.', fieldName)
633                            : hyva.str('El\u0020campo\u0020\u00251\u0020no\u0020puede\u0020tener\u0020m\u00E1s\u0020de\u0020\u00252\u0020caracteres.', fieldName, options)
634                        : n === 1
635                            ? 'Por\u0020favor,\u0020no\u0020introduzcas\u0020m\u00E1s\u0020de\u00201\u0020car\u00E1cter.'
636                            : hyva.strf('Por\u0020favor,\u0020no\u0020introduzcas\u0020m\u00E1s\u0020de\u0020\u00250\u0020caracteres.', options);
637                }
638                return true;
639            },
640            minlength(value, options, field, context) {
641                const n = Number(options)
642                if (value.length > 0 && value.length < n) {
643                    const fieldName = getFieldName(field);
644                    return fieldName
645                        ? n === 1
646                            ? hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020tener\u0020al\u0020menos\u00201\u0020car\u00E1cter.', fieldName)
647                            : hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020tener\u0020al\u0020menos\u0020\u00252\u0020caracteres.', fieldName, options)
648                        : n === 1
649                            ? 'Por\u0020favor,\u0020introduce\u0020al\u0020menos\u00201\u0020car\u00E1cter.'
650                            : hyva.strf('Por\u0020favor,\u0020introduce\u0020al\u0020menos\u0020\u00250\u0020caracteres.', options);
651                }
652                return true;
653            },
654            max(value, options, field, context) {
655                field.element.setAttribute('max', options);
656                field.element.checkValidity();
657                if (field.element.validity.rangeOverflow) {
658                    const fieldName = getFieldName(field);
659                    return fieldName
660                        ? hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020contener\u0020un\u0020valor\u0020menor\u0020o\u0020igual\u0020a\u0020\u0022\u00252\u0022.', fieldName, options)
661                        : hyva.strf('Por\u0020favor,\u0020introduce\u0020un\u0020valor\u0020menor\u0020o\u0020igual\u0020a\u0020\u0022\u00250\u0022.', options);
662                }
663                return true;
664            },
665            min(value, options, field, context) {
666                field.element.setAttribute('min', options);
667                field.element.checkValidity();
668                if (field.element.validity.rangeUnderflow) {
669                    const fieldName = getFieldName(field);
670                    return fieldName
671                        ? hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020contener\u0020un\u0020valor\u0020mayor\u0020o\u0020igual\u0020a\u0020\u0022\u00252\u0022.', fieldName, options)
672                        : hyva.strf('Por\u0020favor,\u0020introduce\u0020un\u0020valor\u0020mayor\u0020o\u0020igual\u0020a\u0020\u0022\u00250\u0022.', options);
673                }
674                return true;
675            },
676            step(value, options, field, context) {
677                field.element.setAttribute('step', options);
678                field.element.checkValidity();
679                if (field.element.validity.stepMismatch) {
680                    const val = Number(value),
681                        step = Number(options),
682                        fieldName = getFieldName(field),
683                        nearestLowerValue = Math.floor(val / step) * step,
684                        nearestUpperValue = Math.ceil(val / step) * step;
685                    return fieldName
686                        ? hyva.str('El\u0020campo\u0020\u00251\u0020no\u0020es\u0020v\u00E1lido.\u0020Los\u0020dos\u0020valores\u0020v\u00E1lidos\u0020m\u00E1s\u0020cercanos\u0020son\u0020\u0022\u00252\u0022\u0020y\u0020\u0022\u00253\u0022.', fieldName, nearestLowerValue, nearestUpperValue)
687                        : hyva.strf('Por\u0020favor,\u0020introduce\u0020un\u0020valor\u0020v\u00E1lido.\u0020Los\u0020dos\u0020valores\u0020v\u00E1lidos\u0020m\u00E1s\u0020cercanos\u0020son\u0020\u0022\u00250\u0022\u0020y\u0020\u0022\u00251\u0022.', nearestLowerValue, nearestUpperValue);
688                }
689                return true;
690            },
691            pattern(value, options, field, context) {
692                field.element.setAttribute('pattern', options);
693                field.element.checkValidity();
694                if (field.element.validity.patternMismatch) {
695                    const fieldName = getFieldName(field);
696                    return fieldName
697                        ? field.element.pattern
698                            ? hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020coincidir\u0020con\u0020el\u0020formato\u0020solicitado\u003A\u0020\u00252.', fieldName, field.element.pattern)
699                            : hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020coincidir\u0020con\u0020el\u0020formato\u0020solicitado.', fieldName)
700                        : field.element.pattern
701                            ? hyva.strf('Por\u0020favor,\u0020utiliza\u0020el\u0020formato\u0020solicitado\u003A\u0020\u00250.', field.element.pattern)
702                            : 'Por\u0020favor,\u0020utiliza\u0020el\u0020formato\u0020solicitado.';
703                }
704                return true;
705            },
706            email(value, options, field, context) {
707                                const rule = /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i;
708                if (value.length > 0 && !rule.test(value)) {
709                    const fieldName = getFieldName(field);
710                    return fieldName
711                        ? hyva.str('El\u0020campo\u0020\u00251\u0020debe\u0020contener\u0020una\u0020direcci\u00F3n\u0020de\u0020correo\u0020v\u00E1lida\u0020\u0028Ej\u003A\u0020juandiez\u0040dominio.com\u0029.', fieldName)
712                        : 'Por\u0020favor,\u0020introduce\u0020una\u0020direcci\u00F3n\u0020de\u0020correo\u0020v\u00E1lida\u0020\u0028Ej\u003A\u0020juandiez\u0040dominio.com\u0029.';
713                }
714                return true;
715            },
716            password(value, options, field, context) {
717                const rule = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/;
718                if (value.length > 0 && !rule.test(value)) {
719                    const fieldName = getFieldName(field);
720                    return fieldName
721                        ? hyva.str('\u00251\u0020field\u0020must\u0020contain\u0020at\u0020least\u0020one\u0020upper\u0020case,\u0020one\u0020lower\u0020case,\u0020one\u0020digit\u0020and\u0020one\u0020special\u0020character\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026\u002A\u002D\u0029', fieldName)
722                        : 'Indique\u0020al\u0020menos\u0020una\u0020may\u00FAscula,\u0020una\u0020min\u00FAscula,\u0020un\u0020d\u00EDgito\u0020y\u0020un\u0020car\u00E1cter\u0020especial\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026amp\u003B\u002A\u002D\u0029';
723                }
724                return true;
725            },
726            equalTo(value, options, field, context) {
727                const dependencyField = context.fields[options].element;
728                if (value !== dependencyField.value) {
729                    const dependencyFieldName =
730                        dependencyField.label ||
731                        dependencyField.title ||
732                        (dependencyField.labels && dependencyField.labels[0] && dependencyField.labels[0].innerText) ||
733                        dependencyField.name,
734                        fieldName = getFieldName(field);
735                    return fieldName
736                        ? hyva.str('El\u0020valor\u0020del\u0020campo\u0020\u00251\u0020debe\u0020ser\u0020igual\u0020a\u0020\u0022\u00252\u0022.', fieldName, dependencyFieldName)
737                        : hyva.strf('El\u0020valor\u0020de\u0020este\u0020campo\u0020debe\u0020ser\u0020igual\u0020a\u0020\u0022\u00250\u0022.', dependencyFieldName);
738                }
739                return true;
740            }
741        };
742
743                function raceSome(promises, pred) {
744            return new Promise((resolve, reject) => {
745
746                if (promises.length === 0) {
747                    return resolve();
748                }
749
750                let settled = false, nDone = 0;
751
752                const resolveIf = v => {
753                    if (!settled && (pred(v) || ++nDone === promises.length)) {
754                        settled = true;
755                        resolve(v);
756                    }
757                    return v;
758                }
759
760                promises.map(promise => {
761                    promise.then(resolveIf).catch(reason => {
762                        settled = true;
763                        reject(reason)
764                    });
765                    return promise;
766                });
767            });
768        }
769
770        const INPUT_ATTRIBUTE_RULES = {min: 'min', max: 'max', required: 'required', minlength: 'minlength', maxlength: 'maxlength', step: 'step', pattern: 'pattern'}
771        const INPUT_TYPE_RULES = {email: 'email'}
772
773        function getRules(element) {
774            let rules = {};
775            Object.keys(INPUT_ATTRIBUTE_RULES).forEach(attrName => {
776                if (element.hasAttribute(attrName)) {
777                    rules[INPUT_ATTRIBUTE_RULES[attrName]] = element.getAttribute(attrName);
778                }
779            })
780            if (INPUT_TYPE_RULES[element.type]) {
781                rules[INPUT_TYPE_RULES[element.type]] = true;
782            }
783
784            if (element.dataset.validate) {
785                try {
786                    Object.assign(rules, JSON.parse(element.dataset.validate));
787                } catch (error) {
788                    console.error('Validator error. Cannot parse data-validate attribute of element:\n', element);
789                }
790            }
791
792            return rules;
793        }
794
795        function isInvalidRuleResult(ruleState) {
796            return typeof ruleState === 'string' || !ruleState || (ruleState.type && ruleState.content);
797        }
798
799        async function runValidateFn(rule, options, value, field) {
800            return formValidationRules[rule](value, options, field, this);
801        }
802
803        function generateId() {
804            let id;
805            do {
806                id = `${this.idPrefix}-${++this.idSeq}`;
807            } while (document.getElementById(id));
808            return id;
809        }
810
811        function isVisible(element) {
812            const el = element.type !== 'hidden' ? element : (element.parentElement || {});
813            return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)
814        }
815
816        function elementWillValidate(element) {
817            return (element.willValidate || element.type === 'hidden')
818                && element.tagName !== 'BUTTON'
819                && element.disabled === false
820                && !(element.tagName === 'INPUT' && element.type === 'submit')
821                && (element.hasAttribute('data-validate-hidden') || isVisible(element))
822        }
823
824        function createMessageContainer(el, fieldWrapperClassName) {
825            if (! el.parentElement) {
826                return;
827            }
828            const refocus = document.activeElement === el;
829            const wrapper = document.createElement('div');
830            wrapper.classList.add.apply(wrapper.classList, fieldWrapperClassName.split(' '));
831            el.parentElement.insertBefore(wrapper, el);
832            wrapper.appendChild(el);
833            refocus && document.activeElement !== el && el.focus();
834            return wrapper;
835        }
836
837        function containerNotFound(selector, el) {
838            const msg = `Cannot find message container element ${selector} of ${el.name}`;
839            console.error(msg, el);
840            throw msg;
841        }
842
843        function createTextInputFrom(el) {
844            const text = document.createElement('INPUT');
845            text.type = 'text';
846            text.value = el.value;
847            return text;
848        }
849
850        function classNamesToSelector(classNames) {
851            return classNames.split(' ')
852                .filter(className => className.length > 0)
853                .map(className => `.${className}`)
854                .join('')
855        }
856
857        function hasMessagesWrapper(field, messagesWrapperClassName) {
858            return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName));
859        }
860
861        function getMessagesWrapper(field, messagesWrapperClassName) {
862            if (hasMessagesWrapper.call(this, field, messagesWrapperClassName)) {
863                return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName));
864            }
865
866            const msgWrapper = document.createElement('ul');
867            const msgId = generateId.call(this);
868            msgWrapper.id = msgId;
869            field.element.setAttribute('aria-errormessage', msgId);
870            field.element.setAttribute('aria-describedby', msgId);
871            msgWrapper.classList.add.apply(msgWrapper.classList, messagesWrapperClassName.split(' '));
872            if (field.validateOnChange) {
873                msgWrapper.setAttribute('aria-live', 'polite');
874            }
875            this.getMessageContainer(field).appendChild(msgWrapper);
876
877            return msgWrapper;
878        }
879
880        function getCheckedValues(field) {
881            const name = field.element.name.replace(/([\\"])/g, '\\$1');
882            const elements = field.element.form.querySelectorAll('input[name="' + name + '"]:checked');
883            return Array.from(elements).map(el => el.value);
884        }
885
886        function escapeHtml(s) {
887            const div = document.createElement('div')
888            div.innerText = s;
889            return div.innerHTML;
890        }
891
892        
893        function formValidation(form, options = {}) {
894            const formElement = form || this.$el;
895
896            if (formElement.dataset && formElement.dataset.options) {
897                try {
898                    options = Object.assign(options, JSON.parse(formElement.dataset.options || '{}'));
899                } catch (e) {
900                    throw new Error('Cannot read the form options from the data-options attribute: not val
900id JSON');
901                }
902            }
903
904            // Disable browser default validation
905            if (formElement.tagName === 'FORM') {
906                formElement.setAttribute('novalidate', '');
907            } else {
908                console.error('formValidation can be initialized only on FORM element', formElement);
909                return;
910            }
911
912            options = Object.assign({
913                fieldWrapperClassName: 'field field-reserved',
914                messagesWrapperClassName: 'messages',
915                validClassName: 'field-success',
916                invalidClassName: 'field-error',
917                pageMessagesWrapperSelector: null,
918                scrollToFirstError: true,
919            }, options || {});
920
921            return {
922                state: {
923                    valid: false,
924                },
925                fields: {},
926                idSeq: 0,
927                idPrefix: formElement.id || 'vld-msg',
928                setupFields(elements) {
929                    this.fields = {};
930                    Array.from(elements).forEach(element => {
931                        if (elementWillValidate(element)) {
932                            this.setupField(element);
933                        }
934                    });
935                },
936                setupField(element) {
937                    if (! element) return;
938                    const onChange = !!element.dataset.onChange;
939                    if (elementWillValidate(element)) {
940                        const rules = getRules(element);
941                        if (Object.keys(rules).length > 0) {
942                            if (this.fields[element.name]) {
943                                Object.assign(this.fields[element.name].rules, rules);
944                            } else {
945                                this.fields[element.name] = {
946                                    element,
947                                    rules: rules,
948                                    validateOnChange: onChange,
949                                    state: {
950                                        valid: null,
951                                        rules: {}
952                                    }
953                                }
954                            }
955                        }
956                    } else {
957                        console.error('Element will not validate', element);
958                    }
959                },
960                onSubmit(event) {
961                    if (event.target.tagName === 'FORM') {
962                        event.preventDefault();
963
964                        this.validate()
965                            .then(() => event.target.submit())
966                            .catch(invalidElements => {});
967                    }
968                },
969                onChange(event) {
970                    event.target.dataset.onChange = 'true';
971                    if (!Object.keys(this.fields).length) {
972                        this.setupFields(formElement.elements);
973                    }
974                    if (!Object.keys(this.fields).includes(event.target.name)) {
975                        this.setupField(event.target);
976                    }
977                    const field = this.fields[event.target.name];
978
979                    this.validateField(field);
980                    field && field.element.removeAttribute('data-on-change')
981                },
982                validateSafe() {
983                    return new Promise(resolve => this.validate().then(() => resolve(true)).catch(() => {}))
984                },
985                validate() {
986                    if (!Object.keys(this.fields).length || !Object.keys(this.fields).length !== formElement.elements.length) {
987                        this.setupFields(formElement.elements);
988                    }
989                    return new Promise(async (resolve, reject) => {
990                        if (formElement.elements) {
991                                                        await raceSome(this.validateFields(), result => result !== true)
992                            const invalidFields = Object.values(this.fields).filter(field => !field.state.valid);
993                            this.state.valid = invalidFields.length === 0;
994                            if (this.state.valid) {
995                                resolve();
996                            } else {
997                                if (options.scrollToFirstError && invalidFields.length > 0) {
998                                    invalidFields[0].element.focus()
999                                    invalidFields[0].element.select && invalidFields[0].element.select();
1000                                }
1001                                reject(invalidFields.map(field => field.element));
1002                            }
1003                        }
1004                    });
1005                },
1006                                validateFields() {
1007                    const fields = Object.values(this.fields);
1008
1009                                        fields.forEach(field => {
1010                        this.getMessageContainer(field).classList.remove(options.validClassName, options.invalidClassName)
1011                    });
1012                                        return fields.map(field => this.validateField(field))
1013                },
1014                                validateField(field) {
1015                                        if (! field || ! elementWillValidate(field.element)) {
1016                        return new Promise(resolve => resolve(true))
1017                    }
1018
1019                    let value;
1020                    if (field.element.type === 'checkbox') {
1021                        value = getCheckedValues(field);
1022                    } else if (field.element.type === 'radio') {
1023                        value = getCheckedValues(field)[0] || undefined;
1024                    } else if (field.element.tagName === 'SELECT' && field.element.multiple) {
1025                        value = Array.from(field.element.selectedOptions).map(opt => opt.value);
1026                    } else {
1027                        value = field.element.value;
1028                    }
1029
1030                    const rules = field.rules || {};
1031
1032                                        field.state.valid = true;
1033                    this.showFieldState(field);
1034
1035                
1036                                        const fieldValidations = Object.keys(rules).filter(rule => formValidationRules[rule]).map(async rule => {
1037                        return runValidateFn.call(this, rule, rules[rule], value, field).then(result => {
1038                            field.state.rules[rule] = result;
1039                            return result;
1040                        })
1041                    });
1042
1043                    return new Promise(resolve => {
1044                                                Promise.all(fieldValidations).then(results => {
1045                                                                                    field.state.valid = !elementWillValidate(field.element) || rules.length === 0 || !results.some(isInvalidRuleResult)
1046                            this.showFieldState(field);
1047                            resolve(field.state.valid);
1048                        })
1049                    });
1050                },
1051                                getMessagesByField(field) {
1052                    const messages = [];
1053                    const invalidRules = Object.keys(field.state.rules).filter(rule => isInvalidRuleResult(field.state.rules[rule]));
1054
1055                    field.rules && Object.keys(field.rules).forEach((rule) => {
1056                        if (invalidRules.includes(rule)) {
1057                            const customMessage = field.element.getAttribute('data-msg-' + rule);
1058                            const message = customMessage ? customMessage : field.state.rules[rule];
1059                            const ruleOptions = JSON.parse(JSON.stringify(field.rules[rule]));
1060
1061                            if (typeof message === 'undefined' || message === null || (typeof message !== 'string' && ! message.type)) {
1062                                messages.push(hyva.strf('Validation rule "%0" failed.', rule));
1063                            } else if (Array.isArray(ruleOptions)) {
1064                                ruleOptions.unshift(message.type ? message.content : message);
1065                                const content = hyva.strf.apply(null, ruleOptions);
1066                                messages.push(message.type ? {type: message.type, content} : content);
1067                            } else {
1068                                const content = hyva.strf(message.type ? message.content : message, ruleOptions)
1069                                messages.push(message.type ? {type: message.type, content} : content);
1070                            }
1071                        }
1072                    });
1073                    return messages;
1074                },
1075                /** @deprecated */
1076                getFieldWrapper(field) {
1077                                        return this.getMessageContainer(field)
1078                },
1079                getMessageContainer(field) {
1080                    let container;
1081                    const pageSelector = field.element.getAttribute('data-validation-container') || options.pageMessagesContainerSelector;
1082                    if (pageSelector) {
1083                        container = document.querySelector(pageSelector)
1084                            || containerNotFound(pageSelector, field.element)
1085                    } else {
1086                        const containerSelector = classNamesToSelector(options.fieldWrapperClassName);
1087                        container = field.element.closest(containerSelector)
1088                            || createMessageContainer(field.element, options.fieldWrapperClassName)
1089                            || containerNotFound(containerSelector, field.element);
1090                    }
1091
1092                    return container;
1093                },
1094                showFieldState(field) {
1095                    const container = this.getMessageContainer(field),
1096                        hasErrorMessages = hasMessagesWrapper.call(this, field, options.messagesWrapperClassName),
1097                        messages = this.getMessagesByField(field).map(m => {
1098                            return m.type !== 'html' ? escapeHtml(m.type ? m.content : m) : m.content;
1099                        });
1100                    container.classList.toggle(options.validClassName, field.state.valid && ! hasErrorMessages);
1101                    container.classList.toggle(options.invalidClassName, !field.state.valid || hasErrorMessages);
1102                    this.createHtmlErrorMessage(field, messages);
1103
1104                    if (field.state.valid) {
1105                        field.element.removeAttribute('aria-invalid');
1106                    } else {
1107                        field.element.setAttribute('aria-invalid', 'true');
1108                        if (! document.activeElement) {
1109                            field.element.focus();
1110                        }
1111                    }
1112                },
1113                removeMessages(field, messagesClass) {
1114                    if (! hasMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName)) {
1115                        return;
1116                    }
1117
1118                    const msgWrapper = getMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName);
1119                    const messages = msgWrapper.querySelectorAll(`[data-msg-field='${field.element.name}']`);
1120                    Array.from(messages).forEach(msg => msg.remove());
1121                    if (msgWrapper && msgWrapper.childElementCount === 0) {
1122                        field.element.removeAttribute('aria-errormessage');
1123                        field.element.removeAttribute('aria-describedby');
1124                        msgWrapper.remove();
1125                    }
1126                },
1127                createErrorMessage(field, messages) {
1128                    const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml)
1129                    this.createHtmlErrorMessage(field, htmlMessages);
1130                },
1131                createHtmlErrorMessage(field, messages) {
1132                    this.removeMessages(field, options.messagesWrapperClassName);
1133                    field.element.removeAttribute('aria-errormessage');
1134                    field.element.removeAttribute('aria-describedby');
1135
1136                    if (!field.state.valid) {
1137                        const msgWrapper = this.addHtmlMessages(field, options.messagesWrapperClassName, messages);
1138                        field.element.setAttribute('aria-errormessage', msgWrapper.id);
1139                        field.element.setAttribute('aria-describedby', msgWrapper.id);
1140                    }
1141                },
1142                /** @deprecated */
1143                createMessage(field, message) {
1144                                        return this.addMessages(field, options.messagesWrapperClassName, message);
1145                },
1146                addMessages(field, messagesClass, messages) {
1147                    const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml)
1148                    return this.addHtmlMessages(field, messagesClass, htmlMessages);
1149                },
1150                addHtmlMessages(field, messagesClass, htmlMessages) {
1151                    const msgWrapper = getMessagesWrapper.call(this, field, messagesClass);
1152
1153                    (Array.isArray(htmlMessages) ? htmlMessages : [htmlMessages]).forEach((htmlMessage) => {
1154                        const li = document.createElement('li');
1155                        li.innerHTML = htmlMessage;
1156                        li.setAttribute('data-msg-field', field.element.name);
1157                        msgWrapper.appendChild(li);
1158                    });
1159
1160                    return msgWrapper;
1161                },
1162                setField(name, value) {
1163                    this.fields[name].element.value = value;
1164                    this.fields[name].element.dispatchEvent((new Event('input')));
1165                    this.validateField(this.fields[name]);
1166                }
1167            }
1168        }
1169
1170        function getFieldName(field) {
1171                        const fieldName = field.element?.getAttribute('title')
1172                || document.querySelector(`label[for="${field.element?.id}"]`)?.innerText;
1173
1174            return fieldName
1175                ? fieldName.trim()
1176                : '';
1177        }
1178
1179        hyva.formValidation = formValidation;
1180        hyva.formValidation.rules = formValidationRules;
1181        hyva.formValidation.setInputAttributeRuleName = (attrName, ruleName) => INPUT_ATTRIBUTE_RULES[attrName] = ruleName || attrName;
1182        hyva.formValidation.setInputTypeRuleName = (typeName, ruleName) => INPUT_TYPE_RULES[typeName] = ruleName || typeName;
1183        hyva.formValidation.addRule = (name, validator) => formValidationRules[name] = validator;
1184        hyva.formValidation.getFieldName = getFieldName;
1185    }(window.hyva = window.hyva || {}));
1186
1187    window.addEventListener('alpine:init', () => {
1188        Alpine.data('hyva.formValidation', hyva.formValidation);
1189        Alpine.data('hyva.formValidation($el)', hyva.formValidation);
1190    }, {once: true});
1191    //# sourceURL=hyva-advanced-form-validation.js
1192</script>
1192
1193<div class="page-wrapper"><header class="page-header"><a class="action skip sr-only focus:not-sr-only focus:absolute focus:z-40 focus:bg-white
1194   contentarea"
1195   href="#contentarea">
1196    <span>
1197        Skip to Content    </span>
1198</a>
1199<script>
1200  function initHeader() {
1201    return {
1202      // estado
1203      searchOpen: false,
1204      cart: {},
1205      isCartOpen: false,
1206
1207      // scroll behavior
1208      lastScrollY: 0,
1209      showHeader: true, // visible al cargar
1210      overlayOpen: false, // menú/buscador/minicart abiertos
1211
1212      // medidas/posiciones
1213      noticeHeight: 0,
1214      headerHeight: 0,
1215      topValue: '0px', // se bindea al style del header
1216
1217      init() {
1218        this.lastScrollY = window.scrollY || 0;
1219
1220        this.measureBars();
1221        this.applyBodyPadding();
1222        this.updateTop(); // coloca el header en su sitio según estado actual
1223
1224        this.setupOverlayWatchers();
1225        this.setupScrollListener();
1226        this.setupResizeListener();
1227        this.observeDomChanges();
1228      },
1229
1230      isDesktop() {
1231        return window.matchMedia('(min-width: 1024px)').matches;
1232      },
1233
1234      setupOverlayWatchers() {
1235        const update = () => {
1236          const html = document.documentElement;
1237          const body = document.body;
1238          const has = (cls) => html.classList.contains(cls) || body.classList.contains(cls);
1239          this.overlayOpen = this.isCartOpen ||
1240            has('mobile-menu-open') || has('menu-open') || has('nav-open') ||
1241            has('mobile-search-open') || has('drawer-open') || has('offcanvas-open');
1242
1243          if (this.overlayOpen) {
1244            this.showHeader = true; // nunca ocultes con overlays abiertos
1245            this.updateTop();
1246          }
1247        };
1248        const opts = {
1249          attributes: true,
1250          attributeFilter: ['class']
1251        };
1252        new MutationObserver(update).observe(document.documentElement, opts);
1253        new MutationObserver(update).observe(document.body, opts);
1254        window.addEventListener('resize', update, {
1255          passive: true
1256        });
1257        update();
1258      },
1259
1260      setupScrollListener() {
1261        const onScroll = () => {
1262          const current = window.scrollY || 0;
1263
1264          if (this.overlayOpen || this.isDesktop()) {
1265            // desktop: sin sticky; overlays: no ocultar
1266            this.showHeader = true;
1267          } else {
1268            // móvil: oculta al bajar (tras 100px), muestra al subir
1269            this.showHeader = !(current > this.lastScrollY && current > 100);
1270          }
1271
1272          this.lastScrollY = current;
1273          this.updateTop();
1274        };
1275
1276        // RAF throttling básico
1277        let ticking = false;
1278        const handle = () => {
1279          if (!ticking) {
1280            ticking = true;
1281            requestAnimationFrame(() => {
1282              onScroll();
1283              ticking = false;
1284            });
1285          }
1286        };
1287
1288        onScroll(); // estado correcto al inicio
1289        window.addEventListener('scroll', handle, {
1290          passive: true
1291        });
1292      },
1293
1294      setupResizeListener() {
1295        window.addEventListener('resize', () => {
1296          this.measureBars();
1297          this.applyBodyPadding();
1298          this.updateTop();
1299        }, {
1300          passive: true
1301        });
1302      },
1303
1304      // Calcula alturas de notice (si existe) y header
1305      measureBars() {
1306        const headerEl = document.getElementById('header');
1307        const explicitNotice = document.querySelector('#site-notice');
1308        const prevSibling = headerEl ? headerEl.previousElementSibling : null;
1309        const fallbackNotice = document.querySelector('#notification, .page-notice, .page.messages, .messages');
1310        const bar = explicitNotice || prevSibling || fallbackNotice;
1311
1312        this.noticeHeight = (bar && getComputedStyle(bar).display !== 'none') ? (bar.offsetHeight || 0) : 0;
1313        this.headerHeight = headerEl ? (headerEl.offsetHeight || 0) : 0;
1314
1315        // variables CSS útiles (por si las usas en otros sitios)
1316        document.documentElement.style.setProperty('--page-header-height', `${this.headerHeight}px`);
1317        const total = this.headerHeight + (!this.isDesktop() ? this.noticeHeight : 0);
1318        document.documentElement.style.setProperty('--page-header-total', `${total}px`);
1319      },
1320
1321      // En móvil empuja el body por debajo (header + notice). En desktop, sin padding extra (como tenías)
1322      applyBodyPadding() {
1323        if (!this.isDesktop()) {
1324          const total = this.headerHeight + this.noticeHeight;
1325          document.body.style.paddingTop = `${total}px`;
1326        } else {
1327          document.body.style.paddingTop = '';
1328        }
1329      },
1330
1331      // No usamos transform: solo movemos con top (no rompe position: fixed de los hijos)
1332      updateTop() {
1333        if (this.isDesktop()) {
1334          // desktop: header es relative, 'top' no aplica pero no estorba
1335          this.topValue = '0px';
1336          return;
1337        }
1338        this.topValue = this.showHeader ? `${this.noticeHeight}px` : `-${this.headerHeight}px`;
1339      },
1340
1341      // Observa posibles cambios en el DOM que alteren alturas (ej: aparece un mensaje)
1342      observeDomChanges() {
1343        if (!window.MutationObserver) return;
1344        const obs = new MutationObserver(() => {
1345          this.$nextTick(() => {
1346            this.measureBars();
1347            this.applyBodyPadding();
1348            this.updateTop();
1349          });
1350        });
1351        obs.observe(document.body, {
1352          childList: true,
1353          subtree: true
1354        });
1355      },
1356
1357      // --- Igual que tu header antiguo ---
1358      summaryCount() {
1359        return this.cart.summary_count || 0;
1360      },
1361      getData() {
1362        const data = this.$event.detail.data;
1363        if (data.cart) this.cart = data.cart;
1364      },
1365      ariaLabel() {
1366        return 'Toggle\u0020minicart, ' +
1367          (this.isCartEmpty() ? 'El\u0020carrito\u0020est\u00E1\u0020vac\u00EDo' : (
1368            Math.abs(this.summaryCount()) > 1 ?
1369            hyva.str('\u00251\u0020items', this.summaryCount()) :
1370            hyva.str('\u00251\u0020art\u00EDculo', this.summaryCount())
1371          ));
1372      },
1373      isCartEmpty() {
1374        return !this.summaryCount();
1375      },
1376      openCart() {
1377        this.$dispatch('toggle-cart', {
1378          isOpen: true
1379        });
1380      },
1381      toggleCart() {
1382        const event = this.$event;
1383        if (event.detail && event.detail.isOpen !== undefined) {
1384          this.isCartOpen = event.detail.isOpen;
1385          if (!this.isCartOpen && this.$refs && this.$refs.cartButton) this.$refs.cartButton.focus();
1386        } else {
1387          this.isCartOpen = true;
1388        }
1389      },
1390
1391      // -------- BUSCADOR (TOGGLE) --------
1392      toggleSearch() {
1393        const html = document.documentElement;
1394        const body = document.body;
1395        const site = document.getElementById('site-search');
1396        if (!site) return;
1397
1398        const isHidden = getComputedStyle(site).display === 'none';
1399
1400        if (isHidden) {
1401          html.classList.add('mobile-search-open');
1402          body.classList.add('mobile-search-open');
1403          html.classList.remove('mobile-search-closed');
1404          body.classList.remove('mobile-search-closed');
1405
1406          this.$nextTick(() => {
1407            try {
1408              site.scrollIntoView({
1409                behavior: 'smooth',
1410                block: 'start'
1411              });
1412            } catch (e) {}
1413          });
1414        } else {
1415          html.classList.remove('mobile-search-open');
1416          body.classList.remove('mobile-search-open');
1417          html.classList.add('mobile-search-closed');
1418          body.classList.add('mobile-search-closed');
1419
1420          const i = site.querySelector('input[type=search]');
1421          if (i) i.blur();
1422        }
1423      },
1424      // -----------------------------------
1425
1426      searchClosed() {
1427        return !this.searchOpen;
1428      },
1429      toggleSearchForm() {
1430        this.searchOpen = !this.searchOpen;
1431        this.$dispatch('search-open');
1432      },
1433      searchClose() {
1434        this.searchOpen = false;
1435      },
1436      searchEscape() {
1437        this.searchOpen = false;
1438        this.$refs.searchButton && this.$refs.searchButton.focus();
1439      },
1440    }
1441  }
1442
1443  function initCompareHeader() {
1444    return {
1445      compareProducts: null,
1446      itemCount: 0,
1447      hiddenIfEmpty() {
1448        return {
1449          'hidden': this.itemCount < 1
1450        }
1451      },
1452      linkAriaLabel() {
1453        const countLabel = this.itemCount > 1 ?
1454          hyva.str('\u00251\u0020productos', this.itemCount) :
1455          hyva.str('\u00251\u0020producto', this.itemCount);
1456        return `Comparar\u0020Productos (${countLabel})`;
1457      },
1458      receiveCompareData() {
1459        const data = this.$event.detail.data;
1460        if (data['compare-products'] && data['compare-products'].count) {
1461          this.compareProducts = data['compare-products'];
1462          this.itemCount = this.compareProducts.count;
1463        }
1464      },
1465      itemCountLabel() {
1466        return `(${this.itemCount})`;
1467      }
1468    }
1469  }
1470
1471  function initWishlistHeader() {
1472    return {
1473      wishlistProducts: null,
1474      itemCount: 0,
1475      linkAriaLabel() {
1476        const countLabel = this.itemCount > 1 ?
1477          hyva.str('\u00251\u0020productos', this.itemCount) :
1478          hyva.str('\u00251\u0020producto', this.itemCount);
1479        return `Wishlist\u0020Products (${countLabel})`;
1480      },
1481      receiveWishlistData() {
1482        const data = this.$event.detail.data;
1483        this.itemCount = data.wishlist && data.wishlist.items ? data.wishlist.items.length : 0;
1484      }
1485    }
1486  }
1487
1488  window.addEventListener('alpine:init', () => {
1489    Alpine.data('initHeader', initHeader);
1490    Alpine.data('initCompareHeader', initCompareHeader);
1491    Alpine.data('initWishlistHeader', initWishlistHeader);
1492  }, {
1493    once: true
1494  });
1495
1496  // Cerrar con ESC (global)
1497  window.addEventListener('keydown', (e) => {
1498    if (e.key === 'Escape') {
1499      document.documentElement.classList.remove('mobile-search-open');
1500      document.body.classList.remove('mobile-search-open');
1501      document.documentElement.classList.add('mobile-search-closed');
1502      document.body.classList.add('mobile-search-closed');
1503    }
1504  });
1505</script>
1505
1506
1507<div
1508  id="header"
1509  x-data="initHeader"
1510  class="z-30 bg-white fixed left-0 right-0 lg:relative transition-all duration-300 ease-in-out"
1511  @private-content-loaded.window="getData"
1512  @resize.window="measureBars"
1513  :style="{ top: topValue }">
1514
1515  <div class="container pt-3.5 mt-4 lg:pb-3.5 grid grid-cols-[auto_minmax(0px,1fr)_auto]
1516              lg:grid-cols-[auto_minmax(0px,1fr)_auto] gap-y-3.5 lg:gap-y-0 gap-x-4 lg:gap-x-10 items-center">
1517    <nav
1518    x-data="initMenuMobile"
1519    @load.window="setActiveMenu"
1520    @keydown.window.escape="closeMenu"
1521    class="navigation lg:hidden"
1522    aria-label="Navegaci&#xF3;n"
1523    role="navigation">
1524    <button
1525        x-ref="mobileMenuTrigger"
1526        @click="openMenu"
1527        type="button"
1528        class="p-2 rounded-md ring-1 ring-black/5 shadow-sm bg-white hover:bg-slate-50 active:scale-95 transition"
1529        aria-label="Abrir&#x20;men&#xFA;"
1530        aria-haspopup="menu"
1531        :aria-expanded="open"
1532        :hidden="open">
1533        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-7 h-7" width="28" height="28" aria-hidden="true">
1534  <path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16"/>
1535</svg>
1536    </button>
1537
1538    <div
1539        x-ref="mobileMenuNavLinks"
1540        class="fixed inset-x-0 z-40 hidden"
1541        style="top: var(--page-header-height); height: calc(100% - var(--page-header-height));"
1542        :class="{ 'block': open, 'hidden': !open }"
1543        :aria-hidden="closed"
1544        role="dialog"
1545        aria-modal="true">
1546
1547        <div
1548            class="absolute inset-0 bg-black/55 backdrop-blur-md"
1549            @click="closeMenu"
1550            x-show="open"
1551            x-transition:enter="transition ease-out duration-250"
1552            x-transition:enter-start="opacity-0"
1553            x-transition:enter-end="opacity-100"
1554            x-transition:leave="transition ease-in duration-200"
1555            x-transition:leave-start="opacity-100"
1556            x-transition:leave-end="opacity-0"></div>
1557
1558        <div
1559            class="drawer-panel absolute inset-y-0 left-0 w-full max-w-[92vw] bg-white dark:bg-slate-900 border-r border-slate-200/60 dark:border-slate-700/60 shadow-2xl rounded-r-2xl overflow-hidden flex flex-col"
1560            x-show="open"
1561            x-transition:enter="transition-transform ease-out duration-350"
1562            x-transition:enter-start="-translate-x-full"
1563            x-transition:enter-end="translate-x-0"
1564            x-transition:leave="transition-transform ease-in duration-250"
1565            x-transition:leave-start="translate-x-0"
1566            x-transition:leave-end="-translate-x-full">
1567
1568            <div class="relative flex items-center justify-between px-4 py-3 border-b border-slate-200/70 bg-white/85 backdrop-blur">
1569                <span class="text-base font-semibold tracking-tight text-slate-900">Menú</span>
1570                <button
1571                    @click="closeMenu"
1572                    class="p-2 rounded-md hover:bg-slate-100 transition focus:outline-none focus-visible:ring-2 focus-visible:ring-[#1a798e]"
1573                    aria-label="Cerrar&#x20;men&#xFA;"
1574                    type="button">
1575                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6" width="24" height="24" aria-hidden="true">
1576  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
1577</svg>
1578                </button>
1579            </div>
1580
1581            <div class="flex-1 overflow-y-auto">
1582                <ul class="py-2" aria-label="Enlaces&#x20;de&#x20;navegaci&#xF3;n">
1583                                                                    <li data-child-id="category-node-37-main" class="level-0">
1584                                                            <button
1585                                    type="button"
1586                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
1587                                    @click="toggleSubcategory('category-node-37')"
1588                                    :aria-expanded="isOpen('category-node-37')"
1589                                    aria-controls="panel-category-node-37">
1590                                    <span class="text-[15px] font-medium text-slate-900">
1591                                        Salones Modernos                                    </span>
1592
1593                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-37') ? 'rotate-180' : ''">
1594  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
1595</svg>
1596                                </button>
1597                            
1598                                                            <div
1599                                    id="panel-category-node-37"
1600                                    x-ref="panel-category-node-37"
1601                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
1602                                    style="max-height:0; opacity:0; display:none;">
1603                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
1604                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
1605                                            <li>
1606                                                <a
1607                                                    href="https://www.mueblesbonitos.com/salon"
1608                                                    title="Salones&#x20;Modernos"
1609                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
1610                                                    <span class="ml-1">Ver todos/as</span>
1611                                                </a>
1612                                            </li>
1613
1614                                                                                            <li>
1615                                                    <a
1616                                                        href="https://www.mueblesbonitos.com/salon/mueble-tv"
1617                                                        title="Mueble&#x20;TV"
1618                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1619                                                        <span class="ml-1">Mueble TV</span>
1620                                                    </a>
1621                                                </li>
1622                                                                                            <li>
1623                                                    <a
1624                                                        href="https://www.mueblesbonitos.com/salon/aparadores"
1625                                                        title="Aparador"
1626                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1627                                                        <span class="ml-1">Aparador</span>
1628                                                    </a>
1629                                                </li>
1630                                                                                            <li>
1631                                                    <a
1632                                                        href="https://www.mueblesbonitos.com/salon/mesas-de-centro"
1633                                                        title="Mesas&#x20;de&#x20;Centro"
1634                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1635                                                        <span class="ml-1">Mesas de Centro</span>
1636                                                    </a>
1637                                                </li>
1638                                                                                            <li>
1639                                                    <a
1640                                                        href="https://www.mueblesbonitos.com/salon/mesas-y-sillas-de-comedor"
1641                                                        title="Mesas&#x20;de&#x20;Comedor"
1642                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1643                                                        <span class="ml-1">Mesas de Comedor</span>
1644                                                    </a>
1645                                                </li>
1646                                                                                            <li>
1647                                                    <a
1648                                                        href="https://www.mueblesbonitos.com/salon/estanterias"
1649                                                        title="Estanter&#xED;as&#x20;de&#x20;Dise&#xF1;o"
1650                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1651                                                        <span class="ml-1">Estanterías de Diseño</span>
1652                                                    </a>
1653                                                </li>
1654                                                                                            <li>
1655                                                    <a
1656                                                        href="https://www.mueblesbonitos.com/salon/vitrinas"
1657                                                        title="Vitrinas"
1658                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1659                                                        <span class="ml-1">Vitrinas</span>
1660                                                    </a>
1661                                                </li>
1662                                                                                            <li>
1663                                                    <a
1664                                                        href="https://www.mueblesbonitos.com/salon/armario"
1665                                                        title="Armarios&#x20;de&#x20;Sal&#xF3;n"
1666                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1667                                                        <span class="ml-1">Armarios de Salón</span>
1668                                                    </a>
1669                                                </li>
1670                                                                                            <li>
1671                                                    <a
1672                                                        href="https://www.mueblesbonitos.com/salon/conjuntos-de-salon"
1673                                                        title="Conjuntos&#x20;de&#x20;Sal&#xF3;n"
1674                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1675                                                        <span class="ml-1">Conjuntos de Salón</span>
1676                                                    </a>
1677                                                </li>
1678                                                                                            <li>
1679                                                    <a
1680                                                        href="https://www.mueblesbonitos.com/salon/muebles-con-chimenea"
1681                                                        title="Muebles&#x20;con&#x20;Chimenea"
1682                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1683                                                        <span class="ml-1">Muebles con Chimenea</span>
1684                                                    </a>
1685                                                </li>
1686                                                                                    </ul>
1687                                    </div>
1688                                </div>
1689                                                    </li>
1690                                                                    <li data-child-id="category-node-110-main" class="level-0">
1691                                                            <button
1692                                    type="button"
1693                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
1694                                    @click="toggleSubcategory('category-node-110')"
1695                                    :aria-expanded="isOpen('category-node-110')"
1696                                    aria-controls="panel-category-node-110">
1697                                    <span class="text-[15px] font-medium text-slate-900">
1698                                        Recibidores                                    </span>
1699
1700                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-110') ? 'rotate-180' : ''">
1701  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
1702</svg>
1703                                </button>
1704                            
1705                                                            <div
1706                                    id="panel-category-node-110"
1707                                    x-ref="panel-category-node-110"
1708                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
1709                                    style="max-height:0; opacity:0; display:none;">
1710                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
1711                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
1712                                            <li>
1713                                                <a
1714                                                    href="https://www.mueblesbonitos.com/recibidores"
1715                                                    title="Recibidores"
1716                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
1717                                                    <span class="ml-1">Ver todos/as</span>
1718                                                </a>
1719                                            </li>
1720
1721                                                                                            <li>
1722                                                    <a
1723                                                        href="https://www.mueblesbonitos.com/recibidores/consolas-y-zapateros"
1724                                                        title="Consola&#x20;Recibidor"
1725                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1726                                                        <span class="ml-1">Consola Recibidor</span>
1727                                                    </a>
1728                                                </li>
1729                                                                                            <li>
1730                                                    <a
1731                                                        href="https://www.mueblesbonitos.com/recibidores/conjuntos-con-espejo"
1732                                                        title="Recibidor&#x20;con&#x20;Espejo"
1733                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1734                                                        <span class="ml-1">Recibidor con Espejo</span>
1735                                                    </a>
1736                                                </li>
1737                                                                                    </ul>
1738                                    </div>
1739                                </div>
1740                                                    </li>
1741                                                                    <li data-child-id="category-node-3-main" class="level-0">
1742                                                            <button
1743                                    type="button"
1744                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
1745                                    @click="toggleSubcategory('category-node-3')"
1746                                    :aria-expanded="isOpen('category-node-3')"
1747                                    aria-controls="panel-category-node-3">
1748                                    <span class="text-[15px] font-medium text-slate-900">
1749                                        Dormitorios                                    </span>
1750
1751                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-3') ? 'rotate-180' : ''">
1752  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
1753</svg>
1754                                </button>
1755                            
1756                                                            <div
1757                                    id="panel-category-node-3"
1758                                    x-ref="panel-category-node-3"
1759                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
1760                                    style="max-height:0; opacity:0; display:none;">
1761                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
1762                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
1763                                            <li>
1764                                                <a
1765                                                    href="https://www.mueblesbonitos.com/dormitorio"
1766                                                    title="Dormitorios"
1767                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
1768                                                    <span class="ml-1">Ver todos/as</span>
1769                                                </a>
1770                                            </li>
1771
1772                                                                                            <li>
1773                                                    <a
1774                                                        href="https://www.mueblesbonitos.com/dormitorio/camas-de-matrimonio"
1775                                                        title="Camas&#x20;de&#x20;Matrimonio"
1776                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1777                                                        <span class="ml-1">Camas de Matrimonio</span>
1778                                                    </a>
1779                                                </li>
1780                                                                                            <li>
1781                                                    <a
1782                                                        href="https://www.mueblesbonitos.com/dormitorio/mesitas-de-noche"
1783                                                        title="Mesitas&#x20;de&#x20;Noche"
1784                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1785                                                        <span class="ml-1">Mesitas de Noche</span>
1786                                                    </a>
1787                                                </li>
1788                                                                                            <li>
1789                                                    <a
1790                                                        href="https://www.mueblesbonitos.com/dormitorio/armarios"
1791                                                        title="Armarios&#x20;Roperos"
1792                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1793                                                        <span class="ml-1">Armarios Roperos</span>
1794                                                    </a>
1795                                                </li>
1796                                                                                            <li>
1797                                                    <a
1798                                                        href="https://www.mueblesbonitos.com/dormitorio/comodas-y-cajoneras"
1799                                                        title="C&#xF3;modas"
1800                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1801                                                        <span class="ml-1">Cómodas</span>
1802                                                    </a>
1803                                                </li>
1804                                                                                            <li>
1805                                                    <a
1806                                                        href="https://www.mueblesbonitos.com/dormitorio/tocadores"
1807                                                        title="Tocador"
1808                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1809                                                        <span class="ml-1">Tocador</span>
1810                                                    </a>
1811                                                </li>
1812                                                                                    </ul>
1813                                    </div>
1814                                </div>
1815                                                    </li>
1816                                                                    <li data-child-id="category-node-841-main" class="level-0">
1817                                                            <button
1818                                    type="button"
1819                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
1820                                    @click="toggleSubcategory('category-node-841')"
1821                                    :aria-expanded="isOpen('category-node-841')"
1822                                    aria-controls="panel-category-node-841">
1823                                    <span class="text-[15px] font-medium text-slate-900">
1824                                        Muebles de Cocina                                    </span>
1825
1826                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-841') ? 'rotate-180' : ''">
1827  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
1828</svg>
1829                                </button>
1830                            
1831                                                            <div
1832                                    id="panel-category-node-841"
1833                                    x-ref="panel-category-node-841"
1834                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
1835                                    style="max-height:0; opacity:0; display:none;">
1836                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
1837                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
1838                                            <li>
1839                                                <a
1840                                                    href="https://www.mueblesbonitos.com/cocina"
1841                                                    title="Muebles&#x20;de&#x20;Cocina"
1842                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
1843                                                    <span class="ml-1">Ver todos/as</span>
1844                                                </a>
1845                                            </li>
1846
1847                                                                                            <li>
1848                                                    <a
1849                                                        href="https://www.mueblesbonitos.com/cocina/mesas-altas"
1850                                                        title="Mesas&#x20;Altas&#x20;de&#x20;Cocina"
1851                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1852                                                        <span class="ml-1">Mesas Altas de Cocina</span>
1853                                                    </a>
1854                                                </li>
1855                                                                                            <li>
1856                                                    <a
1857                                                        href="https://www.mueblesbonitos.com/cocina/taburetes"
1858                                                        title="Taburetes&#x20;de&#x20;Cocina"
1859                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1860                                                        <span class="ml-1">Taburetes de Cocina</span>
1861                                                    </a>
1862                                                </li>
1863                                                                                            <li>
1864                                                    <a
1865                                                        href="https://www.mueblesbonitos.com/cocina/armarios-de-cocina"
1866                                                        title="Armarios&#x20;de&#x20;Cocina"
1867                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1868                                                        <span class="ml-1">Armarios de Cocina</span>
1869                                                    </a>
1870                                                </li>
1871                                                                                    </ul>
1872                                    </div>
1873                                </div>
1874                                                    </li>
1875                                                                    <li data-child-id="category-node-843-main" class="level-0">
1876                                                            <button
1877                                    type="button"
1878                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
1879                                    @click="toggleSubcategory('category-node-843')"
1880                                    :aria-expanded="isOpen('category-node-843')"
1881                                    aria-controls="panel-category-node-843">
1882                                    <span class="text-[15px] font-medium text-slate-900">
1883                                        Muebles de Baño                                    </span>
1884
1885                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-843') ? 'rotate-180' : ''">
1886  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
1887</svg>
1888                                </button>
1889                            
1890                                                            <div
1891                                    id="panel-category-node-843"
1892                                    x-ref="panel-category-node-843"
1893                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
1894                                    style="max-height:0; opacity:0; display:none;">
1895                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
1896                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
1897                                            <li>
1898                                                <a
1899                                                    href="https://www.mueblesbonitos.com/bano"
1900                                                    title="Muebles&#x20;de&#x20;Ba&#xF1;o"
1901                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
1902                                                    <span class="ml-1">Ver todos/as</span>
1903                                                </a>
1904                                            </li>
1905
1906                                                                                            <li>
1907                                                    <a
1908                                                        href="https://www.mueblesbonitos.com/bano/conjuntos-de-bano"
1909                                                        title="Conjuntos&#x20;de&#x20;ba&#xF1;o"
1910                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1911                                                        <span class="ml-1">Conjuntos de baño</span>
1912                                                    </a>
1913                                                </li>
1914                                                                                            <li>
1915                                                    <a
1916                                                        href="https://www.mueblesbonitos.com/bano/columnas-y-armarios-de-bano"
1917                                                        title="Columna&#x20;de&#x20;Ba&#xF1;o"
1918                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1919                                                        <span class="ml-1">Columna de Baño</span>
1920                                                    </a>
1921                                                </li>
1922                                                                                    </ul>
1923                                    </div>
1924                                </div>
1925                                                    </li>
1926                                                                    <li data-child-id="category-node-76-main" class="level-0">
1927                                                            <button
1928                                    type="button"
1929                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
1930                                    @click="toggleSubcategory('category-node-76')"
1931                                    :aria-expanded="isOpen('category-node-76')"
1932                                    aria-controls="panel-category-node-76">
1933                                    <span class="text-[15px] font-medium text-slate-900">
1934                                        Muebles Auxiliares                                    </span>
1935
1936                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-76') ? 'rotate-180' : ''">
1937  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
1938</svg>
1939                                </button>
1940                            
1941                                                            <div
1942                                    id="panel-category-node-76"
1943                                    x-ref="panel-category-node-76"
1944                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
1945                                    style="max-height:0; opacity:0; display:none;">
1946                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
1947                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
1948                                            <li>
1949                                                <a
1950                                                    href="https://www.mueblesbonitos.com/decoracion-y-auxiliares"
1951                                                    title="Muebles&#x20;Auxiliares"
1952                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
1953                                                    <span class="ml-1">Ver todos/as</span>
1954                                                </a>
1955                                            </li>
1956
1957                                                                                            <li>
1958                                                    <a
1959                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/zapateros"
1960                                                        title="Zapateros"
1961                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1962                                                        <span class="ml-1">Zapateros</span>
1963                                                    </a>
1964                                                </li>
1965                                                                                            <li>
1966                                                    <a
1967                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/escritorios"
1968                                                        title="Escritorios&#x20;Modernos"
1969                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1970                                                        <span class="ml-1">Escritorios Modernos</span>
1971                                                    </a>
1972                                                </li>
1973                                                                                            <li>
1974                                                    <a
1975                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/baules"
1976                                                        title="Ba&#xFA;les"
1977                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1978                                                        <span class="ml-1">Baúles</span>
1979                                                    </a>
1980                                                </li>
1981                                                                                            <li>
1982                                                    <a
1983                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/armarios-multiusos"
1984                                                        title="Armario&#x20;Multiusos"
1985                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1986                                                        <span class="ml-1">Armario Multiusos</span>
1987                                                    </a>
1988                                                </li>
1989                                                                                            <li>
1990                                                    <a
1991                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/plantas-artificiales"
1992                                                        title="Plantas&#x20;artificiales"
1993                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
1994                                                        <span class="ml-1">Plantas artificiales</span>
1995                                                    </a>
1996                                                </li>
1997                                                                                            <li>
1998                                                    <a
1999                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/mesa-altavoz"
2000                                                        title="Mesa&#x20;altavoz"
2001                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
2002                                                        <span class="ml-1">Mesa altavoz</span>
2003                                                    </a>
2004                                                </li>
2005                                                                                            <li>
2006                                                    <a
2007                                                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/mini-huertas"
2008                                                        title="Mini&#x20;Huerto&#x20;en&#x20;Casa"
2009                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
2010                                                        <span class="ml-1">Mini Huerto en Casa</span>
2011                                                    </a>
2012                                                </li>
2013                                                                                    </ul>
2014                                    </div>
2015                                </div>
2016                                                    </li>
2017                                                                    <li data-child-id="category-node-525-main" class="level-0">
2018                                                            <button
2019                                    type="button"
2020                                    class="w-full text-left flex items-center justify-between px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70"
2021                                    @click="toggleSubcategory('category-node-525')"
2022                                    :aria-expanded="isOpen('category-node-525')"
2023                                    aria-controls="panel-category-node-525">
2024                                    <span class="text-[15px] font-medium text-slate-900">
2025                                        Ofertas                                    </span>
2026
2027                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 text-slate-400 transition-transform duration-300" width="20" height="20" aria-hidden="true" :class="isOpen('category-node-525') ? 'rotate-180' : ''">
2028  <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/>
2029</svg>
2030                                </button>
2031                            
2032                                                            <div
2033                                    id="panel-category-node-525"
2034                                    x-ref="panel-category-node-525"
2035                                    class="overflow-hidden will-change-[max-height,opacity] mx-3"
2036                                    style="max-height:0; opacity:0; display:none;">
2037                                    <div class="my-2 rounded-2xl ring-1 ring-slate-200/80 bg-slate-50/70 shadow-sm overflow-hidden">
2038                                        <ul class="py-2" aria-label="Subcategor&#xED;as">
2039                                            <li>
2040                                                <a
2041                                                    href="https://www.mueblesbonitos.com/ofertas"
2042                                                    title="Ofertas"
2043                                                    class="flex items-center w-full px-4 py-3 text-[#1a798e] font-medium hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
2044                                                    <span class="ml-1">Ver todos/as</span>
2045                                                </a>
2046                                            </li>
2047
2048                                                                                            <li>
2049                                                    <a
2050                                                        href="https://www.mueblesbonitos.com/ofertas/ultimas-unidades"
2051                                                        title="&#xDA;ltimas&#x20;unidades"
2052                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
2053                                                        <span class="ml-1">Últimas unidades</span>
2054                                                    </a>
2055                                                </li>
2056                                                                                            <li>
2057                                                    <a
2058                                                        href="https://www.mueblesbonitos.com/ofertas/muebles-de-segunda-vida"
2059                                                        title="Muebles&#x20;de&#x20;Segunda&#x20;Vida"
2060                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
2061                                                        <span class="ml-1">Muebles de Segunda Vida</span>
2062                                                    </a>
2063                                                </li>
2064                                                                                            <li>
2065                                                    <a
2066                                                        href="https://www.mueblesbonitos.com/ofertas/outlet"
2067                                                        title="Outlet&#x20;"
2068                                                        class="flex items-center w-full px-4 py-3 text-slate-800 hover:bg-slate-100/80 transition">
2069                                                        <span class="ml-1">Outlet </span>
2070                                                    </a>
2071                                                </li>
2072                                                                                    </ul>
2073                                    </div>
2074                                </div>
2075                                                    </li>
2076                                                                    <li data-child-id="category-node-518-main" class="level-0">
2077                                                            <a
2078                                    class="flex items-center w-full px-5 py-4 bg-white hover:bg-slate-50 transition border-b border-slate-100/70 level-0 text-[15px] font-medium text-slate-900"
2079                                    href="https://www.mueblesbonitos.com/novedades"
2080                                    title="Novedades">
2081                                    Novedades                                </a>
2082                            
2083                                                    </li>
2084                                    </ul>
2085
2086                <div class="px-4 pb-6">
2087                    <div class="mobile-help-card rounded-2xl overflow-hidden ring-1 ring-[#8cc4b2] ring-opacity-60 bg-[#8cc4b2] bg-opacity-20">
2088                        <div class="px-3 py-2 text-[13px] uppercase tracking-wide font-semibold text-[#1a798e]">
2089                            Ayuda &amp; Información                        </div>
2090                        <ul class="divide-y divide-[#8cc4b2] divide-opacity-40">
2091                            <li>
2092                                <a
2093                                    href="https://www.mueblesbonitos.com/quienes-somos/"
2094                                    class="flex items-center justify-between py-3 px-3 text-[15px] font-medium text-[#1a798e] hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
2095                                    <span>Quiénes somos/Contactar</span>
2096                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4" width="16" height="16" aria-hidden="true">
2097  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
2098</svg>
2099                                </a>
2100                            </li>
2101                            <li>
2102                                <a
2103                                    href="https://www.mueblesbonitos.com/customers/"
2104                                    rel="nofollow"
2105                                    class="flex items-center justify-between py-3 px-3 text-[15px] font-medium text-[#1a798e] hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
2106                                    <span>Comunicar una incidencia</span>
2107                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4" width="16" height="16" aria-hidden="true">
2108  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
2109</svg>
2110                                </a>
2111                            </li>
2112                            <li>
2113                                <a
2114                                    href="https://www.mueblesbonitos.com/mapa-del-sitio/"
2115                                    class="flex items-center justify-between py-3 px-3 text-[15px] font-medium text-[#1a798e] hover:bg-[#8cc4b2] hover:bg-opacity-20 transition">
2116                                    <span>Mapa del sitio</span>
2117                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4" width="16" height="16" aria-hidden="true">
2118  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
2119</svg>
2120                                </a>
2121                            </li>
2122                        </ul>
2123                    </div>
2124                </div>
2125            </div>
2126        </div>
2127    </div>
2128</nav>
2129
2130<script>
2131    const initMenuMobile = () => {
2132        return {
2133            mobilePanelActiveId: null,
2134            open: false,
2135
2136            closed() { return !this.open },
2137            isOpen(id) { return this.mobilePanelActiveId === id },
2138
2139            setActiveMenu() {
2140                const menuNode = this.$root;
2141                Array.from(menuNode.querySelectorAll('a'))
2142                    .filter(link => link.href === window.location.href.split('?')[0])
2143                    .forEach(item => {
2144                        item.classList.add('underline');
2145                        const parent = item.closest('li.level-0');
2146                        if (parent) {
2147                            const topBtn = parent.querySelector('button');
2148                            if (topBtn) { topBtn.classList.add('underline'); }
2149                        }
2150                    });
2151            },
2152
2153            openMenu() {
2154                this.open = true;
2155                this.$nextTick(() => hyva.trapFocus(this.$refs['mobileMenuNavLinks']));
2156                document.body.style.overflow = 'hidden';
2157                document.documentElement.classList.add('mobile-menu-open');
2158            },
2159
2160            closeMenu() {
2161                document.body.style.overflow = '';
2162                if (this.open) {
2163                    this.$nextTick(() => this.$refs['mobileMenuTrigger'].focus() || hyva.releaseFocus());
2164                }
2165                if (this.mobilePanelActiveId) { this.collapse(this.mobilePanelActiveId); }
2166                this.open = false;
2167                this.mobilePanelActiveId = null;
2168                document.documentElement.classList.remove('mobile-menu-open');
2169            },
2170
2171            toggleSubcategory(id) {
2172                if (this.mobilePanelActiveId === id) {
2173                    this.collapse(id);
2174                    this.mobilePanelActiveId = null;
2175                } else {
2176                    if (this.mobilePanelActiveId) this.collapse(this.mobilePanelActiveId);
2177                    this.mobilePanelActiveId = id;
2178                    this.$nextTick(() => this.expand(id));
2179                }
2180            },
2181
2182            expand(id) {
2183                const el = this.$refs['panel-' + id];
2184                if (!el) return;
2185                el.style.display = 'block';
2186                el.style.transition = 'none';
2187                el.style.maxHeight = '0px';
2188                el.style.opacity = '0';
2189                requestAnimationFrame(() => {
2190                    const h = el.scrollHeight;
2191                    el.style.transition = 'max-height 700ms cubic-bezier(.2,.7,0,.995), opacity 500ms ease-out';
2192                    el.style.maxHeight = h + 'px';
2193                    el.style.opacity = '1';
2194                    setTimeout(() => {
2195                        el.style.transition = 'opacity 300ms ease-out';
2196                        el.style.maxHeight = '9999px';
2197                    }, 720);
2198                });
2199            },
2200
2201            collapse(id) {
2202                const el = this.$refs['panel-' + id];
2203                if (!el) return;
2204                const h = el.scrollHeight;
2205                el.style.transition = 'none';
2206                el.style.maxHeight = h + 'px';
2207                el.style.opacity = '1';
2208                requestAnimationFrame(() => {
2209                    el.style.transition = 'max-height 650ms cubic-bezier(.4,0,.2,1), opacity 400ms ease-in';
2210                    el.style.maxHeight = '0px';
2211                    el.style.opacity = '0';
2212                    setTimeout(() => {
2213                        el.style.display = 'none';
2214                        el.style.transition = '';
2215                        el.style.maxHeight = '0px';
2216                        el.style.opacity = '';
2217                    }, 660);
2218                });
2219            },
2220        }
2221    }
2222
2223    window.addEventListener('alpine:init', () => Alpine.data('initMenuMobile', initMenuMobile), {
2224        once: true
2225    })
2226</script>
2226
2227    
2228<a
2229    class="inline-block align-middle"
2230    href="https://www.mueblesbonitos.com/"
2231    title="Ir&#x20;a&#x20;la&#x20;p&#xE1;gina&#x20;de&#x20;inicio">
2232            <picture class="block h-auto w-[180px] sm:w-[286px] lg:w-[189px] max-w-full shrink-0"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/logo/stores/2/Mediano-MueblesBonitos.webp"><img class="block h-auto w-[180px] sm:w-[286px] lg:w-[189px] max-w-full shrink-0" src="https://www.mueblesbonitos.com/media/logo/stores/2/Mediano-MueblesBonitos.png" alt="Muebles&#x20;Bonitos" width="189" height="64" loading="eager" fetchpriority="high" /></picture>
2233
2234    </a>
2235    <div class="ml-auto flex gap-0.5 items-center lg:order-2 shrink-0">
2236
2237      <button
2238        id="menu-search-icon"
2239        class="inline-block rounded p-1 hover:bg-primary/10 outline-offset-2 md:hidden"
2240        type="button"
2241        aria-label="Buscar"
2242        @click.prevent="toggleSearch()"
2243        x-ref="searchButton">
2244        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
2245  <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
2246</svg>
2247      </button>
2248
2249              
2250<a
2251    id="compare-link"
2252    class="relative hidden md:inline-block rounded p-1 hover:bg-primary/10 outline-offset-2 invisible"
2253    :class="hiddenIfEmpty"
2254    href="https://www.mueblesbonitos.com/catalog/product_compare/index/"
2255    rel="nofollow"
2256    title="Comparar&#x20;Productos"
2257    x-data="initCompareHeader"
2258    @private-content-loaded.window="receiveCompareData"
2259    :aria-label="linkAriaLabel"
2260>
2261    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
2262  <path stroke-linecap="round" stroke-linejoin="round" d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"/>
2263</svg>
2264    <span
2265        x-text="itemCount"
2266        class="absolute -top-1.5 -right-1.5 px-2 py-0.5 rounded-full bg-blue-200 text-blue-800
2267            text-xs font-semibold leading-none text-center uppercase tabular-nums"
2268        aria-hidden="true"
2269    ></span>
2270</a>
2271      
2272                    
2273      
2274      <!-- BLOCK header.customer -->
2275<div
2276    class="relative inline-block"
2277    x-data="initCustomerMenu"
2278    @keyup.escape="setOpenFalse"
2279    @click.outside="setOpenFalse"
2280>
2281    <button
2282        type="button"
2283        id="customer-menu"
2284        class="block rounded p-1 hover:bg-primary/10 outline-offset-2"
2285        @click="toggleOpen"
2286        :aria-expanded="ariaExpanded"
2287        aria-label="Mi&#x20;cuenta"
2288        aria-haspopup="true"
2289    >
2290        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
2291  <path stroke-linecap="round" stroke-linejoin="round" d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
2292</svg>
2293    </button>
2294    <nav
2295        class="z-30 absolute -right-4 w-48 sm:w-56 mt-2 py-2 px-1 overflow-auto
2296            rounded shadow-lg lg:mt-3 bg-container-lighter"
2297        x-cloak
2298        x-show="open"
2299        x-transition
2300        aria-labelledby="customer-menu"
2301    >
2302                    
2303<a
2304    id="custom.catalog.compare.link.out"
2305    class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100 relative"
2306    href="https://www.mueblesbonitos.com/catalog/product_compare/index/"
2307    rel="nofollow"
2308    title="Comparar&#x20;Productos"
2309    x-data="initCompareHeader"
2310    @private-content-loaded.window="receiveCompareData"
2311>
2312    Comparar Productos    <template x-if="itemCount">
2313        <span class="tabular-nums" x-text="itemCountLabel"></span>
2314    </template>
2315</a>
2316
2317<script>
2318    document.addEventListener('DOMContentLoaded', () => {
2319        document.getElementById('customer.header.sign.in.link').addEventListener('click', () => {
2320            if (hyva.setCookie) {
2321                hyva.setCookie(
2322                    'login_redirect',
2323                    window.location.href,
2324                    1
2325                );
2326            }
2327        });
2328    });
2329</script>
2329
2330<a id="customer.header.sign.in.link"
2331   class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100"
2332   href="https://www.mueblesbonitos.com/customer/account/index/"
2333   title="Iniciar&#x20;Sesi&#xF3;n"
2334>
2335    Iniciar Sesión</a>
2336
2337    <a id="customer.header.register.link"
2338       class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100"
2339       href="https://www.mueblesbonitos.com/customer/account/create/"
2340       title="Crear&#x20;una&#x20;Cuenta"
2341    >
2342        Crear una Cuenta    </a>
2343            </nav>
2344</div>
2345<script>
2346    function initCustomerMenu() {
2347        return hyva.createBooleanObject('open', false, {
2348            ariaExpanded() {
2349                return this.open() ? 'true' : 'false';
2350            }
2351        })
2352    }
2353    window.addEventListener('alpine:init', () => Alpine.data('initCustomerMenu', initCustomerMenu), {once: true})
2354</script>
2354
2355<!-- /BLOCK header.customer -->
2356              
2357<a
2358    href="https://www.mueblesbonitos.com/wishlist/"
2359    rel="nofollow"
2360    class="relative hidden md:inline-block rounded p-1 hover:bg-primary/10 outline-offset-2"
2361    x-data="initWishlistHeader"
2362    @private-content-loaded.window="receiveWishlistData"
2363    aria-label="Mis&#x20;favoritos"
2364    :aria-label="linkAriaLabel"
2365>
2366    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
2367  <path stroke-linecap="round" stroke-linejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
2368</svg>
2369    <template x-if="itemCount">
2370        <span
2371            x-text="itemCount"
2372            class="absolute -top-1.5 -right-1.5 px-2 py-0.5 rounded-full bg-green-200 text-green-800 text-xs
2373                font-semibold leading-none text-center uppercase tabular-nums"
2374            aria-hidden="true"
2375        ></span>
2376    </template>
2377</a>
2378      
2379              <button
2380                    id="menu-cart-icon"
2381          class="relative inline-block rounded p-1 hover:bg-primary/10 outline-offset-2"
2382          x-ref="cartButton"
2383          :aria-disabled="isCartEmpty"
2384          :aria-label="ariaLabel"
2385                    @click.prevent="openCart"
2386          @toggle-cart.window="toggleCart"
2387          :aria-expanded="isCartOpen"
2388          aria-haspopup="dialog"
2389          >
2390          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
2391  <path stroke-linecap="round" stroke-linejoin="round" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"/>
2392</svg>
2393          <span
2394            x-text="summaryCount"
2395            x-show="summaryCount"
2396            x-cloak
2397            class="absolute -top-1.5 -right-1.5 px-2 py-0.5 rounded-full bg-green-200 text-green-800
2398                 text-xs font-semibold leading-none text-center uppercase tabular-nums"
2399            aria-hidden="true"></span>
2400                  </button>
2401          </div>
2402
2403        <div id="site-search" class="col-span-full py-4 lg:py-0 lg:col-auto lg:order-1">
2404      
2404<script>
2405    'use strict';
2406
2407    function initMiniSearch() {
2408        return {
2409            minSearchLength: 3,
2410                        suggestions: [],
2411            suggest() {
2412                const search = this.$refs.searchInput;
2413                if (search.value.length >= this.minSearchLength) {
2414                    search.setCustomValidity('');
2415                    search.reportValidity();
2416                    this.fetchSuggestions(search.value);
2417                } else {
2418                    this.suggestions = [];
2419                }
2420            },
2421            fetchSuggestions(term) {
2422                fetch(
2423                    window.BASE_URL + 'search/ajax/suggest?' + new URLSearchParams({q: term}),
2424                    {
2425                        headers: {
2426                            'X-Requested-With': 'XMLHttpRequest'
2427                        }
2428                    }
2429                )
2430                .then(response => response.json())
2431                .then(result => this.suggestions = result);
2432            },
2433                        search(term) {
2434                const search = this.$refs.searchInput;
2435                term = term || search.value;
2436                if (term.length < this.minSearchLength) {
2437                    search.setCustomValidity('Minimum\u0020Search\u0020query\u0020length\u0020is\u00203');
2438                    search.reportValidity();
2439                } else {
2440                    search.setCustomValidity('');
2441                    search.value = term;
2442                    this.$refs.form.submit();
2443                }
2444            },
2445            focusElement(element) {
2446                if (element && element.nodeName === "DIV") {
2447                    element.focus();
2448                    return true;
2449                } else {
2450                    return false;
2451                }
2452            }
2453        }
2454    }
2455</script>
2455
2456<div class="container py-2 mx-auto text-black" x-data="initMiniSearch()">
2457    <search title="Tienda" role="search">
2458        <form
2459            id="search_mini_form"
2460            class="form minisearch flex relative"
2461            action="https://www.mueblesbonitos.com/catalogsearch/result/"
2462            method="get"
2463            @submit.prevent="search()"
2464            x-ref="form"
2465        >
2466            <label class="sr-only" for="search">
2467                Buscar            </label>
2468            <input
2469                id="search"
2470                x-ref="searchInput"
2471                type="search"
2472                autocomplete="off"
2473                name="q"
2474                value=""
2475                placeholder="Buscar&#x20;en&#x20;toda&#x20;la&#x20;tienda..."
2476                maxlength="128"
2477                class="w-full text-lg lg:text-xl text-grey-800 focus:border-transparent focus:outline-none rounded-3xl"
2478                @search-open.window.debounce.10="$el.focus(); $el.select()"
2479                                    @focus.once="suggest"
2480                    @input.debounce.300="suggest"
2481                    @keydown.arrow-down.prevent="focusElement($root.querySelector('[tabindex]'))"
2482                            >
2483            <button
2484                type="submit"
2485                class="action search absolute right-0 shrink-0 p-3 shadow-none"
2486                title="Buscar"
2487                aria-label="Buscar"
2488            >
2489                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="20" height="20" aria-hidden="true">
2490  <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
2491</svg>
2492            </button>
2493        </form>
2494    </search>
2495            <template x-if="suggestions.length > 0">
2496            <nav
2497                aria-label="Search&#x20;Suggestions"
2498                class="flex flex-col mt-1 text-grey-800 gap-1"
2499            >
2500                <template x-for="suggestion in suggestions">
2501                    <button
2502                        type="button"
2503                        class="flex justify-between p-2 bg-container-lighter even:bg-container border border-container hover:bg-container-darker"
2504                        @click="search(suggestion.title)"
2505                        @keydown.enter="search(suggestion.title)"
2506                        @keydown.arrow-up.prevent="focusElement($event.target.previousElementSibling) || $refs.searchInput.focus()"
2507                        @keydown.arrow-down.prevent="focusElement($event.target.nextElementSibling)"
2508                    >
2509                        <span x-text="suggestion.title"></span>
2510                        <span x-text="suggestion.num_results"></span>
2511                    </button>
2512                </template>
2513            </nav>
2514        </template>
2515    </div>
2516    </div>
2517  </div>
2518
2519  <div class="hidden lg:block">
2520    <div class="container">
2521      <!-- <style>
2522  .nav-root { outline: 3px solid magenta !important; }
2523</style> -->
2524<nav class="nav-root">
2525  <!-- El UL de nivel 0 lo imprime el child -->
2526  
2527<nav
2528    class="navigation relative hidden lg:block grow"
2529    aria-label="Men&#xFA;&#x20;principal"
2530    data-max-level="4"
2531    x-data="initMenuDesktop"
2532    x-ref="nav-desktop"
2533    @load.window="setActiveMenu">
2534    <ul class="flex flex-wrap gap-x-8">
2535                                    <li
2536                    class="level-0"
2537                    x-data="initMenuDesktopItem"
2538                    @click.outside="close"
2539                    @keydown.escape="close"
2540                    @mouseenter="open = true"
2541                    @mouseleave="open = false">
2542                                                            <a
2543                        href="https://www.mueblesbonitos.com/salon"
2544                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2545                            border-b-[3px] border-transparent hover:border-blue-500 transition
2546                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2547                        :class="{ 'text-blue-500 border-blue-500': open }"
2548                        aria-expanded="false"
2549                        :aria-expanded="open"
2550                        aria-controls="desktop-menu-category-37">
2551                        Salones Modernos                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2552  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2553</svg>
2554                    </a>
2555                    <div
2556                        id="desktop-menu-category-37"
2557                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounded-b-md bg-white shadow-md
2558                            overflow-hidden "
2559                        x-show="open"
2560                        x-transition
2561                        x-cloak>
2562                        <div class="relative overflow-auto min-h-10">
2563                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2564                                                                    
2565    <li class="level-1">
2566        <a
2567            href="https://www.mueblesbonitos.com/salon/mueble-tv"
2568            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2569        >Mueble TV</a>
2570    </li>
2571                                                                    
2572    <li class="level-1">
2573        <a
2574            href="https://www.mueblesbonitos.com/salon/aparadores"
2575            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2576        >Aparador</a>
2577    </li>
2578                                                                    
2579    <li class="level-1">
2580        <a
2581            href="https://www.mueblesbonitos.com/salon/mesas-de-centro"
2582            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2583        >Mesas de Centro</a>
2584    </li>
2585                                                                    
2586    <li class="level-1">
2587        <a
2588            href="https://www.mueblesbonitos.com/salon/mesas-y-sillas-de-comedor"
2589            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2590        >Mesas de Comedor</a>
2591    </li>
2592                                                                    
2593    <li class="level-1">
2594        <a
2595            href="https://www.mueblesbonitos.com/salon/estanterias"
2596            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2597        >Estanterías de Diseño</a>
2598    </li>
2599                                                                    
2600    <li class="level-1">
2601        <a
2602            href="https://www.mueblesbonitos.com/salon/vitrinas"
2603            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2604        >Vitrinas</a>
2605    </li>
2606                                                                    
2607    <li class="level-1">
2608        <a
2609            href="https://www.mueblesbonitos.com/salon/armario"
2610            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2611        >Armarios de Salón</a>
2612    </li>
2613                                                                    
2614    <li class="level-1">
2615        <a
2616            href="https://www.mueblesbonitos.com/salon/conjuntos-de-salon"
2617            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2618        >Conjuntos de Salón</a>
2619    </li>
2620                                                                    
2621    <li class="level-1">
2622        <a
2623            href="https://www.mueblesbonitos.com/salon/muebles-con-chimenea"
2624            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2625        >Muebles con Chimenea</a>
2626    </li>
2627                                                            </ul>
2628                        </div>
2629                                            </div>
2630                </li>
2631                                                <li
2632                    class="level-0"
2633                    x-data="initMenuDesktopItem"
2634                    @click.outside="close"
2635                    @keydown.escape="close"
2636                    @mouseenter="open = true"
2637                    @mouseleave="open = false">
2638                                                            <a
2639                        href="https://www.mueblesbonitos.com/recibidores"
2640                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2641                            border-b-[3px] border-transparent hover:border-blue-500 transition
2642                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2643                        :class="{ 'text-blue-500 border-blue-500': open }"
2644                        aria-expanded="false"
2645                        :aria-expanded="open"
2646                        aria-controls="desktop-menu-category-110">
2647                        Recibidores                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2648  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2649</svg>
2650                    </a>
2651                    <div
2652                        id="desktop-menu-category-110"
2653                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounded-b-md bg-white shadow-md
2654                            overflow-hidden "
2655                        x-show="open"
2656                        x-transition
2657                        x-cloak>
2658                        <div class="relative overflow-auto min-h-10">
2659                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2660                                                                    
2661    <li class="level-1">
2662        <a
2663            href="https://www.mueblesbonitos.com/recibidores/consolas-y-zapateros"
2664            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2665        >Consola Recibidor</a>
2666    </li>
2667                                                                    
2668    <li class="level-1">
2669        <a
2670            href="https://www.mueblesbonitos.com/recibidores/conjuntos-con-espejo"
2671            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2672        >Recibidor con Espejo</a>
2673    </li>
2674                                                            </ul>
2675                        </div>
2676                                            </div>
2677                </li>
2678                                                <li
2679                    class="level-0"
2680                    x-data="initMenuDesktopItem"
2681                    @click.outside="close"
2682                    @keydown.escape="close"
2683                    @mouseenter="open = true"
2684                    @mouseleave="open = false">
2685                                                            <a
2686                        href="https://www.mueblesbonitos.com/dormitorio"
2687                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2688                            border-b-[3px] border-transparent hover:border-blue-500 transition
2689                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2690                        :class="{ 'text-blue-500 border-blue-500': open }"
2691                        aria-expanded="false"
2692                        :aria-expanded="open"
2693                        aria-controls="desktop-menu-category-3">
2694                        Dormitorios                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2695  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2696</svg>
2697                    </a>
2698                    <div
2699                        id="desktop-menu-category-3"
2700                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounded-b-md bg-white shadow-md
2701                            overflow-hidden "
2702                        x-show="open"
2703                        x-transition
2704                        x-cloak>
2705                        <div class="relative overflow-auto min-h-10">
2706                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2707                                                                    
2708    <li class="level-1">
2709        <a
2710            href="https://www.mueblesbonitos.com/dormitorio/camas-de-matrimonio"
2711            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2712        >Camas de Matrimonio</a>
2713    </li>
2714                                                                    
2715    <li class="level-1">
2716        <a
2717            href="https://www.mueblesbonitos.com/dormitorio/mesitas-de-noche"
2718            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2719        >Mesitas de Noche</a>
2720    </li>
2721                                                                    
2722    <li class="level-1">
2723        <a
2724            href="https://www.mueblesbonitos.com/dormitorio/armarios"
2725            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2726        >Armarios Roperos</a>
2727    </li>
2728                                                                    
2729    <li class="level-1">
2730        <a
2731            href="https://www.mueblesbonitos.com/dormitorio/comodas-y-cajoneras"
2732            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2733        >Cómodas</a>
2734    </li>
2735                                                                    
2736    <li class="level-1">
2737        <a
2738            href="https://www.mueblesbonitos.com/dormitorio/tocadores"
2739            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2740        >Tocador</a>
2741    </li>
2742                                                            </ul>
2743                        </div>
2744                                            </div>
2745                </li>
2746                                                <li
2747                    class="level-0"
2748                    x-data="initMenuDesktopItem"
2749                    @click.outside="close"
2750                    @keydown.escape="close"
2751                    @mouseenter="open = true"
2752                    @mouseleave="open = false">
2753                                                            <a
2754                        href="https://www.mueblesbonitos.com/cocina"
2755                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2756                            border-b-[3px] border-transparent hover:border-blue-500 transition
2757                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2758                        :class="{ 'text-blue-500 border-blue-500': open }"
2759                        aria-expanded="false"
2760                        :aria-expanded="open"
2761                        aria-controls="desktop-menu-category-841">
2762                        Muebles de Cocina                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2763  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2764</svg>
2765                    </a>
2766                    <div
2767                        id="desktop-menu-category-841"
2768                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounde
2768d-b-md bg-white shadow-md
2769                            overflow-hidden "
2770                        x-show="open"
2771                        x-transition
2772                        x-cloak>
2773                        <div class="relative overflow-auto min-h-10">
2774                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2775                                                                    
2776    <li class="level-1">
2777        <a
2778            href="https://www.mueblesbonitos.com/cocina/mesas-altas"
2779            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2780        >Mesas Altas de Cocina</a>
2781    </li>
2782                                                                    
2783    <li class="level-1">
2784        <a
2785            href="https://www.mueblesbonitos.com/cocina/taburetes"
2786            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2787        >Taburetes de Cocina</a>
2788    </li>
2789                                                                    
2790    <li class="level-1">
2791        <a
2792            href="https://www.mueblesbonitos.com/cocina/armarios-de-cocina"
2793            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2794        >Armarios de Cocina</a>
2795    </li>
2796                                                            </ul>
2797                        </div>
2798                                            </div>
2799                </li>
2800                                                <li
2801                    class="level-0"
2802                    x-data="initMenuDesktopItem"
2803                    @click.outside="close"
2804                    @keydown.escape="close"
2805                    @mouseenter="open = true"
2806                    @mouseleave="open = false">
2807                                                            <a
2808                        href="https://www.mueblesbonitos.com/bano"
2809                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2810                            border-b-[3px] border-transparent hover:border-blue-500 transition
2811                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2812                        :class="{ 'text-blue-500 border-blue-500': open }"
2813                        aria-expanded="false"
2814                        :aria-expanded="open"
2815                        aria-controls="desktop-menu-category-843">
2816                        Muebles de Baño                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2817  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2818</svg>
2819                    </a>
2820                    <div
2821                        id="desktop-menu-category-843"
2822                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounded-b-md bg-white shadow-md
2823                            overflow-hidden "
2824                        x-show="open"
2825                        x-transition
2826                        x-cloak>
2827                        <div class="relative overflow-auto min-h-10">
2828                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2829                                                                    
2830    <li class="level-1">
2831        <a
2832            href="https://www.mueblesbonitos.com/bano/conjuntos-de-bano"
2833            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2834        >Conjuntos de baño</a>
2835    </li>
2836                                                                    
2837    <li class="level-1">
2838        <a
2839            href="https://www.mueblesbonitos.com/bano/columnas-y-armarios-de-bano"
2840            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2841        >Columna de Baño</a>
2842    </li>
2843                                                            </ul>
2844                        </div>
2845                                            </div>
2846                </li>
2847                                                <li
2848                    class="level-0"
2849                    x-data="initMenuDesktopItem"
2850                    @click.outside="close"
2851                    @keydown.escape="close"
2852                    @mouseenter="open = true"
2853                    @mouseleave="open = false">
2854                                                            <a
2855                        href="https://www.mueblesbonitos.com/decoracion-y-auxiliares"
2856                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2857                            border-b-[3px] border-transparent hover:border-blue-500 transition
2858                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2859                        :class="{ 'text-blue-500 border-blue-500': open }"
2860                        aria-expanded="false"
2861                        :aria-expanded="open"
2862                        aria-controls="desktop-menu-category-76">
2863                        Muebles Auxiliares                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2864  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2865</svg>
2866                    </a>
2867                    <div
2868                        id="desktop-menu-category-76"
2869                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounded-b-md bg-white shadow-md
2870                            overflow-hidden "
2871                        x-show="open"
2872                        x-transition
2873                        x-cloak>
2874                        <div class="relative overflow-auto min-h-10">
2875                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2876                                                                    
2877    <li class="level-1">
2878        <a
2879            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/zapateros"
2880            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2881        >Zapateros</a>
2882    </li>
2883                                                                    
2884    <li class="level-1">
2885        <a
2886            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/escritorios"
2887            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2888        >Escritorios Modernos</a>
2889    </li>
2890                                                                    
2891    <li class="level-1">
2892        <a
2893            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/baules"
2894            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2895        >Baúles</a>
2896    </li>
2897                                                                    
2898    <li class="level-1">
2899        <a
2900            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/armarios-multiusos"
2901            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2902        >Armario Multiusos</a>
2903    </li>
2904                                                                    
2905    <li class="level-1">
2906        <a
2907            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/plantas-artificiales"
2908            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2909        >Plantas artificiales</a>
2910    </li>
2911                                                                    
2912    <li class="level-1">
2913        <a
2914            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/mesa-altavoz"
2915            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2916        >Mesa altavoz</a>
2917    </li>
2918                                                                    
2919    <li class="level-1">
2920        <a
2921            href="https://www.mueblesbonitos.com/decoracion-y-auxiliares/mini-huertas"
2922            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2923        >Mini Huerto en Casa</a>
2924    </li>
2925                                                            </ul>
2926                        </div>
2927                                            </div>
2928                </li>
2929                                                <li
2930                    class="level-0"
2931                    x-data="initMenuDesktopItem"
2932                    @click.outside="close"
2933                    @keydown.escape="close"
2934                    @mouseenter="open = true"
2935                    @mouseleave="open = false">
2936                                                            <a
2937                        href="https://www.mueblesbonitos.com/ofertas"
2938                        class="level-0 group w-full flex justify-between items-center gap-1 py-4
2939                            border-b-[3px] border-transparent hover:border-blue-500 transition
2940                            data-[has-current]:border-slate-400 data-[has-current]:hover:border-blue-500"
2941                        :class="{ 'text-blue-500 border-blue-500': open }"
2942                        aria-expanded="false"
2943                        :aria-expanded="open"
2944                        aria-controls="desktop-menu-category-525">
2945                        Ofertas                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition text-slate-400" width="24" height="24" aria-hidden="true" :class="{ 'rotate-180 text-blue-500': open }">
2946  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
2947</svg>
2948                    </a>
2949                    <div
2950                        id="desktop-menu-category-525"
2951                        class="z-30 absolute top-full inset-x-0 border-t border-slate-100 rounded-b-md bg-white shadow-md
2952                            overflow-hidden "
2953                        x-show="open"
2954                        x-transition
2955                        x-cloak>
2956                        <div class="relative overflow-auto min-h-10">
2957                            <ul class="flex flex-col gap-1 py-2.5 px-2 w-72">
2958                                                                    
2959    <li class="level-1">
2960        <a
2961            href="https://www.mueblesbonitos.com/ofertas/ultimas-unidades"
2962            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2963        >Últimas unidades</a>
2964    </li>
2965                                                                    
2966    <li class="level-1">
2967        <a
2968            href="https://www.mueblesbonitos.com/ofertas/muebles-de-segunda-vida"
2969            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2970        >Muebles de Segunda Vida</a>
2971    </li>
2972                                                                    
2973    <li class="level-1">
2974        <a
2975            href="https://www.mueblesbonitos.com/ofertas/outlet"
2976            class="level-1 flex p-2 rounded-md hover:bg-slate-50 aria-[current=page]:font-medium"
2977        >Outlet </a>
2978    </li>
2979                                                            </ul>
2980                        </div>
2981                                            </div>
2982                </li>
2983                                                <li>
2984                    <a
2985                        href="https://www.mueblesbonitos.com/novedades"
2986                        title="Novedades"
2987                        class="level-0 flex py-4 border-b-[3px] border-transparent hover:border-blue-500
2988                            aria-[current=page]:border-slate-400 aria-[current=page]:hover:border-blue-500
2989                            "
2990                                                rel="nofollow"
2991                        >
2992                        Novedades                    </a>
2993                </li>
2994                        </ul>
2995</nav>
2996<script>
2997    function initMenuDesktop() {
2998        return {
2999            maxLevel: parseInt(this.$root.dataset.maxLevel),
3000            setActiveMenu() {
3001                Array.from(this.$root.querySelectorAll('a'))
3002                    .filter(link => link.href === window.location.href.split('?')[0])
3003                    .forEach(item => {
3004                        item.setAttribute('aria-current', 'page');
3005
3006                        for (let level = 0; level < maxLevel; level++) {
3007                            const closestMenu = item.closest(`.level-${level}`);
3008
3009                            if (closestMenu) {
3010                                const button = closestMenu.querySelector('button') || closestMenu.querySelector('a.level-0');
3011                                if (button) {
3012                                    button.setAttribute('data-has-current', '');
3013                                }
3014                            }
3015                        }
3016                    });
3017            }
3018        }
3019    }
3020
3021    function initMenuDesktopItem() {
3022        return {
3023            open: false,
3024            canHover(func) {
3025                return window.matchMedia('(hover: hover) and (pointer: fine)').matches;
3026            },
3027            canHoverOpen() {
3028                if (!this.canHover()) return;
3029                this.open = true;
3030            },
3031            canHoverClose() {
3032                if (!this.canHover()) return;
3033                this.open = false;
3034            },
3035            toggle() {
3036                this.open = !this.open;
3037            },
3038            close() {
3039                this.open = false;
3040            }
3041        }
3042    }
3043
3044    function initSubMenuDesktopItem() {
3045        return {
3046            open: false,
3047            toggle() {
3048                this.open = !this.open;
3049                this.$nextTick(() => {
3050                    this.$refs.childmenuViewAll.focus();
3051                    this.$refs.childmenuWrapper.scrollIntoView({
3052                        behavior: 'smooth',
3053                        block: 'nearest',
3054                        inline: 'end'
3055                    });
3056                });
3057            },
3058            close() {
3059                this.open = false;
3060                this.$refs.childmenuToggle.focus();
3061            },
3062        }
3063    }
3064
3065    window.addEventListener('alpine:init', () => {
3066        Alpine.data('initMenuDesktop', initMenuDesktop);
3067        Alpine.data('initMenuDesktopItem', initMenuDesktopItem);
3068        Alpine.data('initSubMenuDesktopItem', initSubMenuDesktopItem);
3069    }, {
3070        once: true
3071    })
3072</script>
3072
3073</nav>
3074
3075    </div>
3076  </div>
3077
3078  
3079<script>
3080    function initCartDrawer() {
3081        return {
3082            open: false,
3083            isLoading: false,
3084            cart: {},
3085            maxItemsToDisplay: 10,
3086            itemsCount: 0,
3087            isLoggedIn: false,
3088            isVipCustomer: false,
3089            updateQtyUrl: 'https\u003A\u002F\u002Fwww.mueblesbonitos.com\u002Fcheckout\u002Fsidebar\u002FupdateItemQty\u002F',
3090            removeItemUrl: 'https\u003A\u002F\u002Fwww.mueblesbonitos.com\u002Fcheckout\u002Fsidebar\u002FremoveItem\u002F',
3091            cartItems: [],
3092
3093            getData(data) {
3094                if (data.cart) {
3095                    this.cart = data.cart;
3096                    this.itemsCount = (data.cart.items && data.cart.items.length) || 0;
3097                    this.setCartItems();
3098                    this.isVipCustomer = data.cart.is_vip_customer || false;
3099                }
3100                this.isLoggedIn = !!(data.customer && data.customer.fullname);
3101                this.isLoading = false;
3102            },
3103            getItemCountTitle() {
3104                return hyva.strf('Mostrando\u0020\u00250\u0020de\u0020\u00251\u0020productos\u0020en\u0020el\u0020carrito', this.maxItemsToDisplay, this.itemsCount)
3105            },
3106            setCartItems() {
3107                this.cartItems = (this.cart.items && this.cart.items.sort((a, b) => b.item_id - a.item_id)) || [];
3108                if (this.maxItemsToDisplay > 0) {
3109                    this.cartItems = this.cartItems.slice(0, parseInt(this.maxItemsToDisplay, 10));
3110                }
3111            },
3112            updateItemQty(itemId, currentQty, operation) {
3113                this.isLoading = true;
3114                const qty = Number(String(currentQty).replace(',', '.'));
3115                const safeQty = Number.isFinite(qty) ? qty : 1;
3116                let newQty = operation === 'add' ? safeQty + 1 : safeQty - 1;
3117                newQty = Math.round(newQty);
3118                if (newQty <= 0) {
3119                    this.deleteItemFromCart(itemId);
3120                    return;
3121                }
3122
3123                fetch(this.updateQtyUrl, {
3124                        method: 'POST',
3125                        credentials: 'include',
3126                        headers: {
3127                            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
3128                            'X-Requested-With': 'XMLHttpRequest',
3129                            'Accept': 'application/json'
3130                        },
3131                        body: new URLSearchParams({
3132                            form_key: hyva.getFormKey(),
3133                            item_id: String(Math.round(Number(itemId))),
3134                            item_qty: String(newQty),
3135                            qty: String(newQty)
3136                        })
3137                    })
3138                    .then(async (response) => {
3139                        if (response.redirected) {
3140                            this.isLoading = false;
3141                            return null;
3142                        }
3143                        const data = await response.json().catch(() => null);
3144                        if (!response.ok) throw new Error(data?.error_message || 'Error');
3145                        return data;
3146                    })
3147                    .then((result) => {
3148                        this.isLoading = false;
3149                        if (result && !result.error_message) window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
3150                    }).catch(() => {
3151                        this.isLoading = false;
3152                    });
3153            },
3154            deleteItemFromCart(itemId) {
3155                this.isLoading = true;
3156                fetch(this.removeItemUrl, {
3157                    method: 'POST',
3158                    credentials: 'include',
3159                    headers: {
3160                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
3161                        'X-Requested-With': 'XMLHttpRequest',
3162                        'Accept': 'application/json'
3163                    },
3164                    body: new URLSearchParams({
3165                        form_key: hyva.getFormKey(),
3166                        item_id: String(Math.round(Number(itemId)))
3167                    })
3168                }).then(() => {
3169                    this.isLoading = false;
3170                    window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
3171                });
3172            },
3173            scrollLock(use = true) {
3174                document.body.style.overflow = use ? "hidden" : "";
3175            },
3176            toggleCartDrawer(event) {
3177                if (event.detail && event.detail.isOpen !== undefined) {
3178                    if (event.detail.isOpen) {
3179                        this.openCartDrawer();
3180                    } else {
3181                        this.open = false;
3182                        this.scrollLock(false);
3183                    }
3184                } else {
3185                    this.openCartDrawer();
3186                }
3187            },
3188            openCartDrawer() {
3189                this.open = true;
3190                this.scrollLock(true);
3191            },
3192            closeCartDrawer() {
3193                this.$dispatch('toggle-cart', {
3194                    isOpen: false
3195                });
3196            },
3197            getSectionDataExtraActions() {
3198                if (!this.cart.extra_actions) return '';
3199                const contentNode = document.createElement('div');
3200                contentNode.innerHTML = this.cart.extra_actions;
3201                hyva.activateScripts(contentNode);
3202                return contentNode.innerHTML;
3203            }
3204        }
3205    }
3206</script>
3206
3207
3208<section x-cloak x-show="cart" id="cart-drawer" x-data="initCartDrawer()"
3209    @private-content-loaded.window="getData($event.detail.data)"
3210    @toggle-cart.window="toggleCartDrawer($event)"
3211    @keydown.escape="closeCartDrawer">
3212
3213    <div role="dialog" aria-modal="true" :aria-hidden="!open" class="fixed inset-y-0 right-0 z-30 flex max-w-full">
3214        <div class="backdrop" x-show="open" x-transition:enter="ease-out duration-500" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" @click="closeCartDrawer"></div>
3215
3216        <div class="relative w-screen max-w-md shadow-2xl" x-show="open" x-transition:enter="transform transition ease-in-out duration-500" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0">
3217
3218            <div class="flex flex-col h-full bg-white text-black shadow-xl overflow-hidden">
3219
3220                <header class="relative px-4 py-4 sm:px-6 border-b border-gray-100 flex-shrink-0 flex items-center justify-between bg-white z-[60]">
3221                    <div id="cart-drawer-title" class="text-lg font-medium text-gray-900">
3222                        <strong>Mi Carrito</strong>
3223                        <span class="text-xs ml-2" x-show="maxItemsToDisplay && maxItemsToDisplay < itemsCount" x-text="getItemCountTitle()"></span>
3224                    </div>
3225
3226                    <button type="button" @click="closeCartDrawer" class="p-2 text-gray-400 hover:text-[#34515E] transition-colors" aria-label="Cerrar">
3227                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6" width="24" height="24" role="img">
3228  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
3229<title>x</title></svg>
3230                    </button>
3231                </header>
3232
3233                <div class="flex-1 overflow-y-auto overscroll-contain px-1 py-3 sm:px-3 bg-white">
3234                    
3235                    <template x-if="!itemsCount">
3236                        <div class="px-4 py-6 text-center text-gray-500">El carrito está vacío</div>
3237                    </template>
3238
3239                    <template x-if="itemsCount">
3240                        <div class="relative grid gap-6 sm:gap-8 overflow-y-auto overscroll-y-contain">
3241                            <template x-for="item in cartItems" :key="item.item_id">
3242                                <div class="flex items-start p-3 space-x-4 transition duration-150 ease-in-out rounded-lg hover:bg-gray-100">
3243                                    <div class="w-1/4 !ml-0">
3244                                        <img :src="item.product_image.src" loading="lazy" :alt="item.product_name" />
3245                                    </div>
3246
3247                                    <div class="w-3/4 space-y-2">
3248                                        <div>
3249                                            <p class="text-xl font-bold" x-show="item.serie" x-text="item.serie"></p>
3250                                            <p class="text-lg text-gray-700">
3251                                                <span x-text="item.qty"></span> x <span x-html="item.product_name"></span>
3252                                            </p>
3253                                        </div>
3254
3255                                        <template x-for="option in item.options" :key="option.label">
3256                                            <div class="pt-2">
3257                                                <p class="font-semibold" x-text="option.label + ':'"></p>
3258                                                <p class="text-secondary" x-html="option.value"></p>
3259                                            </div>
3260                                        </template>
3261
3262                                        <div class="flex items-end justify-between w-full mt-3">
3263                                            <div class="flex items-center space-x-4">
3264                                                <div class="flex items-center space-x-1 border border-gray-300 rounded-md">
3265                                                    <button type="button" class="p-1 text-gray-500 hover:text-gray-700" @click.prevent="updateItemQty(item.item_id, item.qty, 'sub')">-</button>
3266                                                    <span class="text-base font-bold px-1" x-text="item.qty"></span>
3267                                                    <button type="button" class="p-1 text-gray-500 hover:text-gray-700" @click.prevent="updateItemQty(item.item_id, item.qty, 'add')">+</button>
3268                                                </div>
3269
3270                                                <button type="button" @click="deleteItemFromCart(item.item_id)" class="p-1 text-gray-700 hover:text-red-600 transition">
3271                                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5" width="24" height="24" role="img">
3272  <path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
3273<title>trash</title></svg>
3274                                                </button>
3275                                            </div>
3276
3277                                            <div class="text-right">
3278                                                <p :class="{'font-bold text-base': isVipCustomer, 'text-gray-500 text-sm': !isVipCustomer && item.vip_price, 'font-bold': !item.vip_price}">
3279                                                    <span x-html="isVipCustomer ? item.vip_price : item.product_price"></span>
3280                                                </p>
3281                                                <div x-show="!isVipCustomer && item.vip_price" class="flex items-baseline justify-end gap-1.5 mt-1">
3282                                                    <span class="text-[11px] font-semibold text-gray-700 whitespace-nowrap tracking-wider uppercase">VIP</span>
3283                                                    <span class="font-bold text-lg leading-none" style="color: #8cc4b2;" x-html="item.vip_price"></span>
3284                                                </div>
3285                                            </div>
3286                                        </div>
3287                                    </div>
3288                                </div>
3289                            </template>
3290                        </div>
3291                    </template>
3292                </div>
3293
3294                <div class="flex-shrink-0 bg-gray-50 border-t border-gray-200 overflow-y-auto max-h-[40vh]">
3295                    <template x-if="itemsCount">
3296                        <div class="p-3 space-y-3">
3297                            <div class="space-y-1">
3298                                <div class="flex justify-between text-s text-gray-500">
3299                                    <span x-text="isLoggedIn ? 'Subtotal\u0020al\u0020precio\u0020VIP' : 'Subtotal'"></span>
3300                                    <span x-html="cart.subtotal"></span>
3301                                </div>
3302                                <template x-if="!isVipCustomer && cart.vip_subtotal">
3303                                    <div class="flex justify-between items-center border-b border-gray-200 pb-2">
3304                                        <span class="text-s font-bold text-[#34515E]">Subtotal VIP</span>
3305                                        <span x-html="cart.vip_subtotal" class="text-xl font-bold text-[#8cc4b2]"></span>
3306                                    </div>
3307                                </template>
3308                            </div>
3309
3310                            <div class="space-y-4">
3311                                <div class="minicart-payment-logos flex flex-wrap justify-center gap-1 opacity-70 scale-[0.75] origin-center mt-2 mb-4" id="logos_minicart">
3312                                    
3313<div
3314    class="container flex gap-4 flex-wrap justify-center"
3315    aria-label="Payment Providers">
3316        <!--  -->
3317    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a)"><path fill="#d9dff7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#1434cb" d="M19.108 10.212 14.243 21.82H11.07l-2.393-9.263c-.146-.57-.272-.78-.714-1.02-.722-.391-1.913-.759-2.962-.987l.071-.337h5.109c.651 0 1.237.434 1.385 1.184l1.264 6.715 3.124-7.9zm12.435 7.817c.013-3.063-4.236-3.232-4.206-4.6.009-.417.405-.86 1.273-.973.43-.056 1.616-.099 2.96.52l.527-2.461A8.1 8.1 0 0 0 29.29 10c-2.968 0-5.056 1.578-5.074 3.837-.019 1.67 1.491 2.603 2.629 3.158 1.17.569 1.563.934 1.558 1.443-.008.778-.933 1.122-1.798 1.135-1.509.024-2.385-.408-3.083-.733l-.544 2.543c.702.322 1.997.603 3.339.617 3.154 0 5.218-1.558 5.227-3.97m7.837 3.79h2.777l-2.424-11.607H37.17c-.577 0-1.063.336-1.278.852L31.387 21.82h3.152l.626-1.734h3.852zm-3.35-4.113 1.58-4.358.91 4.358zm-12.632-7.494L20.915 21.82h-3.002l2.483-11.607z"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>visa</title></svg>
3318    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_2)"><path fill="#f1efeb" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#ff5f00" d="M28.376 8.139h-8.75v15.725h8.75z"/><path fill="#eb001b" d="M20.181 16a9.98 9.98 0 0 1 3.82-7.861A9.96 9.96 0 0 0 17.82 6c-5.522 0-10 4.478-10 10s4.478 10 10 10A9.96 9.96 0 0 0 24 23.861 9.98 9.98 0 0 1 20.182 16"/><path fill="#f79e1b" d="M40.178 16c0 5.522-4.477 10-10 10-2.333 0-4.477-.8-6.18-2.139A9.98 9.98 0 0 0 27.818 16a9.98 9.98 0 0 0-3.82-7.861A9.96 9.96 0 0 1 30.178 6c5.522 0 10 4.478 10 10"/></g><defs><clipPath id="a_2"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>mastercard</title></svg>
3319    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_3)"><path fill="#d6edff" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#000" d="M43 10.5v9.523h-2.167V10.5zm-2.965 3.214v6.327H38.11v-.546a2.6 2.6 0 0 1-.83.546q-.465.201-1.006.203-.679 0-1.259-.253a3.2 3.2 0 0 1-1.006-.72 3.5 3.5 0 0 1-.682-1.06 3.7 3.7 0 0 1-.238-1.33q-.001-.708.238-1.313.252-.619.682-1.
3319076a3 3 0 0 1 1.006-.708 3 3 0 0 1 1.26-.267q.539 0 1.006.203.466.19.83.545v-.545h1.925zm-3.414 4.604q.592.001.97-.407.39-.404.39-1.035c0-.42-.13-.769-.39-1.036a1.27 1.27 0 0 0-.97-.406c-.391 0-.722.134-.983.406q-.377.405-.377 1.036c0 .42.127.769.377 1.035q.391.406.983.407M29.996 10.5q.857 0 1.462.24.604.24 1.02.67.428.444.668 1.013.239.57.238 1.227.001.657-.238 1.227c-.157.377-.383.72-.667 1.013q-.415.43-1.021.67-.604.24-1.462.24h-1.044v3.238h-2.205V10.5zm-.316 4.34c.296 0 .519-.03.681-.09q.254-.103.415-.253.34-.316.34-.847t-.34-.847a1.2 1.2 0 0 0-.415-.24q-.239-.101-.681-.102h-.731v2.378zm-11.055-1.126h2.393l1.624 3.034h.027l1.447-3.034h2.216l-4.748 9.538h-2.205l2.167-4.363zm-.427 0v6.327h-1.926v-.546a2.6 2.6 0 0 1-.83.546q-.466.201-1.006.203-.679 0-1.259-.253a3.2 3.2 0 0 1-1.006-.72 3.6 3.6 0 0 1-.682-1.06 3.7 3.7 0 0 1-.238-1.33q0-.708.238-1.313.251-.619.682-1.076a3 3 0 0 1 1.006-.708 3 3 0 0 1 1.26-.267q.539 0 1.006.203.467.19.83.545v-.545h1.925zm-3.414 4.604q.591.001.972-.407.392-.404.392-1.035c0-.42-.13-.769-.392-1.036a1.27 1.27 0 0 0-.972-.406q-.591-.001-.983.406-.378.405-.377 1.036c0 .42.128.769.377 1.035q.392.406.983.407M8.25 10.5q.857 0 1.462.24.604.24 1.02.67.428.444.668 1.013.239.57.238 1.227.001.657-.238 1.227c-.156.377-.383.72-.667 1.013q-.415.43-1.021.67-.604.24-1.462.24H7.205v3.238H5V10.5zm-.313 4.34c.295 0 .519-.03.681-.09a1.3 1.3 0 0 0 .415-.253q.34-.316.34-.847t-.34-.847a1.2 1.2 0 0 0-.415-.24q-.24-.101-.681-.102h-.731v2.378z"/></g><defs><clipPath id="a_3"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>paypal</title></svg>
3320    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_4)"><path fill="#fff1f7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#000" d="M39.478 18.825c-.884 0-1.572-.724-1.572-1.603 0-.88.688-1.603 1.572-1.603s1.573.724 1.573 1.603c0 .88-.69 1.603-1.573 1.603m-.442 1.694c.754 0 1.716-.284 2.249-1.396l.052.025c-.234.608-.234.97-.234 1.06v.143H43v-6.258h-1.897v.142c0 .09 0 .453.233 1.06l-.051.026c-.533-1.112-1.495-1.396-2.249-1.396-1.806 0-3.08 1.422-3.08 3.297s1.274 3.297 3.08 3.297m-6.38-6.594c-.858 0-1.534.297-2.08 1.396l-.052-.026c.234-.607.234-.97.234-1.06v-.142H28.86v6.258h1.95v-3.297c0-.866.507-1.41 1.325-1.41.82 0 1.222.466 1.222 1.397v3.31h1.95v-3.982c0-1.423-1.118-2.444-2.652-2.444M26.04 15.32l-.052-.026c.234-.607.234-.97.234-1.06v-.142h-1.897v6.258h1.95l.012-3.013c0-.879.468-1.41 1.235-1.41.208 0 .377.027.572.078v-1.913c-.858-.181-1.625.142-2.054 1.228m-6.199 3.504c-.883 0-1.572-.724-1.572-1.603 0-.88.689-1.603 1.572-1.603s1.573.724 1.573 1.603c0 .88-.689 1.603-1.5
332073 1.603M19.4 20.52c.754 0 1.716-.284 2.249-1.396l.052.025c-.234.608-.234.97-.234 1.06v.143h1.897v-6.258h-1.897v.142c0 .09 0 .453.234 1.06l-.052.026c-.533-1.112-1.495-1.396-2.248-1.396-1.807 0-3.08 1.422-3.08 3.297s1.273 3.297 3.08 3.297m-5.796-.168h1.95V11.3h-1.95zm-1.43-9.051h-1.988c0 1.616-1 3.064-2.52 4.099l-.599.414V11.3H5v9.05h2.066v-4.486l3.418 4.487h2.521l-3.288-4.293c1.495-1.073 2.47-2.74 2.457-4.758"/></g><defs><clipPath id="a_4"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>klarna</title></svg>
3321    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_5)"><path fill="#e6e6e6" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#000" d="M13.422 11.356a2.62 2.62 0 0 0 .604-1.856 2.6 2.6 0 0 0-1.718.88 2.47 2.47 0 0 0-.615 1.793 2.12 2.12 0 0 0 1.729-.817m.605.944c-.955-.063-1.761.541-2.217.541s-1.157-.509-1.91-.498a2.81 2.81 0 0 0-2.397 1.453c-1.06 1.76-.265 4.38.732 5.823.488.71 1.06 1.496 1.835 1.464s1.008-.467 1.888-.467 1.146.467 1.91.456c.763-.01 1.293-.71 1.781-1.421a6.4 6.4 0 0 0 .796-1.644 2.57 2.57 0 0 1-1.549-2.344 2.61 2.61 0 0 1 1.252-2.207 2.73 2.73 0 0 0-2.121-1.156m8.305-1.983a3.34 3.34 0 0 1 3.51 3.51 3.393 3.393 0 0 1-3.563 3.48h-2.291v3.648h-1.666V10.317zm-2.344 5.643h1.92a2.005 2.005 0 0 0 2.259-2.122 1.983 1.983 0 0 0-2.249-2.121h-1.91zm6.29 2.821c0-1.358 1.06-2.196 2.895-2.302l2.122-.127v-.594c0-.87-.584-1.39-1.56-1.39a1.485 1.485 0 0 0-1.644 1.146h-1.506c.096-1.39 1.294-2.45 3.214-2.45s3.097 1.008 3.097 2.567v5.367H31.37v-1.283a2.76 2.76 0 0 1-2.46 1.41 2.364 2.364 0 0 1-2.631-2.344m5.027-.7v-.615l-1.92.116c-.954.064-1.495.488-1.495 1.157 0 .668.562 1.124 1.421 1.124a1.87 1.87 0 0 0 1.994-1.782m3.033 5.781V22.61q.26.024.52 0a1.305 1.305 0 0 0 1.39-1.06l.137-.478-2.81-7.86h1.728l1.973 6.365 1.962-6.365H41l-2.917 8.189c-.657 1.888-1.432 2.493-3.044 2.493-.18 0-.573-.011-.7-.032"/></g><defs><clipPath id="a_5"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>apple-pay</title></svg>
3322    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_6)"><path fill="#e4e5e7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#3c4043" d="M22.869 16.488v3.933H21.62v-9.712h3.309q1.259 0 2.139.838.897.84.897 2.048c0 .826-.3 1.508-.898 2.06q-.869.828-2.138.827h-2.061zm0-4.583v3.387h2.087c.494 0 .91-.17 1.235-.5.331-.332.5-.735.5-1.19a1.62 1.62 0 0 0-.5-1.177q-.486-.516-1.235-.514h-2.087zm8.361 1.651q1.383 0 2.183.741.8.74.8 2.029v4.095h-1.19v-.923h-.052q-.771 1.139-2.06 1.138-1.1.001-1.84-.65-.741-.652-.741-1.626 0-1.033.78-1.638.781-.613 2.08-.611 1.113 0 1.827.41v-.287c0-.435-.17-.8-.514-1.105a1.76 1.76 0 0 0-1.209-.455c-.695 0-1.248.293-1.651.884l-1.099-.689q.909-1.314 2.685-1.313m-1.613 4.824c0 .325.136.598.416.812q.411.324.968.325.79 0 1.405-.585.616-.583.617-1.371-.584-.46-1.625-.462-.76.002-1.268.364-.515.381-.513.917M41 13.77l-4.16 9.57h-1.288l1.547-3.348-2.743-6.221h1.359l1.976 4.771h.026l1.924-4.771z"/><path fill="#4285f4" d="M17.904 15.695q-.001-.61-.104-1.171h-5.232v2.145l3.013.001a2.58 2.58 0 0 1-1.118 1.728v1.392h1.794c1.047-.97 1.647-2.402 1.647-4.095"/><path fill="#34a853" d="M14.464 18.398c-.5.337-1.142.534-1.895.534-1.453 0-2.685-.98-3.127-2.3h-1.85v1.436a5.57 5.57 0 0 0 4.977 3.067c1.505 0 2.768-.494 3.688-1.346z"/><path fill="#fabb05" d="M9.268 15.568c0-.37.062-.729.174-1.065v-1.436h-1.85A5.54 5.54 0 0 0 7 15.568c0 .9.214 1.749.592 2.501l1.85-1.435a3.4 3.4 0 0 1-.174-1.066"/><path fill="#e94235" d="M12.57 12.204c.82 0 1.556.283 2.136.835l1.59-1.588c-.966-.9-2.224-1.451-3.727-1.451a5.57 5.57 0 0 0-4.977 3.067l1.85 1.436c.442-1.32 1.674-2.3 3.127-2.3"/></g><defs><clipPath id="a_6"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>google-pay</title></svg>
3323
3324</div>                                </div>
3325
3326                                <a @click.prevent.stop="closeCartDrawer; $dispatch('toggle-authentication', {url: 'https://www.mueblesbonitos.com/checkout/'});"
3327                                    href="https://www.mueblesbonitos.com/checkout/"
3328                                    class="block w-full text-center rounded-lg shadow font-bold text-base text-white py-3 transition hover:brightness-110"
3329                                    style="background-color: #34515E !important;">
3330                                    Finalizar compra                                </a>
3331                            </div>
3332
3333                            <template x-if="!isVipCustomer">
3334                                <a href="https://www.mueblesbonitos.com/customer/account/login/"
3335                                    rel="nofollow"
3336                                    class="block p-2 rounded-lg bg-white border border-gray-200 text-center shadow-sm">
3337                                    <span class="text-[14px] font-bold text-[#34515E]">
3338                                        ¿Quieres ser VIP?                                        <span style="color: #8cc4b2;" class="underline ml-1">Pincha aquí</span>
3339                                    </span>
3340                                </a>
3341                            </template>
3342                        </div>
3343                    </template>
3344                </div>
3345            </div>
3346        </div>
3347    </div>
3348</section>
3349<klarna-placement data-key="top-strip-promotion-badge" data-locale="es-ES"></klarna-placement>  <!-- BLOCK authentication-popup -->
3349<script>
3350    function initAuthentication() {
3351        return {
3352            open: false,
3353            close() {
3354                this.open = false;
3355            },
3356            forceAuthentication: false,
3357            checkoutUrl: 'https://www.mueblesbonitos.com/checkout/index/',
3358            errors: 0,
3359            hasCaptchaToken: 0,
3360            displayErrorMessage: false,
3361            errorMessages: [],
3362            setErrorMessages(message) {
3363                this.errorMessages = [message];
3364                this.displayErrorMessage = true;
3365            },
3366            submitForm() {
3367                // Do not rename $form, the variable is expected to be declared in the recaptcha output
3368                const $form = document.querySelector('#login-form');
3369                    if (!this.hasCaptchaToken) {
3370        this.errors = 1;
3371
3372
3373        const executeGreCaptcha = () => {
3374            grecaptcha.ready(() => {
3375                grecaptcha.execute(
3376                    '6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3',
3377                    {action: 'submit'}
3378                ).then((token) => {
3379                    const tokenElement = $form['g\u002Drecaptcha\u002Dresponse'];
3380
3381                    if (tokenElement && token && token.length > 0) {
3382                        $form['g\u002Drecaptcha\u002Dresponse'].value = token;
3383                        this.errors = 0;
3384                        this.hasCaptchaToken = 1;
3385                        (this.submitForm || $form.submit).call(this);
3386                    } else {
3387                        this.errors = 1;
3388                        const error = tokenElement
3389                            ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'
3390                            : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.';
3391                        if (this.setErrorMessages) {
3392                            this.setErrorMessages([error])
3393                            this.displayErrorMessage = true;
3394                        } else {
3395                            window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000);
3396                        }
3397                    }
3398                }).catch(exception => {
3399                    console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`)
3400                });
3401            })
3402        }
3403
3404        if (window.grecaptcha) {
3405            executeGreCaptcha();
3406        } else {
3407            const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3";
3408            const script = document.createElement('script');
3409            script.setAttribute('type', 'text/javascript');
3410            script.setAttribute('src', recaptchaUrl);
3411            document.head.appendChild(script);
3412
3413            script.addEventListener("load", executeGreCaptcha, false);
3414        }
3415    }
3416
3417                if (this.errors === 0) {
3418                    this.dispatchLoginRequest($form);
3419                }
3420            },
3421            onPrivateContentLoaded() {
3422                const data = this.$event.detail.data;
3423                const isLoggedIn = data.customer && data.customer.firstname;
3424                if (data.cart && !isLoggedIn) {
3425                    this.forceAuthentication = !data.cart.isGuestCheckoutAllowed;
3426                }
3427            },
3428            redirectIfAuthenticated() {
3429                const event = this.$event;
3430                this.open = this.forceAuthentication;
3431
3432                if (event.detail && event.detail.url) {
3433                    this.checkoutUrl = event.detail.url;
3434                }
3435                if (!this.forceAuthentication) {
3436                    window.location.href = this.checkoutUrl;
3437                }
3438            },
3439            resetErrors() {
3440                this.errors = 0;
3441            },
3442            dispatchLoginRequest(form) {
3443                this.isLoading = true;
3444                const username = this.$refs['customer-email'].value;
3445                const password = this.$refs['customer-password'].value;
3446                const formKey = hyva.getFormKey();
3447                const bodyFields = {
3448                    'username': username,
3449                    'password': password,
3450                    'formKey': formKey
3451                };
3452                                const fieldName = 'g\u002Drecaptcha\u002Dresponse';
3453                const recaptchaField = fieldName && form[fieldName];
3454                if (recaptchaField) {
3455                    bodyFields[fieldName] = recaptchaField.value;
3456                }
3457                fetch('https://www.mueblesbonitos.com/customer/ajax/login/', {
3458                        method: 'POST',
3459                        headers: {
3460                            'Content-Type': 'application/json',
3461                            'X-Requested-With': 'XMLHttpRequest'
3462                        },
3463                        body: JSON.stringify(bodyFields)
3464                    }
3465                ).then(response => {
3466                        return response.json()
3467                    }
3468                ).then(data => {
3469                    this.isLoading = false;
3470                    if (data.errors) {
3471                        this.setErrorMessages(data.message);
3472                        this.errors = 1;
3473                        this.hasCaptchaToken = 0;
3474                    } else {
3475                        window.location.href = this.checkoutUrl;
3476                    }
3477                });
3478            },
3479            eventListeners: {
3480                ['@private-content-loaded.window']() {
3481                    this.onPrivateContentLoaded();
3482                },
3483                ['@toggle-authentication.window']() {
3484                    this.redirectIfAuthenticated();
3485                },
3486                ['@pageshow.window'](event) {
3487                    if (event.persisted) {
3488                        this.close();
3489                    };
3490                }
3491            }
3492        }
3493    }
3494
3495    window.addEventListener('alpine:init', () => Alpine.data('initAuthentication', initAuthentication), {once: true})
3496</script>
3496
3497
3498<dialog
3499    id="authentication-popup"
3500    aria-labelledby="authentication-popup-title"
3501    class="open:flex flex-col transition ease-out duration-300 motion-reduce:duration-0 p-0"
3502    x-data="initAuthentication"
3503    x-bind="eventListeners"
3504    x-show="open"
3505    x-htmldialog="close"
3506    closeby="any"
3507    x-transition
3508>
3509    <div class="pt-8 px-8">
3510        <div class="flex gap-2 justify-between items-center">
3511            <p id="authentication-popup-title" class="text-xl">
3512                <strong>Identificador de cliente</strong>
3513            </p>
3514            <button
3515                type="button"
3516                class="btn bg-transparent border-transparent p-2"
3517                @click="close"
3518                aria-label="Cerrar&#x20;panel"
3519            >
3520                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>
3521            </button>
3522        </div>
3523
3524        <div class="message error" x-show="errors" x-cloak>
3525            <template x-for="(message, index) in errorMessages" :key="index">
3526                <div>
3527                    <template x-if="message">
3528                        <span x-html="message"></span>
3529                    </template>
3530                </div>
3531            </template>
3532        </div>
3533    </div>
3534
3535    <div class="block-customer-login p-8">
3536        <p id="authenticate-customer-login" class="text-lg mb-2">
3537            <strong>Checkout using your account</strong>
3538        </p>
3539
3540        <form
3541            id="login-form"
3542            class="form form-login"
3543            method="post"
3544            @submit.prevent="submitForm"
3545        >
3546            <div class="control">
3547    <input type="hidden"
3548           value=""
3549           name="g-recaptcha-response"
3550    >
3551</div>
3552            <input name="context" type="hidden" value="checkout">
3553
3554            <div class="flex flex-col gap-4">
3555                <div class="field email required">
3556                    <label for="form-login-username">
3557                        <span>Correo Electrónico</span>
3558                    </label>
3559                    <div class="control">
3560                        <input
3561                            id="form-login-username"
3562                            name="username"
3563                            type="email"
3564                            class="form-input w-full"
3565                            required
3566                            autocomplete="off"
3567                            x-ref="customer-email"
3568                            @change="resetErrors"
3569                        >
3570                    </div>
3571                </div>
3572                <div class="field password required">
3573                    <label for="form-login-password">
3574                        <span>Contraseña</span>
3575                    </label>
3576                    <div class="control">
3577                        <input
3578                            id="form-login-password"
3579                            name="password"
3580                            type="password"
3581                            class="form-input w-full"
3582                            required
3583                            autocomplete="off"
3584                            x-ref="customer-password"
3585                            @change="resetErrors"
3586                        >
3587                    </div>
3588                </div>
3589            </div>
3590
3591            <div class="actions-toolbar">
3592                <button
3593                    type="submit"
3594                                        class="btn btn-primary"
3595                >
3596                    Iniciar Sesión                </button>
3597                <a
3598                    href="https://www.mueblesbonitos.com/customer/account/forgotpassword/"
3599                    class="underline hover:no-underline"
3600                >
3601                    ¿Olvidó su Contraseña?                </a>
3602            </div>
3603        </form>
3604        <p class="prose my-4 text-sm">
3605    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
3606</p>
3607    </div>
3608    <div class="block-new-customer p-8 border-t border-gray-300">
3609        <p id="authenticate-new-customer" class="text-lg mb-2">
3610            <strong>Checkout as a new customer</strong>
3611        </p>
3612
3613        <div class="block-content">
3614            <p class="mb-1">
3615                Creating an account has many benefits:            </p>
3616            <ul class="list-disc pl-5">
3617                <li> See order and shipping status</li>
3618                <li> Track order history</li>
3619                <li> Check out faster</li>
3620            </ul>
3621            <div class="actions-toolbar mt-6 mb-2">
3622                <a href="https://www.mueblesbonitos.com/customer/account/create/"
3623                    class="inline-flex btn btn-primary">
3624                    Crear una Cuenta                </a>
3625            </div>
3626        </div>
3627    </div>
3628</dialog>
3629<!-- /BLOCK authentication-popup --></div>
3630
3631<script>
3632  document.addEventListener('alpine:init', () => {
3633    window.initMenuDesktop = function() {
3634      return {
3635        maxLevel: parseInt(this.$el?.dataset?.maxLevel ?? '4', 10),
3636        setActiveMenu() {
3637          try {
3638            this.$el.querySelectorAll('[data-level]').forEach(() => {});
3639          } catch (e) {
3640            console.warn('[menu] setActiveMenu skipped:', e);
3641          }
3642        }
3643      }
3644    }
3645  });
3646</script>
3646
3647</header><div class="top-container"><nav class="breadcrumbs bg-container-lighter shadow-sm" aria-label="Breadcrumb">
3648    <div class="container">
3649        <ol class="items list-reset py-4 rounded flex flex-wrap text-grey text-sm">
3650                            <li class="item flex home">
3651                                                    <a
3652                        href="https://www.mueblesbonitos.com/"
3653                                                    aria-label="Ir&#x20;a&#x20;la&#x20;p&#xE1;gina&#x20;de&#x20;inicio"
3654                                            >Inicio</a>
3655                                </li>
3656                            <li class="item flex category37">
3657                                    <span aria-hidden="true" class="separator text-primary-lighter px-2">/</span>
3658                                                    <span
3659                       class="text-primary-lighter"
3660                       aria-current="page"
3661                    >Salones Modernos</span>
3662                                </li>
3663                    </ol>
3664    </div>
3665</nav>
3666
3667<script type="application/ld+json">
3668{
3669    "@context": "https://schema.org",
3670    "@type": "BreadcrumbList",
3671    "itemListElement": [
3672        {
3673            "@type": "ListItem",
3674            "position": 1,
3675            "name": "Inicio",
3676            "item": "https://www.mueblesbonitos.com/"
3677        },
3678        {
3679            "@type": "ListItem",
3680            "position": 2,
3681            "name": "Salones Modernos"
3682        }
3683    ]
3684}</script>
3684
3685
3686</div><main id="maincontent" class="page-main"><div id="contentarea" tabindex="-1"></div>
3687<div class="page messages">
3687<script>
3688        function initMessages() {
3689        "use strict";
3690        return {
3691            messages: window.mageMessages || [],
3692            isEmpty() {
3693                return this.messages.reduce(
3694                    function (isEmpty, message) {
3695                        return isEmpty && message === undefined
3696                    }, true
3697                )
3698            },
3699            hasMessages() {
3700                return !this.isEmpty();
3701            },
3702            hasMessage() {
3703                return !!this.message;
3704            },
3705            removeMessage() {
3706                this.messages[this.index] = undefined;
3707            },
3708            addMessages(messages, hideAfter) {
3709                messages.map((message) => {
3710                    this.messages = this.messages.concat(message);
3711                    if (hideAfter === undefined && message.type === 'success' && window.defaultSuccessMessageTimeout) {
3712                        hideAfter = window.defaultSuccessMessageTimeout;
3713                    }
3714                    if (hideAfter) {
3715                        this.setHideTimeOut(this.messages.length -1, hideAfter);
3716                    }
3717                });
3718            },
3719            setHideTimeOut(messageIndex, hideAfter) {
3720                setTimeout((messageIndex) => {
3721                    this.messages[messageIndex] = undefined;
3722                }, hideAfter, messageIndex);
3723            },
3724            eventListeners: {
3725                ['@messages-loaded.window'](event) {
3726                    this.addMessages(event.detail.messages, event.detail.hideAfter)
3727                },
3728                ['@private-content-loaded.window'](event) {
3729                    const data = event.detail.data;
3730                    if (
3731                        data.messages &&
3732                        data.messages.messages &&
3733                        data.messages.messages.length
3734                    ) {
3735                        this.addMessages(data.messages.messages);
3736                    }
3737                },
3738                ['@clear-messages.window']() {
3739                    this.messages = [];
3740                }
3741            },
3742            getMessageUiId() {
3743                return 'message-' + this.message.type;
3744            }
3745        }
3746    }
3747
3748    window.addEventListener('alpine:init', () => Alpine.data('initMessages', initMessages), {once: true})
3749</script>
3749
3750<section id="messages"
3751         x-data="initMessages"
3752         x-bind="eventListeners"
3753         aria-live="assertive"
3754         role="alert"
3755>
3756    <template x-if="hasMessages">
3757        <div class="w-full">
3758            <div class="messages container mx-auto py-3">
3759                <template x-for="(message, index) in messages" :key="index">
3760                    <div>
3761                        <template x-if="hasMessage">
3762                            <div class="message"
3763                                 :class="message.type"
3764                                 :ui-id="getMessageUiId"
3765                            >
3766                                <span x-html="message.text"></span>
3767                                <button
3768                                    type="button"
3769                                    class="text-gray-600 hover:text-black"
3770                                    aria-label="Cerrar mensaje"
3771                                    @click.prevent="removeMessage"
3772                                >
3773                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="stroke-current" width="18" height="18" aria-hidden="true">
3774  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
3775</svg>
3776                                </button>
3777                            </div>
3778                        </template>
3779                    </div>
3780                </template>
3781            </div>
3782        </div>
3783    </template>
3784</section>
3785</div><div class="columns"><div class="column main"><div>
3786    <div class="category-buttons my-2 flex&#x20;gap-2&#x20;overflow-x-auto&#x20;snap-x&#x20;snap-mandatory&#x20;pb-2">
3787                    <a href="https://www.mueblesbonitos.com/salon/mueble-tv"
3788           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3789                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3790                  snap-start shrink-0">
3791            Mueble TV        </a>
3792                    <a href="https://www.mueblesbonitos.com/salon/aparadores"
3793           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3794                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3795                  snap-start shrink-0">
3796            Aparador        </a>
3797                    <a href="https://www.mueblesbonitos.com/salon/mesas-de-centro"
3798           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3799                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3800                  snap-start shrink-0">
3801            Mesas de Centro        </a>
3802                    <a href="https://www.mueblesbonitos.com/salon/mesas-y-sillas-de-comedor"
3803           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3804                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3805                  snap-start shrink-0">
3806            Mesas de Comedor        </a>
3807                    <a href="https://www.mueblesbonitos.com/salon/estanterias"
3808           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3809                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3810                  snap-start shrink-0">
3811            Estanterías de Diseño        </a>
3812                    <a href="https://www.mueblesbonitos.com/salon/vitrinas"
3813           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3814                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3815                  snap-start shrink-0">
3816            Vitrinas        </a>
3817                    <a href="https://www.mueblesbonitos.com/salon/armario"
3818           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3819                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3820                  snap-start shrink-0">
3821            Armarios de Salón        </a>
3822                    <a href="https://www.mueblesbonitos.com/salon/conjuntos-de-salon"
3823           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3824                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3825                  snap-start shrink-0">
3826            Conjuntos de Salón        </a>
3827                    <a href="https://www.mueblesbonitos.com/salon/muebles-con-chimenea"
3828           class="inline-flex items-center px-4 py-1 border rounded-full text-sm font-medium
3829                  text-gray-700 bg-gray-200 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500
3830                  snap-start shrink-0">
3831            Muebles con Chimenea        </a>
3832    </div>
3833</div>
3834
3835
3836    <div id="amasty-shopby-product-list">
3837
3838    <style>
3839        .products-grid .price-container,
3840        .products-list .price-container {
3841            display: none;
3842        }
3843    </style>
3844
3845    <div class="container flex flex-col items-start text-left mb-6 mt-4">
3846                <h1 class="text-xl font-bold uppercase">
3847            Salones modernos        </h1>
3848        <div style="display: none">
3849            <h2>Descubre nuestro catálogo de  Salones Modernos</h2>
3850        </div>
3851
3852                
3853            </div>
3854
3855    
3856    <div class="container">
3857            </div>
3858
3859    <section class="" id="product-list" aria-label="Lista&#x20;de&#x20;productos" tabindex="-1">
3860                        <div class="products wrapper mode-grid products-grid">
3861            <ul role="list" class="mx-auto pt-4 pb-12 grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
3862                                    <li class="flex flex-col">
3863                        
3864<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
3865
3866    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-blanco-y-sonoma-140-cm-ani" class="flex flex-col grow w-full">
3867        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
3868            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-ani-140cm-branca-e-sonoma_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-ani-140cm-branca-e-sonoma_1.jpg" width="360" height="360" alt="mesa-alta-ani-140cm-branca-e-sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-6916.window="updateImage" loading="lazy"></picture>
3869            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
3870                    </div>
3871
3872        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
3873                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
3874                    <strong>Ani</strong>
3875                </div>
3876            
3877            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
3878                <span class="product-item-link">Mesa alta Blanco y Sonoma 140 cm Ani</span>
3879            </div>
3880
3881            
3882            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-6916.window="updatePrice($event.detail);">
3883                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="6916" data-price-box="product-id-6916">
3884    <span
3885    x-data x-id="['product\u002Dprice\u002D6916']"     class="price-container price-final_price&#x20;tax&#x20;weee"
3886    >
3887    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
3888        <span class="price"><span class="price">89,00 €</span></span>
3889    </span>
3890    
3891                        <span class="old-price mr-1">
3892                <span class="price line-through text-gray-600">
3893                    <span class="price"><span class="price">95,00 €</span></span>
3894
3895                </span>
3896            </span>
3897        
3898    
3899    
3900    </span>
3901</div></div>
3902                            </div>
3903        </div>
3904    </a>
3905
3906
3907            <!-- <div>CATEGORIA: </div> -->
3908        <div class="product-item-variations px-4 py-2 mt-auto">
3909            <div id="variaciones-listado-6916">
3910                                    <div class="color-picker-grid-mode-clean">
3911        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
3912            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
3913                Colores Disponibles:
3914            </span>
3915
3916            <div class="flex flex-wrap gap-4 items-center">
3917                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-140-cm-ani" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-140-cm-ani"></div>            </div>
3918        </div>
3919    </div>                            </div>
3920        </div>
3921        <div class="px-4 pb-4">
3922        
3923<div class="mt-1 flex flex-col">
3924            <!-- Invitado: base price + línea VIP (si existe) -->
3925        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
3926            95,00 €        </span>
3927
3928                    <div class="flex items-baseline gap-1.5">
3929                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
3930                    89,00 €                </span>
3931                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
3932                    Precio VIP                </span>
3933            </div>
3934
3935
3936            </div>    </div>
3937</div>
3938
3939<style>
3940    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
3941    .color-picker-grid-mode-clean,
3942    .color-picker-grid-mode-clean>div {
3943        display: flex !important;
3944        flex-direction: row !important;
3945        flex-wrap: wrap !important;
3946        align-items: center !important;
3947        gap: 6px !important;
3948        padding: 0 !important;
3949        margin: 0 !important;
3950        border: none !important;
3951    }
3952
3953    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
3954    /* El método renderSection imprime un span con el título, lo eliminamos */
3955    .color-picker-grid-mode-clean span.text-sm.font-bold,
3956    .color-picker-grid-mode-clean .w-32 {
3957        display: none !important;
3958    }
3959
3960    /* 3. Ajuste de las "bolitas" de color */
3961    .color-picker-grid-mode-clean .w-9.h-9 {
3962        width: 22px !important;
3963        /* Tamaño reducido ideal para rejilla */
3964        height: 22px !important;
3965        min-width: 22px !important;
3966        min-height: 22px !important;
3967        margin: 0 !important;
3968        transform: none !important;
3969        /* Evitamos que el seleccionado crezca y descuadre */
3970        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
3971    }
3972
3973    /* 4. Ajuste del icono Check (V) de selección */
3974    .color-picker-grid-mode-clean svg {
3975        width: 14px !important;
3976        height: 14px !important;
3977    }
3978
3979    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
3980    .product-item-variations {
3981        margin-top: 4px !important;
3982        margin-bottom: 4px !important;
3983        padding-top: 0 !important;
3984        padding-bottom: 0 !important;
3985    }
3986
3987    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
3988    .color-picker-grid-mode-clean .flex-wrap {
3989        gap: 6px !important;
3990    }
3991
3992    .product-item-photo>span picture,
3993    .product-item-photo>span img {
3994        width: 100% !important;
3995        height: auto !important;
3996        display: block !important;
3997    }
3998
3999    .product-item-photo>span picture {
4000        position: static !important;
4001    }
4002</style>                    </li>
4003                                    <li class="flex flex-col">
4004                        
4005<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4006
4007    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-kyra-110cm-color-blanco-y-sonoma" class="flex flex-col grow w-full">
4008        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4009            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-kyra-110cm-cor-branca-e-sonoma.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-kyra-110cm-cor-branca-e-sonoma.jpg" width="360" height="360" alt="mesa-alta-kyra-110cm-cor-branca-e-sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-6917.window="updateImage" loading="lazy"></picture>
4010            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4011                    </div>
4012
4013        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4014                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4015                    <strong>Kyra</strong>
4016                </div>
4017            
4018            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4019                <span class="product-item-link">Mesa alta Kyra  (110cm) color blanco y sonoma</span>
4020            </div>
4021
4022            
4023            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-6917.window="updatePrice($event.detail);">
4024                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="6917" data-price-box="product-id-6917">
4025    <span
4026    x-data x-id="['product\u002Dprice\u002D6917']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4027    >
4028    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4029        <span class="price"><span class="price">79,00 €</span></span>
4030    </span>
4031    
4032                        <span class="old-price mr-1">
4033                <span class="price line-through text-gray-600">
4034                    <span class="price"><span class="price">89,00 €</span></span>
4035
4036                </span>
4037            </span>
4038        
4039    
4040    
4041    </span>
4042</div></div>
4043                            </div>
4044        </div>
4045    </a>
4046
4047
4048            <!-- <div>CATEGORIA: </div> -->
4049        <div class="product-item-variations px-4 py-2 mt-auto">
4050            <div id="variaciones-listado-6917">
4051                                    <div class="color-picker-grid-mode-clean">
4052        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4053            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4054                Colores Disponibles:
4055            </span>
4056
4057            <div class="flex flex-wrap gap-4 items-center">
4058                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-110-cm-kyra" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-110-cm-kyra"></div>            </div>
4059        </div>
4060    </div>                            </div>
4061        </div>
4062        <div class="px-4 pb-4">
4063        
4064<div class="mt-1 flex flex-col">
4065            <!-- Invitado: base price + línea VIP (si existe) -->
4066        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4067            89,00 €        </span>
4068
4069                    <div class="flex items-baseline gap-1.5">
4070                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4071                    79,00 €                </span>
4072                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4073                    Precio VIP                </span>
4074            </div>
4075
4076
4077            </div>    </div>
4078</div>
4079
4080<style>
4081    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4082    .color-picker-grid-mode-clean,
4083    .color-picker-grid-mode-clean>div {
4084        display: flex !important;
4085        flex-direction: row !important;
4086        flex-wrap: wrap !important;
4087        align-items: center !important;
4088        gap: 6px !important;
4089        padding: 0 !important;
4090        margin: 0 !important;
4091        border: none !important;
4092    }
4093
4094    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4095    /* El método renderSection imprime un span con el título, lo eliminamos */
4096    .color-picker-grid-mode-clean span.text-sm.font-bold,
4097    .color-picker-grid-mode-clean .w-32 {
4098        display: none !important;
4099    }
4100
4101    /* 3. Ajuste de las "bolitas" de color */
4102    .color-picker-grid-mode-clean .w-9.h-9 {
4103        width: 22px !important;
4104        /* Tamaño reducido ideal para rejilla */
4105        height: 22px !important;
4106        min-width: 22px !important;
4107        min-height: 22px !important;
4108        margin: 0 !important;
4109        transform: none !important;
4110        /* Evitamos que el seleccionado crezca y descuadre */
4111        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4112    }
4113
4114    /* 4. Ajuste del icono Check (V) de selección */
4115    .color-picker-grid-mode-clean svg {
4116        width: 14px !important;
4117        height: 14px !important;
4118    }
4119
4120    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4121    .product-item-variations {
4122        margin-top: 4px !important;
4123        margin-bottom: 4px !important;
4124        padding-top: 0 !important;
4125        padding-bottom: 0 !important;
4126    }
4127
4128    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4129    .color-picker-grid-mode-clean .flex-wrap {
4130        gap: 6px !important;
4131    }
4132
4133    .product-item-photo>span picture,
4134    .product-item-photo>span img {
4135        width: 100% !important;
4136        height: auto !important;
4137        display: block !important;
4138    }
4139
4140    .product-item-photo>span picture {
4141        position: static !important;
4142    }
4143</style>                    </li>
4144                                    <li class="flex flex-col">
4145                        
4146<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4147
4148    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-kyra-110cm-color-blanco" class="flex flex-col grow w-full">
4149        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4150            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-kyra-110cm-branca.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-kyra-110cm-branca.jpg" width="360" height="360" alt="mesa-alta-kyra-110cm-branca" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-6918.window="updateImage" loading="lazy"></picture>
4151            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4152                    </div>
4153
4154        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4155                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4156                    <strong>Kyra</strong>
4157                </div>
4158            
4159            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4160                <span class="product-item-link">Mesa alta Kyra  (110cm) color blanco</span>
4161            </div>
4162
4163            
4164            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-6918.window="updatePrice($event.detail);">
4165                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="6918" data-price-box="product-id-6918">
4166    <span
4167    x-data x-id="['product\u002Dprice\u002D6918']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4168    >
4169    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4170        <span class="price"><span class="price">79,00 €</span></span>
4171    </span>
4172    
4173                        <span class="old-price mr-1">
4174                <span class="price line-through text-gray-600">
4175                    <span class="price"><span class="price">89,00 €</span></span>
4176
4177                </span>
4178            </span>
4179        
4180    
4181    
4182    </span>
4183</div></div>
4184                            </div>
4185        </div>
4186    </a>
4187
4188
4189            <!-- <div>CATEGORIA: </div> -->
4190        <div class="product-item-variations px-4 py-2 mt-auto">
4191            <div id="variaciones-listado-6918">
4192                                    <div class="color-picker-grid-mode-clean">
4193        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4194            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4195                Colores Disponibles:
4196            </span>
4197
4198            <div class="flex flex-wrap gap-4 items-center">
4199                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco-y-sonoma" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco-y-sonoma"></div><div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-110-cm-kyra" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-110-cm-kyra"></div>            </div>
4200        </div>
4201    </div>                            </div>
4202        </div>
4203        <div class="px-4 pb-4">
4204        
4205<div class="mt-1 flex flex-col">
4206            <!-- Invitado: base price + línea VIP (si existe) -->
4207        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4208            89,00 €        </span>
4209
4210                    <div class="flex items-baseline gap-1.5">
4211                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4212                    79,00 €                </span>
4213                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4214                    Precio VIP                </span>
4215            </div>
4216
4217
4218            </div>    </div>
4219</div>
4220
4221<style>
4222    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4223    .color-picker-grid-mode-clean,
4224    .color-picker-grid-mode-clean>div {
4225        display: flex !important;
4226        flex-direction: row !important;
4227        flex-wrap: wrap !important;
4228        align-items: center !important;
4229        gap: 6px !important;
4230        padding: 0 !important;
4231        margin: 0 !important;
4232        border: none !important;
4233    }
4234
4235    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4236    /* El método renderSection imprime un span con el título, lo eliminamos */
4237    .color-picker-grid-mode-clean span.text-sm.font-bold,
4238    .color-picker-grid-mode-clean .w-32 {
4239        display: none !important;
4240    }
4241
4242    /* 3. Ajuste de las "bolitas" de color */
4243    .color-picker-grid-mode-clean .w-9.h-9 {
4244        width: 22px !important;
4245        /* Tamaño reducido ideal para rejilla */
4246        height: 22px !important;
4247        min-width: 22px !important;
4248        min-height: 22px !important;
4249        margin: 0 !important;
4250        transform: none !important;
4251        /* Evitamos que el seleccionado crezca y descuadre */
4252        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4253    }
4254
4255    /* 4. Ajuste del icono Check (V) de selección */
4256    .color-picker-grid-mode-clean svg {
4257        width: 14px !important;
4258        height: 14px !important;
4259    }
4260
4261    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4262    .product-item-variations {
4263        margin-top: 4px !important;
4264        margin-bottom: 4px !important;
4265        padding-top: 0 !important;
4266        padding-bottom: 0 !important;
4267    }
4268
4269    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4270    .color-picker-grid-mode-clean .flex-wrap {
4271        gap: 6px !important;
4272    }
4273
4274    .product-item-photo>span picture,
4275    .product-item-photo>span img {
4276        width: 100% !important;
4277        height: auto !important;
4278        display: block !important;
4279    }
4280
4281    .product-item-photo>span picture {
4282        position: static !important;
4283    }
4284</style>                    </li>
4285                                    <li class="flex flex-col">
4286                        
4287<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4288
4289    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-110-cm-kyra" class="flex flex-col grow w-full">
4290        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4291            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-110-cm-kyra-03.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-110-cm-kyra-03.jpg" width="360" height="360" alt="mesa-alta-negro-sonoma-110-cm-kyra" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7140.window="updateImage" loading="lazy"></picture>
4292            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4293                    </div>
4294
4295        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4296                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4297                    <strong>Kyra</strong>
4298                </div>
4299            
4300            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4301                <span class="product-item-link">Mesa alta Negro y Sonoma 110 cm Kyra</span>
4302            </div>
4303
4304            
4305            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7140.window="updatePrice($event.detail);">
4306                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7140" data-price-box="product-id-7140">
4307    <span
4308    x-data x-id="['product\u002Dprice\u002D7140']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4309    >
4310    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4311        <span class="price"><span class="price">79,00 €</span></span>
4312    </span>
4313    
4314                        <span class="old-price mr-1">
4315                <span class="price line-through text-gray-600">
4316                    <span class="price"><span class="price">89,00 €</span></span>
4317
4318                </span>
4319            </span>
4320        
4321    
4322    
4323    </span>
4324</div></div>
4325                            </div>
4326        </div>
4327    </a>
4328
4329
4330            <!-- <div>CATEGORIA: </div> -->
4331        <div class="product-item-variations px-4 py-2 mt-auto">
4332            <div id="variaciones-listado-7140">
4333                                    <div class="color-picker-grid-mode-clean">
4334        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4335            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4336                Colores Disponibles:
4337            </span>
4338
4339            <div class="flex flex-wrap gap-4 items-center">
4340                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco-y-sonoma" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco-y-sonoma"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-kyra-110cm-color-blanco"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
4341        </div>
4342    </div>                            </div>
4343        </div>
4344        <div class="px-4 pb-4">
4345        
4346<div class="mt-1 flex flex-col">
4347            <!-- Invitado: base price + línea VIP (si existe) -->
4348        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4349            89,00 €        </span>
4350
4351                    <div class="flex items-baseline gap-1.5">
4352                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4353                    79,00 €                </span>
4354                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4355                    Precio VIP                </span>
4356            </div>
4357
4358
4359            </div>    </div>
4360</div>
4361
4362<style>
4363    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4364    .color-picker-grid-mode-clean,
4365    .color-picker-grid-mode-clean>div {
4366        display: flex !important;
4367        flex-direction: row !important;
4368        flex-wrap: wrap !important;
4369        align-items: center !important;
4370        gap: 6px !important;
4371        padding: 0 !important;
4372        margin: 0 !important;
4373        border: none !important;
4374    }
4375
4376    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4377    /* El método renderSection imprime un span con el título, lo eliminamos */
4378    .color-picker-grid-mode-clean span.text-sm.font-bold,
4379    .color-picker-grid-mode-clean .w-32 {
4380        display: none !important;
4381    }
4382
4383    /* 3. Ajuste de las "bolitas" de color */
4384    .color-picker-grid-mode-clean .w-9.h-9 {
4385        width: 22px !important;
4386        /* Tamaño reducido ideal para rejilla */
4387        height: 22px !important;
4388        min-width: 22px !important;
4389        min-height: 22px !important;
4390        margin: 0 !important;
4391        transform: none !important;
4392        /* Evitamos que el seleccionado crezca y descuadre */
4393        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4394    }
4395
4396    /* 4. Ajuste del icono Check (V) de selección */
4397    .color-picker-grid-mode-clean svg {
4398        width: 14px !important;
4399        height: 14px !important;
4400    }
4401
4402    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4403    .product-item-variations {
4404        margin-top: 4px !important;
4405        margin-bottom: 4px !important;
4406        padding-top: 0 !important;
4407        padding-bottom: 0 !important;
4408    }
4409
4410    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4411    .color-picker-grid-mode-clean .flex-wrap {
4412        gap: 6px !important;
4413    }
4414
4415    .product-item-photo>span picture,
4416    .product-item-photo>span img {
4417        width: 100% !important;
4418        height: auto !important;
4419        display: block !important;
4420    }
4421
4422    .product-item-photo>span picture {
4423        position: static !important;
4424    }
4425</style>                    </li>
4426                                    <li class="flex flex-col">
4427                        
4428<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4429
4430    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-140-cm-ani" class="flex flex-col grow w-full">
4431        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4432            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-preto-sonoma-140-cm-ani_2.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-preto-sonoma-140-cm-ani_2.jpg" width="360" height="360" alt="mesa-alta-preto-sonoma-140-cm-ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7141.window="updateImage" loading="lazy"></picture>
4433            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4434                    </div>
4435
4436        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4437                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4438                    <strong>Ani</strong>
4439                </div>
4440            
4441            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4442                <span class="product-item-link">Mesa alta Negro y Sonoma 140 cm Ani</span>
4443            </div>
4444
4445            
4446            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7141.window="updatePrice($event.detail);">
4447                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7141" data-price-box="product-id-7141">
4448    <span
4449    x-data x-id="['product\u002Dprice\u002D7141']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4450    >
4451    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4452        <span class="price"><span class="price">89,00 €</span></span>
4453    </span>
4454    
4455                        <span class="old-price mr-1">
4456                <span class="price line-through text-gray-600">
4457                    <span class="price"><span class="price">95,00 €</span></span>
4458
4459                </span>
4460            </span>
4461        
4462    
4463    
4464    </span>
4465</div></div>
4466                            </div>
4467        </div>
4468    </a>
4469
4470
4471            <!-- <div>CATEGORIA: </div> -->
4472        <div class="product-item-variations px-4 py-2 mt-auto">
4473            <div id="variaciones-listado-7141">
4474                                    <div class="color-picker-grid-mode-clean">
4475        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4476            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4477                Colores Disponibles:
4478            </span>
4479
4480            <div class="flex flex-wrap gap-4 items-center">
4481                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-blanco-y-sonoma-140-cm-ani" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-blanco-y-sonoma-140-cm-ani"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
4482        </div>
4483    </div>                            </div>
4484        </div>
4485        <div class="px-4 pb-4">
4486        
4487<div class="mt-1 flex flex-col">
4488            <!-- Invitado: base price + línea VIP (si existe) -->
4489        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4490            95,00 €        </span>
4491
4492                    <div class="flex items-baseline gap-1.5">
4493                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4494                    89,00 €                </span>
4495                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4496                    Precio VIP                </span>
4497            </div>
4498
4499
4500            </div>    </div>
4501</div>
4502
4503<style>
4504    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4505    .color-picker-grid-mode-clean,
4506    .color-picker-grid-mode-clean>div {
4507        display: flex !important;
4508        flex-direction: row !important;
4509        flex-wrap: wrap !important;
4510        align-items: center !important;
4511        gap: 6px !important;
4512        padding: 0 !important;
4513        margin: 0 !important;
4514        border: none !important;
4515    }
4516
4517    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4518    /* El método renderSection imprime un span con el título, lo eliminamos */
4519    .color-picker-grid-mode-clean span.text-sm.font-bold,
4520    .color-picker-grid-mode-clean .w-32 {
4521        display: none !important;
4522    }
4523
4524    /* 3. Ajuste de las "bolitas" de color */
4525    .color-picker-grid-mode-clean .w-9.h-9 {
4526        width: 22px !important;
4527        /* Tamaño reducido ideal para rejilla */
4528        height: 22px !important;
4529        min-width: 22px !important;
4530        min-height: 22px !important;
4531        margin: 0 !important;
4532        transform: none !important;
4533        /* Evitamos que el seleccionado crezca y descuadre */
4534        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4535    }
4536
4537    /* 4. Ajuste del icono Check (V) de selección */
4538    .color-picker-grid-mode-clean svg {
4539        width: 14px !important;
4540        height: 14px !important;
4541    }
4542
4543    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4544    .product-item-variations {
4545        margin-top: 4px !important;
4546        margin-bottom: 4px !important;
4547        padding-top: 0 !important;
4548        padding-bottom: 0 !important;
4549    }
4550
4551    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4552    .color-picker-grid-mode-clean .flex-wrap {
4553        gap: 6px !important;
4554    }
4555
4556    .product-item-photo>span picture,
4557    .product-item-photo>span img {
4558        width: 100% !important;
4559        height: auto !important;
4560        display: block !important;
4561    }
4562
4563    .product-item-photo>span picture {
4564        position: static !important;
4565    }
4566</style>                    </li>
4567                                    <li class="flex flex-col">
4568                        
4569<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4570
4571    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-blanco-y-sonoma-120-cm-ani" class="flex flex-col grow w-full">
4572        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4573            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-120-cm-ani-01_4.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-120-cm-ani-01_4.jpg" width="360" height="360" alt="Mesa&#x20;alta&#x20;Blanco&#x20;y&#x20;Sonoma&#x20;120&#x20;cm&#x20;Ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7142.window="updateImage" loading="lazy"></picture>
4574            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4575                    </div>
4576
4577        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4578                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4579                    <strong>Ani</strong>
4580                </div>
4581            
4582            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4583                <span class="product-item-link">Mesa alta Blanco y Sonoma 120 cm Ani</span>
4584            </div>
4585
4586            
4587            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7142.window="updatePrice($event.detail);">
4588                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7142" data-price-box="product-id-7142">
4589    <span
4590    x-data x-id="['product\u002Dprice\u002D7142']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4591    >
4592    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4593        <span class="price"><span class="price">79,00 €</span></span>
4594    </span>
4595    
4596                        <span class="old-price mr-1">
4597                <span class="price line-through text-gray-600">
4598                    <span class="price"><span class="price">89,00 €</span></span>
4599
4600                </span>
4601            </span>
4602        
4603    
4604    
4605    </span>
4606</div></div>
4607                            </div>
4608        </div>
4609    </a>
4610
4611
4612            <!-- <div>CATEGORIA: </div> -->
4613        <div class="product-item-variations px-4 py-2 mt-auto">
4614            <div id="variaciones-listado-7142">
4615                                    <div class="color-picker-grid-mode-clean">
4616        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4617            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4618                Colores Disponibles:
4619            </span>
4620
4621            <div class="flex flex-wrap gap-4 items-center">
4622                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-120-cm-ani" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-120-cm-ani"></div>            </div>
4623        </div>
4624    </div>                            </div>
4625        </div>
4626        <div class="px-4 pb-4">
4627        
4628<div class="mt-1 flex flex-col">
4629            <!-- Invitado: base price + línea VIP (si existe) -->
4630        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4631            89,00 €        </span>
4632
4633                    <div class="flex items-baseline gap-1.5">
4634                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4635                    79,00 €                </span>
4636                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4637                    Precio VIP                </span>
4638            </div>
4639
4640
4641            </div>    </div>
4642</div>
4643
4644<style>
4645    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4646    .color-picker-grid-mode-clean,
4647    .color-picker-grid-mode-clean>div {
4648        display: flex !important;
4649        flex-direction: row !important;
4650        flex-wrap: wrap !important;
4651        align-items: center !important;
4652        gap: 6px !important;
4653        padding: 0 !important;
4654        margin: 0 !important;
4655        border: none !important;
4656    }
4657
4658    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4659    /* El método renderSection imprime un span con el título, lo eliminamos */
4660    .color-picker-grid-mode-clean span.text-sm.font-bold,
4661    .color-picker-grid-mode-clean .w-32 {
4662        display: none !important;
4663    }
4664
4665    /* 3. Ajuste de las "bolitas" de color */
4666    .color-picker-grid-mode-clean .w-9.h-9 {
4667        width: 22px !important;
4668        /* Tamaño reducido ideal para rejilla */
4669        height: 22px !important;
4670        min-width: 22px !important;
4671        min-height: 22px !important;
4672        margin: 0 !important;
4673        transform: none !important;
4674        /* Evitamos que el seleccionado crezca y descuadre */
4675        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4676    }
4677
4678    /* 4. Ajuste del icono Check (V) de selección */
4679    .color-picker-grid-mode-clean svg {
4680        width: 14px !important;
4681        height: 14px !important;
4682    }
4683
4684    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4685    .product-item-variations {
4686        margin-top: 4px !important;
4687        margin-bottom: 4px !important;
4688        padding-top: 0 !important;
4689        padding-bottom: 0 !important;
4690    }
4691
4692    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4693    .color-picker-grid-mode-clean .flex-wrap {
4694        gap: 6px !important;
4695    }
4696
4697    .product-item-photo>span picture,
4698    .product-item-photo>span img {
4699        width: 100% !important;
4700        height: auto !important;
4701        display: block !important;
4702    }
4703
4704    .product-item-photo>span picture {
4705        position: static !important;
4706    }
4707</style>                    </li>
4708                                    <li class="flex flex-col">
4709                        
4710<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4711
4712    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-120-cm-ani" class="flex flex-col grow w-full">
4713        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4714            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-120-cm-ani-01_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-120-cm-ani-01_1.jpg" width="360" height="360" alt="Mesa&#x20;alta&#x20;Negro&#x20;y&#x20;Sonoma&#x20;120&#x20;cm&#x20;Ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7143.window="updateImage" loading="lazy"></picture>
4715            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4716                    </div>
4717
4718        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4719                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4720                    <strong>Ani</strong>
4721                </div>
4722            
4723            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4724                <span class="product-item-link">Mesa alta Negro y Sonoma 120 cm Ani</span>
4725            </div>
4726
4727            
4728            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7143.window="updatePrice($event.detail);">
4729                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7143" data-price-box="product-id-7143">
4730    <span
4731    x-data x-id="['product\u002Dprice\u002D7143']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4732    >
4733    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4734        <span class="price"><span class="price">79,00 €</span></span>
4735    </span>
4736    
4737                        <span class="old-price mr-1">
4738                <span class="price line-through text-gray-600">
4739                    <span class="price"><span class="price">89,00 €</span></span>
4740
4741                </span>
4742            </span>
4743        
4744    
4745    
4746    </span>
4747</div></div>
4748                            </div>
4749        </div>
4750    </a>
4751
4752
4753            <!-- <div>CATEGORIA: </div> -->
4754        <div class="product-item-variations px-4 py-2 mt-auto">
4755            <div id="variaciones-listado-7143">
4756                                    <div class="color-picker-grid-mode-clean">
4757        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4758            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4759                Colores Disponibles:
4760            </span>
4761
4762            <div class="flex flex-wrap gap-4 items-center">
4763                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-blanco-y-sonoma-120-cm-ani" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-blanco-y-sonoma-120-cm-ani"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
4764        </div>
4765    </div>                            </div>
4766        </div>
4767        <div class="px-4 pb-4">
4768        
4769<div class="mt-1 flex flex-col">
4770            <!-- Invitado: base price + línea VIP (si existe) -->
4771        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4772            89,00 €        </span>
4773
4774                    <div class="flex items-baseline gap-1.5">
4775                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4776                    79,00 €                </span>
4777                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4778                    Precio VIP                </span>
4779            </div>
4780
4781
4782            </div>    </div>
4783</div>
4784
4785<style>
4786    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4787    .color-picker-grid-mode-clean,
4788    .color-picker-grid-mode-clean>div {
4789        display: flex !important;
4790        flex-direction: row !important;
4791        flex-wrap: wrap !important;
4792        align-items: center !important;
4793        gap: 6px !important;
4794        padding: 0 !important;
4795        margin: 0 !important;
4796        border: none !important;
4797    }
4798
4799    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4800    /* El método renderSection imprime un span con el título, lo eliminamos */
4801    .color-picker-grid-mode-clean span.text-sm.font-bold,
4802    .color-picker-grid-mode-clean .w-32 {
4803        display: none !important;
4804    }
4805
4806    /* 3. Ajuste de las "bolitas" de color */
4807    .color-picker-grid-mode-clean .w-9.h-9 {
4808        width: 22px !important;
4809        /* Tamaño reducido ideal para rejilla */
4810        height: 22px !important;
4811        min-width: 22px !important;
4812        min-height: 22px !important;
4813        margin: 0 !important;
4814        transform: none !important;
4815        /* Evitamos que el seleccionado crezca y descuadre */
4816        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4817    }
4818
4819    /* 4. Ajuste del icono Check (V) de selección */
4820    .color-picker-grid-mode-clean svg {
4821        width: 14px !important;
4822        height: 14px !important;
4823    }
4824
4825    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4826    .product-item-variations {
4827        margin-top: 4px !important;
4828        margin-bottom: 4px !important;
4829        padding-top: 0 !important;
4830        padding-bottom: 0 !important;
4831    }
4832
4833    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4834    .color-picker-grid-mode-clean .flex-wrap {
4835        gap: 6px !important;
4836    }
4837
4838    .product-item-photo>span picture,
4839    .product-item-photo>span img {
4840        width: 100% !important;
4841        height: auto !important;
4842        display: block !important;
4843    }
4844
4845    .product-item-photo>span picture {
4846        position: static !important;
4847    }
4848</style>                    </li>
4849                                    <li class="flex flex-col">
4850                        
4851<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4852
4853    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-blanco-y-sonoma-100-cm-ani" class="flex flex-col grow w-full">
4854        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4855            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-100-cm-ani-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-100-cm-ani-01.jpg" width="360" height="360" alt="Mesa&#x20;alta&#x20;Blanco&#x20;y&#x20;Sonoma&#x20;100&#x20;cm&#x20;Ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7144.window="updateImage" loading="lazy"></picture>
4856            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4857                    </div>
4858
4859        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
4860                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
4861                    <strong>Ani</strong>
4862                </div>
4863            
4864            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
4865                <span class="product-item-link">Mesa alta Blanco y Sonoma 100 cm Ani</span>
4866            </div>
4867
4868            
4869            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7144.window="updatePrice($event.detail);">
4870                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7144" data-price-box="product-id-7144">
4871    <span
4872    x-data x-id="['product\u002Dprice\u002D7144']"     class="price-container price-final_price&#x20;tax&#x20;weee"
4873    >
4874    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
4875        <span class="price"><span class="price">69,00 €</span></span>
4876    </span>
4877    
4878                        <span class="old-price mr-1">
4879                <span class="price line-through text-gray-600">
4880                    <span class="price"><span class="price">79,00 €</span></span>
4881
4882                </span>
4883            </span>
4884        
4885    
4886    
4887    </span>
4888</div></div>
4889                            </div>
4890        </div>
4891    </a>
4892
4893
4894            <!-- <div>CATEGORIA: </div> -->
4895        <div class="product-item-variations px-4 py-2 mt-auto">
4896            <div id="variaciones-listado-7144">
4897                                    <div class="color-picker-grid-mode-clean">
4898        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
4899            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
4900                Colores Disponibles:
4901            </span>
4902
4903            <div class="flex flex-wrap gap-4 items-center">
4904                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-100-cm-ani" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-negro-y-sonoma-100-cm-ani"></div>            </div>
4905        </div>
4906    </div>                            </div>
4907        </div>
4908        <div class="px-4 pb-4">
4909        
4910<div class="mt-1 flex flex-col">
4911            <!-- Invitado: base price + línea VIP (si existe) -->
4912        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
4913            79,00 €        </span>
4914
4915                    <div class="flex items-baseline gap-1.5">
4916                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
4917                    69,00 €                </span>
4918                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
4919                    Precio VIP                </span>
4920            </div>
4921
4922
4923            </div>    </div>
4924</div>
4925
4926<style>
4927    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
4928    .color-picker-grid-mode-clean,
4929    .color-picker-grid-mode-clean>div {
4930        display: flex !important;
4931        flex-direction: row !important;
4932        flex-wrap: wrap !important;
4933        align-items: center !important;
4934        gap: 6px !important;
4935        padding: 0 !important;
4936        margin: 0 !important;
4937        border: none !important;
4938    }
4939
4940    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
4941    /* El método renderSection imprime un span con el título, lo eliminamos */
4942    .color-picker-grid-mode-clean span.text-sm.font-bold,
4943    .color-picker-grid-mode-clean .w-32 {
4944        display: none !important;
4945    }
4946
4947    /* 3. Ajuste de las "bolitas" de color */
4948    .color-picker-grid-mode-clean .w-9.h-9 {
4949        width: 22px !important;
4950        /* Tamaño reducido ideal para rejilla */
4951        height: 22px !important;
4952        min-width: 22px !important;
4953        min-height: 22px !important;
4954        margin: 0 !important;
4955        transform: none !important;
4956        /* Evitamos que el seleccionado crezca y descuadre */
4957        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
4958    }
4959
4960    /* 4. Ajuste del icono Check (V) de selección */
4961    .color-picker-grid-mode-clean svg {
4962        width: 14px !important;
4963        height: 14px !important;
4964    }
4965
4966    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
4967    .product-item-variations {
4968        margin-top: 4px !important;
4969        margin-bottom: 4px !important;
4970        padding-top: 0 !important;
4971        padding-bottom: 0 !important;
4972    }
4973
4974    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
4975    .color-picker-grid-mode-clean .flex-wrap {
4976        gap: 6px !important;
4977    }
4978
4979    .product-item-photo>span picture,
4980    .product-item-photo>span img {
4981        width: 100% !important;
4982        height: auto !important;
4983        display: block !important;
4984    }
4985
4986    .product-item-photo>span picture {
4987        position: static !important;
4988    }
4989</style>                    </li>
4990                                    <li class="flex flex-col">
4991                        
4992<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
4993
4994    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-100-cm-ani" class="flex flex-col grow w-full">
4995        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
4996            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-100-cm-ani-01_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-100-cm-ani-01_1.jpg" width="360" height="360" alt="mesa-alta-negro-sonoma-100-cm-ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7145.window="updateImage" loading="lazy"></picture>
4997            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
4998                    </div>
4999
5000        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5001                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5002                    <strong>Ani</strong>
5003                </div>
5004            
5005            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5006                <span class="product-item-link">Mesa alta Negro y Sonoma 100 cm Ani</span>
5007            </div>
5008
5009            
5010            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7145.window="updatePrice($event.detail);">
5011                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7145" data-price-box="product-id-7145">
5012    <span
5013    x-data x-id="['product\u002Dprice\u002D7145']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5014    >
5015    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5016        <span class="price"><span class="price">69,00 €</span></span>
5017    </span>
5018    
5019                        <span class="old-price mr-1">
5020                <span class="price line-through text-gray-600">
5021                    <span class="price"><span class="price">79,00 €</span></span>
5022
5023                </span>
5024            </span>
5025        
5026    
5027    
5028    </span>
5029</div></div>
5030                            </div>
5031        </div>
5032    </a>
5033
5034
5035            <!-- <div>CATEGORIA: </div> -->
5036        <div class="product-item-variations px-4 py-2 mt-auto">
5037            <div id="variaciones-listado-7145">
5038                                    <div class="color-picker-grid-mode-clean">
5039        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5040            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5041                Colores Disponibles:
5042            </span>
5043
5044            <div class="flex flex-wrap gap-4 items-center">
5045                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-blanco-y-sonoma-100-cm-ani" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-blanco-y-sonoma-100-cm-ani"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
5046        </div>
5047    </div>                            </div>
5048        </div>
5049        <div class="px-4 pb-4">
5050        
5051<div class="mt-1 flex flex-col">
5052            <!-- Invitado: base price + línea VIP (si existe) -->
5053        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5054            79,00 €        </span>
5055
5056                    <div class="flex items-baseline gap-1.5">
5057                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5058                    69,00 €                </span>
5059                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5060                    Precio VIP                </span>
5061            </div>
5062
5063
5064            </div>    </div>
5065</div>
5066
5067<style>
5068    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5069    .color-picker-grid-mode-clean,
5070    .color-picker-grid-mode-clean>div {
5071        display: flex !important;
5072        flex-direction: row !important;
5073        flex-wrap: wrap !important;
5074        align-items: center !important;
5075        gap: 6px !important;
5076        padding: 0 !important;
5077        margin: 0 !important;
5078        border: none !important;
5079    }
5080
5081    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5082    /* El método renderSection imprime un span con el título, lo eliminamos */
5083    .color-picker-grid-mode-clean span.text-sm.font-bold,
5084    .color-picker-grid-mode-clean .w-32 {
5085        display: none !important;
5086    }
5087
5088    /* 3. Ajuste de las "bolitas" de color */
5089    .color-picker-grid-mode-clean .w-9.h-9 {
5090        width: 22px !important;
5091        /* Tamaño reducido ideal para rejilla */
5092        height: 22px !important;
5093        min-width: 22px !important;
5094        min-height: 22px !important;
5095        margin: 0 !important;
5096        transform: none !important;
5097        /* Evitamos que el seleccionado crezca y descuadre */
5098        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5099    }
5100
5101    /* 4. Ajuste del icono Check (V) de selección */
5102    .color-picker-grid-mode-clean svg {
5103        width: 14px !important;
5104        height: 14px !important;
5105    }
5106
5107    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5108    .product-item-variations {
5109        margin-top: 4px !important;
5110        margin-bottom: 4px !important;
5111        padding-top: 0 !important;
5112        padding-bottom: 0 !important;
5113    }
5114
5115    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5116    .color-picker-grid-mode-clean .flex-wrap {
5117        gap: 6px !important;
5118    }
5119
5120    .product-item-photo>span picture,
5121    .product-item-photo>span img {
5122        width: 100% !important;
5123        height: auto !important;
5124        display: block !important;
5125    }
5126
5127    .product-item-photo>span picture {
5128        position: static !important;
5129    }
5130</style>                    </li>
5131                                    <li class="flex flex-col">
5132                        
5133<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5134
5135    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-140-cm-ani" class="flex flex-col grow w-full">
5136        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5137            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-140-cm-ani-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-140-cm-ani-01.jpg" width="360" height="360" alt="Mesa&#x20;alta&#x20;con&#x20;2&#x20;Taburetes&#x20;Blanco&#x20;y&#x20;Sonoma&#x20;140&#x20;cm&#x20;Ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7147.window="updateImage" loading="lazy"></picture>
5138            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5139                    </div>
5140
5141        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5142                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5143                    <strong>Ani</strong>
5144                </div>
5145            
5146            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5147                <span class="product-item-link">Mesa alta con 2 Taburetes Blanco y Sonoma 140 cm Ani</span>
5148            </div>
5149
5150            
5151            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7147.window="updatePrice($event.detail);">
5152                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7147" data-price-box="product-id-7147">
5153    <span
5154    x-data x-id="['product\u002Dprice\u002D7147']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5155    >
5156    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5157        <span class="price"><span class="price">125,00 €</span></span>
5158    </span>
5159    
5160                        <span class="old-price mr-1">
5161                <span class="price line-through text-gray-600">
5162                    <span class="price"><span class="price">139,00 €</span></span>
5163
5164                </span>
5165            </span>
5166        
5167    
5168    
5169    </span>
5170</div></div>
5171                            </div>
5172        </div>
5173    </a>
5174
5175
5176            <!-- <div>CATEGORIA: </div> -->
5177        <div class="product-item-variations px-4 py-2 mt-auto">
5178            <div id="variaciones-listado-7147">
5179                                    <div class="color-picker-grid-mode-clean">
5180        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5181            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5182                Colores Disponibles:
5183            </span>
5184
5185            <div class="flex flex-wrap gap-4 items-center">
5186                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-140-cm-ani" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-140-cm-ani"></div>            </div>
5187        </div>
5188    </div>                            </div>
5189        </div>
5190        <div class="px-4 pb-4">
5191        
5192<div class="mt-1 flex flex-col">
5193            <!-- Invitado: base price + línea VIP (si existe) -->
5194        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5195            139,00 €        </span>
5196
5197                    <div class="flex items-baseline gap-1.5">
5198                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5199                    125,00 €                </span>
5200                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5201                    Precio VIP                </span>
5202            </div>
5203
5204
5205            </div>    </div>
5206</div>
5207
5208<style>
5209    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5210    .color-picker-grid-mode-clean,
5211    .color-picker-grid-mode-clean>div {
5212        display: flex !important;
5213        flex-direction: row !important;
5214        flex-wrap: wrap !important;
5215        align-items: center !important;
5216        gap: 6px !important;
5217        padding: 0 !important;
5218        margin: 0 !important;
5219        border: none !important;
5220    }
5221
5222    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5223    /* El método renderSection imprime un span con el título, lo eliminamos */
5224    .color-picker-grid-mode-clean span.text-sm.font-bold,
5225    .color-picker-grid-mode-clean .w-32 {
5226        display: none !important;
5227    }
5228
5229    /* 3. Ajuste de las "bolitas" de color */
5230    .color-picker-grid-mode-clean .w-9.h-9 {
5231        width: 22px !important;
5232        /* Tamaño reducido ideal para rejilla */
5233        height: 22px !important;
5234        min-width: 22px !important;
5235        min-height: 22px !important;
5236        margin: 0 !important;
5237        transform: none !important;
5238        /* Evitamos que el seleccionado crezca y descuadre */
5239        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5240    }
5241
5242    /* 4. Ajuste del icono Check (V) de selección */
5243    .color-picker-grid-mode-clean svg {
5244        width: 14px !important;
5245        height: 14px !important;
5246    }
5247
5248    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5249    .product-item-variations {
5250        margin-top: 4px !important;
5251        margin-bottom: 4px !important;
5252        padding-top: 0 !important;
5253        padding-bottom: 0 !important;
5254    }
5255
5256    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5257    .color-picker-grid-mode-clean .flex-wrap {
5258        gap: 6px !important;
5259    }
5260
5261    .product-item-photo>span picture,
5262    .product-item-photo>span img {
5263        width: 100% !important;
5264        height: auto !important;
5265        display: block !important;
5266    }
5267
5268    .product-item-photo>span picture {
5269        position: static !important;
5270    }
5271</style>                    </li>
5272                                    <li class="flex flex-col">
5273                        
5274<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5275
5276    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-140-cm-ani" class="flex flex-col grow w-full">
5277        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5278            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-140-cm-ani-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-140-cm-ani-01.jpg" width="360" height="360" alt="mesa-alta-con-2-taburetes-negro-sonoma-140-cm-ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7148.window="updateImage" loading="lazy"></picture>
5279            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5280                    </div>
5281
5282        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5283                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5284                    <strong>Ani</strong>
5285                </div>
5286            
5287            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5288                <span class="product-item-link">Mesa alta con 2 Taburetes Negro y Sonoma 140 cm Ani</span>
5289            </div>
5290
5291            
5292            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7148.window="updatePrice($event.detail);">
5293                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7148" data-price-box="product-id-7148">
5294    <span
5295    x-data x-id="['product\u002Dprice\u002D7148']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5296    >
5297    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5298        <span class="price"><span class="price">125,00 €</span></span>
5299    </span>
5300    
5301                        <span class="old-price mr-1">
5302                <span class="price line-through text-gray-600">
5303                    <span class="price"><span class="price">139,00 €</span></span>
5304
5305                </span>
5306            </span>
5307        
5308    
5309    
5310    </span>
5311</div></div>
5312                            </div>
5313        </div>
5314    </a>
5315
5316
5317            <!-- <div>CATEGORIA: </div> -->
5318        <div class="product-item-variations px-4 py-2 mt-auto">
5319            <div id="variaciones-listado-7148">
5320                                    <div class="color-picker-grid-mode-clean">
5321        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5322            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5323                Colores Disponibles:
5324            </span>
5325
5326            <div class="flex flex-wrap gap-4 items-center">
5327                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-140-cm-ani" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-140-cm-ani"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
5328        </div>
5329    </div>                            </div>
5330        </div>
5331        <div class="px-4 pb-4">
5332        
5333<div class="mt-1 flex flex-col">
5334            <!-- Invitado: base price + línea VIP (si existe) -->
5335        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5336            139,00 €        </span>
5337
5338                    <div class="flex items-baseline gap-1.5">
5339                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5340                    125,00 €                </span>
5341                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5342                    Precio VIP                </span>
5343            </div>
5344
5345
5346            </div>    </div>
5347</div>
5348
5349<style>
5350    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5351    .color-picker-grid-mode-clean,
5352    .color-picker-grid-mode-clean>div {
5353        display: flex !important;
5354        flex-direction: row !important;
5355        flex-wrap: wrap !important;
5356        align-items: center !important;
5357        gap: 6px !important;
5358        padding: 0 !important;
5359        margin: 0 !important;
5360        border: none !important;
5361    }
5362
5363    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5364    /* El método renderSection imprime un span con el título, lo eliminamos */
5365    .color-picker-grid-mode-clean span.text-sm.font-bold,
5366    .color-picker-grid-mode-clean .w-32 {
5367        display: none !important;
5368    }
5369
5370    /* 3. Ajuste de las "bolitas" de color */
5371    .color-picker-grid-mode-clean .w-9.h-9 {
5372        width: 22px !important;
5373        /* Tamaño reducido ideal para rejilla */
5374        height: 22px !important;
5375        min-width: 22px !important;
5376        min-height: 22px !important;
5377        margin: 0 !important;
5378        transform: none !important;
5379        /* Evitamos que el seleccionado crezca y descuadre */
5380        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5381    }
5382
5383    /* 4. Ajuste del icono Check (V) de selección */
5384    .color-picker-grid-mode-clean svg {
5385        width: 14px !important;
5386        height: 14px !important;
5387    }
5388
5389    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5390    .product-item-variations {
5391        margin-top: 4px !important;
5392        margin-bottom: 4px !important;
5393        padding-top: 0 !important;
5394        padding-bottom: 0 !important;
5395    }
5396
5397    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5398    .color-picker-grid-mode-clean .flex-wrap {
5399        gap: 6px !important;
5400    }
5401
5402    .product-item-photo>span picture,
5403    .product-item-photo>span img {
5404        width: 100% !important;
5405        height: auto !important;
5406        display: block !important;
5407    }
5408
5409    .product-item-photo>span picture {
5410        position: static !important;
5411    }
5412</style>                    </li>
5413                                    <li class="flex flex-col">
5414                        
5415<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5416
5417    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-120-cm-ani" class="flex flex-col grow w-full">
5418        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5419            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-120-cm-ani-01_3.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-120-cm-ani-01_3.jpg" width="360" height="360" alt="mesa-alta-blanco-sonoma-120-cm-ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7149.window="updateImage" loading="lazy"></picture>
5420            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5421                    </div>
5422
5423        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5424                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5425                    <strong>Ani</strong>
5426                </div>
5427            
5428            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5429                <span class="product-item-link">Mesa alta con 2 Taburetes Blanco y Sonoma 120 cm Ani</span>
5430            </div>
5431
5432            
5433            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7149.window="updatePrice($event.detail);">
5434                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7149" data-price-box="product-id-7149">
5435    <span
5436    x-data x-id="['product\u002Dprice\u002D7149']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5437    >
5438    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5439        <span class="price"><span class="price">119,00 €</span></span>
5440    </span>
5441    
5442                        <span class="old-price mr-1">
5443                <span class="price line-through text-gray-600">
5444                    <span class="price"><span class="price">129,00 €</span></span>
5445
5446                </span>
5447            </span>
5448        
5449    
5450    
5451    </span>
5452</div></div>
5453                            </div>
5454        </div>
5455    </a>
5456
5457
5458            <!-- <div>CATEGORIA: </div> -->
5459        <div class="product-item-variations px-4 py-2 mt-auto">
5460            <div id="variaciones-listado-7149">
5461                                    <div class="color-picker-grid-mode-clean">
5462        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5463            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5464                Colores Disponibles:
5465            </span>
5466
5467            <div class="flex flex-wrap gap-4 items-center">
5468                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-120-cm-ani" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-120-cm-ani"></div>            </div>
5469        </div>
5470    </div>                            </div>
5471        </div>
5472        <div class="px-4 pb-4">
5473        
5474<div class="mt-1 flex flex-col">
5475            <!-- Invitado: base price + línea VIP (si existe) -->
5476        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5477            129,00 €        </span>
5478
5479                    <div class="flex items-baseline gap-1.5">
5480                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5481                    119,00 €                </span>
5482                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5483                    Precio VIP                </span>
5484            </div>
5485
5486
5487            </div>    </div>
5488</div>
5489
5490<style>
5491    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5492    .color-picker-grid-mode-clean,
5493    .color-picker-grid-mode-clean>div {
5494        display: flex !important;
5495        flex-direction: row !important;
5496        flex-wrap: wrap !important;
5497        align-items: center !important;
5498        gap: 6px !important;
5499        padding: 0 !important;
5500        margin: 0 !important;
5501        border: none !important;
5502    }
5503
5504    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5505    /* El método renderSection imprime un span con el título, lo eliminamos */
5506    .color-picker-grid-mode-clean span.text-sm.font-bold,
5507    .color-picker-grid-mode-clean .w-32 {
5508        display: none !important;
5509    }
5510
5511    /* 3. Ajuste de las "bolitas" de color */
5512    .color-picker-grid-mode-clean .w-9.h-9 {
5513        width: 22px !important;
5514        /* Tamaño reducido ideal para rejilla */
5515        height: 22px !important;
5516        min-width: 22px !important;
5517        min-height: 22px !important;
5518        margin: 0 !important;
5519        transform: none !important;
5520        /* Evitamos que el seleccionado crezca y descuadre */
5521        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5522    }
5523
5524    /* 4. Ajuste del icono Check (V) de selección */
5525    .color-picker-grid-mode-clean svg {
5526        width: 14px !important;
5527        height: 14px !important;
5528    }
5529
5530    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5531    .product-item-variations {
5532        margin-top: 4px !important;
5533        margin-bottom: 4px !important;
5534        padding-top: 0 !important;
5535        padding-bottom: 0 !important;
5536    }
5537
5538    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5539    .color-picker-grid-mode-clean .flex-wrap {
5540        gap: 6px !important;
5541    }
5542
5543    .product-item-photo>span picture,
5544    .product-item-photo>span img {
5545        width: 100% !important;
5546        height: auto !important;
5547        display: block !important;
5548    }
5549
5550    .product-item-photo>span picture {
5551        position: static !important;
5552    }
5553</style>                    </li>
5554                                    <li class="flex flex-col">
5555                        
5556<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5557
5558    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-120-cm-ani" class="flex flex-col grow w-full">
5559        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5560            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-120-cm-ani-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-120-cm-ani-01.jpg" width="360" height="360" alt="Mesa&#x20;alta&#x20;con&#x20;2&#x20;Taburetes&#x20;
5560Negro&#x20;y&#x20;Sonoma&#x20;120&#x20;cm&#x20;Ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7150.window="updateImage" loading="lazy"></picture>
5561            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5562                    </div>
5563
5564        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5565                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5566                    <strong>Ani</strong>
5567                </div>
5568            
5569            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5570                <span class="product-item-link">Mesa alta con 2 Taburetes Negro y Sonoma 120 cm Ani</span>
5571            </div>
5572
5573            
5574            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7150.window="updatePrice($event.detail);">
5575                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7150" data-price-box="product-id-7150">
5576    <span
5577    x-data x-id="['product\u002Dprice\u002D7150']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5578    >
5579    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5580        <span class="price"><span class="price">119,00 €</span></span>
5581    </span>
5582    
5583                        <span class="old-price mr-1">
5584                <span class="price line-through text-gray-600">
5585                    <span class="price"><span class="price">129,00 €</span></span>
5586
5587                </span>
5588            </span>
5589        
5590    
5591    
5592    </span>
5593</div></div>
5594                            </div>
5595        </div>
5596    </a>
5597
5598
5599            <!-- <div>CATEGORIA: </div> -->
5600        <div class="product-item-variations px-4 py-2 mt-auto">
5601            <div id="variaciones-listado-7150">
5602                                    <div class="color-picker-grid-mode-clean">
5603        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5604            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5605                Colores Disponibles:
5606            </span>
5607
5608            <div class="flex flex-wrap gap-4 items-center">
5609                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-120-cm-ani" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-120-cm-ani"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
5610        </div>
5611    </div>                            </div>
5612        </div>
5613        <div class="px-4 pb-4">
5614        
5615<div class="mt-1 flex flex-col">
5616            <!-- Invitado: base price + línea VIP (si existe) -->
5617        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5618            129,00 €        </span>
5619
5620                    <div class="flex items-baseline gap-1.5">
5621                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5622                    119,00 €                </span>
5623                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5624                    Precio VIP                </span>
5625            </div>
5626
5627
5628            </div>    </div>
5629</div>
5630
5631<style>
5632    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5633    .color-picker-grid-mode-clean,
5634    .color-picker-grid-mode-clean>div {
5635        display: flex !important;
5636        flex-direction: row !important;
5637        flex-wrap: wrap !important;
5638        align-items: center !important;
5639        gap: 6px !important;
5640        padding: 0 !important;
5641        margin: 0 !important;
5642        border: none !important;
5643    }
5644
5645    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5646    /* El método renderSection imprime un span con el título, lo eliminamos */
5647    .color-picker-grid-mode-clean span.text-sm.font-bold,
5648    .color-picker-grid-mode-clean .w-32 {
5649        display: none !important;
5650    }
5651
5652    /* 3. Ajuste de las "bolitas" de color */
5653    .color-picker-grid-mode-clean .w-9.h-9 {
5654        width: 22px !important;
5655        /* Tamaño reducido ideal para rejilla */
5656        height: 22px !important;
5657        min-width: 22px !important;
5658        min-height: 22px !important;
5659        margin: 0 !important;
5660        transform: none !important;
5661        /* Evitamos que el seleccionado crezca y descuadre */
5662        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5663    }
5664
5665    /* 4. Ajuste del icono Check (V) de selección */
5666    .color-picker-grid-mode-clean svg {
5667        width: 14px !important;
5668        height: 14px !important;
5669    }
5670
5671    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5672    .product-item-variations {
5673        margin-top: 4px !important;
5674        margin-bottom: 4px !important;
5675        padding-top: 0 !important;
5676        padding-bottom: 0 !important;
5677    }
5678
5679    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5680    .color-picker-grid-mode-clean .flex-wrap {
5681        gap: 6px !important;
5682    }
5683
5684    .product-item-photo>span picture,
5685    .product-item-photo>span img {
5686        width: 100% !important;
5687        height: auto !important;
5688        display: block !important;
5689    }
5690
5691    .product-item-photo>span picture {
5692        position: static !important;
5693    }
5694</style>                    </li>
5695                                    <li class="flex flex-col">
5696                        
5697<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5698
5699    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-100-cm-ani" class="flex flex-col grow w-full">
5700        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5701            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-100-cm-ani-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-100-cm-ani-01.jpg" width="360" height="360" alt="mesa-alta-con-2-taburetes-blanco-sonoma-100-cm-ani" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7151.window="updateImage" loading="lazy"></picture>
5702            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5703                    </div>
5704
5705        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5706                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5707                    <strong>Ani</strong>
5708                </div>
5709            
5710            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5711                <span class="product-item-link">Mesa alta con 2 Taburetes Blanco y Sonoma 100 cm Ani</span>
5712            </div>
5713
5714            
5715            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7151.window="updatePrice($event.detail);">
5716                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7151" data-price-box="product-id-7151">
5717    <span
5718    x-data x-id="['product\u002Dprice\u002D7151']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5719    >
5720    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5721        <span class="price"><span class="price">109,00 €</span></span>
5722    </span>
5723    
5724                        <span class="old-price mr-1">
5725                <span class="price line-through text-gray-600">
5726                    <span class="price"><span class="price">119,00 €</span></span>
5727
5728                </span>
5729            </span>
5730        
5731    
5732    
5733    </span>
5734</div></div>
5735                            </div>
5736        </div>
5737    </a>
5738
5739
5740            <!-- <div>CATEGORIA: </div> -->
5741        <div class="product-item-variations px-4 py-2 mt-auto">
5742            <div id="variaciones-listado-7151">
5743                                    <div class="color-picker-grid-mode-clean">
5744        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5745            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5746                Colores Disponibles:
5747            </span>
5748
5749            <div class="flex flex-wrap gap-4 items-center">
5750                <div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-100-cm-ani" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-100-cm-ani"></div>            </div>
5751        </div>
5752    </div>                            </div>
5753        </div>
5754        <div class="px-4 pb-4">
5755        
5756<div class="mt-1 flex flex-col">
5757            <!-- Invitado: base price + línea VIP (si existe) -->
5758        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5759            119,00 €        </span>
5760
5761                    <div class="flex items-baseline gap-1.5">
5762                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5763                    109,00 €                </span>
5764                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5765                    Precio VIP                </span>
5766            </div>
5767
5768
5769            </div>    </div>
5770</div>
5771
5772<style>
5773    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5774    .color-picker-grid-mode-clean,
5775    .color-picker-grid-mode-clean>div {
5776        display: flex !important;
5777        flex-direction: row !important;
5778        flex-wrap: wrap !important;
5779        align-items: center !important;
5780        gap: 6px !important;
5781        padding: 0 !important;
5782        margin: 0 !important;
5783        border: none !important;
5784    }
5785
5786    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5787    /* El método renderSection imprime un span con el título, lo eliminamos */
5788    .color-picker-grid-mode-clean span.text-sm.font-bold,
5789    .color-picker-grid-mode-clean .w-32 {
5790        display: none !important;
5791    }
5792
5793    /* 3. Ajuste de las "bolitas" de color */
5794    .color-picker-grid-mode-clean .w-9.h-9 {
5795        width: 22px !important;
5796        /* Tamaño reducido ideal para rejilla */
5797        height: 22px !important;
5798        min-width: 22px !important;
5799        min-height: 22px !important;
5800        margin: 0 !important;
5801        transform: none !important;
5802        /* Evitamos que el seleccionado crezca y descuadre */
5803        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5804    }
5805
5806    /* 4. Ajuste del icono Check (V) de selección */
5807    .color-picker-grid-mode-clean svg {
5808        width: 14px !important;
5809        height: 14px !important;
5810    }
5811
5812    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5813    .product-item-variations {
5814        margin-top: 4px !important;
5815        margin-bottom: 4px !important;
5816        padding-top: 0 !important;
5817        padding-bottom: 0 !important;
5818    }
5819
5820    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5821    .color-picker-grid-mode-clean .flex-wrap {
5822        gap: 6px !important;
5823    }
5824
5825    .product-item-photo>span picture,
5826    .product-item-photo>span img {
5827        width: 100% !important;
5828        height: auto !important;
5829        display: block !important;
5830    }
5831
5832    .product-item-photo>span picture {
5833        position: static !important;
5834    }
5835</style>                    </li>
5836                                    <li class="flex flex-col">
5837                        
5838<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5839
5840    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-100-cm-ani" class="flex flex-col grow w-full">
5841        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5842            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-100-cm-ani-01_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-100-cm-ani-01_1.jpg" width="360" height="360" alt="mesa-alta-con-2-taburetes-negro-sonoma-100-cm-ani-01" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7152.window="updateImage" loading="lazy"></picture>
5843            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5844                    </div>
5845
5846        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5847                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5848                    <strong>Ani</strong>
5849                </div>
5850            
5851            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5852                <span class="product-item-link">Mesa alta con 2 Taburetes Negro y Sonoma 100 cm Ani</span>
5853            </div>
5854
5855            
5856            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7152.window="updatePrice($event.detail);">
5857                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7152" data-price-box="product-id-7152">
5858    <span
5859    x-data x-id="['product\u002Dprice\u002D7152']"     class="price-container price-final_price&#x20;tax&#x20;weee"
5860    >
5861    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
5862        <span class="price"><span class="price">109,00 €</span></span>
5863    </span>
5864    
5865                        <span class="old-price mr-1">
5866                <span class="price line-through text-gray-600">
5867                    <span class="price"><span class="price">119,00 €</span></span>
5868
5869                </span>
5870            </span>
5871        
5872    
5873    
5874    </span>
5875</div></div>
5876                            </div>
5877        </div>
5878    </a>
5879
5880
5881            <!-- <div>CATEGORIA: </div> -->
5882        <div class="product-item-variations px-4 py-2 mt-auto">
5883            <div id="variaciones-listado-7152">
5884                                    <div class="color-picker-grid-mode-clean">
5885        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
5886            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
5887                Colores Disponibles:
5888            </span>
5889
5890            <div class="flex flex-wrap gap-4 items-center">
5891                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-100-cm-ani" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-100-cm-ani"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
5892        </div>
5893    </div>                            </div>
5894        </div>
5895        <div class="px-4 pb-4">
5896        
5897<div class="mt-1 flex flex-col">
5898            <!-- Invitado: base price + línea VIP (si existe) -->
5899        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
5900            119,00 €        </span>
5901
5902                    <div class="flex items-baseline gap-1.5">
5903                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
5904                    109,00 €                </span>
5905                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
5906                    Precio VIP                </span>
5907            </div>
5908
5909
5910            </div>    </div>
5911</div>
5912
5913<style>
5914    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
5915    .color-picker-grid-mode-clean,
5916    .color-picker-grid-mode-clean>div {
5917        display: flex !important;
5918        flex-direction: row !important;
5919        flex-wrap: wrap !important;
5920        align-items: center !important;
5921        gap: 6px !important;
5922        padding: 0 !important;
5923        margin: 0 !important;
5924        border: none !important;
5925    }
5926
5927    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
5928    /* El método renderSection imprime un span con el título, lo eliminamos */
5929    .color-picker-grid-mode-clean span.text-sm.font-bold,
5930    .color-picker-grid-mode-clean .w-32 {
5931        display: none !important;
5932    }
5933
5934    /* 3. Ajuste de las "bolitas" de color */
5935    .color-picker-grid-mode-clean .w-9.h-9 {
5936        width: 22px !important;
5937        /* Tamaño reducido ideal para rejilla */
5938        height: 22px !important;
5939        min-width: 22px !important;
5940        min-height: 22px !important;
5941        margin: 0 !important;
5942        transform: none !important;
5943        /* Evitamos que el seleccionado crezca y descuadre */
5944        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
5945    }
5946
5947    /* 4. Ajuste del icono Check (V) de selección */
5948    .color-picker-grid-mode-clean svg {
5949        width: 14px !important;
5950        height: 14px !important;
5951    }
5952
5953    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
5954    .product-item-variations {
5955        margin-top: 4px !important;
5956        margin-bottom: 4px !important;
5957        padding-top: 0 !important;
5958        padding-bottom: 0 !important;
5959    }
5960
5961    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
5962    .color-picker-grid-mode-clean .flex-wrap {
5963        gap: 6px !important;
5964    }
5965
5966    .product-item-photo>span picture,
5967    .product-item-photo>span img {
5968        width: 100% !important;
5969        height: auto !important;
5970        display: block !important;
5971    }
5972
5973    .product-item-photo>span picture {
5974        position: static !important;
5975    }
5976</style>                    </li>
5977                                    <li class="flex flex-col">
5978                        
5979<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
5980
5981    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-110-cm-kyra" class="flex flex-col grow w-full">
5982        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
5983            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-blanco-110-cm-kyra-01_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-blanco-110-cm-kyra-01_1.jpg" width="360" height="360" alt="mesa-alta-con-2-taburetes-blanco-blanco-110-cm-kyra" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7154.window="updateImage" loading="lazy"></picture>
5984            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
5985                    </div>
5986
5987        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
5988                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
5989                    <strong>Kyra</strong>
5990                </div>
5991            
5992            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
5993                <span class="product-item-link">Mesa alta con 2 Taburetes Blanco 110 cm Kyra</span>
5994            </div>
5995
5996            
5997            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7154.window="updatePrice($event.detail);">
5998                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7154" data-price-box="product-id-7154">
5999    <span
6000    x-data x-id="['product\u002Dprice\u002D7154']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6001    >
6002    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6003        <span class="price"><span class="price">129,00 €</span></span>
6004    </span>
6005    
6006                        <span class="old-price mr-1">
6007                <span class="price line-through text-gray-600">
6008                    <span class="price"><span class="price">139,00 €</span></span>
6009
6010                </span>
6011            </span>
6012        
6013    
6014    
6015    </span>
6016</div></div>
6017                            </div>
6018        </div>
6019    </a>
6020
6021
6022            <!-- <div>CATEGORIA: </div> -->
6023        <div class="product-item-variations px-4 py-2 mt-auto">
6024            <div id="variaciones-listado-7154">
6025                                    <div class="color-picker-grid-mode-clean">
6026        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6027            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6028                Colores Disponibles:
6029            </span>
6030
6031            <div class="flex flex-wrap gap-4 items-center">
6032                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-110-cm-kyra" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-110-cm-kyra"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-110-cm-kyra" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-110-cm-kyra"></div>            </div>
6033        </div>
6034    </div>                            </div>
6035        </div>
6036        <div class="px-4 pb-4">
6037        
6038<div class="mt-1 flex flex-col">
6039            <!-- Invitado: base price + línea VIP (si existe) -->
6040        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6041            139,00 €        </span>
6042
6043                    <div class="flex items-baseline gap-1.5">
6044                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6045                    129,00 €                </span>
6046                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6047                    Precio VIP                </span>
6048            </div>
6049
6050
6051            </div>    </div>
6052</div>
6053
6054<style>
6055    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6056    .color-picker-grid-mode-clean,
6057    .color-picker-grid-mode-clean>div {
6058        display: flex !important;
6059        flex-direction: row !important;
6060        flex-wrap: wrap !important;
6061        align-items: center !important;
6062        gap: 6px !important;
6063        padding: 0 !important;
6064        margin: 0 !important;
6065        border: none !important;
6066    }
6067
6068    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6069    /* El método renderSection imprime un span con el título, lo eliminamos */
6070    .color-picker-grid-mode-clean span.text-sm.font-bold,
6071    .color-picker-grid-mode-clean .w-32 {
6072        display: none !important;
6073    }
6074
6075    /* 3. Ajuste de las "bolitas" de color */
6076    .color-picker-grid-mode-clean .w-9.h-9 {
6077        width: 22px !important;
6078        /* Tamaño reducido ideal para rejilla */
6079        height: 22px !important;
6080        min-width: 22px !important;
6081        min-height: 22px !important;
6082        margin: 0 !important;
6083        transform: none !important;
6084        /* Evitamos que el seleccionado crezca y descuadre */
6085        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6086    }
6087
6088    /* 4. Ajuste del icono Check (V) de selección */
6089    .color-picker-grid-mode-clean svg {
6090        width: 14px !important;
6091        height: 14px !important;
6092    }
6093
6094    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6095    .product-item-variations {
6096        margin-top: 4px !important;
6097        margin-bottom: 4px !important;
6098        padding-top: 0 !important;
6099        padding-bottom: 0 !important;
6100    }
6101
6102    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6103    .color-picker-grid-mode-clean .flex-wrap {
6104        gap: 6px !important;
6105    }
6106
6107    .product-item-photo>span picture,
6108    .product-item-photo>span img {
6109        width: 100% !important;
6110        height: auto !important;
6111        display: block !important;
6112    }
6113
6114    .product-item-photo>span picture {
6115        position: static !important;
6116    }
6117</style>                    </li>
6118                                    <li class="flex flex-col">
6119                        
6120<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6121
6122    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-110-cm-kyra" class="flex flex-col grow w-full">
6123        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6124            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-110-cm-kyra-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-110-cm-kyra-01.jpg" width="360" height="360" alt="mesa-alta-con-2-taburetes-blanco-sonoma-110-cm-kyra" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7155.window="updateImage" loading="lazy"></picture>
6125            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6126                    </div>
6127
6128        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6129                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6130                    <strong>Kyra</strong>
6131                </div>
6132            
6133            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6134                <span class="product-item-link">Mesa alta con 2 Taburetes Blanco y Sonoma 110 cm Kyra</span>
6135            </div>
6136
6137            
6138            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7155.window="updatePrice($event.detail);">
6139                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7155" data-price-box="product-id-7155">
6140    <span
6141    x-data x-id="['product\u002Dprice\u002D7155']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6142    >
6143    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6144        <span class="price"><span class="price">129,00 €</span></span>
6145    </span>
6146    
6147                        <span class="old-price mr-1">
6148                <span class="price line-through text-gray-600">
6149                    <span class="price"><span class="price">139,00 €</span></span>
6150
6151                </span>
6152            </span>
6153        
6154    
6155    
6156    </span>
6157</div></div>
6158                            </div>
6159        </div>
6160    </a>
6161
6162
6163            <!-- <div>CATEGORIA: </div> -->
6164        <div class="product-item-variations px-4 py-2 mt-auto">
6165            <div id="variaciones-listado-7155">
6166                                    <div class="color-picker-grid-mode-clean">
6167        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6168            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6169                Colores Disponibles:
6170            </span>
6171
6172            <div class="flex flex-wrap gap-4 items-center">
6173                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-110-cm-kyra" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-110-cm-kyra"></div><div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-110-cm-kyra" title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-negro-y-sonoma-110-cm-kyra"></div>            </div>
6174        </div>
6175    </div>                            </div>
6176        </div>
6177        <div class="px-4 pb-4">
6178        
6179<div class="mt-1 flex flex-col">
6180            <!-- Invitado: base price + línea VIP (si existe) -->
6181        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6182            139,00 €        </span>
6183
6184                    <div class="flex items-baseline gap-1.5">
6185                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6186                    129,00 €                </span>
6187                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6188                    Precio VIP                </span>
6189            </div>
6190
6191
6192            </div>    </div>
6193</div>
6194
6195<style>
6196    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6197    .color-picker-grid-mode-clean,
6198    .color-picker-grid-mode-clean>div {
6199        display: flex !important;
6200        flex-direction: row !important;
6201        flex-wrap: wrap !important;
6202        align-items: center !important;
6203        gap: 6px !important;
6204        padding: 0 !important;
6205        margin: 0 !important;
6206        border: none !important;
6207    }
6208
6209    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6210    /* El método renderSection imprime un span con el título, lo eliminamos */
6211    .color-picker-grid-mode-clean span.text-sm.font-bold,
6212    .color-picker-grid-mode-clean .w-32 {
6213        display: none !important;
6214    }
6215
6216    /* 3. Ajuste de las "bolitas" de color */
6217    .color-picker-grid-mode-clean .w-9.h-9 {
6218        width: 22px !important;
6219        /* Tamaño reducido ideal para rejilla */
6220        height: 22px !important;
6221        min-width: 22px !important;
6222        min-height: 22px !important;
6223        margin: 0 !important;
6224        transform: none !important;
6225        /* Evitamos que el seleccionado crezca y descuadre */
6226        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6227    }
6228
6229    /* 4. Ajuste del icono Check (V) de selección */
6230    .color-picker-grid-mode-clean svg {
6231        width: 14px !important;
6232        height: 14px !important;
6233    }
6234
6235    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6236    .product-item-variations {
6237        margin-top: 4px !important;
6238        margin-bottom: 4px !important;
6239        padding-top: 0 !important;
6240        padding-bottom: 0 !important;
6241    }
6242
6243    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6244    .color-picker-grid-mode-clean .flex-wrap {
6245        gap: 6px !important;
6246    }
6247
6248    .product-item-photo>span picture,
6249    .product-item-photo>span img {
6250        width: 100% !important;
6251        height: auto !important;
6252        display: block !important;
6253    }
6254
6255    .product-item-photo>span picture {
6256        position: static !important;
6257    }
6258</style>                    </li>
6259                                    <li class="flex flex-col">
6260                        
6261<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6262
6263    <a href="https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-110-cm-kyra" class="flex flex-col grow w-full">
6264        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6265            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-110-cm-04_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-110-cm-04_1.jpg" width="360" height="360" alt="Mesa&#x20;alta&#x20;con&#x20;2&#x20;Taburetes&#x20;
6265Negro&#x20;y&#x20;Sonoma&#x20;110&#x20;cm&#x20;Kyra" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7219.window="updateImage" loading="lazy"></picture>
6266            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6267                    </div>
6268
6269        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6270                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6271                    <strong>Kyra</strong>
6272                </div>
6273            
6274            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6275                <span class="product-item-link">Mesa alta con 2 Taburetes Negro y Sonoma 110 cm Kyra</span>
6276            </div>
6277
6278            
6279            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7219.window="updatePrice($event.detail);">
6280                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7219" data-price-box="product-id-7219">
6281    <span
6282    x-data x-id="['product\u002Dprice\u002D7219']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6283    >
6284    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6285        <span class="price"><span class="price">129,00 €</span></span>
6286    </span>
6287    
6288                        <span class="old-price mr-1">
6289                <span class="price line-through text-gray-600">
6290                    <span class="price"><span class="price">139,00 €</span></span>
6291
6292                </span>
6293            </span>
6294        
6295    
6296    
6297    </span>
6298</div></div>
6299                            </div>
6300        </div>
6301    </a>
6302
6303
6304            <!-- <div>CATEGORIA: </div> -->
6305        <div class="product-item-variations px-4 py-2 mt-auto">
6306            <div id="variaciones-listado-7219">
6307                                    <div class="color-picker-grid-mode-clean">
6308        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6309            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6310                Colores Disponibles:
6311            </span>
6312
6313            <div class="flex flex-wrap gap-4 items-center">
6314                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-110-cm-kyra" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-110-cm-kyra"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-110-cm-kyra" title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mesa-alta-con-2-taburetes-blanco-y-sonoma-110-cm-kyra"></div><div class="relative flex items-center justify-center"><div title="BLSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #000000 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
6315        </div>
6316    </div>                            </div>
6317        </div>
6318        <div class="px-4 pb-4">
6319        
6320<div class="mt-1 flex flex-col">
6321            <!-- Invitado: base price + línea VIP (si existe) -->
6322        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6323            139,00 €        </span>
6324
6325                    <div class="flex items-baseline gap-1.5">
6326                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6327                    129,00 €                </span>
6328                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6329                    Precio VIP                </span>
6330            </div>
6331
6332
6333            </div>    </div>
6334</div>
6335
6336<style>
6337    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6338    .color-picker-grid-mode-clean,
6339    .color-picker-grid-mode-clean>div {
6340        display: flex !important;
6341        flex-direction: row !important;
6342        flex-wrap: wrap !important;
6343        align-items: center !important;
6344        gap: 6px !important;
6345        padding: 0 !important;
6346        margin: 0 !important;
6347        border: none !important;
6348    }
6349
6350    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6351    /* El método renderSection imprime un span con el título, lo eliminamos */
6352    .color-picker-grid-mode-clean span.text-sm.font-bold,
6353    .color-picker-grid-mode-clean .w-32 {
6354        display: none !important;
6355    }
6356
6357    /* 3. Ajuste de las "bolitas" de color */
6358    .color-picker-grid-mode-clean .w-9.h-9 {
6359        width: 22px !important;
6360        /* Tamaño reducido ideal para rejilla */
6361        height: 22px !important;
6362        min-width: 22px !important;
6363        min-height: 22px !important;
6364        margin: 0 !important;
6365        transform: none !important;
6366        /* Evitamos que el seleccionado crezca y descuadre */
6367        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6368    }
6369
6370    /* 4. Ajuste del icono Check (V) de selección */
6371    .color-picker-grid-mode-clean svg {
6372        width: 14px !important;
6373        height: 14px !important;
6374    }
6375
6376    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6377    .product-item-variations {
6378        margin-top: 4px !important;
6379        margin-bottom: 4px !important;
6380        padding-top: 0 !important;
6381        padding-bottom: 0 !important;
6382    }
6383
6384    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6385    .color-picker-grid-mode-clean .flex-wrap {
6386        gap: 6px !important;
6387    }
6388
6389    .product-item-photo>span picture,
6390    .product-item-photo>span img {
6391        width: 100% !important;
6392        height: auto !important;
6393        display: block !important;
6394    }
6395
6396    .product-item-photo>span picture {
6397        position: static !important;
6398    }
6399</style>                    </li>
6400                                    <li class="flex flex-col">
6401                        
6402<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6403
6404    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-iris-color-roble" class="flex flex-col grow w-full">
6405        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6406            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-iris-color-roble-1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-iris-color-roble-1.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Iris&#x20;color&#x20;Roble&#x20;" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7249.window="updateImage" loading="lazy"></picture>
6407            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6408                    </div>
6409
6410        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6411                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6412                    <strong>Iris</strong>
6413                </div>
6414            
6415            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6416                <span class="product-item-link">Aparador modelo Iris color Roble</span>
6417            </div>
6418
6419            
6420            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7249.window="updatePrice($event.detail);">
6421                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7249" data-price-box="product-id-7249">
6422    <span
6423    x-data x-id="['product\u002Dprice\u002D7249']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6424    >
6425    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6426        <span class="price"><span class="price">99,00 €</span></span>
6427    </span>
6428    
6429                        <span class="old-price mr-1">
6430                <span class="price line-through text-gray-600">
6431                    <span class="price"><span class="price">109,00 €</span></span>
6432
6433                </span>
6434            </span>
6435        
6436    
6437    
6438    </span>
6439</div></div>
6440                            </div>
6441        </div>
6442    </a>
6443
6444
6445            <!-- <div>CATEGORIA: </div> -->
6446        <div class="product-item-variations px-4 py-2 mt-auto">
6447            <div id="variaciones-listado-7249">
6448                                    <div class="color-picker-grid-mode-clean">
6449        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6450            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6451                Colores Disponibles:
6452            </span>
6453
6454            <div class="flex flex-wrap gap-4 items-center">
6455                <div class="relative flex items-center justify-center"><div title="RORO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #D2B48C;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-iris-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-iris-color-blanco"></div>            </div>
6456        </div>
6457    </div>                            </div>
6458        </div>
6459        <div class="px-4 pb-4">
6460        
6461<div class="mt-1 flex flex-col">
6462            <!-- Invitado: base price + línea VIP (si existe) -->
6463        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6464            109,00 €        </span>
6465
6466                    <div class="flex items-baseline gap-1.5">
6467                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6468                    99,00 €                </span>
6469                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6470                    Precio VIP                </span>
6471            </div>
6472
6473
6474            </div>    </div>
6475</div>
6476
6477<style>
6478    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6479    .color-picker-grid-mode-clean,
6480    .color-picker-grid-mode-clean>div {
6481        display: flex !important;
6482        flex-direction: row !important;
6483        flex-wrap: wrap !important;
6484        align-items: center !important;
6485        gap: 6px !important;
6486        padding: 0 !important;
6487        margin: 0 !important;
6488        border: none !important;
6489    }
6490
6491    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6492    /* El método renderSection imprime un span con el título, lo eliminamos */
6493    .color-picker-grid-mode-clean span.text-sm.font-bold,
6494    .color-picker-grid-mode-clean .w-32 {
6495        display: none !important;
6496    }
6497
6498    /* 3. Ajuste de las "bolitas" de color */
6499    .color-picker-grid-mode-clean .w-9.h-9 {
6500        width: 22px !important;
6501        /* Tamaño reducido ideal para rejilla */
6502        height: 22px !important;
6503        min-width: 22px !important;
6504        min-height: 22px !important;
6505        margin: 0 !important;
6506        transform: none !important;
6507        /* Evitamos que el seleccionado crezca y descuadre */
6508        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6509    }
6510
6511    /* 4. Ajuste del icono Check (V) de selección */
6512    .color-picker-grid-mode-clean svg {
6513        width: 14px !important;
6514        height: 14px !important;
6515    }
6516
6517    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6518    .product-item-variations {
6519        margin-top: 4px !important;
6520        margin-bottom: 4px !important;
6521        padding-top: 0 !important;
6522        padding-bottom: 0 !important;
6523    }
6524
6525    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6526    .color-picker-grid-mode-clean .flex-wrap {
6527        gap: 6px !important;
6528    }
6529
6530    .product-item-photo>span picture,
6531    .product-item-photo>span img {
6532        width: 100% !important;
6533        height: auto !important;
6534        display: block !important;
6535    }
6536
6537    .product-item-photo>span picture {
6538        position: static !important;
6539    }
6540</style>                    </li>
6541                                    <li class="flex flex-col">
6542                        
6543<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6544
6545    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-iris-color-blanco" class="flex flex-col grow w-full">
6546        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6547            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-iris-color-blanco-1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-iris-color-blanco-1.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Iris&#x20;color&#x20;Blanco" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7250.window="updateImage" loading="lazy"></picture>
6548            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6549                    </div>
6550
6551        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6552                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6553                    <strong>Iris</strong>
6554                </div>
6555            
6556            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6557                <span class="product-item-link">Aparador modelo Iris color Blanco</span>
6558            </div>
6559
6560            
6561            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7250.window="updatePrice($event.detail);">
6562                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7250" data-price-box="product-id-7250">
6563    <span
6564    x-data x-id="['product\u002Dprice\u002D7250']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6565    >
6566    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6567        <span class="price"><span class="price">99,00 €</span></span>
6568    </span>
6569    
6570                        <span class="old-price mr-1">
6571                <span class="price line-through text-gray-600">
6572                    <span class="price"><span class="price">109,00 €</span></span>
6573
6574                </span>
6575            </span>
6576        
6577    
6578    
6579    </span>
6580</div></div>
6581                            </div>
6582        </div>
6583    </a>
6584
6585
6586            <!-- <div>CATEGORIA: </div> -->
6587        <div class="product-item-variations px-4 py-2 mt-auto">
6588            <div id="variaciones-listado-7250">
6589                                    <div class="color-picker-grid-mode-clean">
6590        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6591            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6592                Colores Disponibles:
6593            </span>
6594
6595            <div class="flex flex-wrap gap-4 items-center">
6596                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-iris-color-roble" title="RORO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #D2B48C;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-iris-color-roble"></div><div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
6597        </div>
6598    </div>                            </div>
6599        </div>
6600        <div class="px-4 pb-4">
6601        
6602<div class="mt-1 flex flex-col">
6603            <!-- Invitado: base price + línea VIP (si existe) -->
6604        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6605            109,00 €        </span>
6606
6607                    <div class="flex items-baseline gap-1.5">
6608                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6609                    99,00 €                </span>
6610                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6611                    Precio VIP                </span>
6612            </div>
6613
6614
6615            </div>    </div>
6616</div>
6617
6618<style>
6619    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6620    .color-picker-grid-mode-clean,
6621    .color-picker-grid-mode-clean>div {
6622        display: flex !important;
6623        flex-direction: row !important;
6624        flex-wrap: wrap !important;
6625        align-items: center !important;
6626        gap: 6px !important;
6627        padding: 0 !important;
6628        margin: 0 !important;
6629        border: none !important;
6630    }
6631
6632    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6633    /* El método renderSection imprime un span con el título, lo eliminamos */
6634    .color-picker-grid-mode-clean span.text-sm.font-bold,
6635    .color-picker-grid-mode-clean .w-32 {
6636        display: none !important;
6637    }
6638
6639    /* 3. Ajuste de las "bolitas" de color */
6640    .color-picker-grid-mode-clean .w-9.h-9 {
6641        width: 22px !important;
6642        /* Tamaño reducido ideal para rejilla */
6643        height: 22px !important;
6644        min-width: 22px !important;
6645        min-height: 22px !important;
6646        margin: 0 !important;
6647        transform: none !important;
6648        /* Evitamos que el seleccionado crezca y descuadre */
6649        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6650    }
6651
6652    /* 4. Ajuste del icono Check (V) de selección */
6653    .color-picker-grid-mode-clean svg {
6654        width: 14px !important;
6655        height: 14px !important;
6656    }
6657
6658    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6659    .product-item-variations {
6660        margin-top: 4px !important;
6661        margin-bottom: 4px !important;
6662        padding-top: 0 !important;
6663        padding-bottom: 0 !important;
6664    }
6665
6666    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6667    .color-picker-grid-mode-clean .flex-wrap {
6668        gap: 6px !important;
6669    }
6670
6671    .product-item-photo>span picture,
6672    .product-item-photo>span img {
6673        width: 100% !important;
6674        height: auto !important;
6675        display: block !important;
6676    }
6677
6678    .product-item-photo>span picture {
6679        position: static !important;
6680    }
6681</style>                    </li>
6682                                    <li class="flex flex-col">
6683                        
6684<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6685
6686    <a href="https://www.mueblesbonitos.com/salon/mueble-tv-color-roble-alba-150cm-renzo" class="flex flex-col grow w-full">
6687        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6688            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-color-roble-alba-150cm-renzo-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-color-roble-alba-150cm-renzo-01.jpg" width="360" height="360" alt="Mueble&#x20;TV&#x20;color&#x20;roble&#x20;alba&#x20;150cm&#x20;Renzo" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7256.window="updateImage" loading="lazy"></picture>
6689            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6690                    </div>
6691
6692        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6693                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6694                    <strong>Renzo</strong>
6695                </div>
6696            
6697            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6698                <span class="product-item-link">Mueble TV color roble alba 150cm Renzo</span>
6699            </div>
6700
6701            
6702            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7256.window="updatePrice($event.detail);">
6703                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7256" data-price-box="product-id-7256">
6704    <span
6705    x-data x-id="['product\u002Dprice\u002D7256']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6706    >
6707    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6708        <span class="price"><span class="price">72,00 €</span></span>
6709    </span>
6710    
6711                        <span class="old-price mr-1">
6712                <span class="price line-through text-gray-600">
6713                    <span class="price"><span class="price">79,00 €</span></span>
6714
6715                </span>
6716            </span>
6717        
6718    
6719    
6720    </span>
6721</div></div>
6722                            </div>
6723        </div>
6724    </a>
6725
6726
6727            <!-- <div>CATEGORIA: </div> -->
6728        <div class="product-item-variations px-4 py-2 mt-auto">
6729            <div id="variaciones-listado-7256">
6730                                    <div class="color-picker-grid-mode-clean">
6731        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6732            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6733                Colores Disponibles:
6734            </span>
6735
6736            <div class="flex flex-wrap gap-4 items-center">
6737                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mueble-tv-color-blanco-150cm-renzo" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mueble-tv-color-blanco-150cm-renzo"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mueble-tv-color-negro-150cm-renzo" title="BLBL" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #000000;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mueble-tv-color-negro-150cm-renzo"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mueble-tv-color-roble-eos-150cm-renzo" title="ZOZO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #bfa37b;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mueble-tv-color-roble-eos-150cm-renzo"></div><div class="relative flex items-center justify-center"><div title="LOLO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #ce9f75;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
6738        </div>
6739    </div>                            </div>
6740        </div>
6741        <div class="px-4 pb-4">
6742        
6743<div class="mt-1 flex flex-col">
6744            <!-- Invitado: base price + línea VIP (si existe) -->
6745        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6746            79,00 €        </span>
6747
6748                    <div class="flex items-baseline gap-1.5">
6749                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6750                    72,00 €                </span>
6751                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6752                    Precio VIP                </span>
6753            </div>
6754
6755
6756            </div>    </div>
6757</div>
6758
6759<style>
6760    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6761    .color-picker-grid-mode-clean,
6762    .color-picker-grid-mode-clean>div {
6763        display: flex !important;
6764        flex-direction: row !important;
6765        flex-wrap: wrap !important;
6766        align-items: center !important;
6767        gap: 6px !important;
6768        padding: 0 !important;
6769        margin: 0 !important;
6770        border: none !important;
6771    }
6772
6773    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6774    /* El método renderSection imprime un span con el título, lo eliminamos */
6775    .color-picker-grid-mode-clean span.text-sm.font-bold,
6776    .color-picker-grid-mode-clean .w-32 {
6777        display: none !important;
6778    }
6779
6780    /* 3. Ajuste de las "bolitas" de color */
6781    .color-picker-grid-mode-clean .w-9.h-9 {
6782        width: 22px !important;
6783        /* Tamaño reducido ideal para rejilla */
6784        height: 22px !important;
6785        min-width: 22px !important;
6786        min-height: 22px !important;
6787        margin: 0 !important;
6788        transform: none !important;
6789        /* Evitamos que el seleccionado crezca y descuadre */
6790        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6791    }
6792
6793    /* 4. Ajuste del icono Check (V) de selección */
6794    .color-picker-grid-mode-clean svg {
6795        width: 14px !important;
6796        height: 14px !important;
6797    }
6798
6799    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6800    .product-item-variations {
6801        margin-top: 4px !important;
6802        margin-bottom: 4px !important;
6803        padding-top: 0 !important;
6804        padding-bottom: 0 !important;
6805    }
6806
6807    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6808    .color-picker-grid-mode-clean .flex-wrap {
6809        gap: 6px !important;
6810    }
6811
6812    .product-item-photo>span picture,
6813    .product-item-photo>span img {
6814        width: 100% !important;
6815        height: auto !important;
6816        display: block !important;
6817    }
6818
6819    .product-item-photo>span picture {
6820        position: static !important;
6821    }
6822</style>                    </li>
6823                                    <li class="flex flex-col">
6824                        
6825<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6826
6827    <a href="https://www.mueblesbonitos.com/salon/aparador-blanco-y-sonoma-moderno-150-cm-serena" class="flex flex-col grow w-full">
6828        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6829            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-color-blanco-y-sonoma-150-cm-serena-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-color-blanco-y-sonoma-150-cm-serena-01.jpg" width="360" height="360" alt="&#x20;Aparador&#x20;color&#x20;Blanco&#x20;y&#x20;Sonoma&#x20;150&#x20;cm&#x20;Serena" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7259.window="updateImage" loading="lazy"></picture>
6830            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6831                    </div>
6832
6833        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6834                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6835                    <strong>Serena</strong>
6836                </div>
6837            
6838            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6839                <span class="product-item-link">Aparador Blanco y Sonoma Moderno 150 cm Serena</span>
6840            </div>
6841
6842            
6843            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7259.window="updatePrice($event.detail);">
6844                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7259" data-price-box="product-id-7259">
6845    <span
6846    x-data x-id="['product\u002Dprice\u002D7259']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6847    >
6848    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6849        <span class="price"><span class="price">179,00 €</span></span>
6850    </span>
6851    
6852                        <span class="old-price mr-1">
6853                <span class="price line-through text-gray-600">
6854                    <span class="price"><span class="price">199,00 €</span></span>
6855
6856                </span>
6857            </span>
6858        
6859    
6860    
6861    </span>
6862</div></div>
6863                            </div>
6864        </div>
6865    </a>
6866
6867
6868            <!-- <div>CATEGORIA: </div> -->
6869        <div class="product-item-variations px-4 py-2 mt-auto">
6870            <div id="variaciones-listado-7259">
6871                                    <div class="color-picker-grid-mode-clean">
6872        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
6873            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
6874                Colores Disponibles:
6875            </span>
6876
6877            <div class="flex flex-wrap gap-4 items-center">
6878                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-blanco-moderno-150-cm-serena" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-blanco-moderno-150-cm-serena"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-roble-alpes-moderno-150-cm-serena" title="MOMO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #b6a77e;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-roble-alpes-moderno-150-cm-serena"></div><div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
6879        </div>
6880    </div>                            </div>
6881        </div>
6882        <div class="px-4 pb-4">
6883        
6884<div class="mt-1 flex flex-col">
6885            <!-- Invitado: base price + línea VIP (si existe) -->
6886        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
6887            199,00 €        </span>
6888
6889                    <div class="flex items-baseline gap-1.5">
6890                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
6891                    179,00 €                </span>
6892                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
6893                    Precio VIP                </span>
6894            </div>
6895
6896
6897            </div>    </div>
6898</div>
6899
6900<style>
6901    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
6902    .color-picker-grid-mode-clean,
6903    .color-picker-grid-mode-clean>div {
6904        display: flex !important;
6905        flex-direction: row !important;
6906        flex-wrap: wrap !important;
6907        align-items: center !important;
6908        gap: 6px !important;
6909        padding: 0 !important;
6910        margin: 0 !important;
6911        border: none !important;
6912    }
6913
6914    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
6915    /* El método renderSection imprime un span con el título, lo eliminamos */
6916    .color-picker-grid-mode-clean span.text-sm.font-bold,
6917    .color-picker-grid-mode-clean .w-32 {
6918        display: none !important;
6919    }
6920
6921    /* 3. Ajuste de las "bolitas" de color */
6922    .color-picker-grid-mode-clean .w-9.h-9 {
6923        width: 22px !important;
6924        /* Tamaño reducido ideal para rejilla */
6925        height: 22px !important;
6926        min-width: 22px !important;
6927        min-height: 22px !important;
6928        margin: 0 !important;
6929        transform: none !important;
6930        /* Evitamos que el seleccionado crezca y descuadre */
6931        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
6932    }
6933
6934    /* 4. Ajuste del icono Check (V) de selección */
6935    .color-picker-grid-mode-clean svg {
6936        width: 14px !important;
6937        height: 14px !important;
6938    }
6939
6940    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
6941    .product-item-variations {
6942        margin-top: 4px !important;
6943        margin-bottom: 4px !important;
6944        padding-top: 0 !important;
6945        padding-bottom: 0 !important;
6946    }
6947
6948    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
6949    .color-picker-grid-mode-clean .flex-wrap {
6950        gap: 6px !important;
6951    }
6952
6953    .product-item-photo>span picture,
6954    .product-item-photo>span img {
6955        width: 100% !important;
6956        height: auto !important;
6957        display: block !important;
6958    }
6959
6960    .product-item-photo>span picture {
6961        position: static !important;
6962    }
6963</style>                    </li>
6964                                    <li class="flex flex-col">
6965                        
6966<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
6967
6968    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-leo-color-blanco-mate" class="flex flex-col grow w-full">
6969        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
6970            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-leo-color-blanco-mate-09.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-leo-color-blanco-mate-09.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Leo&#x20;color&#x20;Blanco&#x20;mate" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7260.window="updateImage" loading="lazy"></picture>
6971            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
6972                    </div>
6973
6974        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
6975                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
6976                    <strong>Leo</strong>
6977                </div>
6978            
6979            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
6980                <span class="product-item-link">Aparador modelo Leo color Blanco mate</span>
6981            </div>
6982
6983            
6984            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7260.window="updatePrice($event.detail);">
6985                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7260" data-price-box="product-id-7260">
6986    <span
6987    x-data x-id="['product\u002Dprice\u002D7260']"     class="price-container price-final_price&#x20;tax&#x20;weee"
6988    >
6989    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
6990        <span class="price"><span class="price">99,00 €</span></span>
6991    </span>
6992    
6993                        <span class="old-price mr-1">
6994                <span class="price line-through text-gray-600">
6995                    <span class="price"><span class="price">109,00 €</span></span>
6996
6997                </span>
6998            </span>
6999        
7000    
7001    
7002    </span>
7003</div></div>
7004                            </div>
7005        </div>
7006    </a>
7007
7008
7009            <!-- <div>CATEGORIA: </div> -->
7010        <div class="product-item-variations px-4 py-2 mt-auto">
7011            <div id="variaciones-listado-7260">
7012                                    <div class="color-picker-grid-mode-clean">
7013        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7014            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7015                Colores Disponibles:
7016            </span>
7017
7018            <div class="flex flex-wrap gap-4 items-center">
7019                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-leo-color-roble-eos" title="ZOZO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #bfa37b;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-leo-color-roble-eos"></div>            </div>
7020        </div>
7021    </div>                            </div>
7022        </div>
7023        <div class="px-4 pb-4">
7024        
7025<div class="mt-1 flex flex-col">
7026            <!-- Invitado: base price + línea VIP (si existe) -->
7027        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7028            109,00 €        </span>
7029
7030                    <div class="flex items-baseline gap-1.5">
7031                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7032                    99,00 €                </span>
7033                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7034                    Precio VIP                </span>
7035            </div>
7036
7037
7038            </div>    </div>
7039</div>
7040
7041<style>
7042    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7043    .color-picker-grid-mode-clean,
7044    .color-picker-grid-mode-clean>div {
7045        display: flex !important;
7046        flex-direction: row !important;
7047        flex-wrap: wrap !important;
7048        align-items: center !important;
7049        gap: 6px !important;
7050        padding: 0 !important;
7051        margin: 0 !important;
7052        border: none !important;
7053    }
7054
7055    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7056    /* El método renderSection imprime un span con el título, lo eliminamos */
7057    .color-picker-grid-mode-clean span.text-sm.font-bold,
7058    .color-picker-grid-mode-clean .w-32 {
7059        display: none !important;
7060    }
7061
7062    /* 3. Ajuste de las "bolitas" de color */
7063    .color-picker-grid-mode-clean .w-9.h-9 {
7064        width: 22px !important;
7065        /* Tamaño reducido ideal para rejilla */
7066        height: 22px !important;
7067        min-width: 22px !important;
7068        min-height: 22px !important;
7069        margin: 0 !important;
7070        transform: none !important;
7071        /* Evitamos que el seleccionado crezca y descuadre */
7072        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7073    }
7074
7075    /* 4. Ajuste del icono Check (V) de selección */
7076    .color-picker-grid-mode-clean svg {
7077        width: 14px !important;
7078        height: 14px !important;
7079    }
7080
7081    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7082    .product-item-variations {
7083        margin-top: 4px !important;
7084        margin-bottom: 4px !important;
7085        padding-top: 0 !important;
7086        padding-bottom: 0 !important;
7087    }
7088
7089    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7090    .color-picker-grid-mode-clean .flex-wrap {
7091        gap: 6px !important;
7092    }
7093
7094    .product-item-photo>span picture,
7095    .product-item-photo>span img {
7096        width: 100% !important;
7097        height: auto !important;
7098        display: block !important;
7099    }
7100
7101    .product-item-photo>span picture {
7102        position: static !important;
7103    }
7104</style>                    </li>
7105                                    <li class="flex flex-col">
7106                        
7107<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7108
7109    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-leo-color-roble-eos" class="flex flex-col grow w-full">
7110        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7111            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-leo-color-roble-eos-mate-05.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-leo-color-roble-eos-mate-05.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Leo&#x20;color&#x20;Roble&#x20;Eos" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7261.window="updateImage" loading="lazy"></picture>
7112            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7113                    </div>
7114
7115        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7116                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7117                    <strong>Leo</strong>
7118                </div>
7119            
7120            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7121                <span class="product-item-link">Aparador modelo Leo color Roble Eos</span>
7122            </div>
7123
7124            
7125            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7261.window="updatePrice($event.detail);">
7126                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7261" data-price-box="product-id-7261">
7127    <span
7128    x-data x-id="['product\u002Dprice\u002D7261']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7129    >
7130    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7131        <span class="price"><span class="price">99,00 €</span></span>
7132    </span>
7133    
7134                        <span class="old-price mr-1">
7135                <span class="price line-through text-gray-600">
7136                    <span class="price"><span class="price">109,00 €</span></span>
7137
7138                </span>
7139            </span>
7140        
7141    
7142    
7143    </span>
7144</div></div>
7145                            </div>
7146        </div>
7147    </a>
7148
7149
7150            <!-- <div>CATEGORIA: </div> -->
7151        <div class="product-item-variations px-4 py-2 mt-auto">
7152            <div id="variaciones-listado-7261">
7153                                    <div class="color-picker-grid-mode-clean">
7154        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7155            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7156                Colores Disponibles:
7157            </span>
7158
7159            <div class="flex flex-wrap gap-4 items-center">
7160                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-leo-color-blanco-mate" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-leo-color-blanco-mate"></div><div class="relative flex items-center justify-center"><div title="ZOZO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #bfa37b;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
7161        </div>
7162    </div>                            </div>
7163        </div>
7164        <div class="px-4 pb-4">
7165        
7166<div class="mt-1 flex flex-col">
7167            <!-- Invitado: base price + línea VIP (si existe) -->
7168        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7169            109,00 €        </span>
7170
7171                    <div class="flex items-baseline gap-1.5">
7172                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7173                    99,00 €                </span>
7174                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7175                    Precio VIP                </span>
7176            </div>
7177
7178
7179            </div>    </div>
7180</div>
7181
7182<style>
7183    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7184    .color-picker-grid-mode-clean,
7185    .color-picker-grid-mode-clean>div {
7186        display: flex !important;
7187        flex-direction: row !important;
7188        flex-wrap: wrap !important;
7189        align-items: center !important;
7190        gap: 6px !important;
7191        padding: 0 !important;
7192        margin: 0 !important;
7193        border: none !important;
7194    }
7195
7196    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7197    /* El método renderSection imprime un span con el título, lo eliminamos */
7198    .color-picker-grid-mode-clean span.text-sm.font-bold,
7199    .color-picker-grid-mode-clean .w-32 {
7200        display: none !important;
7201    }
7202
7203    /* 3. Ajuste de las "bolitas" de color */
7204    .color-picker-grid-mode-clean .w-9.h-9 {
7205        width: 22px !important;
7206        /* Tamaño reducido ideal para rejilla */
7207        height: 22px !important;
7208        min-width: 22px !important;
7209        min-height: 22px !important;
7210        margin: 0 !important;
7211        transform: none !important;
7212        /* Evitamos que el seleccionado crezca y descuadre */
7213        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7214    }
7215
7216    /* 4. Ajuste del icono Check (V) de selección */
7217    .color-picker-grid-mode-clean svg {
7218        width: 14px !important;
7219        height: 14px !important;
7220    }
7221
7222    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7223    .product-item-variations {
7224        margin-top: 4px !important;
7225        margin-bottom: 4px !important;
7226        padding-top: 0 !important;
7227        padding-bottom: 0 !important;
7228    }
7229
7230    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7231    .color-picker-grid-mode-clean .flex-wrap {
7232        gap: 6px !important;
7233    }
7234
7235    .product-item-photo>span picture,
7236    .product-item-photo>span img {
7237        width: 100% !important;
7238        height: auto !important;
7239        display: block !important;
7240    }
7241
7242    .product-item-photo>span picture {
7243        position: static !important;
7244    }
7245</style>                    </li>
7246                                    <li class="flex flex-col">
7247                        
7248<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7249
7250    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-duna-color-roble-eos" class="flex flex-col grow w-full">
7251        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7252            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-duna-color-roble-eos-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-duna-color-roble-eos-01.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Duna&#x20;color&#x20;Roble&#x20;Eos" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7262.window="updateImage" loading="lazy"></picture>
7253            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7254                    </div>
7255
7256        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7257                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7258                    <strong>Duna</strong>
7259                </div>
7260            
7261            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7262                <span class="product-item-link">Aparador modelo Duna color Roble Eos</span>
7263            </div>
7264
7265            
7266            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7262.window="updatePrice($event.detail);">
7267                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7262" data-price-box="product-id-7262">
7268    <span
7269    x-data x-id="['product\u002Dprice\u002D7262']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7270    >
7271    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7272        <span class="price"><span class="price">79,00 €</span></span>
7273    </span>
7274    
7275                        <span class="old-price mr-1">
7276                <span class="price line-through text-gray-600">
7277                    <span class="price"><span class="price">89,00 €</span></span>
7278
7279                </span>
7280            </span>
7281        
7282    
7283    
7284    </span>
7285</div></div>
7286                            </div>
7287        </div>
7288    </a>
7289
7290
7291            <!-- <div>CATEGORIA: </div> -->
7292        <div class="product-item-variations px-4 py-2 mt-auto">
7293            <div id="variaciones-listado-7262">
7294                                    <div class="color-picker-grid-mode-clean">
7295        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7296            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7297                Colores Disponibles:
7298            </span>
7299
7300            <div class="flex flex-wrap gap-4 items-center">
7301                <div class="relative flex items-center justify-center"><div title="ZOZO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #bfa37b;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
7302        </div>
7303    </div>                            </div>
7304        </div>
7305        <div class="px-4 pb-4">
7306        
7307<div class="mt-1 flex flex-col">
7308            <!-- Invitado: base price + línea VIP (si existe) -->
7309        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7310            89,00 €        </span>
7311
7312                    <div class="flex items-baseline gap-1.5">
7313                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7314                    79,00 €                </span>
7315                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7316                    Precio VIP                </span>
7317            </div>
7318
7319
7320            </div>    </div>
7321</div>
7322
7323<style>
7324    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7325    .color-picker-grid-mode-clean,
7326    .color-picker-grid-mode-clean>div {
7327        display: flex !important;
7328        flex-direction: row !important;
7329        flex-wrap: wrap !important;
7330        align-items: center !important;
7331        gap: 6px !important;
7332        padding: 0 !important;
7333        margin: 0 !important;
7334        border: none !important;
7335    }
7336
7337    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7338    /* El método renderSection imprime un span con el título, lo eliminamos */
7339    .color-picker-grid-mode-clean span.text-sm.font-bold,
7340    .color-picker-grid-mode-clean .w-32 {
7341        display: none !important;
7342    }
7343
7344    /* 3. Ajuste de las "bolitas" de color */
7345    .color-picker-grid-mode-clean .w-9.h-9 {
7346        width: 22px !important;
7347        /* Tamaño reducido ideal para rejilla */
7348        height: 22px !important;
7349        min-width: 22px !important;
7350        min-height: 22px !important;
7351        margin: 0 !important;
7352        transform: none !important;
7353        /* Evitamos que el seleccionado crezca y descuadre */
7354        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7355    }
7356
7357    /* 4. Ajuste del icono Check (V) de selección */
7358    .color-picker-grid-mode-clean svg {
7359        width: 14px !important;
7360        height: 14px !important;
7361    }
7362
7363    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7364    .product-item-variations {
7365        margin-top: 4px !important;
7366        margin-bottom: 4px !important;
7367        padding-top: 0 !important;
7368        padding-bottom: 0 !important;
7369    }
7370
7371    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7372    .color-picker-grid-mode-clean .flex-wrap {
7373        gap: 6px !important;
7374    }
7375
7376    .product-item-photo>span picture,
7377    .product-item-photo>span img {
7378        width: 100% !important;
7379        height: auto !important;
7380        display: block !important;
7381    }
7382
7383    .product-item-photo>span picture {
7384        position: static !important;
7385    }
7386</style>                    </li>
7387                                    <li class="flex flex-col">
7388                        
7389<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7390
7391    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-vega-color-blanco-mate" class="flex flex-col grow w-full">
7392        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7393            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-vega-color-blanco-mate-1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-vega-color-blanco-mate-1.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Vega&#x20;cor&#x20;Carvalho&#x20;Alba" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7263.window="updateImage" loading="lazy"></picture>
7394            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7395                    </div>
7396
7397        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7398                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7399                    <strong>Vega</strong>
7400                </div>
7401            
7402            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7403                <span class="product-item-link">Aparador modelo Vega color Blanco mate</span>
7404            </div>
7405
7406            
7407            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7263.window="updatePrice($event.detail);">
7408                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7263" data-price-box="product-id-7263">
7409    <span
7410    x-data x-id="['product\u002Dprice\u002D7263']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7411    >
7412    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7413        <span class="price"><span class="price">89,00 €</span></span>
7414    </span>
7415    
7416                        <span class="old-price mr-1">
7417                <span class="price line-through text-gray-600">
7418                    <span class="price"><span class="price">99,00 €</span></span>
7419
7420                </span>
7421            </span>
7422        
7423    
7424    
7425    </span>
7426</div></div>
7427                            </div>
7428        </div>
7429    </a>
7430
7431
7432            <!-- <div>CATEGORIA: </div> -->
7433        <div class="product-item-variations px-4 py-2 mt-auto">
7434            <div id="variaciones-listado-7263">
7435                                    <div class="color-picker-grid-mode-clean">
7436        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7437            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7438                Colores Disponibles:
7439            </span>
7440
7441            <div class="flex flex-wrap gap-4 items-center">
7442                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-vega-color-roble-alba" title="LOLO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #ce9f75;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-vega-color-roble-alba"></div>            </div>
7443        </div>
7444    </div>                            </div>
7445        </div>
7446        <div class="px-4 pb-4">
7447        
7448<div class="mt-1 flex flex-col">
7449            <!-- Invitado: base price + línea VIP (si existe) -->
7450        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7451            99,00 €        </span>
7452
7453                    <div class="flex items-baseline gap-1.5">
7454                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7455                    89,00 €                </span>
7456                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7457                    Precio VIP                </span>
7458            </div>
7459
7460
7461            </div>    </div>
7462</div>
7463
7464<style>
7465    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7466    .color-picker-grid-mode-clean,
7467    .color-picker-grid-mode-clean>div {
7468        display: flex !important;
7469        flex-direction: row !important;
7470        flex-wrap: wrap !important;
7471        align-items: center !important;
7472        gap: 6px !important;
7473        padding: 0 !important;
7474        margin: 0 !important;
7475        border: none !important;
7476    }
7477
7478    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7479    /* El método renderSection imprime un span con el título, lo eliminamos */
7480    .color-picker-grid-mode-clean span.text-sm.font-bold,
7481    .color-picker-grid-mode-clean .w-32 {
7482        display: none !important;
7483    }
7484
7485    /* 3. Ajuste de las "bolitas" de color */
7486    .color-picker-grid-mode-clean .w-9.h-9 {
7487        width: 22px !important;
7488        /* Tamaño reducido ideal para rejilla */
7489        height: 22px !important;
7490        min-width: 22px !important;
7491        min-height: 22px !important;
7492        margin: 0 !important;
7493        transform: none !important;
7494        /* Evitamos que el seleccionado crezca y descuadre */
7495        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7496    }
7497
7498    /* 4. Ajuste del icono Check (V) de selección */
7499    .color-picker-grid-mode-clean svg {
7500        width: 14px !important;
7501        height: 14px !important;
7502    }
7503
7504    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7505    .product-item-variations {
7506        margin-top: 4px !important;
7507        margin-bottom: 4px !important;
7508        padding-top: 0 !important;
7509        padding-bottom: 0 !important;
7510    }
7511
7512    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7513    .color-picker-grid-mode-clean .flex-wrap {
7514        gap: 6px !important;
7515    }
7516
7517    .product-item-photo>span picture,
7518    .product-item-photo>span img {
7519        width: 100% !important;
7520        height: auto !important;
7521        display: block !important;
7522    }
7523
7524    .product-item-photo>span picture {
7525        position: static !important;
7526    }
7527</style>                    </li>
7528                                    <li class="flex flex-col">
7529                        
7530<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7531
7532    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-vega-color-roble-alba" class="flex flex-col grow w-full">
7533        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7534            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-vega-color-roble-alba-01_1_1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-vega-color-roble-alba-01_1_1.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Vega&#x20;color&#x20;Roble&#x20;Alba&#x20;" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7264.window="updateImage" loading="lazy"></picture>
7535            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7536                    </div>
7537
7538        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7539                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7540                    <strong>Vega</strong>
7541                </div>
7542            
7543            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7544                <span class="product-item-link">Aparador modelo Vega color Roble Alba</span>
7545            </div>
7546
7547            
7548            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7264.window="updatePrice($event.detail);">
7549                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7264" data-price-box="product-id-7264">
7550    <span
7551    x-data x-id="['product\u002Dprice\u002D7264']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7552    >
7553    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7554        <span class="price"><span class="price">89,00 €</span></span>
7555    </span>
7556    
7557                        <span class="old-price mr-1">
7558                <span class="price line-through text-gray-600">
7559                    <span class="price"><span class="price">99,00 €</span></span>
7560
7561                </span>
7562            </span>
7563        
7564    
7565    
7566    </span>
7567</div></div>
7568                            </div>
7569        </div>
7570    </a>
7571
7572
7573            <!-- <div>CATEGORIA: </div> -->
7574        <div class="product-item-variations px-4 py-2 mt-auto">
7575            <div id="variaciones-listado-7264">
7576                                    <div class="color-picker-grid-mode-clean">
7577        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7578            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7579                Colores Disponibles:
7580            </span>
7581
7582            <div class="flex flex-wrap gap-4 items-center">
7583                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-vega-color-blanco-mate" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-vega-color-blanco-mate"></div><div class="relative flex items-center justify-center"><div title="LOLO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #ce9f75;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
7584        </div>
7585    </div>                            </div>
7586        </div>
7587        <div class="px-4 pb-4">
7588        
7589<div class="mt-1 flex flex-col">
7590            <!-- Invitado: base price + línea VIP (si existe) -->
7591        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7592            99,00 €        </span>
7593
7594                    <div class="flex items-baseline gap-1.5">
7595                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7596                    89,00 €                </span>
7597                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7598                    Precio VIP                </span>
7599            </div>
7600
7601
7602            </div>    </div>
7603</div>
7604
7605<style>
7606    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7607    .color-picker-grid-mode-clean,
7608    .color-picker-grid-mode-clean>div {
7609        display: flex !important;
7610        flex-direction: row !important;
7611        flex-wrap: wrap !important;
7612        align-items: center !important;
7613        gap: 6px !important;
7614        padding: 0 !important;
7615        margin: 0 !important;
7616        border: none !important;
7617    }
7618
7619    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7620    /* El método renderSection imprime un span con el título, lo eliminamos */
7621    .color-picker-grid-mode-clean span.text-sm.font-bold,
7622    .color-picker-grid-mode-clean .w-32 {
7623        display: none !important;
7624    }
7625
7626    /* 3. Ajuste de las "bolitas" de color */
7627    .color-picker-grid-mode-clean .w-9.h-9 {
7628        width: 22px !important;
7629        /* Tamaño reducido ideal para rejilla */
7630        height: 22px !important;
7631        min-width: 22px !important;
7632        min-height: 22px !important;
7633        margin: 0 !important;
7634        transform: none !important;
7635        /* Evitamos que el seleccionado crezca y descuadre */
7636        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7637    }
7638
7639    /* 4. Ajuste del icono Check (V) de selección */
7640    .color-picker-grid-mode-clean svg {
7641        width: 14px !important;
7642        height: 14px !important;
7643    }
7644
7645    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7646    .product-item-variations {
7647        margin-top: 4px !important;
7648        margin-bottom: 4px !important;
7649        padding-top: 0 !important;
7650        padding-bottom: 0 !important;
7651    }
7652
7653    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7654    .color-picker-grid-mode-clean .flex-wrap {
7655        gap: 6px !important;
7656    }
7657
7658    .product-item-photo>span picture,
7659    .product-item-photo>span img {
7660        width: 100% !important;
7661        height: auto !important;
7662        display: block !important;
7663    }
7664
7665    .product-item-photo>span picture {
7666        position: static !important;
7667    }
7668</style>                    </li>
7669                                    <li class="flex flex-col">
7670                        
7671<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7672
7673    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-clark-color-blanco-y-sonoma" class="flex flex-col grow w-full">
7674        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7675            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-clark-color-blanco-y-sonoma-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-clark-color-blanco-y-sonoma-01.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Clark&#x20;color&#x20;blanco&#x20;y&#x20;sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7265.window="updateImage" loading="lazy"></picture>
7676            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7677                    </div>
7678
7679        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7680                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7681                    <strong>Clark</strong>
7682                </div>
7683            
7684            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7685                <span class="product-item-link">Aparador modelo Clark color blanco y sonoma</span>
7686            </div>
7687
7688            
7689            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7265.window="updatePrice($event.detail);">
7690                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7265" data-price-box="product-id-7265">
7691    <span
7692    x-data x-id="['product\u002Dprice\u002D7265']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7693    >
7694    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7695        <span class="price"><span class="price">149,00 €</span></span>
7696    </span>
7697    
7698                        <span class="old-price mr-1">
7699                <span class="price line-through text-gray-600">
7700                    <span class="price"><span class="price">169,00 €</span></span>
7701
7702                </span>
7703            </span>
7704        
7705    
7706    
7707    </span>
7708</div></div>
7709                            </div>
7710        </div>
7711    </a>
7712
7713
7714            <!-- <div>CATEGORIA: </div> -->
7715        <div class="product-item-variations px-4 py-2 mt-auto">
7716            <div id="variaciones-listado-7265">
7717                                    <div class="color-picker-grid-mode-clean">
7718        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7719            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7720                Colores Disponibles:
7721            </span>
7722
7723            <div class="flex flex-wrap gap-4 items-center">
7724                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-clark-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-clark-color-blanco"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-clark-color-negro" title="BLBL" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #000000;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-clark-color-negro"></div><div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
7725        </div>
7726    </div>                            </div>
7727        </div>
7728        <div class="px-4 pb-4">
7729        
7730<div class="mt-1 flex flex-col">
7731            <!-- Invitado: base price + línea VIP (si existe) -->
7732        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7733            169,00 €        </span>
7734
7735                    <div class="flex items-baseline gap-1.5">
7736                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7737                    149,00 €                </span>
7738                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7739                    Precio VIP                </span>
7740            </div>
7741
7742
7743            </div>    </div>
7744</div>
7745
7746<style>
7747    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7748    .color-picker-grid-mode-clean,
7749    .color-picker-grid-mode-clean>div {
7750        display: flex !important;
7751        flex-direction: row !important;
7752        flex-wrap: wrap !important;
7753        align-items: center !important;
7754        gap: 6px !important;
7755        padding: 0 !important;
7756        margin: 0 !important;
7757        border: none !important;
7758    }
7759
7760    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7761    /* El método renderSection imprime un span con el título, lo eliminamos */
7762    .color-picker-grid-mode-clean span.text-sm.font-bold,
7763    .color-picker-grid-mode-clean .w-32 {
7764        display: none !important;
7765    }
7766
7767    /* 3. Ajuste de las "bolitas" de color */
7768    .color-picker-grid-mode-clean .w-9.h-9 {
7769        width: 22px !important;
7770        /* Tamaño reducido ideal para rejilla */
7771        height: 22px !important;
7772        min-width: 22px !important;
7773        min-height: 22px !important;
7774        margin: 0 !important;
7775        transform: none !important;
7776        /* Evitamos que el seleccionado crezca y descuadre */
7777        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7778    }
7779
7780    /* 4. Ajuste del icono Check (V) de selección */
7781    .color-picker-grid-mode-clean svg {
7782        width: 14px !important;
7783        height: 14px !important;
7784    }
7785
7786    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7787    .product-item-variations {
7788        margin-top: 4px !important;
7789        margin-bottom: 4px !important;
7790        padding-top: 0 !important;
7791        padding-bottom: 0 !important;
7792    }
7793
7794    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7795    .color-picker-grid-mode-clean .flex-wrap {
7796        gap: 6px !important;
7797    }
7798
7799    .product-item-photo>span picture,
7800    .product-item-photo>span img {
7801        width: 100% !important;
7802        height: auto !important;
7803        display: block !important;
7804    }
7805
7806    .product-item-photo>span picture {
7807        position: static !important;
7808    }
7809</style>                    </li>
7810                                    <li class="flex flex-col">
7811                        
7812<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7813
7814    <a href="https://www.mueblesbonitos.com/salon/aparador-modelo-nevada-color-blanco-y-sonoma" class="flex flex-col grow w-full">
7815        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7816            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-nevada-color-blanco-y-sonoma-1.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-nevada-color-blanco-y-sonoma-1.jpg" width="360" height="360" alt="Aparador&#x20;modelo&#x20;Nevada&#x20;color&#x20;blanco&#x20;y&#x20;sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7266.window="updateImage" loading="lazy"></picture>
7817            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7818                    </div>
7819
7820        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7821                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7822                    <strong>Nevada</strong>
7823                </div>
7824            
7825            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7826                <span class="product-item-link">Aparador modelo Nevada color blanco y sonoma</span>
7827            </div>
7828
7829            
7830            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7266.window="updatePrice($event.detail);">
7831                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7266" data-price-box="product-id-7266">
7832    <span
7833    x-data x-id="['product\u002Dprice\u002D7266']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7834    >
7835    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7836        <span class="price"><span class="price">149,00 €</span></span>
7837    </span>
7838    
7839                        <span class="old-price mr-1">
7840                <span class="price line-through text-gray-600">
7841                    <span class="price"><span class="price">169,00 €</span></span>
7842
7843                </span>
7844            </span>
7845        
7846    
7847    
7848    </span>
7849</div></div>
7850                            </div>
7851        </div>
7852    </a>
7853
7854
7855            <!-- <div>CATEGORIA: </div> -->
7856        <div class="product-item-variations px-4 py-2 mt-auto">
7857            <div id="variaciones-listado-7266">
7858                                    <div class="color-picker-grid-mode-clean">
7859        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
7860            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
7861                Colores Disponibles:
7862            </span>
7863
7864            <div class="flex flex-wrap gap-4 items-center">
7865                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-nevada-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-nevada-color-blanco"></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-modelo-nevada-color-negro" title="BLBL" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #000000;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-modelo-nevada-color-negro"></div><div class="relative flex items-center justify-center"><div title="WHSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background: linear-gradient(135deg, #FFFFFF 50%, #E3C9A6 50%);outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
7866        </div>
7867    </div>                            </div>
7868        </div>
7869        <div class="px-4 pb-4">
7870        
7871<div class="mt-1 flex flex-col">
7872            <!-- Invitado: base price + línea VIP (si existe) -->
7873        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
7874            169,00 €        </span>
7875
7876                    <div class="flex items-baseline gap-1.5">
7877                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
7878                    149,00 €                </span>
7879                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
7880                    Precio VIP                </span>
7881            </div>
7882
7883
7884            </div>    </div>
7885</div>
7886
7887<style>
7888    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
7889    .color-picker-grid-mode-clean,
7890    .color-picker-grid-mode-clean>div {
7891        display: flex !important;
7892        flex-direction: row !important;
7893        flex-wrap: wrap !important;
7894        align-items: center !important;
7895        gap: 6px !important;
7896        padding: 0 !important;
7897        margin: 0 !important;
7898        border: none !important;
7899    }
7900
7901    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
7902    /* El método renderSection imprime un span con el título, lo eliminamos */
7903    .color-picker-grid-mode-clean span.text-sm.font-bold,
7904    .color-picker-grid-mode-clean .w-32 {
7905        display: none !important;
7906    }
7907
7908    /* 3. Ajuste de las "bolitas" de color */
7909    .color-picker-grid-mode-clean .w-9.h-9 {
7910        width: 22px !important;
7911        /* Tamaño reducido ideal para rejilla */
7912        height: 22px !important;
7913        min-width: 22px !important;
7914        min-height: 22px !important;
7915        margin: 0 !important;
7916        transform: none !important;
7917        /* Evitamos que el seleccionado crezca y descuadre */
7918        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
7919    }
7920
7921    /* 4. Ajuste del icono Check (V) de selección */
7922    .color-picker-grid-mode-clean svg {
7923        width: 14px !important;
7924        height: 14px !important;
7925    }
7926
7927    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
7928    .product-item-variations {
7929        margin-top: 4px !important;
7930        margin-bottom: 4px !important;
7931        padding-top: 0 !important;
7932        padding-bottom: 0 !important;
7933    }
7934
7935    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
7936    .color-picker-grid-mode-clean .flex-wrap {
7937        gap: 6px !important;
7938    }
7939
7940    .product-item-photo>span picture,
7941    .product-item-photo>span img {
7942        width: 100% !important;
7943        height: auto !important;
7944        display: block !important;
7945    }
7946
7947    .product-item-photo>span picture {
7948        position: static !important;
7949    }
7950</style>                    </li>
7951                                    <li class="flex flex-col">
7952                        
7953<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
7954
7955    <a href="https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-2-puertas-color-blanco" class="flex flex-col grow w-full">
7956        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
7957            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-2-puertas-color-blanco-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-2-puertas-color-blanco-01.jpg" width="360" height="360" alt="Aparador&#x20;acanalado&#x20;modelo&#x20;Logan&#x20;2&#x20;puertas&#x20;color&#x20;Blanco" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7267.window="updateImage" loading="lazy"></picture>
7958            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
7959                    </div>
7960
7961        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
7962                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
7963                    <strong>Logan</strong>
7964                </div>
7965            
7966            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
7967                <span class="product-item-link">Aparador acanalado modelo Logan 2 puertas color Blanco</span>
7968            </div>
7969
7970            
7971            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7267.window="updatePrice($event.detail);">
7972                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7267" data-price-box="product-id-7267">
7973    <span
7974    x-data x-id="['product\u002Dprice\u002D7267']"     class="price-container price-final_price&#x20;tax&#x20;weee"
7975    >
7976    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
7977        <span class="price"><span class="price">129,00 €</span></span>
7978    </span>
7979    
7980                        <span class="old-price mr-1">
7981                <span class="price line-through text-gray-600">
7982                    <span class="price"><span class="price">139,00 €</span></span>
7983
7984                </span>
7985            </span>
7986        
7987    
7988    
7989    </span>
7990</div></div>
7991                            </div>
7992        </div>
7993    </a>
7994
7995
7996            <!-- <div>CATEGORIA: </div> -->
7997        <div class="product-item-variations px-4 py-2 mt-auto">
7998            <div id="variaciones-listado-7267">
7999                                    <div class="color-picker-grid-mode-clean">
8000        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8001            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8002                Colores Disponibles:
8003            </span>
8004
8005            <div class="flex flex-wrap gap-4 items-center">
8006                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-2-puertas-color-sonoma" title="SOSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #E3C9A6;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-2-puertas-color-sonoma"></div>            </div>
8007        </div>
8008    </div>                            </div>
8009        </div>
8010        <div class="px-4 pb-4">
8011        
8012<div class="mt-1 flex flex-col">
8013            <!-- Invitado: base price + línea VIP (si existe) -->
8014        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8015            139,00 €        </span>
8016
8017                    <div class="flex items-baseline gap-1.5">
8018                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8019                    129,00 €                </span>
8020                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8021                    Precio VIP                </span>
8022            </div>
8023
8024
8025            </div>    </div>
8026</div>
8027
8028<style>
8029    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8030    .color-picker-grid-mode-clean,
8031    .color-picker-grid-mode-clean>div {
8032        display: flex !important;
8033        flex-direction: row !important;
8034        flex-wrap: wrap !important;
8035        align-items: center !important;
8036        gap: 6px !important;
8037        padding: 0 !important;
8038        margin: 0 !important;
8039        border: none !important;
8040    }
8041
8042    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8043    /* El método renderSection imprime un span con el título, lo eliminamos */
8044    .color-picker-grid-mode-clean span.text-sm.font-bold,
8045    .color-picker-grid-mode-clean .w-32 {
8046        display: none !important;
8047    }
8048
8049    /* 3. Ajuste de las "bolitas" de color */
8050    .color-picker-grid-mode-clean .w-9.h-9 {
8051        width: 22px !important;
8052        /* Tamaño reducido ideal para rejilla */
8053        height: 22px !important;
8054        min-width: 22px !important;
8055        min-height: 22px !important;
8056        margin: 0 !important;
8057        transform: none !important;
8058        /* Evitamos que el seleccionado crezca y descuadre */
8059        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8060    }
8061
8062    /* 4. Ajuste del icono Check (V) de selección */
8063    .color-picker-grid-mode-clean svg {
8064        width: 14px !important;
8065        height: 14px !important;
8066    }
8067
8068    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8069    .product-item-variations {
8070        margin-top: 4px !important;
8071        margin-bottom: 4px !important;
8072        padding-top: 0 !important;
8073        padding-bottom: 0 !important;
8074    }
8075
8076    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8077    .color-picker-grid-mode-clean .flex-wrap {
8078        gap: 6px !important;
8079    }
8080
8081    .product-item-photo>span picture,
8082    .product-item-photo>span img {
8083        width: 100% !important;
8084        height: auto !important;
8085        display: block !important;
8086    }
8087
8088    .product-item-photo>span picture {
8089        position: static !important;
8090    }
8091</style>                    </li>
8092                                    <li class="flex flex-col">
8093                        
8094<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
8095
8096    <a href="https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-2-puertas-color-sonoma" class="flex flex-col grow w-full">
8097        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
8098            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-2-puertas-color-sonoma-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-2-puertas-color-sonoma-01.jpg" width="360" height="360" alt="Aparador&#x20;acanalado&#x20;modelo&#x20;Logan&#x20;2&#x20;puertas&#x20;color&#x20;Sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7268.window="updateImage" loading="lazy"></picture>
8099            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
8100                    </div>
8101
8102        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
8103                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
8104                    <strong>Logan</strong>
8105                </div>
8106            
8107            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
8108                <span class="product-item-link">Aparador acanalado modelo Logan 2 puertas color Sonoma</span>
8109            </div>
8110
8111            
8112            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7268.window="updatePrice($event.detail);">
8113                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7268" data-price-box="product-id-7268">
8114    <span
8115    x-data x-id="['product\u002Dprice\u002D7268']"     class="price-container price-final_price&#x20;tax&#x20;weee"
8116    >
8117    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
8118        <span class="price"><span class="price">129,00 €</span></span>
8119    </span>
8120    
8121                        <span class="old-price mr-1">
8122                <span class="price line-through text-gray-600">
8123                    <span class="price"><span class="price">139,00 €</span></span>
8124
8125                </span>
8126            </span>
8127        
8128    
8129    
8130    </span>
8131</div></div>
8132                            </div>
8133        </div>
8134    </a>
8135
8136
8137            <!-- <div>CATEGORIA: </div> -->
8138        <div class="product-item-variations px-4 py-2 mt-auto">
8139            <div id="variaciones-listado-7268">
8140                                    <div class="color-picker-grid-mode-clean">
8141        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8142            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8143                Colores Disponibles:
8144            </span>
8145
8146            <div class="flex flex-wrap gap-4 items-center">
8147                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-2-puertas-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-2-puertas-color-blanco"></div><div class="relative flex items-center justify-center"><div title="SOSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #E3C9A6;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
8148        </div>
8149    </div>                            </div>
8150        </div>
8151        <div class="px-4 pb-4">
8152        
8153<div class="mt-1 flex flex-col">
8154            <!-- Invitado: base price + línea VIP (si existe) -->
8155        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8156            139,00 €        </span>
8157
8158                    <div class="flex items-baseline gap-1.5">
8159                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8160                    129,00 €                </span>
8161                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8162                    Precio VIP                </span>
8163            </div>
8164
8165
8166            </div>    </div>
8167</div>
8168
8169<style>
8170    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8171    .color-picker-grid-mode-clean,
8172    .color-picker-grid-mode-clean>div {
8173        display: flex !important;
8174        flex-direction: row !important;
8175        flex-wrap: wrap !important;
8176        align-items: center !important;
8177        gap: 6px !important;
8178        padding: 0 !important;
8179        margin: 0 !important;
8180        border: none !important;
8181    }
8182
8183    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8184    /* El método renderSection imprime un span con el título, lo eliminamos */
8185    .color-picker-grid-mode-clean span.text-sm.font-bold,
8186    .color-picker-grid-mode-clean .w-32 {
8187        display: none !important;
8188    }
8189
8190    /* 3. Ajuste de las "bolitas" de color */
8191    .color-picker-grid-mode-clean .w-9.h-9 {
8192        width: 22px !important;
8193        /* Tamaño reducido ideal para rejilla */
8194        height: 22px !important;
8195        min-width: 22px !important;
8196        min-height: 22px !important;
8197        margin: 0 !important;
8198        transform: none !important;
8199        /* Evitamos que el seleccionado crezca y descuadre */
8200        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8201    }
8202
8203    /* 4. Ajuste del icono Check (V) de selección */
8204    .color-picker-grid-mode-clean svg {
8205        width: 14px !important;
8206        height: 14px !important;
8207    }
8208
8209    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8210    .product-item-variations {
8211        margin-top: 4px !important;
8212        margin-bottom: 4px !important;
8213        padding-top: 0 !important;
8214        padding-bottom: 0 !important;
8215    }
8216
8217    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8218    .color-picker-grid-mode-clean .flex-wrap {
8219        gap: 6px !important;
8220    }
8221
8222    .product-item-photo>span picture,
8223    .product-item-photo>span img {
8224        width: 100% !important;
8225        height: auto !important;
8226        display: block !important;
8227    }
8228
8229    .product-item-photo>span picture {
8230        position: static !important;
8231    }
8232</style>                    </li>
8233                                    <li class="flex flex-col">
8234                        
8235<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
8236
8237    <a href="https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-3-puertas-color-blanco" class="flex flex-col grow w-full">
8238        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
8239            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-3-puertas-color-blanco-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-3-puertas-color-blanco-01.jpg" width="360" height="360" alt="Aparador&#x20;acanalado&#x20;modelo&#x20;Logan&#x20;3&#x20;puertas&#x20;color&#x20;Blanco" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7269.window="updateImage" loading="lazy"></picture>
8240            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
8241                    </div>
8242
8243        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
8244                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
8245                    <strong>Logan</strong>
8246                </div>
8247            
8248            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
8249                <span class="product-item-link">Aparador acanalado modelo Logan 3 puertas color Blanco</span>
8250            </div>
8251
8252            
8253            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7269.window="updatePrice($event.detail);">
8254                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7269" data-price-box="product-id-7269">
8255    <span
8256    x-data x-id="['product\u002Dprice\u002D7269']"     class="price-container price-final_price&#x20;tax&#x20;weee"
8257    >
8258    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
8259        <span class="price"><span class="price">169,00 €</span></span>
8260    </span>
8261    
8262                        <span class="old-price mr-1">
8263                <span class="price line-through text-gray-600">
8264                    <span class="price"><span class="price">189,00 €</span></span>
8265
8266                </span>
8267            </span>
8268        
8269    
8270    
8271    </span>
8272</div></div>
8273                            </div>
8274        </div>
8275    </a>
8276
8277
8278            <!-- <div>CATEGORIA: </div> -->
8279        <div class="product-item-variations px-4 py-2 mt-auto">
8280            <div id="variaciones-listado-7269">
8281                                    <div class="color-picker-grid-mode-clean">
8282        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8283            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8284                Colores Disponibles:
8285            </span>
8286
8287            <div class="flex flex-wrap gap-4 items-center">
8288                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-3-puertas-color-sonoma" title="SOSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #E3C9A6;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-3-puertas-color-sonoma"></div>            </div>
8289        </div>
8290    </div>                            </div>
8291        </div>
8292        <div class="px-4 pb-4">
8293        
8294<div class="mt-1 flex flex-col">
8295            <!-- Invitado: base price + línea VIP (si existe) -->
8296        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8297            189,00 €        </span>
8298
8299                    <div class="flex items-baseline gap-1.5">
8300                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8301                    169,00 €                </span>
8302                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8303                    Precio VIP                </span>
8304            </div>
8305
8306
8307            </div>    </div>
8308</div>
8309
8310<style>
8311    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8312    .color-picker-grid-mode-clean,
8313    .color-picker-grid-mode-clean>div {
8314        display: flex !important;
8315        flex-direction: row !important;
8316        flex-wrap: wrap !important;
8317        align-items: center !important;
8318        gap: 6px !important;
8319        padding: 0 !important;
8320        margin: 0 !important;
8321        border: none !important;
8322    }
8323
8324    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8325    /* El método renderSection imprime un span con el título, lo eliminamos */
8326    .color-picker-grid-mode-clean span.text-sm.font-bold,
8327    .color-picker-grid-mode-clean .w-32 {
8328        display: none !important;
8329    }
8330
8331    /* 3. Ajuste de las "bolitas" de color */
8332    .color-picker-grid-mode-clean .w-9.h-9 {
8333        width: 22px !important;
8334        /* Tamaño reducido ideal para rejilla */
8335        height: 22px !important;
8336        min-width: 22px !important;
8337        min-height: 22px !important;
8338        margin: 0 !important;
8339        transform: none !important;
8340        /* Evitamos que el seleccionado crezca y descuadre */
8341        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8342    }
8343
8344    /* 4. Ajuste del icono Check (V) de selección */
8345    .color-picker-grid-mode-clean svg {
8346        width: 14px !important;
8347        height: 14px !important;
8348    }
8349
8350    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8351    .product-item-variations {
8352        margin-top: 4px !important;
8353        margin-bottom: 4px !important;
8354        padding-top: 0 !important;
8355        padding-bottom: 0 !important;
8356    }
8357
8358    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8359    .color-picker-grid-mode-clean .flex-wrap {
8360        gap: 6px !important;
8361    }
8362
8363    .product-item-photo>span picture,
8364    .product-item-photo>span img {
8365        width: 100% !important;
8366        height: auto !important;
8367        display: block !important;
8368    }
8369
8370    .product-item-photo>span picture {
8371        position: static !important;
8372    }
8373</style>                    </li>
8374                                    <li class="flex flex-col">
8375                        
8376<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
8377
8378    <a href="https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-3-puertas-color-sonoma" class="flex flex-col grow w-full">
8379        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
8380            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-3-puertas-color-sonoma-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-3-puertas-color-sonoma-01.jpg" width="360" height="360" alt="Aparador&#x20;acanalado&#x20;modelo&#x20;Logan&#x20;3&#x20;puertas&#x20;color&#x20;Sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7270.window="updateImage" loading="lazy"></picture>
8381            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
8382                    </div>
8383
8384        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
8385                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
8386                    <strong>Logan</strong>
8387                </div>
8388            
8389            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
8390                <span class="product-item-link">Aparador acanalado modelo Logan 3 puertas color Sonoma</span>
8391            </div>
8392
8393            
8394            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7270.window="updatePrice($event.detail);">
8395                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7270" data-price-box="product-id-7270">
8396    <span
8397    x-data x-id="['product\u002Dprice\u002D7270']"     class="price-container price-final_price&#x20;tax&#x20;weee"
8398    >
8399    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
8400        <span class="price"><span class="price">169,00 €</span></span>
8401    </span>
8402    
8403                        <span class="old-price mr-1">
8404                <span class="price line-through text-gray-600">
8405                    <span class="price"><span class="price">189,00 €</span></span>
8406
8407                </span>
8408            </span>
8409        
8410    
8411    
8412    </span>
8413</div></div>
8414                            </div>
8415        </div>
8416    </a>
8417
8418
8419            <!-- <div>CATEGORIA: </div> -->
8420        <div class="product-item-variations px-4 py-2 mt-auto">
8421            <div id="variaciones-listado-7270">
8422                                    <div class="color-picker-grid-mode-clean">
8423        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8424            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8425                Colores Disponibles:
8426            </span>
8427
8428            <div class="flex flex-wrap gap-4 items-center">
8429                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-3-puertas-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-acanalado-modelo-logan-3-puertas-color-blanco"></div><div class="relative flex items-center justify-center"><div title="SOSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #E3C9A6;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
8430        </div>
8431    </div>                            </div>
8432        </div>
8433        <div class="px-4 pb-4">
8434        
8435<div class="mt-1 flex flex-col">
8436            <!-- Invitado: base price + línea VIP (si existe) -->
8437        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8438            189,00 €        </span>
8439
8440                    <div class="flex items-baseline gap-1.5">
8441                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8442                    169,00 €                </span>
8443                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8444                    Precio VIP                </span>
8445            </div>
8446
8447
8448            </div>    </div>
8449</div>
8450
8451<style>
8452    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8453    .color-picker-grid-mode-clean,
8454    .color-picker-grid-mode-clean>div {
8455        display: flex !important;
8456        flex-direction: row !important;
8457        flex-wrap: wrap !important;
8458        align-items: center !important;
8459        gap: 6px !important;
8460        padding: 0 !important;
8461        margin: 0 !important;
8462        border: none !important;
8463    }
8464
8465    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8466    /* El método renderSection imprime un span con el título, lo eliminamos */
8467    .color-picker-grid-mode-clean span.text-sm.font-bold,
8468    .color-picker-grid-mode-clean .w-32 {
8469        display: none !important;
8470    }
8471
8472    /* 3. Ajuste de las "bolitas" de color */
8473    .color-picker-grid-mode-clean .w-9.h-9 {
8474        width: 22px !important;
8475        /* Tamaño reducido ideal para rejilla */
8476        height: 22px !important;
8477        min-width: 22px !important;
8478        min-height: 22px !important;
8479        margin: 0 !important;
8480        transform: none !important;
8481        /* Evitamos que el seleccionado crezca y descuadre */
8482        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8483    }
8484
8485    /* 4. Ajuste del icono Check (V) de selección */
8486    .color-picker-grid-mode-clean svg {
8487        width: 14px !important;
8488        height: 14px !important;
8489    }
8490
8491    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8492    .product-item-variations {
8493        margin-top: 4px !important;
8494        margin-bottom: 4px !important;
8495        padding-top: 0 !important;
8496        padding-bottom: 0 !important;
8497    }
8498
8499    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8500    .color-picker-grid-mode-clean .flex-wrap {
8501        gap: 6px !important;
8502    }
8503
8504    .product-item-photo>span picture,
8505    .product-item-photo>span img {
8506        width: 100% !important;
8507        height: auto !important;
8508        display: block !important;
8509    }
8510
8511    .product-item-photo>span picture {
8512        position: static !important;
8513    }
8514</style>                    </li>
8515                                    <li class="flex flex-col">
8516                        
8517<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
8518
8519    <a href="https://www.mueblesbonitos.com/salon/mueble-tv-acanalado-modelo-logan-color-blanco" class="flex flex-col grow w-full">
8520        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
8521            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-acanalado-modelo-logan-color-blanco-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-acanalado-modelo-logan-color-blanco-01.jpg" width="360" height="360" alt="Mueble&#x20;TV&#x20;acanalado&#x20;modelo&#x20;Logan&#x20;color&#x20;Blanco&#x0D;&#x0A;" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7271.window="updateImage" loading="lazy"></picture>
8522            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
8523                    </div>
8524
8525        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
8526                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
8527                    <strong>Logan</strong>
8528                </div>
8529            
8530            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
8531                <span class="product-item-link">Mueble TV acanalado modelo Logan color Blanco</span>
8532            </div>
8533
8534            
8535            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7271.window="updatePrice($event.detail);">
8536                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7271" data-price-box="product-id-7271">
8537    <span
8538    x-data x-id="['product\u002Dprice\u002D7271']"     class="price-container price-final_price&#x20;tax&#x20;weee"
8539    >
8540    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
8541        <span class="price"><span class="price">109,00 €</span></span>
8542    </span>
8543    
8544                        <span class="old-price mr-1">
8545                <span class="price line-through text-gray-600">
8546                    <span class="price"><span class="price">119,00 €</span></span>
8547
8548                </span>
8549            </span>
8550        
8551    
8552    
8553    </span>
8554</div></div>
8555                            </div>
8556        </div>
8557    </a>
8558
8559
8560            <!-- <div>CATEGORIA: </div> -->
8561        <div class="product-item-variations px-4 py-2 mt-auto">
8562            <div id="variaciones-listado-7271">
8563                                    <div class="color-picker-grid-mode-clean">
8564        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8565            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8566                Colores Disponibles:
8567            </span>
8568
8569            <div class="flex flex-wrap gap-4 items-center">
8570                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mueble-tv-acanalado-modelo-logan-color-sonoma" title="SOSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #E3C9A6;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mueble-tv-acanalado-modelo-logan-color-sonoma"></div>            </div>
8571        </div>
8572    </div>                            </div>
8573        </div>
8574        <div class="px-4 pb-4">
8575        
8576<div class="mt-1 flex flex-col">
8577            <!-- Invitado: base price + línea VIP (si existe) -->
8578        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8579            119,00 €        </span>
8580
8581                    <div class="flex items-baseline gap-1.5">
8582                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8583                    109,00 €                </span>
8584                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8585                    Precio VIP                </span>
8586            </div>
8587
8588
8589            </div>    </div>
8590</div>
8591
8592<style>
8593    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8594    .color-picker-grid-mode-clean,
8595    .color-picker-grid-mode-clean>div {
8596        display: flex !important;
8597        flex-direction: row !important;
8598        flex-wrap: wrap !important;
8599        align-items: center !important;
8600        gap: 6px !important;
8601        padding: 0 !important;
8602        margin: 0 !important;
8603        border: none !important;
8604    }
8605
8606    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8607    /* El método renderSection imprime un span con el título, lo eliminamos */
8608    .color-picker-grid-mode-clean span.text-sm.font-bold,
8609    .color-picker-grid-mode-clean .w-32 {
8610        display: none !important;
8611    }
8612
8613    /* 3. Ajuste de las "bolitas" de color */
8614    .color-picker-grid-mode-clean .w-9.h-9 {
8615        width: 22px !important;
8616        /* Tamaño reducido ideal para rejilla */
8617        height: 22px !important;
8618        min-width: 22px !important;
8619        min-height: 22px !important;
8620        margin: 0 !important;
8621        transform: none !important;
8622        /* Evitamos que el seleccionado crezca y descuadre */
8623        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8624    }
8625
8626    /* 4. Ajuste del icono Check (V) de selección */
8627    .color-picker-grid-mode-clean svg {
8628        width: 14px !important;
8629        height: 14px !important;
8630    }
8631
8632    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8633    .product-item-variations {
8634        margin-top: 4px !important;
8635        margin-bottom: 4px !important;
8636        padding-top: 0 !important;
8637        padding-bottom: 0 !important;
8638    }
8639
8640    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8641    .color-picker-grid-mode-clean .flex-wrap {
8642        gap: 6px !important;
8643    }
8644
8645    .product-item-photo>span picture,
8646    .product-item-photo>span img {
8647        width: 100% !important;
8648        height: auto !important;
8649        display: block !important;
8650    }
8651
8652    .product-item-photo>span picture {
8653        position: static !important;
8654    }
8655</style>                    </li>
8656                                    <li class="flex flex-col">
8657                        
8658<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
8659
8660    <a href="https://www.mueblesbonitos.com/salon/mueble-tv-acanalado-modelo-logan-color-sonoma" class="flex flex-col grow w-full">
8661        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
8662            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-acanalado-modelo-logan-color-sonoma-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-acanalado-modelo-logan-color-sonoma-01.jpg" width="360" height="360" alt="Mueble&#x20;TV&#x20;acanalado&#x20;modelo&#x20;Logan&#x20;color&#x20;Sonoma" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7272.window="updateImage" loading="lazy"></picture>
8663            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
8664                    </div>
8665
8666        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
8667                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
8668                    <strong>Logan</strong>
8669                </div>
8670            
8671            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
8672                <span class="product-item-link">Mueble TV acanalado modelo Logan color Sonoma</span>
8673            </div>
8674
8675            
8676            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7272.window="updatePrice($event.detail);">
8677                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7272" data-price-box="product-id-7272">
8678    <span
8679    x-data x-id="['product\u002Dprice\u002D7272']"     class="price-container price-final_price&#x20;tax&#x20;weee"
8680    >
8681    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
8682        <span class="price"><span class="price">109,00 €</span></span>
8683    </span>
8684    
8685                        <span class="old-price mr-1">
8686                <span class="price line-through text-gray-600">
8687                    <span class="price"><span class="price">119,00 €</span></span>
8688
8689                </span>
8690            </span>
8691        
8692    
8693    
8694    </span>
8695</div></div>
8696                            </div>
8697        </div>
8698    </a>
8699
8700
8701            <!-- <div>CATEGORIA: </div> -->
8702        <div class="product-item-variations px-4 py-2 mt-auto">
8703            <div id="variaciones-listado-7272">
8704                                    <div class="color-picker-grid-mode-clean">
8705        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8706            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8707                Colores Disponibles:
8708            </span>
8709
8710            <div class="flex flex-wrap gap-4 items-center">
8711                <div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/mueble-tv-acanalado-modelo-logan-color-blanco" title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/mueble-tv-acanalado-modelo-logan-color-blanco"></div><div class="relative flex items-center justify-center"><div title="SOSO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #E3C9A6;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #FFF" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div>            </div>
8712        </div>
8713    </div>                            </div>
8714        </div>
8715        <div class="px-4 pb-4">
8716        
8717<div class="mt-1 flex flex-col">
8718            <!-- Invitado: base price + línea VIP (si existe) -->
8719        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8720            119,00 €        </span>
8721
8722                    <div class="flex items-baseline gap-1.5">
8723                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8724                    109,00 €                </span>
8725                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8726                    Precio VIP                </span>
8727            </div>
8728
8729
8730            </div>    </div>
8731</div>
8732
8733<style>
8734    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8735    .color-picker-grid-mode-clean,
8736    .color-picker-grid-mode-clean>div {
8737        display: flex !important;
8738        flex-direction: row !important;
8739        flex-wrap: wrap !important;
8740        align-items: center !important;
8741        gap: 6px !important;
8742        padding: 0 !important;
8743        margin: 0 !important;
8744        border: none !important;
8745    }
8746
8747    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8748    /* El método renderSection imprime un span con el título, lo eliminamos */
8749    .color-picker-grid-mode-clean span.text-sm.font-bold,
8750    .color-picker-grid-mode-clean .w-32 {
8751        display: none !important;
8752    }
8753
8754    /* 3. Ajuste de las "bolitas" de color */
8755    .color-picker-grid-mode-clean .w-9.h-9 {
8756        width: 22px !important;
8757        /* Tamaño reducido ideal para rejilla */
8758        height: 22px !important;
8759        min-width: 22px !important;
8760        min-height: 22px !important;
8761        margin: 0 !important;
8762        transform: none !important;
8763        /* Evitamos que el seleccionado crezca y descuadre */
8764        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8765    }
8766
8767    /* 4. Ajuste del icono Check (V) de selección */
8768    .color-picker-grid-mode-clean svg {
8769        width: 14px !important;
8770        height: 14px !important;
8771    }
8772
8773    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8774    .product-item-variations {
8775        margin-top: 4px !important;
8776        margin-bottom: 4px !important;
8777        padding-top: 0 !important;
8778        padding-bottom: 0 !important;
8779    }
8780
8781    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8782    .color-picker-grid-mode-clean .flex-wrap {
8783        gap: 6px !important;
8784    }
8785
8786    .product-item-photo>span picture,
8787    .product-item-photo>span img {
8788        width: 100% !important;
8789        height: auto !important;
8790        display: block !important;
8791    }
8792
8793    .product-item-photo>span picture {
8794        position: static !important;
8795    }
8796</style>                    </li>
8797                                    <li class="flex flex-col">
8798                        
8799<div class="item product product-item product_addtocart_form card card-interactive flex flex-col w-full grow border border-gray-100 shadow-sm hover:shadow-md transition-shadow duration-300 bg-white rounded-md overflow-hidden">
8800
8801    <a href="https://www.mueblesbonitos.com/salon/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-blanco" class="flex flex-col grow w-full">
8802        <div class="product photo product-item-photo w-full relative overflow-hidden z-0" tabindex="-1">
8803            <picture class="product-image-photo"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-blanco-01.webp"><img src="https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-blanco-01.jpg" width="360" height="360" alt="&#x2028;Aparador&#x20;Acanalado&#x20;Renzo&#x20;M&#x20;de&#x20;1&#x20;Puerta&#x20;y&#x20;Cajonera&#x20;-&#x20;Blanco" class="product-image-photo" loading="lazy" x-data="initProductItemImage" @update-gallery-7273.window="updateImage" loading="lazy"></picture>
8804            <!-- BLOQUE DEL DESCUENTO BADGE SUPERPUESTO -->
8805                    </div>
8806
8807        <div class="product-info flex flex-col grow p-4 pb-0 text-left">
8808                            <div class="mt-2 mb-1 text-primary font-semibold text-xl">
8809                    <strong>Renzo</strong>
8810                </div>
8811            
8812            <div class="mt-1 mb-1 text-primary text-texto font-semibold leading-tight">
8813                <span class="product-item-link">
Aparador Acanalado Renzo M de 1 Puerta y Cajonera - Blanco</span>
8814            </div>
8815
8816            
8817            <div class="pt-2 flex justify-start items-center" x-data="initPriceBox()" x-defer="intersect" @update-prices-7273.window="updatePrice($event.detail);">
8818                <div><div class="price-box price-final_price" data-role="priceBox" data-product-id="7273" data-price-box="product-id-7273">
8819    <span
8820    x-data x-id="['product\u002Dprice\u002D7273']"     class="price-container price-final_price&#x20;tax&#x20;weee"
8821    >
8822    <span class="price-wrapper text-3xl text-gray-900 font-semibold">
8823        <span class="price"><span class="price">139,00 €</span></span>
8824    </span>
8825    
8826                        <span class="old-price mr-1">
8827                <span class="price line-through text-gray-600">
8828                    <span class="price"><span class="price">149,00 €</span></span>
8829
8830                </span>
8831            </span>
8832        
8833    
8834    
8835    </span>
8836</div></div>
8837                            </div>
8838        </div>
8839    </a>
8840
8841
8842            <!-- <div>CATEGORIA: </div> -->
8843        <div class="product-item-variations px-4 py-2 mt-auto">
8844            <div id="variaciones-listado-7273">
8845                                    <div class="color-picker-grid-mode-clean">
8846        <div class="flex flex-col md:flex-row md:items-center py-4 border-b border-gray-100 last:border-0">
8847            <span class="text-xl font-bold text-gray-800 md:w-auto md:min-w-max mr-4 whitespace-nowrap mb-2 md:mb-0">
8848                Colores Disponibles:
8849            </span>
8850
8851            <div class="flex flex-wrap gap-4 items-center">
8852                <div class="relative flex items-center justify-center"><div title="WHWH" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #FFFFFF;outline: 2px solid #000; outline-offset: 2px; transform: scale(1.15); z-index: 10;"><svg class="w-5 h-5 drop-shadow-md" style="color: #000" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M5 13l4 4L19 7"></path></svg></div></div><div class="relative flex items-center justify-center"><a href="https://www.mueblesbonitos.com/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-roble-alba" title="LOLO" class="w-9 h-9 rounded-full shadow-sm transition-all duration-200 flex items-center justify-center" style="background-color: #ce9f75;border: 1px solid #e5e7eb;"></a href="https://www.mueblesbonitos.com/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-roble-alba"></div>            </div>
8853        </div>
8854    </div>                            </div>
8855        </div>
8856        <div class="px-4 pb-4">
8857        
8858<div class="mt-1 flex flex-col">
8859            <!-- Invitado: base price + línea VIP (si existe) -->
8860        <span class="text-base md:text-base font-semibold text-gray-400 leading-tight">
8861            149,00 €        </span>
8862
8863                    <div class="flex items-baseline gap-1.5">
8864                <span class="text-3xl  md:text-3xl font-bold leading-tight" style="color: #34515E;">
8865                    139,00 €                </span>
8866                <span class="text-[11px] md:text-xs font-semibold" style="color: #8cc4b2;">
8867                    Precio VIP                </span>
8868            </div>
8869
8870
8871            </div>    </div>
8872</div>
8873
8874<style>
8875    /* 1. Contenedor principal: Alineación horizontal y sin espacios extra */
8876    .color-picker-grid-mode-clean,
8877    .color-picker-grid-mode-clean>div {
8878        display: flex !important;
8879        flex-direction: row !important;
8880        flex-wrap: wrap !important;
8881        align-items: center !important;
8882        gap: 6px !important;
8883        padding: 0 !important;
8884        margin: 0 !important;
8885        border: none !important;
8886    }
8887
8888    /* 2. Ocultar el texto "Colores:" (o Couleurs, Colori, etc.) */
8889    /* El método renderSection imprime un span con el título, lo eliminamos */
8890    .color-picker-grid-mode-clean span.text-sm.font-bold,
8891    .color-picker-grid-mode-clean .w-32 {
8892        display: none !important;
8893    }
8894
8895    /* 3. Ajuste de las "bolitas" de color */
8896    .color-picker-grid-mode-clean .w-9.h-9 {
8897        width: 22px !important;
8898        /* Tamaño reducido ideal para rejilla */
8899        height: 22px !important;
8900        min-width: 22px !important;
8901        min-height: 22px !important;
8902        margin: 0 !important;
8903        transform: none !important;
8904        /* Evitamos que el seleccionado crezca y descuadre */
8905        box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);
8906    }
8907
8908    /* 4. Ajuste del icono Check (V) de selección */
8909    .color-picker-grid-mode-clean svg {
8910        width: 14px !important;
8911        height: 14px !important;
8912    }
8913
8914    /* 5. Aseguramos que el contenedor de variaciones no empuje el precio */
8915    .product-item-variations {
8916        margin-top: 4px !important;
8917        margin-bottom: 4px !important;
8918        padding-top: 0 !important;
8919        padding-bottom: 0 !important;
8920    }
8921
8922    /* 6. Espaciado interno de los grupos (por si acaso el helper mete gaps) */
8923    .color-picker-grid-mode-clean .flex-wrap {
8924        gap: 6px !important;
8925    }
8926
8927    .product-item-photo>span picture,
8928    .product-item-photo>span img {
8929        width: 100% !important;
8930        height: auto !important;
8931        display: block !important;
8932    }
8933
8934    .product-item-photo>span picture {
8935        position: static !important;
8936    }
8937</style>                    </li>
8938                            </ul>
8939        </div>
8940        
8940<script>
8941    function initToolbar_6ac74549b01a6() {
8942        return {
8943            options: {"productListToolbarForm":{"mode":"product_list_mode","direction":"product_list_dir","order":"product_list_order","limit":"product_list_limit","modeDefault":"grid","directionDefault":"asc","orderDefault":"position","limitDefault":36,"url":"https:\/\/www.mueblesbonitos.com\/salon","formKey":"GoQ6wnK4Gflfjncs","post":false,"page":"p"}}.productListToolbarForm || {},
8944            getUrlParams: function () {
8945                let decode = window.decodeURIComponent,
8946                    urlPaths = this.options.url.split('?'),
8947                    urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],
8948                    params = {},
8949                    parameters, i;
8950
8951                for (i = 0; i < urlParams.length; i++) {
8952                    parameters = urlParams[i].split('=');
8953                    params[decode(parameters[0])] = parameters[1] !== undefined ?
8954                        decode(parameters[1].replace(/\+/g, '%20')) :
8955                        '';
8956                }
8957
8958                return params;
8959            },
8960            getCurrentLimit: function () {
8961                return this.getUrlParams()[this.options.limit] || this.options.limitDefault;
8962            },
8963            getCurrentPage: function () {
8964                return this.getUrlParams()[this.options.page] || 1;
8965            },
8966            changeUrl(paramName, paramValue, defaultValue) {
8967                let urlPaths = this.options.url.split('?'),
8968                    baseUrl = urlPaths[0],
8969                    paramData = this.getUrlParams(),
8970                    currentPage = this.getCurrentPage(),
8971                    newPage;
8972
8973                /**
8974                 * calculates the page on which the first item of the current page will
8975                 * be with the new limit and sets that number as the new page
8976                 */
8977                if (currentPage > 1 && paramName === this.options.limit) {
8978                    newPage = Math.floor(this.getCurrentLimit() * (currentPage - 1) / paramValue) + 1;
8979
8980                    if (newPage > 1) {
8981                        paramData[this.options.page] = newPage;
8982                    } else {
8983                        delete paramData[this.options.page];
8984                    }
8985                }
8986
8987                paramData[paramName] = paramValue;
8988
8989                if (this.options.post) {
8990                    hyva.postForm({action: baseUrl, data: paramData, skipUenc: true});
8991                } else {
8992                    if (paramValue === defaultValue.toString()) {
8993                        delete paramData[paramName];
8994                    }
8995                    paramData = Object.keys(paramData).length === 0
8996                        ? ''
8997                        : '?' + (new URLSearchParams(paramData));
8998                    location.href = baseUrl + paramData
8999                }
9000            }
9001        }
9002    }
9003</script>
9003
9004    <div x-data="initToolbar_6ac74549b01a6()"
9005         class="toolbar toolbar-products grid grid-cols-4 sm:grid-cols-8 md:grid-cols-4
9006            lg:grid-cols-8  grid-flow-row gap-2 items-center">
9007                    <p class="toolbar-amount text-sm leading-5 text-gray-700 order-3 sm:order-2 md:order-3
9008    lg:order-2 col-span-2 gap-x-1" id="toolbar-amount">
9009            Productos <span class="toolbar-number">1</span>-<span class="toolbar-number">36</span> of <span class="toolbar-number">377</span>    </p>
9010            
9011    
9012    
9013    <div class="flex justify-center order-2 col-span-4">
9014                    <nav class="inline-flex items-center pages" aria-label="pagination">
9015                <ol class="relative z-0 inline-flex shadow-sm items pages-items">
9016                    <li class="item pages-item-previous">
9017                                                                            <a
9018                                role="link"
9019                                class="previous relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 rounded-l-md px-3 py-2 text-gray-400
9020                                 border-gray-200"
9021                                aria-disabled="true"
9022                                aria-label="Anterior"
9023                            >
9024                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="20" height="20" aria-hidden="true">
9025  <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/>
9026</svg>
9027                            </a>
9028                                            </li>
9029
9030                    
9031                    
9032                                                                        <li class="item -ml-px">
9033                                <a
9034                                    href="https://www.mueblesbonitos.com/salon"
9035                                    class="page relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 transition duration-150 ease-in-out hover:text-gray-400 focus:z-10 focus:outline-none focus:border-primary-lighter focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 z-10 px-4 py-2 text-gray-700 bg-gray-100 border-primary"
9036                                    aria-current="page"
9037                                >
9038                                    <span class="sr-only label">
9039                                        You&#039;re currently reading page                                    </span>
9040                                    1                                </a>
9041                            </li>
9042                                                                                                <li class="item -ml-px">
9043                                <a
9044                                    href="https://www.mueblesbonitos.com/salon?p=2"
9045                                    class="page relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 transition duration-150 ease-in-out hover:text-gray-400 focus:z-10 focus:outline-none focus:border-primary-lighter focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 px-4 py-2 text-gray-700"
9046                                >
9047                                    <span class="sr-only label">Page</span>
9048                                    <span>2</span>
9049                                </a>
9050                            </li>
9051                                                                                                <li class="item -ml-px">
9052                                <a
9053                                    href="https://www.mueblesbonitos.com/salon?p=3"
9054                                    class="page relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 transition duration-150 ease-in-out hover:text-gray-400 focus:z-10 focus:outline-none focus:border-primary-lighter focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 px-4 py-2 text-gray-700"
9055                                >
9056                                    <span class="sr-only label">Page</span>
9057                                    <span>3</span>
9058                                </a>
9059                            </li>
9060                                                                                                <li class="item -ml-px">
9061                                <a
9062                                    href="https://www.mueblesbonitos.com/salon?p=4"
9063                                    class="page relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 transition duration-150 ease-in-out hover:text-gray-400 focus:z-10 focus:outline-none focus:border-primary-lighter focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 px-4 py-2 text-gray-700"
9064                                >
9065                                    <span class="sr-only label">Page</span>
9066                                    <span>4</span>
9067                                </a>
9068                            </li>
9069                                                                                                <li class="item -ml-px">
9070                                <a
9071                                    href="https://www.mueblesbonitos.com/salon?p=5"
9072                                    class="page relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 transition duration-150 ease-in-out hover:text-gray-400 focus:z-10 focus:outline-none focus:border-primary-lighter focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 px-4 py-2 text-gray-700"
9073                                >
9074                                    <span class="sr-only label">Page</span>
9075                                    <span>5</span>
9076                                </a>
9077                            </li>
9078                                            
9079                    
9080                    
9081                    <li class="item pages-item-next -ml-px">
9082                                                                                <a
9083                                href="https://www.mueblesbonitos.com/salon?p=2"
9084                                class="action  next relative inline-flex items-center text-sm font-medium leading-5 bg-white border border-gray-300 transition duration-150 ease-in-out hover:text-gray-400 focus:z-10 focus:outline-none focus:border-primary-lighter focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 rounded-r-md px-3 py-2 text-gray-500"
9085                                                                    aria-label="Siguiente"
9086                                                            >
9087                                                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="20" height="20" aria-hidden="true">
9088  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
9089</svg>
9090                                                            </a>
9091                                            </li>
9092                </ol>
9093            </nav>
9094            </div>
9095
9096    
9097    
9098            
9099    <div class="field limiter flex items-center order-3 sm:order-2 md:order-3 lg:order-2 col-span-2 justify-end">
9100        <div class="control">
9101            <label class="text-sm label">
9102                <span class="mr-2" aria-label="Mostrar&#x20;elementos&#x20;por&#x20;p&#xE1;gina">
9103                    Mostrar                </span>
9104                <select
9105                    class="form-select limiter-options"
9106                    @change="changeUrl(
9107                        'product_list_limit',
9108                        $event.currentTarget.options[$event.currentTarget.selectedIndex].value,
9109                        options.limitDefault
9110                    )"
9111                >
9112                                    <option value="12"
9113                        >
9114                        12                    </option>
9115                                    <option value="24"
9116                        >
9117                        24                    </option>
9118                                    <option value="36"
9119                                                    selected="selected"
9120                        >
9121                        36                    </option>
9122                                </select>
9123            </label>
9124        </div>
9125    </div>
9126            </div>
9127    </section>
9128
9129                <div data-retailrocket-markup-block="REPLACE_ID" data-category-id="37" style="padding: 0px 25px;"></div>
9130        
9130<script type="text/javascript">
9131            (window["rrApiOnReady"] = window["rrApiOnReady"] || []).push(function() {
9132                try {
9133                    rrApi.categoryView(37);
9134                } catch (e) {}
9135            })
9136        </script>
9136
9137    
9138        
9138<script type="application/ld+json" id="carrusel_OK">
9139        {
9140            "@context": "https://schema.org/",
9141            "numberOfItems": "36",
9142            "@type": "ItemList",
9143            "itemListOrder": "Relevance",
9144            "itemListElement": [{"@type":"ListItem","position":1,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-blanco-y-sonoma-140-cm-ani","name":"Mesa alta Blanco y Sonoma 140 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-ani-140cm-branca-e-sonoma_1.jpg"},{"@type":"ListItem","position":2,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-kyra-110cm-color-blanco-y-sonoma","name":"Mesa alta Kyra  (110cm) color blanco y sonoma","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-kyra-110cm-cor-branca-e-sonoma.jpg"},{"@type":"ListItem","position":3,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-kyra-110cm-color-blanco","name":"Mesa alta Kyra  (110cm) color blanco","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-kyra-110cm-branca.jpg"},{"@type":"ListItem","position":4,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-110-cm-kyra","name":"Mesa alta Negro y Sonoma 110 cm Kyra","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-110-cm-kyra-03.jpg"},{"@type":"ListItem","position":5,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-140-cm-ani","name":"Mesa alta Negro y Sonoma 140 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-preto-sonoma-140-cm-ani_2.jpg"},{"@type":"ListItem","position":6,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-blanco-y-sonoma-120-cm-ani","name":"Mesa alta Blanco y Sonoma 120 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-120-cm-ani-01_4.jpg"},{"@type":"ListItem","position":7,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-120-cm-ani","name":"Mesa alta Negro y Sonoma 120 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-120-cm-ani-01_1.jpg"},{"@type":"ListItem","position":8,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-blanco-y-sonoma-100-cm-ani","name":"Mesa alta Blanco y Sonoma 100 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-100-cm-ani-01.jpg"},{"@type":"ListItem","position":9,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-negro-y-sonoma-100-cm-ani","name":"Mesa alta Negro y Sonoma 100 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-negro-sonoma-100-cm-ani-01_1.jpg"},{"@type":"ListItem","position":10,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-140-cm-ani","name":"Mesa alta con 2 Taburetes Blanco y Sonoma 140 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-140-cm-ani-01.jpg"},{"@type":"ListItem","position":11,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-140-cm-ani","name":"Mesa alta con 2 Taburetes Negro y Sonoma 140 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-140-cm-ani-01.jpg"},{"@type":"ListItem","position":12,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-120-cm-ani","name":"Mesa alta con 2 Taburetes Blanco y Sonoma 120 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-blanco-sonoma-120-cm-ani-01_3.jpg"},{"@type":"ListItem","position":13,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-120-cm-ani","name":"Mesa alta con 2 Taburetes Negro y Sonoma 120 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-120-cm-ani-01.jpg"},{"@type":"ListItem","position":14,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-100-cm-ani","name":"Mesa alta con 2 Taburetes Blanco y Sonoma 100 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-100-cm-ani-01.jpg"},{"@type":"ListItem","position":15,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-100-cm-ani","name":"Mesa alta con 2 Taburetes Negro y Sonoma 100 cm Ani","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-100-cm-ani-01_1.jpg"},{"@type":"ListItem","position":16,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-110-cm-kyra","name":"Mesa alta con 2 Taburetes Blanco 110 cm Kyra","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-blanco-110-cm-kyra-01_1.jpg"},{"@type":"ListItem","position":17,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-blanco-y-sonoma-110-cm-kyra","name":"Mesa alta con 2 Taburetes Blanco y Sonoma 110 cm Kyra","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-blanco-sonoma-110-cm-kyra-01.jpg"},{"@type":"ListItem","position":18,"url":"https://www.mueblesbonitos.com/salon/mesa-alta-con-2-taburetes-negro-y-sonoma-110-cm-kyra","name":"Mesa alta con 2 Taburetes Negro y Sonoma 110 cm Kyra","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/e/mesa-alta-con-2-taburetes-negro-sonoma-110-cm-04_1.jpg"},{"@type":"ListItem","position":19,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-iris-color-roble","name":"Aparador modelo Iris color Roble","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-iris-color-roble-1.jpg"},{"@type":"ListItem","position":20,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-iris-color-blanco","name":"Aparador modelo Iris color Blanco","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-iris-color-blanco-1.jpg"},{"@type":"ListItem","position":21,"url":"https://www.mueblesbonitos.com/salon/mueble-tv-color-roble-alba-150cm-renzo","name":"Mueble TV color roble alba 150cm Renzo","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-color-roble-alba-150cm-renzo-01.jpg"},{"@type":"ListItem","position":22,"url":"https://www.mueblesbonitos.com/salon/aparador-blanco-y-sonoma-moderno-150-cm-serena","name":"Aparador Blanco y Sonoma Moderno 150 cm Serena","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-color-blanco-y-sonoma-150-cm-serena-01.jpg"},{"@type":"ListItem","position":23,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-leo-color-blanco-mate","name":"Aparador modelo Leo color Blanco mate","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-leo-color-blanco-mate-09.jpg"},{"@type":"ListItem","position":24,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-leo-color-roble-eos","name":"Aparador modelo Leo color Roble Eos","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-leo-color-roble-eos-mate-05.jpg"},{"@type":"ListItem","position":25,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-duna-color-roble-eos","name":"Aparador modelo Duna color Roble Eos","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-duna-color-roble-eos-01.jpg"},{"@type":"ListItem","position":26,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-vega-color-blanco-mate","name":"Aparador modelo Vega color Blanco mate","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-vega-color-blanco-mate-1.jpg"},{"@type":"ListItem","position":27,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-vega-color-roble-alba","
9144name":"Aparador modelo Vega color Roble Alba","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-vega-color-roble-alba-01_1_1.jpg"},{"@type":"ListItem","position":28,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-clark-color-blanco-y-sonoma","name":"Aparador modelo Clark color blanco y sonoma","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-clark-color-blanco-y-sonoma-01.jpg"},{"@type":"ListItem","position":29,"url":"https://www.mueblesbonitos.com/salon/aparador-modelo-nevada-color-blanco-y-sonoma","name":"Aparador modelo Nevada color blanco y sonoma","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-modelo-nevada-color-blanco-y-sonoma-1.jpg"},{"@type":"ListItem","position":30,"url":"https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-2-puertas-color-blanco","name":"Aparador acanalado modelo Logan 2 puertas color Blanco","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-2-puertas-color-blanco-01.jpg"},{"@type":"ListItem","position":31,"url":"https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-2-puertas-color-sonoma","name":"Aparador acanalado modelo Logan 2 puertas color Sonoma","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-2-puertas-color-sonoma-01.jpg"},{"@type":"ListItem","position":32,"url":"https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-3-puertas-color-blanco","name":"Aparador acanalado modelo Logan 3 puertas color Blanco","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-3-puertas-color-blanco-01.jpg"},{"@type":"ListItem","position":33,"url":"https://www.mueblesbonitos.com/salon/aparador-acanalado-modelo-logan-3-puertas-color-sonoma","name":"Aparador acanalado modelo Logan 3 puertas color Sonoma","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-modelo-logan-3-puertas-color-sonoma-01.jpg"},{"@type":"ListItem","position":34,"url":"https://www.mueblesbonitos.com/salon/mueble-tv-acanalado-modelo-logan-color-blanco","name":"Mueble TV acanalado modelo Logan color Blanco","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-acanalado-modelo-logan-color-blanco-01.jpg"},{"@type":"ListItem","position":35,"url":"https://www.mueblesbonitos.com/salon/mueble-tv-acanalado-modelo-logan-color-sonoma","name":"Mueble TV acanalado modelo Logan color Sonoma","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/m/u/mueble-tv-acanalado-modelo-logan-color-sonoma-01.jpg"},{"@type":"ListItem","position":36,"url":"https://www.mueblesbonitos.com/salon/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-blanco","name":"\u2028Aparador Acanalado Renzo M de 1 Puerta y Cajonera - Blanco","image":"https://www.mueblesbonitos.com/media/catalog/product/cache/67ee89799642c567a71fc92f3699d937/a/p/aparador-acanalado-renzo-m-de-1-puerta-y-cajonera-blanco-01.jpg"}]        }
9145    </script>
9145
9146
9147                <div class="w-full px-4 py-6 custom-category-description-block">
9148            <style>
9149                .custom-category-description-block,
9150                .catdesc-content,
9151                .catdesc-content * {
9152                    font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
9153                }
9154
9155                /* Forzamos visibilidad completa para SEO */
9156                .catdesc-content {
9157                    display: block !important;
9158                    height: auto !important;
9159                    max-height: none !important;
9160                    overflow: visible !important;
9161                    color: #374151;
9162                    line-height: 1.625;
9163                }
9164
9165                /* Limpieza de estilos de Page Builder para ancho completo */
9166                .catdesc-content [data-appearance="contained"],
9167                .catdesc-content [data-element="inner"],
9168                .catdesc-content [data-content-type="row"] {
9169                    max-width: none !important;
9170                    width: 100% !important;
9171                    margin: 0 !important;
9172                    padding: 0 !important;
9173                }
9174
9175                .catdesc-content {
9176                    width: 100% !important;
9177                    max-width: none !important;
9178                }
9179            </style>
9180
9181            <div class="catdesc-wrap relative mt-3 w-full">
9182                <div class="catdesc-content prose max-w-none w-full">
9183                        <div class="category-description">
9184                            <div data-content-type="html" data-appearance="default" data-element="main" data-decoded="true"><h2>Muebles de Salón Modernos y Económicos</h2>
9185<p>Los <strong>muebles de salón modernos</strong> definen el espacio más utilizado del hogar: el lugar donde se descansa, se recibe a los invitados y se convive en familia. En Muebles Bonitos, con más de 15 años de experiencia y exposición en Alicante (visita con cita previa), encontrarás desde muebles TV y aparadores hasta composiciones modulares completas — todos con <strong>3 años de garantía oficial</strong>, <strong>envío gratuito a Península y Baleares</strong> y entrega en <strong>1-3 días hábiles</strong> (Express <strong>24h</strong> disponible). Para envíos a Canarias, Ceuta y Melilla se aplican gastos por tramos.</p>
9186
9187<p>Gracias a la venta directa de fábrica, ofrecemos <strong>conjuntos de salón comedor modernos</strong> con acabados de alta calidad a precios competitivos. La mayoría de nuestros modelos son <strong>modulares</strong>, lo que permite configurar el espacio a medida y adaptarlo a las necesidades cambiantes del hogar. Desde composiciones compactas para pisos pequeños hasta grandes conjuntos que aprovechan toda la pared, el catálogo cubre todos los formatos. Muchos modelos incorporan además <strong>iluminación LED integrada</strong>, un detalle que añade profundidad y ambiente al conjunto sin necesidad de puntos de luz adicionales.</p>
9188
9189<h3>Muebles esenciales para el salón: guía rápida</h3>
9190<p>El salón es la estancia más versátil del hogar. Antes de elegir, es útil tener claro qué piezas necesitas y qué función cumple cada una:</p>
9191
9192<table>
9193<thead>
9194<tr>
9195<th>Tipo de mueble</th>
9196<th>Función principal</th>
9197<th>Ideal para...</th>
9198</tr>
9199</thead>
9200<tbody>
9201<tr>
9202<td><strong>Mueble TV</strong></td>
9203<td>Soporte del televisor y centro de entretenimiento.</td>
9204<td>Organizar la zona de sofás y ocultar el cableado.</td>
9205</tr>
9206<tr>
9207<td><strong>Aparador</strong></td>
9208<td>Almacenaje de vajilla, mantelería y objetos del día a día.</td>
9209<td>Comedores y zonas de paso, con superficie decorativa.</td>
9210</tr>
9211<tr>
9212<td><strong>Vitrina</strong></td>
9213<td>Exposición de vajillas, colecciones y decoración.</td>
9214<td>Salones que buscan combinar almacenaje y exhibición.</td>
9215</tr>
9216<tr>
9217<td><strong>Mesa de centro</strong></td>
9218<td>Superficie de apoyo junto al sofá.</td>
9219<td>Organizar la zona de estar con funcionalidad y estilo.</td>
9220</tr>
9221<tr>
9222<td><strong>Estantería</strong></td>
9223<td>Almacenaje abierto para libros, plantas y decoración.</td>
9224<td>Aprovechar la altura de las paredes y estructurar el espacio.</td>
9225</tr>
9226<tr>
9227<td><strong>Mueble con chimenea</strong></td>
9228<td>Elemento decorativo con chimenea eléctrica integrada.</td>
9229<td>Salones que buscan calidez y un punto focal diferenciador.</td>
9230</tr>
9231</tbody>
9232</table>
9233
9234<h3>Estilos de salón: encuentra tu decoración ideal</h3>
9235<p>En Muebles Bonitos el catálogo responde a los estilos más demandados actualmente. El acabado en <strong>blanco mate o blanco brillo</strong> — nuestra línea Premium — es el más solicitado para salones luminosos y contemporáneos: aporta limpieza visual y hace que los espacios parezcan más amplios. El <strong>roble y el sonoma</strong> encajan a la perfección con estilos nórdicos o naturales, aportando calidez y textura orgánica. Los modelos en <strong>negro</strong> son la opción ideal para quienes buscan un contraste elegante y sofisticado. Y las combinaciones bicolor — por ejemplo blanco con roble — permiten composiciones más ricas visualmente sin perder coherencia estética.</p>
9236<p>La modularidad es otro de los grandes valores del catálogo. Los <strong>muebles de salón modulares</strong> permiten empezar con una composición básica e ir ampliándola con el tiempo: añadir una vitrina lateral, incorporar un armario colgante o completar la pared con estanterías a medida que cambian las necesidades del hogar.</p>
9237
9238<h3>Cómo distribuir los muebles del salón</h3>
9239<p>Una buena distribución mejora tanto la funcionalidad como la sensación de amplitud. Desde Muebles Bonitos recomendamos tener en cuenta estas proporciones básicas: deja al menos <strong>90 cm de paso libre</strong> entre muebles para garantizar la circulación cómoda. El sofá debería estar a entre <strong>150 y 250 cm del mueble TV</strong>, en función del tamaño de la pantalla. En salones rectangulares, colocar el mueble TV en la pared más corta y el sofá frente a él aprovecha mejor el espacio. Para salones pequeños, los muebles con patas o suspendidos liberan el suelo visualmente y aportan sensación de amplitud.</p>
9240
9241<h3>¿Por qué elegir los muebles de salón de Muebles Bonitos?</h3>
9242<p>En Muebles Bonitos trabajamos con venta directa de fábrica, lo que nos permite ofrecer <strong>muebles de salón baratos</strong> sin comprometer la calidad. Todos los productos pasan controles de fabricación rigurosos y están respaldados por <strong>3 años de garantía oficial</strong>. El proceso de compra es sencillo y seguro: elige tu modelo, realiza el pedido online y recíbelo en casa en <strong>1-3 días hábiles</strong> — el 95% de los pedidos llega en menos de 48 horas. Si necesitas verlo antes de comprar, puedes visitar nuestra exposición en Alicante con cita previa o contactarnos a través del chat online.</p>
9243
9244<h3>Preguntas frecuentes sobre muebles de salón</h3>
9245
9246<h4>¿Qué muebles son imprescindibles en un salón?</h4>
9247<p>Los muebles esenciales de un salón son el <strong>mueble TV</strong> como eje central de la zona de entretenimiento, el <strong>sofá</strong> y una <strong>mesa de centro</strong> para la zona de estar. A partir de ahí, un <strong>aparador</strong> aporta almacenaje y superficie decorativa, y una <strong>estantería</strong> permite organizar libros y objetos. En Muebles Bonitos encontrarás todos estos elementos en cole
9247cciones coordinadas, lo que facilita conseguir un resultado coherente sin necesidad de combinar estilos distintos.</p>
9248
9249<h4>¿Cómo amueblar un salón comedor pequeño?</h4>
9250<p>Para salones pequeños, desde Muebles Bonitos recomendamos priorizar muebles con doble función: una <strong>mesa de centro elevable</strong> que sirva también como mesa de comedor, un <strong>mueble TV suspendido</strong> que libere el suelo, y un <strong>aparador estrecho colgante</strong> en lugar de uno voluminoso apoyado. Los acabados en <strong>blanco o tonos claros</strong> reflejan la luz y amplían visualmente el espacio. Evita saturar las paredes y deja al menos un rincón libre para que el ojo descanse.</p>
9251
9252<h4>¿Cómo combinar los muebles del salón?</h4>
9253<p>La clave es elegir una colección coordinada o respetar una misma gama de acabados. En Muebles Bonitos los muebles de salón están disponibles en acabados como <strong>blanco mate, blanco brillo, negro, roble y sonoma</strong>, pensados para combinarse entre sí. Una regla sencilla: elige un acabado dominante para las piezas grandes (mueble TV, aparador) y complementa con un segundo tono en las piezas más pequeñas (mesa de centro, estantería).</p>
9254
9255<h4>¿Cuánto tarda en llegar un pedido de muebles de salón?</h4>
9256<p>Los pedidos con destino a <strong>Península y Baleares</strong> se entregan en <strong>1-3 días hábiles</strong>
9256, y el 95% llega en menos de 48 horas. Si necesitas recibirlo antes, el <strong>servicio Express de Muebles Bonitos</strong> garantiza la entrega en <strong>24h</strong>. La entrega se realiza a pie de calle. Para envíos a Canarias, Ceuta y Melilla el plazo puede ser superior.</p>
9257
9258<h4>¿El envío es gratuito a toda España?</h4>
9259<p>El envío es gratuito para pedidos con destino a <strong>Península y Baleares</strong>. Para envíos a <strong>Canarias, Ceuta y Melilla</strong> se aplican gastos de transporte por tramos según el valor de la mercancía, más los costes de despacho de aduanas (IGIC/IPSI) que se abonan al recibir el pedido.</p>
9260
9261<h4>¿Qué métodos de pago están disponibles?</h4>
9262<p>En Muebles Bonitos puedes pagar con <strong>tarjeta bancaria</strong> (Visa/Mastercard), <strong>Bizum</strong>, <strong>PayPal</strong>, <strong>Apple Pay</strong>, <strong>Google Pay</strong>, <strong>transferencia bancaria</strong> o <strong>contrarreembolso</strong> (con coste de gestión). Si prefieres fraccionar el importe, <strong>Klarna</strong> permite dividir la compra en 3 cuotas sin intereses, pagar a los 30 días o financiar a largo plazo.</p>
9263
9264<h4>¿Los muebles de salón tienen garantía?</h4>
9265<p>Sí. Todos los muebles de salón de Muebles Bonitos incluyen <strong>3 años de garantía oficial</strong>, cubriendo defectos de fabricación y materiales conforme a la normativa vigente en España. Dispones además de <strong>60 días naturales</strong> desde la recepción para solicitar una devolución, sin necesidad de justificar tu decisión. <a href="/garantias_y_devoluciones" rel="nofollow" target="_blank" style="text-decoration: underline;">Más información sobre garantías y devoluciones</a>.</p>
9266
9267<h3>Explora otras categorías de muebles de diseño para tu hogar:</h3>
9268<ul>
9269  <li>Organiza la zona de paso desde la entrada con nuestros <a href="https://www.mueblesbonitos.com/recibidores">Recibidores</a>.</li>
9270  <li>Harmoniza la decoración de tu hogar hasta la zona de descanso con la sección de <a href="https://www.mueblesbonitos.com/dormitorio">Dormitorios</a>.</li>
9271  <li>Completa la línea estilística de tu vivienda descubriendo nuestras opciones de <a href="https://www.mueblesbonitos.com/bano">Muebles de Baño</a>.</li>
9272  <li>Optimiza el espacio con piezas funcionales y versátiles de la gama <a href="https://www.mueblesbonitos.com/decoracion-y-auxiliares">Muebles Auxiliares</a>.</li>
9273</ul>
9274
9275<script type="application/ld+json">
9276{
9277  "@context": "https://schema.org",
9278  "@type": "FAQPage",
9279  "mainEntity": [
9280    {
9281      "@type": "Question",
9282      "name": "¿Qué muebles son imprescindibles en un salón?",
9283      "acceptedAnswer": {
9284        "@type": "Answer",
9285        "text": "Los muebles esenciales de un salón son el mueble TV como eje central de la zona de entretenimiento, el sofá y una mesa de centro para la zona de estar. A partir de ahí, un aparador aporta almacenaje y superficie decorativa, y una estantería permite organizar libros y objetos. En Muebles Bonitos encontrarás todos estos elementos en colecciones coordinadas, lo que facilita conseguir un resultado coherente sin necesidad de combinar estilos distintos."
9286      }
9287    },
9288    {
9289      "@type": "Question",
9290      "name": "¿Cómo amueblar un salón comedor pequeño?",
9291      "acceptedAnswer": {
9292        "@type": "Answer",
9293        "text": "Para salones pequeños, desde Muebles Bonitos recomendamos priorizar muebles con doble función: una mesa de centro elevable que sirva también como mesa de comedor, un mueble TV suspendido que libere el suelo, y un aparador estrecho colgante en lugar de uno voluminoso apoyado. Los acabados en blanco o tonos claros reflejan la luz y amplían visualmente el espacio."
9294      }
9295    },
9296    {
9297      "@type": "Question",
9298      "name": "¿Cómo combinar los muebles del salón?",
9299      "acceptedAnswer": {
9300        "@type": "Answer",
9301        "text": "La clave es elegir una colección coordinada o respetar una misma gama de acabados. En Muebles Bonitos los muebles de salón están disponibles en acabados como blanco mate, blanco brillo, negro, roble y sonoma, pensados para combinarse entre sí. Una regla sencilla: elige un acabado dominante para las piezas grandes (mueble TV, aparador) y complementa con un segundo tono en las piezas más pequeñas (mesa de centro, estantería)."
9302      }
9303    },
9304    {
9305      "@type": "Question",
9306      "name": "¿Cuánto tarda en llegar un pedido de muebles de salón?",
9307      "acceptedAnswer": {
9308        "@type": "Answer",
9309        "text": "Los pedidos con destino a Península y Baleares se entregan en 1-3 días hábiles, y el 95% llega en menos de 48 horas. Si necesitas re
9309cibirlo antes, el servicio Express de Muebles Bonitos garantiza la entrega en 24h. La entrega se realiza a pie de calle. Para envíos a Canarias, Ceuta y Melilla el plazo puede ser superior."
9310      }
9311    },
9312    {
9313      "@type": "Question",
9314      "name": "¿El envío es gratuito a toda España?",
9315      "acceptedAnswer": {
9316        "@type": "Answer",
9317        "text": "El envío es gratuito para pedidos con destino a Península y Baleares. Para envíos a Canarias, Ceuta y Melilla se aplican gastos de transporte por tramos según el valor de la mercancía, más los costes de despacho de aduanas (IGIC/IPSI) que se abonan al recibir el pedido."
9318      }
9319    },
9320    {
9321      "@type": "Question",
9322      "name": "¿Qué métodos de pago están disponibles?",
9323      "acceptedAnswer": {
9324        "@type": "Answer",
9325        "text": "En Muebles Bonitos puedes pagar con tarjeta bancaria (Visa/Mastercard), Bizum, PayPal, Apple Pay, Google Pay, transferencia bancaria o contrarreembolso (con coste de gestión). Si prefieres fraccionar el importe, Klarna permite dividir la compra en 3 cuotas sin intereses, pagar a los 30 días o financiar a largo plazo."
9326      }
9327    },
9328    {
9329      "@type": "Question",
9330      "name": "¿Los muebles de salón tienen garantía?",
9331      "acceptedAnswer": {
9332        "@type": "Answer",
9333        "text": "Sí. Todos los muebles de salón de Muebles Bonitos incluyen 3 años de garantía oficial, cubriendo defectos de fabricación y materiales conforme a la normativa vigente en España. Dispones además de 60 días naturales desde la recepción para solicitar una devolución, sin necesidad de justificar tu decisión."
9334      }
9335    }
9336  ]
9337}
9338</script>
9338</div>            </div>
9339                </div>
9340            </div>
9341        </div>
9342    
9343</div>
9344<script type="text/x-magento-init">
9345    {
9346        ".sidebar #narrow-by-list": {
9347            "accordion": {
9348                "multipleCollapsible": true,
9349                "active": []
9350            }
9351        }
9352    }
9353</script>
9353
9354
9355<script type="text/x-magento-init">
9356    {
9357        ".products-grid, .products-list": {
9358            "amShopbySwatchesChoose": {
9359                "listSwatches": []            }
9360        }
9361    }
9362</script>
9362
9363
9364<script type="text/x-magento-init">
9365    {
9366        "#narrow-by-list": {
9367            "amShopbyFiltersSync": {
9368            }
9369        }
9370    }
9371</script>
9371
9372
9373 
9373<script nonce="NHloMjlxYjRvd29oc2pwMTVtZWtkbWl2eW5peXJnb2Y=">
9374    function hasWebP() {
9375        var elem = document.createElement('canvas');
9376
9377        if (!!(elem.getContext && elem.getContext('2d'))) {
9378            return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;
9379        }
9380        return false;
9381    }
9382
9383    if (hasWebP()) {
9384        document.body.classList.add("webp");
9385    } else {
9386        document.body.classList.add("no-webp");
9387    }</script>
9387<script></script>
9387<div class="amshopby-filters-bottom-cms">
9388    </div>
9389
9390<div data-am-js="js-init">
9391    
9391<script type="text/x-magento-init">
9392        {
9393            "[data-am-js='filter-item-default']": {
9394                "amShopbyFilterItemDefault": {
9395                    "collectFilters": 0,
9396                    "clearUrl": "https://www.mueblesbonitos.com/salon"
9397                }
9398            },
9399            "*": {
9400                "amShopbyResponsive": {}
9401            }
9402        }
9403    </script>
9403
9404
9405    </div>
9406</div></div></main><footer class="page-footer"><div class="footer content">
9407
9408<div class="bg-zinc-100 border-t border-zinc-200">
9409    <div class="container py-8 mx-auto">
9410        <div class="grid grid-cols-1 lg:grid-cols-4 lg:gap-6 text-slate-600">
9411                            
9412<!-- desactivado por Santi -->
9413<!-- <nav aria-label="Shop">
9414    <ul>
9415        <li>
9416            <a
9417                href="https://www.mueblesbonitos.com/home/"
9418                class="block py-1.5 hover:underline"
9419            >What&#039;s new</a>
9420        </li>
9421        <li>
9422            <a
9423                href="https://www.mueblesbonitos.com/home/"
9424                class="block py-1.5 hover:underline"
9425            >Women</a>
9426        </li>
9427        <li>
9428            <a
9429                href="https://www.mueblesbonitos.com/home/"
9430                class="block py-1.5 hover:underline"
9431            >Men</a>
9432        </li>
9433        <li>
9434            <a
9435                href="https://www.mueblesbonitos.com/home/"
9436                class="block py-1.5 hover:underline"
9437            >Gear</a>
9438        </li>
9439        <li>
9440            <a
9441                href="https://www.mueblesbonitos.com/home/"
9442                class="block py-1.5 hover:underline"
9443            >Training</a>
9444        </li>
9445        <li>
9446            <a
9447                href="https://www.mueblesbonitos.com/home/"
9448                class="block py-1.5 hover:underline"
9449            >Sale</a>
9450        </li>
9451    </ul>
9452</nav> -->
9453                                                        
9454    <div
9455        x-data="mobileFooterCollpase"
9456        x-bind="eventListeners"
9457        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
9458        data-open="true"
9459    >
9460        <div
9461            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
9462            data-id="footer_column_1"
9463            x-bind="setToggleRoles"
9464            @click="toggle"
9465            @keyup.enter="toggle"
9466            @keyup.space="toggle"
9467        >
9468            <span>Aviso legal</span>
9469            <span
9470                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
9471                x-ref="toggleIcon"
9472            >
9473                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
9474  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
9475</svg>
9476            </span>
9477        </div>
9478        <div
9479            id="footer_column_1"
9480            class="aria-[hidden=true]:hidden"
9481            x-bind="setCollapseRoles"
9482        >
9483            <div class="pt-0.5 pb-2.5">
9484                
9485<li class="nav item mb-2 last:mb-0">
9486    <a href="https://www.mueblesbonitos.com/garantias_y_devoluciones"
9487              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9488              "
9489    >
9490        Garantías y devoluciones    </a>
9491</li>
9492<li class="nav item mb-2 last:mb-0">
9493    <a href="https://www.mueblesbonitos.com/condiciones-legales"
9494              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9495              "
9496    >
9497        Condiciones legales    </a>
9498</li>
9499<li class="nav item mb-2 last:mb-0">
9500    <a href="https://www.mueblesbonitos.com/privacidad"
9501              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9502              "
9503    >
9504        Política de privacidad    </a>
9505</li>
9506<li class="nav item mb-2 last:mb-0">
9507    <a href="https://www.mueblesbonitos.com/cookies-mb"
9508              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9509              "
9510    >
9511        Política de cookies    </a>
9512</li>            </div>
9513        </div>
9514    </div>
9515                            
9516    <div
9517        x-data="mobileFooterCollpase"
9518        x-bind="eventListeners"
9519        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
9520        data-open="false"
9521    >
9522        <div
9523            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
9524            data-id="footer_column_2"
9525            x-bind="setToggleRoles"
9526            @click="toggle"
9527            @keyup.enter="toggle"
9528            @keyup.space="toggle"
9529        >
9530            <span>Porqué comprar aquí</span>
9531            <span
9532                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
9533                x-ref="toggleIcon"
9534            >
9535                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
9536  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
9537</svg>
9538            </span>
9539        </div>
9540        <div
9541            id="footer_column_2"
9542            class="aria-[hidden=true]:hidden"
9543            x-bind="setCollapseRoles"
9544        >
9545            <div class="pt-0.5 pb-2.5">
9546                
9547<li class="nav item mb-2 last:mb-0">
9548    <a href="https://www.mueblesbonitos.com/comprar_es_muy_facil"
9549              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9550              "
9551    >
9552        Comprar es muy fácil    </a>
9553</li>
9554<li class="nav item mb-2 last:mb-0">
9555    <a href="https://www.mueblesbonitos.com/como-pagar"
9556              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9557              "
9558    >
9559        Formas de pago    </a>
9560</li>
9561<li class="nav item mb-2 last:mb-0">
9562    <a href="https://www.mueblesbonitos.com/envios-muebles-bonitos"
9563              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9564              "
9565    >
9566        Envío gratuito    </a>
9567</li>
9568<li class="nav item mb-2 last:mb-0">
9569    <a href="https://www.mueblesbonitos.com/concurso"
9570              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9571              "
9572    >
9573        Consigue un 10% de descuento    </a>
9574</li>
9575<li class="nav item mb-2 last:mb-0">
9576    <a href="https://www.mueblesbonitos.com/black-friday-muebles"
9577              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9578              "
9579    >
9580        Black Friday muebles    </a>
9581</li>            </div>
9582        </div>
9583    </div>
9584                            
9585    <div
9586        x-data="mobileFooterCollpase"
9587        x-bind="eventListeners"
9588        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
9589        data-open="false"
9590    >
9591        <div
9592            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
9593            data-id="footer_column_3"
9594            x-bind="setToggleRoles"
9595            @click="toggle"
9596            @keyup.enter="toggle"
9597            @keyup.space="toggle"
9598        >
9599            <span>Quiénes somos</span>
9600            <span
9601                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
9602                x-ref="toggleIcon"
9603            >
9604                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
9605  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
9606</svg>
9607            </span>
9608        </div>
9609        <div
9610            id="footer_column_3"
9611            class="aria-[hidden=true]:hidden"
9612            x-bind="setCollapseRoles"
9613        >
9614            <div class="pt-0.5 pb-2.5">
9615                
9616<li class="nav item mb-2 last:mb-0">
9617    <a href="https://www.mueblesbonitos.com/quienes-somos"
9618              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9619              "
9620    >
9621        Quiénes somos/contactar    </a>
9622</li>
9623<li class="nav item mb-2 last:mb-0">
9624    <a href="https://www.mueblesbonitos.com/customers"
9625                  rel="nofollow"
9626              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9627              "
9628    >
9629        Comunicar una incidencia    </a>
9630</li>
9631<li class="nav item mb-2 last:mb-0">
9632    <a href="https://www.mueblesbonitos.com/preguntas-frecuentes"
9633              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dar
9633k:hover:text-blue-400
9634              "
9635    >
9636        Preguntas frecuentes    </a>
9637</li>
9638<li class="nav item mb-2 last:mb-0">
9639    <a href="https://www.mueblesbonitos.com/consejos-utiles"
9640              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9641              "
9642    >
9643        Consejos útiles    </a>
9644</li>
9645<li class="nav item mb-2 last:mb-0">
9646    <a href="https://www.mueblesbonitos.com/reviews_mb"
9647              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9648              "
9649    >
9650        Opiniones de clientes    </a>
9651</li>
9652<li class="nav item mb-2 last:mb-0">
9653    <a href="https://www.mueblesbonitos.com/mapa-del-sitio"
9654              class="text-gray-600 dark:text-gray-500 hover:text-blue-600 dark:hover:text-blue-400
9655              "
9656    >
9657        Mapa del sitio    </a>
9658</li>            </div>
9659        </div>
9660    </div>
9661                            
9662    <div
9663        x-data="mobileFooterCollpase"
9664        x-bind="eventListeners"
9665        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
9666        data-open="false"
9667    >
9668        <div
9669            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
9670            data-id="footer_column_4"
9671            x-bind="setToggleRoles"
9672            @click="toggle"
9673            @keyup.enter="toggle"
9674            @keyup.space="toggle"
9675        >
9676            <span>Mi cuenta</span>
9677            <span
9678                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
9679                x-ref="toggleIcon"
9680            >
9681                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
9682  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
9683</svg>
9684            </span>
9685        </div>
9686        <div
9687            id="footer_column_4"
9688            class="aria-[hidden=true]:hidden"
9689            x-bind="setCollapseRoles"
9690        >
9691            <div class="pt-0.5 pb-2.5">
9692                <!-- BLOCK footer.customer.menu -->
9693    
9694<script>
9695    document.addEventListener('DOMContentLoaded', () => {
9696        document.getElementById('customer.footer.sign.in.link').addEventListener('click', () => {
9697            if (hyva.setCookie) {
9698                hyva.setCookie(
9699                    'login_redirect',
9700                    window.location.href,
9701                    1
9702                );
9703            }
9704        });
9705    });
9706</script>
9706
9707<a
9708    id="customer.footer.sign.in.link"
9709    class="block py-1.5 hover:underline"
9710    rel="nofollow"
9711    onclick="hyva.setCookie && hyva.setCookie(
9712        'login_redirect',
9713        window.location.href,
9714        1
9715    )"
9716    href="https://www.mueblesbonitos.com/customer/account/index/"
9717>
9718    Iniciar Sesión</a>
9719
9720    <a
9721        class="block py-1.5 hover:underline"
9722        rel="nofollow"
9723        href="https://www.mueblesbonitos.com/customer/account/create/"
9724    >Crear una Cuenta</a>
9725<!-- /BLOCK footer.customer.menu -->            </div>
9726        </div>
9727    </div>
9728                                                                            </div>
9729    </div>
9730            <div class="space-y-10 bg-zinc-50 py-4">
9731            
9732<div
9733    class="container flex gap-4 flex-wrap justify-center"
9734    aria-label="Payment Providers">
9735        <!--  -->
9736    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_7)"><path fill="#d9dff7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#1434cb" d="M19.108 10.212 14.243 21.82H11.07l-2.393-9.263c-.146-.57-.272-.78-.714-1.02-.722-.391-1.913-.759-2.962-.987l.071-.337h5.109c.651 0 1.237.434 1.385 1.184l1.264 6.715 3.124-7.9zm12.435 7.817c.013-3.063-4.236-3.232-4.206-4.6.009-.417.405-.86 1.273-.973.43-.056 1.616-.099 2.96.52l.527-2.461A8.1 8.1 0 0 0 29.29 10c-2.968 0-5.056 1.578-5.074 3.837-.019 1.67 1.491 2.603 2.629 3.158 1.17.569 1.563.934 1.558 1.443-.008.778-.933 1.122-1.798 1.135-1.509.024-2.385-.408-3.083-.733l-.544 2.543c.702.322 1.997.603 3.339.617 3.154 0 5.218-1.558 5.227-3.97m7.837 3.79h2.777l-2.424-11.607H37.17c-.577 0-1.063.336-1.278.852L31.387 21.82h3.152l.626-1.734h3.852zm-3.35-4.113 1.58-4.358.91 4.358zm-12.632-7.494L20.915 21.82h-3.002l2.483-11.607z"/></g><defs><clipPath id="a_7"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>visa</title></svg>
9737    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_8)"><path fill="#f1efeb" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#ff5f00" d="M28.376 8.139h-8.75v15.725h8.75z"/><path fill="#eb001b" d="M20.181 16a9.98 9.98 0 0 1 3.82-7.861A9.96 9.96 0 0 0 17.82 6c-5.522 0-10 4.478-10 10s4.478 10 10 10A9.96 9.96 0 0 0 24 23.861 9.98 9.98 0 0 1 20.182 16"/><path fill="#f79e1b" d="M40.178 16c0 5.522-4.477 10-10 10-2.333 0-4.477-.8-6.18-2.139A9.98 9.98 0 0 0 27.818 16a9.98 9.98 0 0 0-3.82-7.861A9.96 9.96 0 0 1 30.178 6c5.522 0 10 4.478 10 10"/></g><defs><clipPath id="a_8"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>mastercard</title></svg>
9738    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_9)"><path fill="#d6edff" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#000" d="M43 10.5v9.523h-2.167V10.5zm-2.965 3.214v6.327H38.11v-.546a2.6 2.6 0 0 1-.83.546q-.465.201-1.006.203-.679 0-1.259-.253a3.2 3.2 0 0 1-1.006-.72 3.5 3.5 0 0 1-.682-1.06 3.7 3.7 0 0 1-.238-1.33q-.001-.708.238-1.313.252-.619.682-1.076a3 3 0 0 1 1.006-.708 3 3 0 0 1 1.26-.267q.539 0 1.006.203.466.19.83.545v-.545h1.925zm-3.414 4.604q.592.001.97-.407.39-.404.39-1.035c0-.42-.13-.769-.39-1.036a1.27 1.27 0 0 0-.97-.406c-.391 0-.722.134-.983.406q-.377.405-.377 1.036c0 .42.127.769.377 1.035q.391.406.983.407M29.996 10.5q.857 0 1.462.24.604.24 1.02.67.428.444.668 1.013.239.57.238 1.227.001.657-.238 1.227c-.157.377-.383.72-.667 1.013q-.415.43-1.021.67-.604.24-1.462.24h-1.044v3.238h-2.205V10.5zm-.316 4.34c.296 0 .519-.03.681-.09q.254-.103.415-.253.34-.316.34-.847t-.34-.847a1.2 1.2 0 0 0-.415-.24q-.239-.101-.681-.102h-.731v2.378zm-11.055-1.126h2.393l1.624 3.034h.027l1.447-3.034h2.216l-4.748 9.538h-2.205l2.167-4.363zm-.427 0v6.327h-1.926v-.546a2.6 2.6 0 0 1-.83.546q-.466.201-1.006.203-.679 0-1.259-.253a3.2 3.2 0 0 1-1.006-.72 3.6 3.6 0 0 1-.682-1.06 3.7 3.7 0 0 1-.238-1.33q0-.708.238-1.313.251-.619.682-1.076a3 3 0 0 1 1.006-.708 3 3 0 0 1 1.26-.267q.539 0 1.006.203.467.19.83.545v-.545h1.925zm-3.414 4.604q.591.001.972-.407.392-.404.392-1.035c0-.42-.13
9738-.769-.392-1.036a1.27 1.27 0 0 0-.972-.406q-.591-.001-.983.406-.378.405-.377 1.036c0 .42.128.769.377 1.035q.392.406.983.407M8.25 10.5q.857 0 1.462.24.604.24 1.02.67.428.444.668 1.013.239.57.238 1.227.001.657-.238 1.227c-.156.377-.383.72-.667 1.013q-.415.43-1.021.67-.604.24-1.462.24H7.205v3.238H5V10.5zm-.313 4.34c.295 0 .519-.03.681-.09a1.3 1.3 0 0 0 .415-.253q.34-.316.34-.847t-.34-.847a1.2 1.2 0 0 0-.415-.24q-.24-.101-.681-.102h-.731v2.378z"/></g><defs><clipPath id="a_9"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>paypal</title></svg>
9739    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_10)"><path fill="#fff1f7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#000" d="M39.478 18.825c-.884 0-1.572-.724-1.572-1.603 0-.88.688-1.603 1.572-1.603s1.573.724 1.573 1.603c0 .88-.69 1.603-1.573 1.603m-.442 1.694c.754 0 1.716-.284 2.249-1.396l.052.025c-.234.608-.234.97-.234 1.06v.143H43v-6.258h-1.897v.142c0 .09 0 .453.233 1.06l-.051.026c-.533-1.112-1.495-1.396-2.249-1.396-1.806 0-3.08 1.422-3.08 3.297s1.274 3.297 3.08 3.297m-6.38-6.594c-.858 0-1.534.297-2.08 1.396l-.052-.026c.234-.607.234-.97.234-1.06v-.142H28.86v6.258h1.95v-3.297c0-.866.507-1.41 1.325-1.41.82 0 1.222.466 1.222 1.397v3.31h1.95v-3.982c0-1.423-1.118-2.444-2.652-2.444M26.04 15.32l-.052-.026c.234-.607.234-.97.234-1.06v-.142h-1.897v6.258h1.95l.012-3.013c0-.879.468-1.41 1.235-1.41.208 0 .377.027.572.078v-1.913c-.858-.181-1.625.142-2.054 1.228m-6.199 3.504c-.883 0-1.572-.724-1.572-1.603 0-.88.689-1.603 1.572-1.603s1.573.724 1.573 1.603c0 .88-.689 1.603-1.5
973973 1.603M19.4 20.52c.754 0 1.716-.284 2.249-1.396l.052.025c-.234.608-.234.97-.234 1.06v.143h1.897v-6.258h-1.897v.142c0 .09 0 .453.234 1.06l-.052.026c-.533-1.112-1.495-1.396-2.248-1.396-1.807 0-3.08 1.422-3.08 3.297s1.273 3.297 3.08 3.297m-5.796-.168h1.95V11.3h-1.95zm-1.43-9.051h-1.988c0 1.616-1 3.064-2.52 4.099l-.599.414V11.3H5v9.05h2.066v-4.486l3.418 4.487h2.521l-3.288-4.293c1.495-1.073 2.47-2.74 2.457-4.758"/></g><defs><clipPath id="a_10"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>klarna</title></svg>
9740    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_11)"><path fill="#e6e6e6" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#000" d="M13.422 11.356a2.62 2.62 0 0 0 .604-1.856 2.6 2.6 0 0 0-1.718.88 2.47 2.47 0 0 0-.615 1.793 2.12 2.12 0 0 0 1.729-.817m.605.944c-.955-.063-1.761.541-2.217.541s-1.157-.509-1.91-.498a2.81 2.81 0 0 0-2.397 1.453c-1.06 1.76-.265 4.38.732 5.823.488.71 1.06 1.496 1.835 1.464s1.008-.467 1.888-.467 1.146.467 1.91.456c.763-.01 1.293-.71 1.781-1.421a6.4 6.4 0 0 0 .796-1.644 2.57 2.57 0 0 1-1.549-2.344 2.61 2.61 0 0 1 1.252-2.207 2.73 2.73 0 0 0-2.121-1.156m8.305-1.983a3.34 3.34 0 0 1 3.51 3.51 3.393 3.393 0 0 1-3.563 3.48h-2.291v3.648h-1.666V10.317zm-2.344 5.643h1.92a2.005 2.005 0 0 0 2.259-2.122 1.983 1.983 0 0 0-2.249-2.121h-1.91zm6.29 2.821c0-1.358 1.06-2.196 2.895-2.302l2.122-.127v-.594c0-.87-.584-1.39-1.56-1.39a1.485 1.485 0 0 0-1.644 1.146h-1.506c.096-1.39 1.294-2.45 3.214-2.45s3.097 1.008 3.097 2.567v5.367H31.37v-1.283a2.76 2.76 0 0 1-2.46 1.41 2.364 2.364 0 0 1-2.631-2.344m5.027-.7v-.615l-1.92.116c-.954.064-1.495.488-1.495 1.157 0 .668.562 1.124 1.421 1.124a1.87 1.87 0 0 0 1.994-1.782m3.033 5.781V22.61q.26.024.52 0a1.305 1.305 0 0 0 1.39-1.06l.137-.478-2.81-7.86h1.728l1.973 6.365 1.962-6.365H41l-2.917 8.189c-.657 1.888-1.432 2.493-3.044 2.493-.18 0-.573-.011-.7-.032"/></g><defs><clipPath id="a_11"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>apple-pay</title></svg>
9741    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_12)"><path fill="#e4e5e7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#3c4043" d="M22.869 16.488v3.933H21.62v-9.712h3.309q1.259 0 2.139.838.897.84.897 2.048c0 .826-.3 1.508-.898 2.06q-.869.828-2.138.827h-2.061zm0-4.583v3.387h2.087c.494 0 .91-.17 1.235-.5.331-.332.5-.735.5-1.19a1.62 1.62 0 0 0-.5-1.177q-.486-.516-1.235-.514h-2.087zm8.361 1.651q1.383 0 2.183.741.8.74.8 2.029v4.095h-1.19v-.923h-.052q-.771 1.139-2.06 1.138-1.1.001-1.84-.65-.741-.652-.741-1.626 0-1.033.78-1.638.781-.613 2.08-.611 1.113 0 1.827.41v-.287c0-.435-.17-.8-.514-1.105a1.76 1.76 0 0 0-1.209-.455c-.695 0-1.248.293-1.651.884l-1.099-.689q.909-1.314 2.685-1.313m-1.613 4.824c0 .325.136.598.416.812q.411.324.968.325.79 0 1.405-.585.616-.583.617-1.371-.584-.46-1.625-.462-.76.002-1.268.364-.515.381-.513.917M41 13.77l-4.16 9.57h-1.288l1.547-3.348-2.743-6.221h1.359l1.976 4.771h.026l1.924-4.771z"/><path fill="#4285f4" d="M17.904 15.695q-.001-.61-.104-1.171h-5.232v2.145l3.013.001a2.58 2.58 0 0 1-1.118 1.728v1.392h1.794c1.047-.97 1.647-2.402 1.647-4.095"/><path fill="#34a853" d="M14.464 18.398c-.5.337-1.142.534-1.895.534-1.453 0-2.685-.98-3.127-2.3h-1.85v1.436a5.57 5.57 0 0 0 4.977 3.067c1.505 0 2.768-.494 3.688-1.346z"/><path fill="#fabb05" d="M9.268 15.568c0-.37.062-.729.174-1.065v-1.436h-1.85A5.54 5.54 0 0 0 7 15.568c0 .9.214 1.749.592 2.501l1.85-1.435a3.4 3.4 0 0 1-.174-1.066"/><path fill="#e94235" d="M12.57 12.204c.82 0 1.556.283 2.136.835l1.59-1.588c-.966-.9-2.224-1.451-3.727-1.451a5.57 5.57 0 0 0-4.977 3.067l1.85 1.436c.442-1.32 1.674-2.3 3.127-2.3"/></g><defs><clipPath id="a_12"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>google-pay</title></svg>
9742
9743</div>        </div>
9744        <div class="container pt-7 pb-5 border-t border-zinc-200 flex justify-center items-center flex-col sm:flex-row text-sm">
9745        
9746<div class="border-t border-gray-200 bg-gray-50 py-6 mt-10">
9747    <div class="container mx-auto px-4">
9748        <div class="flex flex-col gap-6">
9749
9750            <div class="text-center text-sm text-gray-700 border-b border-gray-200 pb-4">
9751                <span class="font-semibold text-gray-900">Muebles Bonitos S.L.</span>
9752                <span class="mx-2">|</span>
9753                <span>C/ Nieve 34, 03006 Alicante</span>
9754                <span class="mx-2">|</span>
9755                <span>Telf: +34 965 104 517</span>
9756                <span class="mx-2">|</span>
9757                <span>CIF: B54778238</span>
9758            </div>
9759
9760            <div class="flex flex-col md:flex-row justify-between items-center gap-4">
9761
9762                <div class="flex items-center gap-4">
9763                    <span class="text-xs font-bold text-gray-500 uppercase tracking-widest">Colabora:</span>
9764
9765                    <!-- <img src="/media/logo_generalitat.webp"
9766                         alt="Logo Generalitat Valenciana"
9767                         width="140" height="75"
9768                         class="h-auto object-contain"
9769                         loading="lazy"> -->
9770
9771                    <a rel="noindex,nofollow" href="/media/labora.png" target="_blank" class="hover:opacity-80 transition-opacity">
9772                        <picture class="h-auto object-contain"><source type="image/webp" srcset="https://www.mueblesbonitos.com/media/labora.webp"><img src="/media/labora.png" alt="Cartel Labora" width="140" height="75" class="h-auto object-contain" loading="lazy" loading="lazy"></picture>
9773                    </a>
9774                </div>
9775
9776                <div class="text-[10px] text-gray-500 text-center md:text-right max-w-md leading-tight">
9777                    <p>Suport a la promoció exterior de la Comunitat Valenciana 2025. Import rebut: 15.170,87€</p>
9778                    <p class="mt-1">&copy; 2026 Muebles Bonitos.</p>
9779                </div>
9780
9781            </div>
9782        </div>
9783    </div>
9784</div>
9785<!--         <nav class="text-slate-600" aria-label="Legal Menu">
9786            <a
9787                href="https://www.mueblesbonitos.com/privacy-policy-cookie-restriction-mode/"
9788                class="inline-block py-1 px-2 sm:px-0 sm:mr-4 sm:last:mr-0 hover:underline"
9789            >Terms &amp; Conditions</a>
9790            <a
9791                href="https://www.mueblesbonitos.com/privacy-policy-cookie-restriction-mode/"
9792                class="inline-block py-1 px-2 sm:px-0 sm:mr-4 sm:last:mr-0 hover:underline"
9793            >Política de privacidad</a>
9794        </nav> -->
9795    </div>
9796</div>
9797<script>
9798    function mobileFooterCollpase() {
9799        return {
9800            open: false,
9801            isMobile: false,
9802            init() {
9803                this.open = this.$root.dataset.open;
9804                this.checkIsMobileResolution();
9805            },
9806            checkIsMobileResolution() {
9807                this.isMobile = getComputedStyle(this.$refs.toggleIcon).display !== 'none'
9808            },
9809            isOpen() {
9810                return this.isMobile ? this.open : true;
9811            },
9812            toggle() {
9813                return this.isMobile ? this.open = !this.open : true;
9814            },
9815            eventListeners: {
9816                ['@resize.window.debounce']() {
9817                    this.checkIsMobileResolution();
9818                },
9819                ['@visibilitychange.window.debounce']() {
9820                    this.checkIsMobileResolution();
9821                }
9822            },
9823            setToggleRoles: {
9824                [':role']() {
9825                    return this.isMobile && 'button';
9826                },
9827                [':tabindex']() {
9828                    return this.isMobile && '0';
9829                },
9830                [':aria-expanded']() {
9831                    return this.isMobile ? this.open : null;
9832                },
9833                [':aria-controls']() {
9834                    return this.isMobile ? this.$el.dataset.id : null;
9835                }
9836            },
9837            setCollapseRoles: {
9838                [':aria-hidden']() {
9839                    return this.isMobile ? !!this.open : null;
9840                },
9841                [':aria-labelledby']() {
9842                    return this.isMobile ? this.$el.id : null;
9843                }
9844            }
9845        }
9846    }
9847    window.addEventListener('alpine:init', () => Alpine.data('mobileFooterCollpase', mobileFooterCollpase), { once: true })
9848</script>
9848
9849
9850</div></footer>
9851<script type="text/javascript">
9852    var oct8ne = document.createElement("script");
9853    oct8ne.server = "backoffice-eu.oct8ne.com/";
9854    oct8ne.type = "text/javascript";
9855    oct8ne.async = true;
9856    oct8ne.license = "4DC4F0B70B4A312415678D0EE1F6CE11"; // Licencia fija
9857    oct8ne.src = (document.location.protocol == "https:" ? "https://" : "http://") + "static-eu.oct8ne.com/api/v2/oct8ne.js?" + (Math.round(new Date().getTime() / 86400000));
9858
9859    // ** Inyección de Variables PHP **
9860    oct8ne.locale = "es-ES";
9861    oct8ne.baseUrl = "//www.mueblesbonitos.com";
9862    oct8ne.allowedDepartmentsId = 1204;
9863
9864    var s = document.getElementsByTagName("script")[0];
9865    insertOct8ne();
9866
9867    function insertOct8ne() {
9868        // Mejor práctica: Inyectar al final del body (donde estamos) o usar un fallback robusto.
9869        // Dado que estamos en before.body.end, la lógica original está bien si funciona,
9870        // pero usar document.body.appendChild(oct8ne) es más seguro.
9871        s.parentNode.insertBefore(oct8ne, s);
9872    }
9873</script>
9873
9874
9875<script>
9876    (() => {
9877        function alpineSnapSlider(Alpine) {
9878            function roundUpIfGreaterThan(number, min = 8) {
9879                const decimalPart = number - Math.floor(number);
9880                return decimalPart >= min ? Math.ceil(number) : Math.floor(number);
9881            }
9882            Alpine.directive("snap-slider", (el, { modifiers }, { cleanup }) => {
9883                const track = el.querySelector("[data-track]");
9884                if (!track) {
9885                    console.warn(
9886                        "No Slider track defined, reverting back to CSS slider.\nPlease create a wrapper element for your slides with the attribute data-track"
9887                    );
9888                    return;
9889                }
9890                let initialLoad = true;
9891                let pager = el.querySelector("[data-pager]");
9892                let slides = [];
9893                let inViewObserver, mutationObserver, resizeObserver;
9894                const navBtns = Array.from(
9895                    el.querySelectorAll("[data-next], [data-prev]")
9896                );
9897                const slideLabelSepparator = el.dataset.slideLabelSepparator || "of";
9898                const useAutoPager = modifiers.includes("auto-pager");
9899                const useGroupPager = modifiers.includes("group-pager");
9900                const sliderLabel = el.hasAttribute("aria-label") && el.getAttribute("aria-label").toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
9901                const sliderId = el.id || sliderLabel || "slider";
9902                const markerIdName = "data-target-id";
9903                const pagerClasses = el.dataset.pagerClass || "pager";
9904                const markerClasses = el.dataset.markerClass || "pager-item";
9905                function getInViewItems() {
9906                    const inViewSlides = track.querySelectorAll("[data-in-view]");
9907                    const firstInViewSlide = inViewSlides[0] || null;
9908                    const lastInViewSlide = inViewSlides[inViewSlides.length - 1] || null;
9909                    const isAtStart = firstInViewSlide === slides[0];
9910                    const isAtEnd = lastInViewSlide === slides[slides.length - 1];
9911                    return {
9912                        inViewSlides,
9913                        totalInViewSlides: inViewSlides.length,
9914                        firstInViewSlide,
9915                        lastInViewSlide,
9916                        isAtStart,
9917                        isAtEnd,
9918                        hasNoOverflow: isAtStart && isAtEnd
9919                    };
9920                }
9921                function groupPagerMarkers() {
9922                    if (!pager || !useGroupPager) return;
9923                    const totalVisibleSlides = roundUpIfGreaterThan(
9924                        track.offsetWidth / slides[0].offsetWidth
9925                    );
9926                    const markers = Array.from(pager.querySelectorAll("a, button"));
9927                    markers.forEach((marker, index) => {
9928                        marker.style.display = index % totalVisibleSlides === 0 ? null : "none";
9929                    });
9930                }
9931                function handleInView(entries) {
9932                    entries.forEach((entry) => {
9933                        const marker = pager && (pager.querySelector(`[href="#${entry.target.id}"]`) || pager.querySelector(
9934                            `[${markerIdName}="${entry.target.id}"]`
9935                        ));
9936                        entry.target.toggleAttribute(
9937                            "data-in-view",
9938                            entry.isIntersecting
9939                        );
9940                        entry.target.toggleAttribute("inert", !entry.isIntersecting);
9941                        marker?.setAttribute("aria-current", entry.isIntersecting);
9942                        marker?.setAttribute(
9943                            "tabindex",
9944                            entry.isIntersecting ? "0" : "-1"
9945                        );
9946                    });
9947                    const { isAtStart, isAtEnd, hasNoOverflow } = getInViewItems();
9948                    navBtns.forEach((btn) => {
9949                        if (btn.hasAttribute("data-next")) {
9950                            btn.style.visibility = hasNoOverflow ? "hidden" : null;
9951                            isAtEnd ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled");
9952                        }
9953                        if (btn.hasAttribute("data-prev")) {
9954                            btn.style.visibility = hasNoOverflow ? "hidden" : null;
9955                            isAtStart ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled");
9956                        }
9957                    });
9958                    if (pager) {
9959                        pager.style.visibility = hasNoOverflow ? "hidden" : null;
9960                    }
9961                    if (!initialLoad) {
9962                        el.dispatchEvent(
9963                            new CustomEvent("slideChange", { detail: getInViewItems() })
9964                        );
9965                    } else {
9966                        initialLoad = false;
9967                    }
9968                    if (document.activeElement.parentElement.hasAttribute("data-pager")) {
9969                        const activeItems = pager.querySelectorAll('[tabindex="0"]');
9970                        if (activeItems.length) {
9971                            activeItems[0].focus();
9972                        }
9973                    }
9974                }
9975                function getSlides() {
9976                    if (!track) return [];
9977                    return Array.from(track.children).filter(
9978                        (child) => child.tagName.toLowerCase() !== "template" && child.tagName.toLowerCase() !== "script"
9979                    );
9980                }
9981                function refreshSlides() {
9982                    initialLoad = true;
9983                    slides = getSlides();
9984                    setupSlides();
9985                    if (useAutoPager) {
9986                        createPager();
9987                    } else {
9988                        setupPager();
9989                    }
9990                    groupPagerMarkers();
9991                    setupObservers();
9992                }
9993                function setupSlides() {
9994                    slides = getSlides();
9995                    slides.forEach((slide, index) => {
9996                        const totalSlides = slides.length;
9997                        const currentSlide = index + 1;
9998                        const existingLabel = slide.getAttribute("aria-label") || "";
9999                        const isImage = slide.tagName.toLowerCase() === "img" || slide.tagName.toLowerCase() === "picture";
10000                        const slideLabelTag = isImage ? "alt" : "aria-label";
10001                        const hasAutoLabel = existingLabel.startsWith(`${currentSlide} ${slideLabelSepparator} `);
10002                        if (!slide.hasAttribute("id")) {
10003                            slide.setAttribute("id", `${sliderId}-item-${currentSlide}`);
10004                        }
10005
10006                        if ((!slide.hasAttribute(slideLabelTag) || slide.getAttribute(slideLabelTag) === "") || hasAutoLabel) {
10007                            slide.setAttribute(slideLabelTag, `${currentSlide} ${slideLabelSepparator} ${totalSlides}`);
10008                        }
10009
10010                        if (slide.tagName.toLowerCase() === "div" && !slide.hasAttribute("role")) {
10011                            slide.setAttribute("role", "group");
10012                        }
10013
10014                        if (pager && !isImage) {
10015                            slide.setAttribute("role", "tabpanel");
10016                        }
10017
10018                        if (slide.getAttribute('role') === "group") {
10019                            slide.setAttribute("aria-roledescription", "item");
10020                        }
10021                    });
10022                    if (!el.hasAttribute("role")) {
10023                        el.setAttribute("role", "region");
10024                    }
10025                    if (!el.hasAttribute("aria-roledescription")) {
10026                        el.setAttribute("aria-roledescription", "carousel");
10027                    }
10028                    track.setAttribute("tabindex", 0);
10029                    track.setAttribute("aria-live", "polite");
10030                }
10031                function setupNav() {
10032                    navBtns.forEach((btn) => {
10033                        btn.setAttribute("disabled", "");
10034                        btn.removeAttribute("hidden");
10035                        btn.classList.remove("invisible");
10036                        btn.style.visibility = null;
10037                    });
10038                }
10039                function createPager() {
10040                    const newPager = document.createElement("nav");
10041                    newPager.setAttribute("data-pager", "");
10042                    newPager.setAttribute("role", "tablist");
10043                    newPager.classList.add(...pagerClasses.split(" "));
10044
10045                    slides.forEach((slide, index) => {
10046                        const marker = document.createElement("button");
10047                        const slideId = slide.id || `${sliderId}-item-${index + 1}`;
10048                        marker.setAttribute(markerIdName, slideId);
10049                        marker.classList.add(...markerClasses.split(" "));
10050                        setupPagerMarker(marker, index);
10051                        newPager.appendChild(marker);
10052
10053                        if (slide.tagName.toLowerCase() !== "img" && slide.tagName.toLowerCase() !== "picture") {
10054                            slide.removeAttribute("aria-roledescription");
10055                            slide.setAttribute("role", "tabpanel");
10056                        }
10057                    });
10058
10059                    if (pager) {
10060                        pager.setAttribute("role", "tablist");
10061                        pager.replaceChildren(...newPager.children);
10062                    } else {
10063                        track.after(newPager);
10064                        pager = el.querySelector("[data-pager]");
10065                    }
10066                }
10067                function setupPager() {
10068                    if (!pager) return;
10069                    pager.setAttribute("role", "tablist");
10070                    const items = Array.from(pager.querySelectorAll("a, button"));
10071                    items.forEach((marker, index) => setupPagerMarker(marker, index));
10072                }
10073                function setupPagerMarker(marker, index) {
10074                    const markerId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(markerIdName);
10075                    const slideId = markerId || `${sliderId}-item-${index + 1}`;
10076                    if (!markerId) {
10077                        marker.setAttribute(markerIdName, slideId);
10078                    }
10079                    marker.setAttribute("role", "tab");
10080                    marker.setAttribute("aria-controls", slideId);
10081                    marker.setAttribute("aria-posinset", index + 1);
10082                    marker.setAttribute("aria-setsize", slides.length);
10083                    marker.setAttribute("tabindex", "-1");
10084                    if (!marker.hasAttribute("aria-label")) {
10085                        marker.setAttribute("aria-label", `Slide ${index + 1}`);
10086                    }
10087                }
10088                function setupObservers() {
10089                    if (inViewObserver) {
10090                        inViewObserver.disconnect();
10091                    }
10092                    inViewObserver = new IntersectionObserver(
10093                        handleInView.bind(track),
10094                        { root: track, threshold: 0.8 }
10095                    );
10096                    slides.forEach((slide) => inViewObserver.observe(slide));
10097                }
10098                function setupMutationObserver() {
10099                    mutationObserver = new MutationObserver(refreshSlides.bind(track));
10100                    mutationObserver.observe(track, {
10101                        childList: true,
10102                        subtree: false
10103                    });
10104                }
10105                function setupResizeObserver() {
10106                    resizeObserver = new ResizeObserver(groupPagerMarkers.bind(el));
10107                    resizeObserver.observe(el);
10108                }
10109                function goToSlideDir(dir = "next") {
10110                    const { firstInViewSlide, lastInViewSlide } = getInViewItems();
10111                    const isPrev = dir === "prev";
10112                    let targetSlide = isPrev ? firstInViewSlide?.previousElementSibling : lastInViewSlide?.nextElementSibling;
10113                    if (!targetSlide) return;
10114                    if (targetSlide.tagName.toLowerCase() === "template") {
10115                        targetSlide = isPrev ? targetSlide?.previousElementSibling : targetSlide?.nextElementSibling;
10116                    }
10117                    targetSlide.scrollIntoView({
10118                        block: "nearest",
10119                        inline: isPrev ? "end" : "start",
10120                        behavior: "smooth"
10121                    });
10122                }
10123                function pagerToSlide(event) {
10124                    if (!event.target.closest("[data-pager]")) return;
10125                    const marker = event.target.closest("a, button");
10126                    if (!marker) return;
10127                    event.preventDefault();
10128                    const slideId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(markerIdName);
10129                    const targetSlide = track.querySelector(`#${slideId}`);
10130                    targetSlide?.scrollIntoView({
10131                        block: "nearest",
10132                        inline: "start",
10133                        behavior: "smooth"
10134                    });
10135                }
10136                setupSlides();
10137                setupNav();
10138                if (useAutoPager) {
10139                    createPager();
10140                } else {
10141                    setupPager();
10142                }
10143                setupObservers();
10144                setupMutationObserver();
10145                setupResizeObserver();
10146                function eventHandler(event) {
10147                    const target = event.target.closest(
10148                        "[data-next], [data-prev], [data-pager]"
10149                    );
10150                    if (!target) return;
10151                    if (event.type === "click") {
10152                        if (target.hasAttribute("data-next")) {
10153                            goToSlideDir("next");
10154                        } else if (target.hasAttribute("data-prev")) {
10155                            goToSlideDir("prev");
10156                        } else if (target.closest("[data-pager]")) {
10157                            pagerToSlide(event);
10158                        }
10159                    }
10160                    if (event.type === "keydown" && target.closest("[data-pager]")) {
10161                        if (event.key === "ArrowRight") {
10162                            goToSlideDir("next");
10163                        } else if (event.key === "ArrowLeft") {
10164                            goToSlideDir("prev");
10165                        }
10166                    }
10167                }
10168                el.addEventListener("click", eventHandler);
10169                el.addEventListener("keydown", eventHandler);
10170                cleanup(() => {
10171                    inViewObserver?.disconnect();
10172                    mutationObserver?.disconnect();
10173                    resizeObserver?.disconnect();
10174                    el.removeEventListener("click", eventHandler);
10175                    el.removeEventListener("keydown", eventHandler);
10176                });
10177            });
10178        }
10179
10180        document.addEventListener("alpine:init", () => {
10181            window.Alpine.plugin(alpineSnapSlider);
10182        });
10183    })();
10184</script>
vendor: 1 bytes, line 10184
10184
10185<script>
10186    (() => {
10187        // src/dialog.js
10188        function dialog_default(Alpine) {
10189            Alpine.directive("htmldialog", fylgjaAlpineDialog);
10190            function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) {
10191            const evaluate = expression.length ? evaluateLater(expression) : () => {};
10192            const canEvaluate = expression.length > 0;
10193            const lockPageScroll = modifiers.includes("noscroll");
10194            const closeBy = el.getAttribute("closeby") || modifierValue(modifiers, "closeby", "closerequest");
10195            el.style.display = null;
10196            el.style.length === 0 && el.removeAttribute("style");
10197            if (el._x_isShown) {
10198                open();
10199            }
10200            const closeBySupported = (() => {
10201                return "closedBy" in HTMLDialogElement.prototype;
10202            })();
10203            function scrollLock(use = true) {
10204                document.body.style.overflow = use ? "hidden" : "";
10205            }
10206            function dialogSubmit(event) {
10207                if (event.target.getAttribute("method") === "dialog" || event.submitter?.getAttribute("formmethod") === "dialog") {
10208                event.preventDefault();
10209                evaluate();
10210                }
10211            }
10212            function escapeDialog(event) {
10213                if (event.key !== "Escape") return;
10214                event.preventDefault();
10215                if (closeBy === "none") return;
10216                evaluate();
10217            }
10218            function handleCloseByEvent(event) {
10219                if (event.target !== el) return;
10220                const rect = el.getBoundingClientRect();
10221                const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width;
10222                if (!isInDialog) {
10223                if (closeBy === "any") {
10224                    if (closeBySupported) {
10225                    event.preventDefault();
10226                    }
10227                    evaluate();
10228                }
10229                }
10230            }
10231            function handleCloseEvent() {
10232                evaluate();
10233            }
10234            function open() {
10235                if (el.hasAttribute("open")) return;
10236                el.showModal();
10237                scrollLock(lockPageScroll);
10238            }
10239            function close() {
10240                if (!el.hasAttribute("open")) return;
10241                el.close();
10242                scrollLock(false);
10243            }
10244            el._x_doShow = () => open();
10245            el._x_doHide = () => close();
10246            el.addEventListener("keydown", escapeDialog);
10247            el.addEventListener("submit", dialogSubmit);
10248            el.addEventListener("click", handleCloseByEvent);
10249            el.addEventListener("cancel", handleCloseEvent);
10250            cleanup(() => {
10251                el.removeEventListener("keydown", escapeDialog);
10252                el.removeEventListener("submit", dialogSubmit);
10253                el.removeEventListener("click", handleCloseByEvent);
10254                el.removeEventListener("cancel", handleCloseEvent);
10255                scrollLock(false);
10256            });
10257            }
10258        }
10259        function modifierValue(modifiers, key, fallback) {
10260            if (modifiers.indexOf(key) === -1) return fallback;
10261            const rawValue = modifiers[modifiers.indexOf(key) + 1];
10262            if (!rawValue) return fallback;
10263            if (key === "closeby") {
10264            const allowedValues = ["auto", "none", "closerequest", "any"];
10265            const options = allowedValues.join(", ");
10266            if (!allowedValues.includes(rawValue)) {
10267                console.warn(
10268                `"${rawValue}" is not one of the allowed values for closeby: ${options}`
10269                );
10270                return fallback;
10271            }
10272            }
10273            return rawValue;
10274        }
10275
10276        // src/cdn.js
10277        document.addEventListener("alpine:init", () => {
10278            window.Alpine.plugin(dialog_default);
10279        });
10280    })();
10281    //# sourceURL=alpine-htmldialog.js
10282</script>
vendor: 1 bytes, line 10282
10282
10283<script>
10284    (() => {
10285        function src_default(Alpine) {
10286            Alpine.directive("intersect", Alpine.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
10287                let evaluate = evaluateLater(expression);
10288                let options = {
10289                    rootMargin: getRootMargin(modifiers),
10290                    threshold: getThreshold(modifiers)
10291                };
10292                let observer = new IntersectionObserver((entries) => {
10293                    entries.forEach((entry) => {
10294                        if (entry.isIntersecting === (value === "leave"))
10295                            return;
10296                        evaluate();
10297                        modifiers.includes("once") && observer.disconnect();
10298                    });
10299                }, options);
10300                observer.observe(el);
10301                cleanup(() => {
10302                    observer.disconnect();
10303                });
10304            }));
10305        }
10306        function getThreshold(modifiers) {
10307            if (modifiers.includes("full"))
10308                return 0.99;
10309            if (modifiers.includes("half"))
10310                return 0.5;
10311            if (!modifiers.includes("threshold"))
10312                return 0;
10313            let threshold = modifiers[modifiers.indexOf("threshold") + 1];
10314            if (threshold === "100")
10315                return 1;
10316            if (threshold === "0")
10317                return 0;
10318            return Number(`.${threshold}`);
10319        }
10320        function getLengthValue(rawValue) {
10321            let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/);
10322            return match ? match[1] + (match[2] || "px") : void 0;
10323        }
10324        function getRootMargin(modifiers) {
10325            const key = "margin";
10326            const fallback = "0px 0px 0px 0px";
10327            const index = modifiers.indexOf(key);
10328            if (index === -1)
10329                return fallback;
10330            let values = [];
10331            for (let i = 1; i < 5; i++) {
10332                values.push(getLengthValue(modifiers[index + i] || ""));
10333            }
10334            values = values.filter((v) => v !== void 0);
10335            return values.length ? values.join(" ").trim() : fallback;
10336        }
10337
10338        document.addEventListener("alpine:init", () => {
10339            window.Alpine.plugin(src_default);
10340        });
10341    })();
10342    //# sourceURL=alpine-intersect.js
10343</script>
vendor: 1 bytes, line 10343
10343
10344<script>
10345    for (const [selector, deferUntil] of Object.entries({".product-slider section[x-data]:not([x-data] [x-data])":"intersect",".product-info [x-data]:not([x-data] [x-data])":"intersect","#filters-content [x-data]:not([x-data] [x-data])":"intersect","#review_form":"intersect","section[x-data^=initRecentlyViewedProductsComponent]":"intersect","div[x-data^=initBundleOptions]":"intersect","#product_addtocart_form [x-data]:not([x-data] [x-data])":"intersect","#notice-cookie-block":"idle"})) {
10346        document.querySelectorAll(selector).forEach(el => el.setAttribute('x-defer', `${deferUntil}`));
10347    }
10348    //# sourceURL=alpine-defer-rules.js
10349</script>
vendor: 1 bytes, line 10349
10349
10350<script>
10351    (() => {
10352        const hasAlpine = new Promise(resolve => {
10353            window.addEventListener('alpine:initialized', resolve, {once: true, passive: true});
10354        });
10355
10356        const hasInteract = new Promise(resolve => {
10357            (events => {
10358                const onInteract = () => {
10359                    resolve();
10360                    events.forEach(type => window.removeEventListener(type, onInteract));
10361                }
10362                events.forEach(type => window.addEventListener(type, onInteract, {once: true, passive: true}))
10363            })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown'])
10364        });
10365
10366        const onIntersect = (el) => {
10367            return new Promise(resolve => {
10368                const observer = new IntersectionObserver(entries => {
10369                    for (const entry of entries) {
10370                        if (entry.isIntersecting) {
10371                            observer.disconnect()
10372                            resolve();
10373                        }
10374                    }
10375                }, {});
10376                observer.observe(el);
10377            });
10378        }
10379
10380        function runComponent(el) {
10381            hasAlpine.then(() => {
10382                el.removeAttribute('x-ignore');
10383                queueMicrotask(() => Alpine.initTree(el));
10384            });
10385        }
10386
10387        function initDeferredComponents() {
10388            document.querySelectorAll('[x-data][x-defer]').forEach(el => {
10389                el.setAttribute('x-ignore', '');
10390                const deferUntil = (el.getAttribute('x-defer') || '').trim();
10391                switch (deferUntil) {
10392                    case 'interact':
10393                        hasInteract.then(() => runComponent(el));
10394                        break;
10395                    case 'intersect':
10396                        onIntersect(el).then(() => runComponent(el))
10397                        break;
10398                    case 'idle':
10399                        window.requestIdleCallback
10400                            ? window.requestIdleCallback(() => runComponent(el), {timeout: 4000})
10401                            : setTimeout(() => runComponent(el), 4000);
10402                        break;
10403                    case 'eager':
10404                        runComponent(el);
10405                        break;
10406                    default:
10407                        if (deferUntil.startsWith('event:') && deferUntil.length > 6) {
10408                            window.addEventListener(deferUntil.substring(6), () => runComponent(el), {once: true, passive: true});
10409                        }
10410                }
10411            });
10412        }
10413
10414        window.addEventListener('alpine:init', initDeferredComponents, {once: true, passive: true});
10415    })();
10416    //# sourceURL=alpine-defer.js
10417</script>
vendor: 1 bytes, line 10417
10417
10418<script src="https&#x3A;&#x2F;&#x2F;cdn.jsdelivr.net&#x2F;npm&#x2F;&#x40;alpinejs&#x2F;collapse&#x40;3.x.x&#x2F;dist&#x2F;cdn.min.js" defer="1"></script>
vendor: 1 bytes, line 10418
10418
10419<script type="module"
10420        src="https://www.mueblesbonitos.com/static/frontend/Mb/Hyva2/es_ES/Hyva_Theme/js/alpine3.min.js"
10421        defer
10422        crossorigin
10423></script>
vendor: 1 bytes, line 10423
10423
10424<script>
10425    function dispatchMessages(messages, hideAfter) {
10426        const messagesEvent = new CustomEvent("messages-loaded", {
10427            detail: {
10428                messages: messages,
10429                hideAfter: hideAfter
10430            }
10431        });
10432        window.dispatchEvent(messagesEvent);
10433    }
10434
10435    if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) {
10436        console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script");
10437    }
10438
10439    (function( hyva, undefined ) {
10440
10441        hyva.initFormKey = () => {
10442            const inputSelector = 'input[name="form_key"]',
10443                formKey = hyva.getFormKey();
10444
10445            Array.from(document.querySelectorAll(inputSelector)).map(function (input) {
10446                input.value = formKey
10447            });
10448        }
10449
10450        hyva.initMessages = () => {
10451            try {
10452                const messages = hyva.getCookie('mage-messages');
10453                window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : [];
10454
10455                dispatchMessages(window.mageMessages);
10456
10457                                // empty `mage-messages` cookie
10458                const skipSetDomain = true;
10459                hyva.setCookie('mage-messages','', -1, skipSetDomain);
10460
10461            } catch (error) {
10462                console.warn('Error parsing Cookie Messages:', error);
10463            }
10464        }
10465
10466        window.addEventListener('DOMContentLoaded', hyva.initFormKey);
10467        hyva.alpineInitialized(hyva.initMessages)
10468
10469    }( window.hyva = window.hyva || {} ));
10470    //# sourceURL=hyva-cookies.js
10471</script>
vendor: 1 bytes, line 10471
10471
10472<script>
10473    {
10474        const private_content_key = 'mage-cache-storage';
10475        const private_content_expire_key = 'mage-cache-timeout';
10476        const private_content_version_key = 'private_content_version';
10477        const section_data_ids_key = 'section_data_ids';
10478        const mage_cache_session_id_key = 'mage-cache-sessid';
10479        const last_visited_store_key = 'last_visited_store';
10480
10481        const ttl = 3600;
10482
10483        if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) {
10484            console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script");
10485        }
10486
10487        function loadSectionData () {
10488            const browserStorage = hyva.getBrowserStorage();
10489            if (!browserStorage) {
10490                typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
10491                    [{
10492                        type: "warning",
10493                        text: "Por favor, active LocalStorage en su navegador."
10494                    }]
10495                );
10496                return;
10497            }
10498            try {
10499                let isInvalid = false;
10500
10501                if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) {
10502                    isInvalid = true;
10503                }
10504                hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false);
10505
10506                if (!hyva.getCookie(mage_cache_session_id_key)) {
10507                    isInvalid = true;
10508                    browserStorage.removeItem(private_content_key);
10509                    const skipSetDomain = true;
10510                    const days = false;
10511                    hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain)
10512                }
10513
10514                const cookieVersion = hyva.getCookie(private_content_version_key);
10515                const storageVersion = browserStorage.getItem(private_content_version_key);
10516
10517                if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) {
10518                    isInvalid = true;
10519                }
10520
10521                const privateContentExpires = browserStorage.getItem(private_content_expire_key);
10522                if (privateContentExpires && new Date(privateContentExpires) < new Date()) {
10523                    browserStorage.removeItem(private_content_key);
10524                }
10525
10526                if (isInvalid && cookieVersion) {
10527                    fetchPrivateContent([]);
10528                } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) {
10529                    const privateContent = JSON.parse(browserStorage.getItem(private_content_key));
10530                    if (
10531                        privateContent &&
10532                        privateContentExpires &&
10533                        privateContent.cart &&
10534                        privateContent.customer
10535                    ) {
10536                        dispatchPrivateContent(privateContent);
10537                    } else {
10538                        fetchPrivateContent([]);
10539                    }
10540                } else {
10541                    if (document.getElementById('default-section-data')) {
10542                        const privateContent = JSON.parse(document.getElementById('default-section-data').innerText.trim());
10543                        dispatchPrivateContent(privateContent);
10544                    } else {
10545                        dispatchPrivateContent({});
10546                    }
10547                }
10548
10549            } catch (error) {
10550                console.warn('Error retrieving Private Content:', error);
10551            }
10552        }
10553
10554        hyva.alpineInitialized(loadSectionData)
10555        window.addEventListener('reload-customer-section-data', loadSectionData);
10556
10557        window.processSectionDataBeforeDispatch = window.processSectionDataBeforeDispatch || (data => data);
10558
10559        function dispatchPrivateContent(data) {
10560
10561            const privateContentEvent = new CustomEvent("private-content-loaded", {
10562                detail: {
10563                    data: window.processSectionDataBeforeDispatch(data)
10564                }
10565            });
10566            window.dispatchEvent(privateContentEvent);
10567        }
10568
10569        function fetchPrivateContent(sections) {
10570            fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, {
10571                method: 'GET',
10572                headers: {
10573                    'Content-Type': 'application/json',
10574                    'X-Requested-With': 'XMLHttpRequest'
10575                }
10576            })
10577                .then(response => response.ok && response.json())
10578                .then(
10579                    data => {
10580                        if (data) {
10581                            try {
10582                                const browserStorage = hyva.getBrowserStorage();
10583
10584                                // merge new data preserving non-invalidated sections
10585                                const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}') || {};
10586
10587                                if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) {
10588                                    delete oldSectionData['checkout-data'];
10589                                }
10590                                const newSectionData = Object.assign(oldSectionData, data);
10591
10592                                dispatchPrivateContent(newSectionData);
10593
10594                                // don't persist messages, they've been dispatched already
10595                                if (newSectionData.messages && newSectionData.messages.messages ) {
10596                                    newSectionData.messages.messages = [];
10597                                }
10598
10599                                browserStorage.setItem(private_content_key, JSON.stringify(newSectionData));
10600
10601                                const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString();
10602                                browserStorage.setItem(private_content_expire_key, expiresAt);
10603
10604                                const newCookieVersion = hyva.getCookie(private_content_version_key);
10605                                browserStorage.setItem(private_content_version_key, newCookieVersion);
10606
10607                                // We don't need the section_data_ids in Hyvä, but we store them for compatibility
10608                                // with Luma Fallback. Otherwise, not all sections are loaded in Luma Checkout
10609                                hyva.setCookie(
10610                                    section_data_ids_key,
10611                                    JSON.stringify(
10612                                        Object.keys(data).reduce((sectionDataIds, sectionKey) => {
10613                                            sectionDataIds[sectionKey] = data[sectionKey]['data_id'];
10614                                            return sectionDataIds;
10615                                        }, {})
10616                                    ),
10617                                    false,
10618                                    true
10619                                );
10620                            } catch (error) {
10621                                console.warn("Couldn't store privateContent", error);
10622                            }
10623                        }
10624                    }
10625                );
10626        }
10627    }
10628    //# sourceURL=hyva-private-content.js
10629</script>
vendor: 1 bytes, line 10629
10629
10630<script>
10631    (() => {
10632        document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc()));
10633    })()
10634</script>
vendor: 1 bytes, line 10634
10634
10635<script>
10636    (events => {
10637        const dispatchUserInteractionEvent = () => {
10638            events.forEach(type => window.removeEventListener(type, dispatchUserInteractionEvent))
10639            window.dispatchEvent(new Event('init-external-scripts'))
10640        };
10641        events.forEach(type => window.addEventListener(type, dispatchUserInteractionEvent, {once: true, passive: true}))
10642    })(['touchstart', 'mousemove', 'wheel', 'scroll', 'keydown']);
10643    //# sourceURL=hyva-init-external-scripts.js
10644</script>
vendor: 1 bytes, line 10644
10644
10645<script>
10646    function initWishlist() {
10647        return {
10648            addToWishlist() {
10649                const productId = this.$el.dataset.productId;
10650                const formKey = hyva.getFormKey();
10651                const postUrl = BASE_URL + 'wishlist/index/add/';
10652
10653                fetch(postUrl, {
10654                    "headers": {
10655                        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
10656                    },
10657                    "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(),
10658                    "method": "POST",
10659                    "mode": "cors",
10660                    "credentials": "include"
10661                }).then(function (response) {
10662                    if (response.redirected) {
10663                        window.location.href = response.url;
10664                    } else if (response.ok) {
10665                        return response.json();
10666                    } else {
10667                        typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
10668                            [{
10669                                type: "warning",
10670                                text: "No\u0020se\u0020ha\u0020podido\u0020a\u00F1adir\u0020el\u0020art\u00EDculo\u0020a\u0020la\u0020lista\u0020de\u0020deseos."
10671                            }], 5000
10672                        );
10673                    }
10674                }).then(function (response) {
10675                    if (!response) { return }
10676                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
10677                        [{
10678                            type: (response.success) ? "success" : "error",
10679                            text: (response.success)
10680                                ? "Producto\u0020has\u0020been\u0020added\u0020to\u0020your\u0020Wish\u0020List."
10681                                : response.error_message
10682                        }], 5000
10683                    );
10684                    const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data");
10685                    window.dispatchEvent(reloadCustomerDataEvent);
10686                }).catch(function (error) {
10687                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
10688                        [{
10689                            type: "error",
10690                            text: error
10691                        }], 5000
10692                    );
10693                });
10694            }
10695        }
10696    }
10697    window.addEventListener('alpine:init', () => Alpine.data('initWishlist', initWishlist), {once: true})
10698</script>
10698
10699    
10699<script>
10700    function initProductItemImage() {
10701        return {
10702            updateImage() {
10703                const image = this.$event.detail.medium;
10704                if (!image) return;
10705                this.$el.src = image;
10706            }
10707        }
10708    }
10709    window.addEventListener('alpine:init', () => {
10710        Alpine.data('initProductItemImage', initProductItemImage);
10711    }, { once: true });
10712</script>
vendor: 1 bytes, line 10712
10712
10713<script>
10714    function initPriceBox()
10715    {
10716        return {
10717            updatePrice() {
10718                const priceData = this.$event.detail;
10719                const regularPriceLabel = this.$root.querySelector('.normal-price .price-label');
10720                const regularPriceElement = this.$root.querySelector('.normal-price [data-price-type=finalPrice].price-wrapper .price');
10721                const basePriceElement = this.$root.querySelector('.normal-price [data-price-type=basePrice].price-wrapper .price');
10722                if (priceData.finalPrice.amount < priceData.oldPrice.amount) {
10723                    regularPriceLabel && regularPriceLabel.classList.add('hidden');
10724                } else {
10725                    regularPriceLabel && regularPriceLabel.classList.remove('hidden');
10726                }
10727                regularPriceElement && (regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount));
10728                basePriceElement && (basePriceElement.innerText = hyva.formatPrice(priceData.basePrice.amount));
10729            },
10730            htmlPriceIdGroup() {
10731                return [this.$el.dataset.priceId];
10732            },
10733            htmlPriceId() {
10734                return this.$id(this.$el.closest('[data-price-id]').dataset.priceId);
10735            }
10736        }
10737    }
10738    window.addEventListener('alpine:init', () => Alpine.data('initPriceBox', initPriceBox), {once: true})
10739</script>
vendor: 1 bytes, line 10739
10739
10740<script>
10741    function initPriceBox()
10742    {
10743        return {
10744            updatePrice() {
10745                const priceData = this.$event.detail;
10746                const regularPriceLabel = this.$root.querySelector('.normal-price .price-label');
10747                const regularPriceElement = this.$root.querySelector('.normal-price [data-price-type=finalPrice].price-wrapper .price');
10748                const basePriceElement = this.$root.querySelector('.normal-price [data-price-type=basePrice].price-wrapper .price');
10749                if (priceData.finalPrice.amount < priceData.oldPrice.amount) {
10750                    regularPriceLabel && regularPriceLabel.classList.add('hidden');
10751                } else {
10752                    regularPriceLabel && regularPriceLabel.classList.remove('hidden');
10753                }
10754                regularPriceElement && (regularPriceElement.innerText = hyva.formatPrice(priceData.finalPrice.amount));
10755                basePriceElement && (basePriceElement.innerText = hyva.formatPrice(priceData.basePrice.amount));
10756            },
10757            htmlPriceIdGroup() {
10758                return [this.$el.dataset.priceId];
10759            },
10760            htmlPriceId() {
10761                return this.$id(this.$el.closest('[data-price-id]').dataset.priceId);
10762            }
10763        }
10764    }
10765    window.addEventListener('alpine:init', () => Alpine.data('initPriceBox', initPriceBox), {once: true})
10766</script>
vendor: 1 bytes, line 10766
10766
10767<script>
10768    function initConfigurableOptions(productId, optionConfig) {
10769
10770        function findPathParam(key) {
10771                        const baseUrl = (BASE_URL.substring(0, 2) === '//' ? 'http:' : '') + BASE_URL;
10772            const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/');
10773            const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3);
10774            for (let i = 0; i < pathParts.length; i += 2) {
10775                if (pathParts[i] === key && pathParts.length > i) {
10776                    return pathParts[i + 1];
10777                }
10778            }
10779        }
10780
10781        return {
10782            optionConfig,
10783            productId,
10784            itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'),
10785            allowedAttributeOptions: [],
10786            selectedValues: [],
10787            init() {
10788                this.buildLookupMap();
10789                this.findAllowedAttributeOptions();
10790                this.$nextTick(() => {
10791                    if (typeof this.optionConfig.defaultValues === 'object') {
10792                        for (const [attributeId, value] of Object.entries(this.optionConfig.defaultValues)) {
10793                            this.changeOption(attributeId, value + '');
10794                        }
10795                    }
10796                    this.preselectQuerystringItems();
10797                    this.preselectLocationHashItems();
10798                });
10799            },
10800            productIndex: 0,
10801            productIndexForPrice: 0,
10802            productIndexesMap: null,
10803            productIndexesKeys: null,
10804            attributeCount: 0,
10805            optionIsActive() {
10806                                const attributeId = this.getDataAttributeId(this.$el);
10807                return !!this.getAllowedAttributeOptions(attributeId).find(
10808                    option => option.id === this.item.id
10809                )
10810            },
10811                        ['!optionIsActive']() {
10812                return ! this.optionIsActive();
10813            },
10814            ['notOptionIsActive']() {
10815                return ! this.optionIsActive();
10816            },
10817            optionIsEnabled() {
10818                                const attributeId = this.getDataAttributeId(this.$el);
10819
10820                for (const productId in this.optionConfig.index) {
10821                    if (this.optionConfig.index[productId][attributeId] === this.item.id) {
10822                        return true;
10823                    }
10824                }
10825                return false;
10826            },
10827
10828            isOptionEnabledAndInStock() {
10829                return this.optionIsEnabled() && this.optionIsActive();
10830            },
10831            isOptionEnabledAndOutOfStock() {
10832                return this.optionIsEnabled() && ! this.optionIsActive();
10833            },
10834            findSimpleIndex() {
10835                                this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues);
10836                this.productIndexForPrice = this.findCheapestProductForPartialSelection(this.selectedValues);
10837            },
10838            calculateSimpleIndexForPartialSelection(selectedValues) {
10839                if (selectedValues.length === 0) return 0;
10840                return this.findProductIdsForPartialSelection(selectedValues)[0];
10841            },
10842            buildLookupMap() {
10843                                this.productIndexesMap = new Map();
10844                this.attributeCount = Object.keys(this.optionConfig.attributes).length;
10845                for (const id in this.optionConfig.index) {
10846                    const options = this.optionConfig.index[id];
10847                    if (! this.productIndexesKeys) {
10848                        this.productIndexesKeys = Object.keys(options).sort();
10849                    }
10850                    const key = JSON.stringify(options, this.productIndexesKeys);
10851                    this.productIndexesMap.set(key, id);
10852                }
10853            },
10854            calculateSimpleIndexForFullSelection(selectedValues) {
10855                if (! this.isFullSelection(selectedValues)) return false;
10856
10857                                const attrKeys = this.productIndexesKeys || [];
10858                const normalised = {};
10859                for (let i = 0; i < attrKeys.length; i++) {
10860                    normalised[attrKeys[i]] = selectedValues[attrKeys[i]];
10861                }
10862                const queryKey = JSON.stringify(normalised, attrKeys);
10863                return this.productIndexesMap.get(queryKey);
10864            },
10865            findAllowedAttributeOptions() {
10866                                this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues);
10867            },
10868            calculateAllowedAttributeOptions(selectedValues) {
10869                const allAttributes = this.optionConfig.attributes;
10870                const allAttributesSorted = Object.values(allAttributes).sort((a,b) => {
10871                    return a.position - b.position
10872                });
10873
10874                const newAllowedAttributeOptions = [];
10875
10876                allAttributesSorted.forEach(attribute => {
10877                    const selectionWithoutAttr = Object.assign({}, this.removeAttrFromSelection(selectedValues, attribute.id));
10878                    const availableIndexes = this.calculateAvailableProductIndexes(selectionWithoutAttr);
10879                    newAllowedAttributeOptions[attribute.id] = allAttributes[attribute.id].options.filter(option => {
10880                        return !!option.products.find(product => {
10881                            return availableIndexes.includes(product);
10882                        })
10883                    });
10884                });
10885                return newAllowedAttributeOptions;
10886            },
10887            calculateAvailableProductIndexes(selectedOptions) {
10888                if (Object.keys(selectedOptions).length === 0) {
10889                                        if (Object.values(this.optionConfig.salable || {}).length) {
10890                                                return [].concat.apply([], [].concat.apply([], Object.values(this.optionConfig.salable).map(Object.values))).filter((x, i, a) => a.indexOf(x) === i)
10891                    }
10892                                        return Object.keys(this.optionConfig.index);
10893                }
10894
10895                                const selectedIds = Object.keys(selectedOptions);
10896                if (Object.values(this.optionConfig.salable || {}).length) {
10897                                        const selectedOptionIndexes = selectedIds.map(attrId => {
10898                        const optionValue = selectedOptions[attrId];
10899                        return this.optionConfig.salable[attrId] && this.optionConfig.salable[attrId][optionValue] || []
10900                    })
10901                                        return selectedOptionIndexes.reduce((acc, optionIndexes) => {
10902                        return acc.filter(index => optionIndexes.includes(index));
10903                    });
10904                } else {
10905                                        const productIndexes = this.optionConfig.index;
10906                    return Object.keys(productIndexes).filter(index => {
10907                                                for (const attrId of selectedIds) {
10908                            if (productIndexes[index][attrId] !== `${selectedOptions[attrId]}`) return false
10909                        }
10910                        return true
10911                    });
10912                }
10913            },
10914            findAttributeByOptionId(optionId) {
10915                for (const attributeId in this.optionConfig.attributes) {
10916                    const attributeOptions = this.optionConfig.attributes[attributeId].options || [];
10917                    if (attributeOptions.find(option => option.id === optionId)) {
10918                        return attributeId;
10919                    }
10920                }
10921            },
10922            getAllowedAttributeOptions(attributeId) {
10923                return this.allowedAttributeOptions[attributeId] || []
10924            },
10925            getDataAttributeId(el) {
10926                return el.closest('[data-attribute-id]').dataset.attributeId;
10927            },
10928            getDataOptionId(el) {
10929                return el.closest('[data-option-id]').dataset.optionId;
10930            },
10931            getAllAttributeOptions(attributeId) {
10932                if (attributeId === undefined) {
10933                    attributeId = this.getDataAttributeId(this.$el);
10934                }
10935                return (
10936                    this.optionConfig.attributes[attributeId] &&
10937                    this.optionConfig.attributes[attributeId].options
10938                ) || []
10939            },
10940            getProductIdsForOption(option) {
10941                const attributeId = this.findAttributeByOptionId(option.id);
10942                const allOptions = this.optionConfig.attributes[attributeId];
10943                const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id);
10944                return opt && opt.products
10945                    ? opt.products
10946                    : [];
10947            },
10948            findProductIdsForPartialSelection(optionSelection) {
10949                const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => {
10950                    const newCandidates = this.getProductIdsForOption({id: optionId});
10951                    return candidates === null
10952                        ? newCandidates
10953                        : candidates.filter(productId => newCandidates.includes(productId));
10954                }, null);
10955                return candidateProducts || [];
10956            },
10957            findCheapestProductForPartialSelection(optionSelection) {
10958                const candidateProducts = this.findProductIdsForPartialSelection(optionSelection);
10959                return candidateProducts.reduce((cheapest, simpleIdx) => {
10960                    // in the first iteration we start with simpleIdx as the currently cheapest product
10961                    if (! this.optionConfig.optionPrices[cheapest]) return simpleIdx;
10962                    const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount;
10963                    return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount
10964                        ? simpleIdx
10965                        : cheapest;
10966                }, 0)
10967            },
10968            findProductIdToUseForOptionPrice(option) {
10969                // try to find a product for a complete selection
10970                const attributeId = this.findAttributeByOptionId(option.id);
10971                const optionSelection = Object.assign({}, this.selectedValues, {[attributeId]: option.id});
10972                const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection);
10973                // if there is no complete selection, use the cheapest product for the option
10974                return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection);
10975            },
10976            getAttributeOptionLabel() {
10977                const option = this.item;
10978                const optionProduct = this.findProductIdToUseForOptionPrice(option);
10979
10980                if ((! optionProduct) || (optionProduct === this.productIndexForPrice)) {
10981                    return option.label;
10982                }
10983
10984                const currentPrice = this.getOptionPriceAdjustmentBasePrice();
10985
10986                if (this.optionConfig.optionPrices[optionProduct]) {
10987                    const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount;
10988                    if (optionPrice !== currentPrice){
10989                        return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true);
10990                    }
10991                }
10992                return option.label;
10993            },
10994            getOptionPriceAdjustmentBasePrice() {
10995                if (this.optionConfig.optionPrices[this.productIndexForPrice]) {
10996                    return this.optionConfig.optionPrices[this.productIndexForPrice].finalPrice.amount
10997                }
10998                return this.optionConfig.prices.finalPrice.amount; // default price if no option selection
10999            },
11000            isSelected() {
11001                const attributeId = this.getDataAttributeId(this.$el);
11002                return this.selectedValues[attributeId] === this.item.id;
11003            },
11004            clearOptionIfActive() {
11005                const attributeId = this.getDataAttributeId(this.$el);
11006                if (this.selectedValues[attributeId] === this.item.id) {
11007                    this.blurLabel()
11008                    this.changeOption(attributeId, '')
11009                }
11010            },
11011            removeAttrFromSelection(selectedValues, attributeId) {
11012                                attributeId = parseInt(attributeId);
11013                return selectedValues.reduce((newSelection, val, attr) => {
11014                    if (attr !== attributeId) {
11015                        newSelection[attr] = val;
11016                    }
11017                    return newSelection;
11018                }, []);
11019            },
11020            onChangeOption() {
11021                const attributeId = this.getDataAttributeId(this.$event.target);
11022                const optionId = this.$event.target.value;
11023                this.changeOption(attributeId, optionId)
11024            },
11025            changeOption(attributeId, value) {
11026                if (value === '') {
11027                    this.selectedValues = this.removeAttrFromSelection(this.selectedValues, attributeId)
11028                } else if (value && this.getAllowedAttributeOptions(attributeId).find(option => option.id === value)) {
11029                                        this.selectedValues[attributeId] = value;
11030                }
11031                this.findSimpleIndex();
11032                this.findAllowedAttributeOptions();
11033                this.updatePrices();
11034                this.updateGallery();
11035
11036                const candidates = this.findProductIdsForPartialSelection(this.selectedValues);
11037
11038                                window.dispatchEvent(
11039                    new CustomEvent(
11040                        'configurable-selection-changed',
11041                        {
11042                            detail: {
11043                                productId: this.productId,
11044                                optionId: attributeId,
11045                                value: value,
11046                                productIndex: this.productIndex,
11047                                selectedValues: this.selectedValues,
11048                                candidates: candidates,
11049                                skuCandidates: Object.values(candidates).map(id =>
11049 this.optionConfig.sku?.[id] ?? null).filter(Boolean),
11050                            }
11051                        }
11052                    )
11053                );
11054            },
11055            calculateIsMinimalPrice() {
11056                return ! this.isFullSelection(this.selectedValues);
11057            },
11058            isFullSelection(selectedValues) {
11059                return Object.keys(selectedValues).length === this.attributeCount;
11060            },
11061            updatePrices() {
11062                const value = this.optionConfig.optionPrices[this.productIndexForPrice] || this.optionConfig.prices;
11063                window.dispatchEvent(
11064                    new CustomEvent(
11065                        "update-prices-" + this.productId,
11066                        {
11067                            detail: Object.assign(
11068                                value,
11069                                { isMinimalPrice: this.calculateIsMinimalPrice() }
11070                            )
11071                        }
11072                    )
11073                );
11074            },
11075            updateGallery () {
11076                if (this.productIndex) {
11077                    const images = this.optionConfig.images[this.productIndex];
11078                    images && window.dispatchEvent(new CustomEvent(
11079                        "update-gallery",
11080                        { detail: this.sortImagesByPosition(images) }
11081                    ));
11082                } else {
11083                    window.dispatchEvent(new Event("reset-gallery"));
11084                }
11085            },
11086            sortImagesByPosition(images) {
11087                return images.sort((x, y) => {
11088                    return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1)
11089                });
11090            },
11091            onGetCartData() {
11092                const data = this.$event.detail.data;
11093                            },
11094            preselectCartItems(data) {
11095                // pre-select options based on cart data for current (quote) itemId
11096                const cart = data && data.cart;
11097                if (cart && cart.items) {
11098                    const cartItem = cart.items.find((item) => {
11099                        return (
11100                            item.item_id === this.itemId
11101                            && item.product_id === this.productId
11102                        )
11103                    });
11104                    if (cartItem && cartItem.options && cartItem.options.length) {
11105                        cartItem.options.map(option => {
11106                            this.changeOption(option.option_id, option.option_value);
11107                        })
11108                    }
11109                }
11110            },
11111            preselectQuerystringItems() {
11112                // pre-select option like ?size=167
11113                const urlQueryParams = new URLSearchParams(window.location.search.replace('?',''));
11114                this.preselectItemsBasedOnLocation(attribute => urlQueryParams.get(attribute.code));
11115            },
11116            preselectLocationHashItems() {
11117                // pre-select option like #144=167
11118                const urlHashParams = new URLSearchParams(window.location.hash.replace('#',''));
11119                this.preselectItemsBasedOnLocation(attribute => urlHashParams.get(attribute.id));
11120            },
11121            preselectItemsBasedOnLocation(getLocationValue) {
11122                Object.values(this.optionConfig.attributes).map(attribute => {
11123                    const v = getLocationValue(attribute);
11124                    v && this.changeOption(attribute.id, v)
11125                });
11126            }
11127        }
11128    }
11129</script>
vendor: 1 bytes, line 11129
11129
11130<script>
11131    function initSwatchOptions(swatchConfig) {
11132        return {
11133            swatchConfig,
11134            getAttributeSwatchData(attributeId) {
11135                const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]);
11136                swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']);
11137
11138                return swatchConfig;
11139            },
11140            mapSwatchTypeNumberToTypeCode(typeNumber) {
11141                switch ("" + typeNumber) {
11142                    case "1":
11143                        return "color"
11144                    case "2":
11145                        return "image"
11146                    case "3":
11147                        return "empty"
11148                    case "0":
11149                    default:
11150                        return "text"
11151                }
11152            },
11153            getTypeOfFirstOption(attributeId) {
11154                for (const optionId in this.swatchConfig[attributeId]) {
11155                    const option = this.swatchConfig[attributeId][optionId];
11156                    if (typeof option.type !== 'undefined') {
11157                        return this.mapSwatchTypeNumberToTypeCode(option.type);
11158                    }
11159                }
11160            },
11161            getVisualSwatchType(attributeId, targetOptionId) {
11162                // If a type configuration is present for the given option id, use it
11163                const config = this.swatchConfig[attributeId];
11164                if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') {
11165                    return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type);
11166                }
11167
11168                // Otherwise - if no config is present for the target option - use the type of the first option
11169                // with a type property from the attribute, thus assuming its the same type as the target option.
11170                // (This edge case condition can occur on single swatch products if some options are not salable)
11171                return this.getTypeOfFirstOption(attributeId);
11172            },
11173            getSwatchType(attributeId, optionId) {
11174                // Deserialize the attribute details the first time they are used
11175                if (this.swatchConfig[attributeId] && ! this.swatchConfig[attributeId].details) {
11176                    this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId);
11177                }
11178                const type =  this.swatchConfig[attributeId] &&
11179                    this.swatchConfig[attributeId].details &&
11180                    this.swatchConfig[attributeId].details.swatch_input_type ||
11181                    "empty";
11182                return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type;
11183            },
11184            isTextSwatch() {
11185                const attributeId = this.getDataAttributeId(this.$el);
11186                return this.getSwatchType(attributeId, this.item.id) === 'text';
11187            },
11188            isVisualSwatch() {
11189                const attributeId = this.activeTooltipItem.attribute;
11190                const type = this.getSwatchType(attributeId, this.activeTooltipItem.item);
11191
11192                return ['image', 'color'].includes(type);
11193            },
11194            getSwatchBackgroundStyle() {
11195                const attributeId = this.getDataAttributeId(this.$el);
11196                const config = this.getSwatchConfig(attributeId, this.item.id);
11197                const type = this.getSwatchType(attributeId, this.item.id);
11198
11199                if (type === "color") {
11200                        return 'background-color:' + config.value;
11201                } else if (type === "image") {
11202                        return "background: #fff url('" + config.value + "') no-repeat center";
11203                } else {
11204                    return '';
11205                }
11206            },
11207            getSwatchText() {
11208                const attributeId = this.getDataAttributeId(this.$el);
11209                const optionId = this.$el.dataset.optionId || this.selectedValues[attributeId];
11210                const config = this.getSwatchConfig(attributeId, optionId);
11211                return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId);
11212            },
11213            getOptionLabelFromOptionConfig(attributeId, optionId) {
11214                // Fallback if no value is present in swatchConfig data
11215                // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190
11216                const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId);
11217                return option && option[0] && option[0].label ||'';
11218            },
11219            getSwatchConfig(attributeId, optionId) {
11220                return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId]
11221                    ? this.swatchConfig[attributeId][optionId]
11222                    : false;
11223            },
11224            activeTooltipItem: false,
11225            tooltipPositionElement: false,
11226            isTooltipVisible() {
11227                return this.activeTooltipItem &&
11228                    this.getSwatchConfig(
11229                        this.activeTooltipItem.attribute,
11230                        this.activeTooltipItem.item
11231                    );
11232            },
11233            isFirstItemCol() {
11234                return this.activeTooltipItem.index === 0;
11235            },
11236            getTooltipImageStyle() {
11237                const attributeId = this.activeTooltipItem.attribute;
11238                const optionId = this.activeTooltipItem.item;
11239                const config = this.getSwatchConfig(attributeId, optionId);
11240                const type = this.getSwatchType(attributeId, optionId);
11241
11242                if (type === "color") {
11243                    return 'background-color:' + config.value + '; width: 110px; height: 90px;';
11244                } else if (type === "image") {
11245                    return "background: #ffffff url('" + config.thumb +
11246                        "') center center no-repeat; width: 110px; height: 90px;";
11247                } else {
11248                    return 'display:none';
11249                }
11250            },
11251            getTooltipWrapperClasses() {
11252                return {
11253                    '-translate-x-5': this.isFirstItemCol()
11254                }
11255            },
11256            getTooltipPosition() {
11257                return this.tooltipPositionElement ?
11258                    `top: ${this.tooltipPositionElement.offsetTop}px;` +
11259                    `left: ${
11260                        this.tooltipPositionElement.offsetLeft - (
11261                            this.tooltipPositionElement.closest('.snap') &&
11262                            this.tooltipPositionElement.closest('.snap').scrollLeft ||
11263                            0
11264                        )
11265                    }px;` : ''
11266            },
11267            getTooltipLabel() {
11268                return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label
11269            },
11270            focusedLabel: false,
11271            focusLabel(optionId) {
11272                this.focusedLabel = optionId;
11273            },
11274            blurLabel() {
11275                this.focusedLabel = false;
11276            },
11277            getSwatchOptionHtmlId() {
11278                const productId = this.$el.closest('[data-product-id]').dataset.productId;
11279                return this.$id(`attribute-option-${productId}-${this.item.id}`)
11280            },
11281            getSwatchOptionHtmlIdGroup() {
11282                const productId = this.$el.closest('[data-product-id]').dataset.productId;
11283                return [`attribute-option-${productId}-${this.item.id}`];
11284            },
11285            swatchOptionClasses() {
11286                const attributeId = this.getDataAttributeId(this.$el);
11287                return {
11288                    'border-gray-100 ring ring-primary/50': (this.selectedValues[attributeId] === this.item.id),
11289                    'border-gray-300': (this.selectedValues[attributeId] !== this.item.id),
11290                    'w-6 h-6': !this.isTextSwatch(),
11291                    'border-gray-100 ring ring-primary/75': this.focusedLabel === this.item.id,
11292                }
11293            },
11294            outOfStockSwatchWrapperClasses() {
11295                return {
11296                    'w-6 h-6': !this.isTextSwatch(),
11297                }
11298            },
11299            outOfStockSwatchContentClasses() {
11300                return {
11301                    'sr-only': !this.isTextSwatch()
11302                };
11303            },
11304            setActiveTooltipItem() {
11305                this.activeTooltipItem = {
11306                    attribute: this.getDataAttributeId(this.$el),
11307                    item: this.item.id,
11308                    index: this.index
11309                };
11310                this.tooltipPositionElement = this.$event.target;
11311            },
11312            unsetActiveTooltipItem() {
11313                this.activeTooltipItem = false;
11314            },
11315            onFocusSwatchItem() {
11316                this.focusLabel(this.item.id);
11317            },
11318            isSwatchRequired() {
11319                const attributeId = this.getDataAttributeId(this.$el);
11320                return this.getAllowedAttributeOptions(attributeId)
11321                    .filter(attributeOption => this.selectedValues[attributeOption])
11322                    .length === 0
11323            },
11324            modelBinding() {
11325                const attributeId = this.getDataAttributeId(this.$el);
11326                return this.selectedValues[attributeId];
11327            }
11328        }
11329    }
11330</script>
vendor: 1 bytes, line 11330
11330
11331<script>
11332    function initPayPalInContextButton() {
11333        const renderTargetId = this.$root.dataset.renderTargetId;
11334        const config = JSON.parse(this.$root.dataset.clientConfig);
11335        const isMinicart = parseInt(this.$root.dataset.isMiniCart);
11336
11337        return {
11338            cartSection: false,
11339            actions: {},
11340            paypalButtons: null,
11341            getData(sectionData) {
11342                this.cartSection = sectionData.cart;
11343            },
11344            initMiniCartButtons() {
11345                this.cartSection = this.cart;
11346            },
11347                        initializePayPalScript() {
11348                if (!window.paypalScriptPromise) {
11349                    window.paypalScriptPromise = new Promise((resolve, reject) => {
11350                        const scriptId = 'paypal-script';
11351
11352                        const paypalScript = document.getElementById(scriptId);
11353                        if (paypalScript) {
11354                            if (window.paypal) {
11355                                return resolve(window.paypal);
11356                            }
11357                        }
11358
11359                        const script = document.createElement('script');
11360                        script.src = config.sdkUrl;
11361                        script.id = scriptId;
11362                        script.setAttribute('data-partner-attribution-id', config.dataAttributes['data-partner-attribution-id']);
11363                        script.onload = () => resolve(window.paypal);
11364                        script.onerror = () => reject(new Error('PayPal\u0020SDK\u0020could\u0020not\u0020be\u0020loaded'));
11365                        document.body.appendChild(script);
11366                    });
11367                }
11368
11369                return window.paypalScriptPromise;
11370            },
11371            async initializeButtons() {
11372                try {
11373                    const paypal = await this.initializePayPalScript();
11374                    return paypal && paypal.Buttons({
11375                        style: Object.assign({}, config.styles, {
11376                            height: 44, // Sets the style.height option to a value from 25 to 55.
11377                            disableMaxWidth: false, // The button has a default maximum width of 750px, but you can make the button larger with true and set container size
11378                            tagline: false // Set the style.layout to horizontal for taglines.
11379                        }),
11380                        onInit: (data, actions) => {
11381                            this.actions = actions || this.actions;
11382                        },
11383                        onClick: async (data, actions) => {
11384                            this.actions = actions || this.actions;
11385                        },
11386                        createOrder() {
11387                            const params = 'quote_id=' + config.quoteId +
11388                                '&customer_id=' + (config.customerId || '') +
11389                                '&form_key=' + hyva.getFormKey() +
11390                                '&button=' + config.button;
11391
11392                            return window.fetch(config.getTokenUrl, {
11393                                headers: {
11394                                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
11395                                    'X-Requested-With': 'XMLHttpRequest',
11396                                },
11397                                body: params,
11398                                method: 'POST',
11399                                mode: 'cors',
11400                                credentials: 'include'
11401                            })
11402                                .then(response => response.json())
11403                                .then(result => result.token)
11404                                .catch(console.error);
11405                        },
11406
11407                        onApprove(data, actions) {
11408                            const params = 'paymentToken=' + (data.orderID || '') +
11409                                '&payerId=' + (data.payerID || '') +
11410                                '&quoteId=' + (config.quoteId || '') +
11411                                '&customerId=' + (config.customerId || '') +
11412                                '&form_key=' + hyva.getFormKey();
11413
11414                            return window.fetch(config.onAuthorizeUrl, {
11415                                headers: {
11416                                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
11417                                    'X-Requested-With': 'XMLHttpRequest',
11418                                },
11419                                body: params,
11420                                method: 'POST',
11421                                mode: 'cors',
11422                                credentials: 'include'
11423                            })
11424                                .then(response => response.json())
11425                                .then(result => {
11426                                    if (result.success) {
11427                                        return actions.redirect(result.redirectUrl);
11428                                    }
11429
11430                                    throw new Error(result['error_message']);
11431                                })
11432                                .catch(console.error).finally(() => {
11433                                    window.dispatchEvent(new Event('reload-customer-section-data'));
11434                                });
11435                        },
11436                        onCancel(data, actions) {
11437                            window.dispatchEvent(new Event('reload-customer-section-data'));
11438
11439                            if (isMinicart) {
11440                                window.dispatchEvent(new CustomEvent('toggle-cart', {detail: {isOpen: false}}));
11441                            }
11442
11443                            return window.dispatchMessages([{
11444                                type: 'error',
11445                                text: 'Express\u0020Checkout\u0020has\u0020been\u0020canceled.'
11446                            }]);
11447                        },
11448                        onError(err) {
11449                            window.dispatchEvent(new Event('reload-customer-section-data'));
11450
11451                            // Alternative: forward to cart
11452                            //window.location.href = config.onCancelUrl;
11453
11454                            if (isMinicart) {
11455                                window.dispatchEvent(new CustomEvent('toggle-cart', {detail: {isOpen: false}}));
11456                            }
11457
11458                            return window.dispatchMessages([{
11459                                type: 'error',
11460                                text: 'Error\u0020al\u0020inicializar\u0020Express\u0020Checkout,\u0020int\u00E9ntelo\u0020de\u0020nuevo\u0020m\u00E1s\u0020tarde\u0020o\u0020elija\u0020otro\u0020m\u00E9todo\u0020de\u0020checkout.'
11461                            }]);
11462                        }
11463                    })
11464                } catch (error) {
11465                    document.getElementById(renderTargetId).innerHTML = '';
11466                    console.error('Error loading PayPal SDK', error);
11467                }
11468            },
11469            async checkAndInitializeButtons() {
11470                if (this.cartSection.items && this.cartSection.items.length) {
11471                    if (! this.paypalButtons) {
11472                        this.paypalButtons = await this.initializeButtons();
11473                        this.paypalButtons && this.paypalButtons.render(document.getElementById(renderTargetId));
11474                    }
11475                }
11476            }
11477        }
11478    }
11479    window.addEventListener('alpine:init', () => Alpine.data('initPayPalInContextButton', initPayPalInContextButton), {once: true})
11480</script>
vendor: 1 bytes, line 11480
11480
11481<script>
11482    'use strict';
11483
11484    const grecaptchaV2LoadCallbacks = [];
11485
11486    function executeRecaptchaLoadCallbacks () {
11487        while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) {
11488            const callback = grecaptchaV2LoadCallbacks.pop();
11489            typeof callback === 'string' ? window[callback]() : callback();
11490        }
11491    }
11492
11493    (function() {
11494        const loadRecaptchaScript = (event) => {
11495
11496            if (window.grecaptcha || !event.target.form) {
11497                return;
11498            }
11499
11500            const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks';
11501            const siteKey = '6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3';
11502            const script = document.createElement('script');
11503            script.type = 'text/javascript';
11504            script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`;
11505            script.async = true;
11506            document.head.appendChild(script);
11507
11508            script.addEventListener('load', () => {
11509                Array.from(document.querySelectorAll('button[data-recaptcha-btn]:disabled')).forEach(btn => btn.removeAttribute('disabled'));
11510            });
11511        }
11512
11513        window.forceLoadRecaptchaScript = (form) => {
11514            loadRecaptchaScript({target: {form: form || 'dummy'}});
11515            executeRecaptchaLoadCallbacks();
11516        };
11517
11518        document.body.addEventListener('input', loadRecaptchaScript, { once: true });
11519        document.body.addEventListener('focus', loadRecaptchaScript, { once: true });
11520
11521    }());
11522
11523</script>
11523
11524
11525<script>
11526    function initLayeredSwatch() {
11527        return {
11528            getSwatchType(typeNumber) {
11529                switch ("" + typeNumber) {
11530                    case '1':
11531                        return "color"
11532                    case '2':
11533                        return "image"
11534                    case '0':
11535                    default:
11536                        return "text"
11537                }
11538            },
11539            getSwatchBackgroundStyle(type, value, image) {
11540                if (this.getSwatchType(type) === "color") {
11541                    return 'background-color:' + value;
11542                } else if (this.getSwatchType(type) === "image") {
11543                    return "background: #ffffff url('" + image + "') no-repeat center";
11544                } else {
11545                    return '';
11546                }
11547            },
11548            activeTooltipItem: false,
11549            tooltipPositionElement: false,
11550            isTooltipVisible() {
11551                return this.activeTooltipItem
11552            },
11553            isFirstItemCol() {
11554                const left = this.tooltipPositionElement.offsetLeft;
11555                const leftParent = this.tooltipPositionElement.parentNode.offsetLeft;
11556                const width = this.tooltipPositionElement.offsetWidth;
11557                return left - leftParent < width;
11558            },
11559            getTooltipImageStyle() {
11560                const type = this.activeTooltipItem.type;
11561
11562                if (this.getSwatchType(type) === "color") {
11563                    return 'background-color:' + this.activeTooltipItem.value + '; width: 110px; height: 90px;';
11564                } else if (this.getSwatchType(type) === "image") {
11565                    return "background: #ffffff url('" + this.activeTooltipItem.thumb +
11566                        "') center center no-repeat; width: 110px; height: 90px;";
11567                } else {
11568                    return 'display:none';
11569                }
11570            },
11571            getTooltipPosition() {
11572                return this.tooltipPositionElement ?
11573                    (
11574                        `top: ${this.tooltipPositionElement.offsetTop}px;` +
11575                        `left: ${this.tooltipPositionElement.offsetLeft}px;`
11576                    ) : ''
11577            },
11578            getTooltipLabel() {
11579                return this.activeTooltipItem.label || ''
11580            },
11581            isVisualSwatch() {
11582                return this.getSwatchType(this.activeTooltipItem.type) !== 'text'
11583            },
11584            getSwatchTypeClasses() {
11585                return {
11586                    'w-6 h-6': this.getSwatchType(this.$el.dataset.swatchType) !== 'text'
11587                }
11588            },
11589            getNonTextSwatchBackgroundStyle() {
11590                return this.getSwatchBackgroundStyle(this.$el.dataset.swatchType, this.$el.dataset.swatchValue, this.$el.dataset.swatchImage)
11591            },
11592            onMouseEnter() {
11593                this.activeTooltipItem = {
11594                    attribute: this.$el.dataset.swatchValue,
11595                    type: this.$el.dataset.swatchType,
11596                    id: this.$el.dataset.swatchOption,
11597                    label: this.$el.dataset.swatchLabel,
11598                    thumb: this.$el.dataset.swatchThumb,
11599                    value: this.$el.dataset.swatchValue
11600                };
11601                this.tooltipPositionElement = this.$event.target;
11602            },
11603            onMouseLeave() {
11604                this.activeTooltipItem = false;
11605            },
11606            getTooltipWrapperClasses() {
11607                return {
11608                    '-translate-x-5': this.isFirstItemCol()
11609                }
11610            }
11611        }
11612    }
11613    window.addEventListener('alpine:init', () => Alpine.data('initLayeredSwatch', initLayeredSwatch), {once: true})
11614</script>
vendor: 1 bytes, line 11614
11614
11615<script>
11616    (function () {
11617        const modals = [];
11618        const excludedFromFocusTrapping = new Set();
11619
11620        function trapFocusInNextModalWithOverlay() {
11621            for (let idx = modals.length -1; idx >= 0; idx--) {
11622                const nextOnStack = modals[idx];
11623                const nextDialogElement = nextOnStack.instance.$refs[nextOnStack.name];
11624                if (! isOverlayDisabled(nextDialogElement)) {
11625                    hyva.trapFocus(nextDialogElement);
11626                    break;
11627                }
11628            }
11629        }
11630
11631        function focusables(dialogElement) {
11632            const selector = 'button, [href], input, textarea, select, details, [tabindex]:not([tabindex="-1"])';
11633            return Array.from(dialogElement.querySelectorAll(selector))
11634                .filter(el => !el.hasAttribute('disabled'));
11635        }
11636
11637        function firstVisible(elements) {
11638            const a = Array.from(elements);
11639            for (let i = 0; i < a.length; i++) {
11640                if (a[i].offsetWidth || a[i].offsetHeight || a[i].getClientRects().length) return a[i];
11641            }
11642            return null;
11643        }
11644
11645        function isInViewport(element) {
11646            const rect = element && element.getBoundingClientRect();
11647            return rect &&
11648                rect.top >= 0 &&
11649                rect.left >= 0 &&
11650                rect.right <= window.innerWidth &&
11651                rect.bottom <= window.innerHeight;
11652        }
11653
11654        function setFocusAfterTransition(dialogElement, duration) {
11655                        const nested = Array.from(dialogElement.querySelectorAll('[role="dialog"]'));
11656            const candidates = Array.from(dialogElement.querySelectorAll('[x-focus-first]'));
11657            next: for (let candidate of candidates) {
11658                for (let child of nested) {
11659                    if (child.contains(candidate)) continue next;
11660                }
11661                setTimeout(() => candidate.focus(), 50);
11662                break;
11663            }
11664            window.setTimeout(() => {
11665                const focusElement = firstVisible(dialogElement.querySelectorAll('[x-focus-first]')) ||
11666                    focusables(dialogElement)[0] ||
11667                    null;
11668                focusElement && isInViewport(focusElement) && focusElement.focus();
11669            }, Math.max(1, duration));
11670        }
11671
11672        function determineTrigger($refs, dialog, trigger) {
11673                        if (typeof trigger === 'undefined' && typeof dialog === 'object' && dialog.target instanceof HTMLElement) {
11674                return dialog.target;
11675            }
11676                        if (typeof dialog === 'string' && typeof trigger === 'object' && trigger.target instanceof HTMLElement) {
11677                return trigger.target;
11678            }
11679                        if (typeof trigger === 'string') {
11680                try {
11681                    return $refs[trigger] || document.querySelector(trigger)
11682                } catch (e) {}
11683            }
11684                        if (trigger instanceof Element) {
11685                return trigger;
11686            }
11687
11688                        return null;
11689        }
11690
11691        function isOverlayDisabled(dialog) {
11692            return dialog && dialog.hasAttribute('x-no-overlay')
11693        }
11694
11695        function areRemainingModalsWithoutOverlay(modals)
11696        {
11697            const overflowDisabled = modals.map(modal => modal.instance.$refs[modal.name]).filter(isOverlayDisabled);
11698
11699            return overflowDisabled.length === modals.length;
11700        }
11701
11702        window.hyva.modal = function(options = {}) {
11703                        if (this.$el && this.$el.dataset && this.$el.dataset.options) {
11704                try {
11705                    options = Object.assign(options, JSON.parse(this.$el.dataset.options || '{}'));
11706                } catch (e) {
11707                    throw new Error('Cannot read the dialog options from the data-options attribute: not valid JSON');
11708                }
11709            }
11710
11711            const config = Object.assign({
11712                dialog: 'dialog',                 duration: 300,                 transitionEnter: 'transition ease-out duration-300',
11713                transitionEnterStart: 'opacity-0',
11714                transitionEnterEnd: 'opacity-100',
11715                transitionLeave: 'transition ease-in duration-300',
11716                transitionLeaveStart: 'opacity-100',
11717                transitionLeaveEnd: 'opacity-0',
11718            }, options);
11719            let lastHide = 0;
11720
11721            return {
11722                opened: {},
11723                show(dialog, trigger) {
11724                    const focusTargetAfterHide = determineTrigger(this.$refs, dialog, trigger);
11725                    const name = typeof dialog === 'string' ? dialog : config.dialog;
11726                    const dialogElement = this.$refs[name];
11727                    if (! dialogElement) {
11728                                                return;
11729                    }
11730                    const useOverlay = ! dialogElement.hasAttribute('x-no-overlay');
11731
11732                    dialogElement.scrollTop = 0;
11733
11734                                        if (this.opened[name]) {
11735                        return;
11736                    }
11737
11738                    if (focusTargetAfterHide) {
11739                        focusTargetAfterHide.setAttribute('aria-expanded', 'true');
11740                    }
11741
11742                    this.opened[name] = true;
11743                    useOverlay && this.$nextTick(() => hyva.trapFocus(dialogElement));
11744                    setFocusAfterTransition(dialogElement, config.duration);
11745
11746                    const frame = {name, instance: this, focusTarget: focu
11746sTargetAfterHide, time: Date.now()};
11747
11748                    modals.push(frame);
11749                    if (useOverlay) {
11750                        document.body.classList.add('overflow-hidden');
11751                    }
11752                    return new Promise(resolve => frame.resolve = resolve);
11753                },
11754                cancel() {
11755                    this.hide(false);
11756                },
11757                ok() {
11758                    this.hide(true);
11759                },
11760                hide(value) {
11761                                        if (Date.now() - lastHide < config.duration) {
11762                        return;
11763                    }
11764                    lastHide = Date.now();
11765
11766                    const modal = modals.pop() || {};
11767                    if (! modal.instance) {
11768                        return;
11769                    }
11770
11771                    const name = modal.name;
11772                    this.opened[name] = false;
11773                    hyva.releaseFocus(modal.instance.$refs[modal.name])
11774                    trapFocusInNextModalWithOverlay();
11775
11776                    const nextFocusAfterHide = modal.focusTarget;
11777                    nextFocusAfterHide && setTimeout(() => {
11778                        nextFocusAfterHide.setAttribute('aria-expanded', 'false');
11779                        nextFocusAfterHide.focus()
11780                    }, config.duration);
11781
11782                    if (modals.length === 0 || areRemainingModalsWithoutOverlay(modals)) {
11783                        document.body.classList.remove('overflow-hidden');
11784                    }
11785
11786                    modal.resolve(value);
11787                },
11788                overlay(dialog) {
11789                    dialog = this.$el.dataset.dialogRefName || dialog;
11790                    const name = typeof dialog === 'string' ? dialog : config.dialog;
11791                    return {
11792                        ['x-show']() {
11793                            return this.opened[name]
11794                        },
11795                        ['x-transition:enter']: config.transitionEnter,
11796                        ['x-transition:enter-start']: config.transitionEnterStart,
11797                        ['x-transition:enter-end']: config.transitionEnterEnd,
11798                        ['x-transition:leave']: config.transitionLeave,
11799                        ['x-transition:leave-start']: config.transitionLeaveStart,
11800                        ['x-transition:leave-end']: config.transitionLeaveEnd,
11801                        ['@hyva-modal-show.window'](event) {
11802                            event.detail && event.detail.dialog === name && this.show(name, event.detail.focusAfterHide)
11803                        }
11804                    };
11805                },
11806                showDialogOnInit() {
11807                    const parent = this.$el.closest('[data-dialog-ref-name]');
11808                    if (parent && parent.dataset.dialogRefName) {
11809                        this.$dispatch('hyva-modal-show', {dialog: parent.dataset.dialogRefName})
11810                    }
11811                }
11812            };
11813        }
11814
11815        window.hyva.modal.peek = () => modals.length > 0 && modals[modals.length -1]
11816
11817        window.hyva.modal.pop = function () {
11818            if (modals.length > 0) {
11819                const modal = modals[modals.length -1];
11820                modal.instance.hide();
11821            }
11822        }
11823
11824        window.hyva.modal.excludeSelectorsFromFocusTrap = function (selectors) {
11825            typeof selectors === 'string' || selectors instanceof String
11826                ? excludedFromFocusTrapping.add(selectors)
11827                : selectors.map(selector => excludedFromFocusTrapping.add(selector));
11828        }
11829
11830        window.hyva.modal.eventListeners = {
11831            keydown: event => {
11832                if (event.key === 'Escape') {
11833                    window.hyva.modal.pop();
11834                }
11835            },
11836                        click: event => {
11837                if (modals.length > 0) {
11838                    const modal = modals[modals.length -1];
11839                    const dialog = modal.instance.$refs[modal.name];
11840                    if (modal.time + 50 < Date.now() && // if last click processing is more than 50ms ago
11841                        ! isOverlayDisabled(dialog) && // if dialog has overlay
11842                        ! dialog.contains(event.target)) { // if click is outside of dialog
11843                        modal.instance.hide();
11844                    }
11845                }
11846            }
11847        };
11848
11849        document.addEventListener('keydown', window.hyva.modal.eventListeners.keydown);
11850
11851        document.addEventListener('click', window.hyva.modal.eventListeners.click);
11852    })();
11853    window.addEventListener('alpine:init', () => {
11854        Alpine.data('hyvaModal', window.hyva.modal);
11855    }, {once: true});
11856</script>
vendor: 1 bytes, line 11856
11856
11857<script>
11858    function initAmBundlePackGallery() {
11859        return {
11860            "active": 0,
11861            "initialImages": [],
11862            "images": [],
11863            "isSelected" : false,
11864            "currentElement": false,
11865            "appendOnReceiveImages": false,
11866            receiveImages(images) {
11867                if (this.appendOnReceiveImages) {
11868                    const initialUrls = this.initialImages.map(image => image.full);
11869                    const newImages = images.filter(image => ! initialUrls.includes(image.full));
11870                    this.images = [].concat(this.initialImages, newImages);
11871                    this.setActive(newImages.length ? this.initialImages.length : 0);
11872                } else {
11873                    this.images = images;
11874                }
11875            },
11876            init() {
11877                this.appendOnReceiveImages = this.$el.dataset.appendOnReceiveImages;
11878                this.currentElement = this.$el;
11879                let active = this.images.findIndex(function(image) {
11880                    return image.isMain === true
11881                });
11882                if (active === -1) {
11883                    active = 0;
11884                }
11885                this.setActive(active);
11886            },
11887            setActive(index) {
11888                this.active = index;
11889            },
11890            resetGallery() {
11891                this.images = this.initialImages;
11892                this.setActive(0);
11893            },
11894            imageCaption() {
11895                return this.image.caption || this.$el.dataset.productName;
11896            },
11897            imageSrc() {
11898                return this.image.img;
11899            },
11900            typeLoading() {
11901                return this.active !== this.index ? 'lazy' : 'eager';
11902            },
11903            showImg() {
11904                return this.active === this.index;
11905            },
11906            eventListeners: {
11907                ['@update-gallery.window'](event) {
11908                    setTimeout(() => {
11909                        if (this.isSelected) {
11910                            this.receiveImages(event.detail);
11911                        }
11912                        this.isSelected = false;
11913                    }, 0)
11914                },
11915                ['@bundle-popup-gallery-option-selected.window'](event) {
11916                    let product = this.currentElement.closest('.amrelated-product-info');
11917                    let currentId = event.detail.getAttribute('id');
11918                    if (product.querySelector('#' + currentId)){
11919                        this.isSelected = true;
11920                    }
11921                },
11922                ['@reset-gallery.window'](event) {
11923                    this.resetGallery();
11924                }
11925            }
11926        }
11927    }
11928
11929    window.addEventListener(
11930        'alpine:init',
11931        () => Alpine.data('initAmBundlePackGallery', initAmBundlePackGallery),
11932        { once: true }
11933    );
11934</script>
11934
11935    
11935<script>
11936        function amBundlePackAddPopupData() {
11937            return {
11938                popupData: '',
11939                forms: false,
11940                formsData: '',
11941                popupWrapper: '',
11942                selectors: {
11943                    forms: '.amrelated-product-info form.info-container-form',
11944                    innerForm: 'form[id*="product_addtocart_form"]',
11945                    body: 'body',
11946                    productPageClass: 'catalog-product-view',
11947                    cartPageClass: 'checkout-cart-index',
11948                    popupWrapper: '[x-ref="bundlePopup"]',
11949                    hidePopupButtonClass: '.hide-bundle-popup',
11950                    swatchInputs: '.amrelated-product-info.configurable .product-option-value-input, .amrelated-product-info.configurable select'
11951                },
11952
11953                init() {
11954                    this.popupData = JSON.parse(this.$el.dataset.config);
11955                    this.isOsnHyvaEnabled = Boolean(Number(this.$el.dataset.isOsnHyvaEnabled));
11956                    this.forms = this.$el.querySelectorAll(this.selectors.forms);
11957                    this.popupWrapper = this.$el.closest(this.selectors.popupWrapper);
11958                    this.$nextTick(() => {
11959                        this.$el.addEventListener('change', (event) => {
11960                            if (event.target.closest(this.selectors.swatchInputs)) {
11961                                window.dispatchEvent(new CustomEvent('bundle-popup-gallery-option-selected', { detail: event.target }));
11962                            }
11963                        });
11964                    })
11965                },
11966
11967                serializeForm(form) {
11968                    const data = new FormData(form)
11969                    let array = [];
11970                    this._setInputsToArray(data, array);
11971
11972                    if (this.isOsnHyvaEnabled) {
11973                        if (form.querySelector(this.selectors.innerForm)) {
11974                            const data = new FormData(form.querySelector(this.selectors.innerForm));
11975                            this._setInputsToArray(data, array);
11976                        }
11977                    }
11978
11979                    return array;
11980                },
11981
11982                _setInputsToArray(data, arrayToSet) {
11983                    for (let [key, value] of data) {
11984                        arrayToSet.push({
11985                            name: key,
11986                            value: value
11987                        });
11988                    }
11989                },
11990
11991                getIsProductPage() {
11992                    return !!document.querySelector(this.selectors.body)
11993                        .classList.contains(this.selectors.productPageClass);
11994                },
11995
11996                getIsCartPage() {
11997                    return !!document.querySelector(this.selectors.body)
11998                        .classList.contains(this.selectors.cartPageClass);
11999                },
12000
12001                scrollToElement(el) {
12002                    el.scrollIntoView({
12003                        behavior: "smooth",
12004                        block: "start"
12005                    });
12006                },
12007
12008                scrollToTop() {
12009                    window.scrollTo({ top: 0, behavior: 'smooth' });
12010                },
12011
12012                validateProductForm(form) {
12013                    let flag = false;
12014                    let isValid = form.reportValidity();
12015                    if (isValid) {
12016                        flag = true;
12017                    } else {
12018                        this.scrollToElement(form);
12019                    }
12020                    return flag;
12021                },
12022
12023                prepareData() {
12024                    const inCartResponse = this.popupData.productsInCart;
12025                    let data = false;
12026                    let serializedForms = [];
12027                    let formsData = '';
12028                    let isFormsValid = true;
12029
12030                    this.forms.forEach((form) => {
12031                        if (this.isOsnHyvaEnabled) {
12032                            if (form.querySelector(this.selectors.innerForm)) {
12033                                if (!this.validateProductForm(form.querySelector(this.selectors.innerForm))) {
12034                                    isFormsValid = false;
12035                                    return false;
12036                                }
12037                            }
12038                        }
12039
12040                        if (!this.validateProductForm(form)) {
12041                            isFormsValid = false;
12042                            return false;
12043                        }
12044                    });
12045
12046                    if (isFormsValid) {
12047                        //forms data collect
12048                        this.forms.forEach((form) => {
12049                            serializedForms.push(this.serializeForm(form));
12050                        });
12051
12052                        serializedForms.forEach((form) => {
12053                            formsData += 'amrelated_products_popup[]=';
12054                            form.forEach((fileld, index, currentForm) => {
12055                                formsData += fileld.name + '=' + fileld.value
12056                                    + (currentForm.length > (index + 1) ? encodeURIComponent('&') : '');
12057                            })
12058                            formsData += '&';
12059                        })
12060
12061                        data = formsData;
12062
12063                        //product in cart data
12064                        for (let productId in inCartResponse) {
12065                            data += 'products_in_cart[' + productId + '][qty]=' + inCartResponse[productId]['qty'] + '&';
12066                        }
12067
12068                        data += 'ajax_cart=' + this.popupData.isAjaxCartEnabled;
12069                        data += '&form_key=' + hyva.getFormKey();
12070                        data += '&product_page=' + this.getIsProductPage();
12071                        data += '&pack_id=' + this.popupData.packId;
12072                    }
12073
12074                    return data;
12075                },
12076
12077                addToCart() {
12078                    const data = this.prepareData();
12079                    if (!data) {
12080                        return;
12081                    }
12082                    this.isLoading = true;
12083                    fetch(this.popupData.url, {
12084                        headers: {
12085                            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
12086                        },
12087                        body: new URLSearchParams(data),
12088                        method: "POST",
12089                        mode: "cors",
12090                        credentials: "include"
12091                    }).then(
12092                        response => response.json()
12093                    ).then((result) => {
12094                        if (result.backUrl) {
12095                            window.location.href = result.backUrl;
12096                        } else {
12097                            window.dispatchEvent(new CustomEvent('mostviewed-items-added'));
12098                            const ref = this.$el.closest('[x-ref]').getAttribute('x-ref');
12099                            if (ref) {
12100                                window.dispatchEvent(new CustomEvent('amrelated-modal-hide', {detail: ref}));
12101                            }
12102                        }
12103                    }).catch(() => {
12104                        dispatchMessages([{
12105                            type: "error",
12106                            text: "Something went wrong. Please try again later."
12107                        }], 2000);
12108                        const ref = this.$el.closest('[x-ref]').getAttribute('x-ref');
12109                        if (ref) {
12110                            window.dispatchEvent(new CustomEvent('amrelated-modal-hide', {detail: ref}));
12111                        }
12112                    }).finally(() => {
12113                        this.isLoading = false;
12114                        this.scrollToTop();
12115                    })
12116                }
12117            }
12118        }
12119
12120        window.addEventListener(
12121            'alpine:init',
12122            () => Alpine.data('amBundlePackAddPopupData', amBundlePackAddPopupData),
12123            { once: true }
12124        );
12125    </script>
vendor: 1 bytes, line 12125
12125
12126<script>
12127    function initAmBundlePackWishlist() {
12128        return {
12129            addToWishlist() {
12130                const productId = this.$el.dataset.productId;
12131                const postParams =                 {
12132                    action: BASE_URL + "wishlist/index/add/",
12133                        data: {
12134                    product: productId,
12135                        uenc: hyva.getUenc()
12136                }
12137                }
12138                
12139                postParams.data['form_key'] = hyva.getFormKey();
12140                postParams.data['qty'] = document.getElementById(`qty[${productId}]`)
12141                    ? document.getElementById(`qty[${productId}]`).value || 1
12142                    : 1;
12143
12144                let postData = Object.keys(postParams.data).map(key => {
12145                    return `${key}=${postParams.data[key]}`;
12146                }).join('&');
12147
12148                // take the all the input fields that configure this product
12149                // includes custom, configurable, grouped and bundled options
12150                Array.from(document.querySelectorAll(
12151                    '[name^=options], [name^=super_attribute], [name^=bundle_option], [name^=super_group], [name^=links]')
12152                ).map(input => {
12153                    if (input.type === "select-multiple") {
12154                        Array.from(input.selectedOptions).forEach(option => {
12155                            postData += `&${input.name}=${option.value}`
12156                        })
12157                    } else {
12158                        // skip "checkable inputs" that are not checked
12159                        if(!(['radio', 'checkbox', 'select'].includes(input.type) && !input.checked)) {
12160                            postData += `&${input.name}=${input.value}`
12161                        }
12162                    }
12163                });
12164                fetch(postParams.action, {
12165                    "headers": {
12166                        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
12167                    },
12168                    "body": postData,
12169                    "method": "POST",
12170                    "mode": "cors",
12171                    "credentials": "include"
12172                }).then((response) => {
12173                    if (response.redirected) {
12174                        window.location.href = response.url;
12175                    } else if (response.ok) {
12176                        return response.json();
12177                    } else {
12178                        typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
12179                            [{
12180                                type: "warning",
12181                                text: "No se ha podido añadir el artículo a la lista de deseos."
12182                            }], 5000
12183                        );
12184                    }
12185                }).then((response) => {
12186                    if (!response) {
12187                        return;
12188                    }
12189                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
12190                        [{
12191                            type: (response.success) ? "success" : "error",
12192                            text: (response.success)
12193                                ? "Producto has been added to your Wish List."
12194                                : response.error_message
12195                        }], 5000
12196                    );
12197                    const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data");
12198                    window.dispatchEvent(reloadCustomerDataEvent);
12199                }).catch((error) => {
12200                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
12201                        [{
12202                            type: "error",
12203                            text: error
12204                        }], 5000
12205                    );
12206                });
12207            }
12208        }
12209    }
12210    window.addEventListener('alpine:init', () => Alpine.data('initAmBundlePackWishlist', initAmBundlePackWishlist), {once: true})
12211</script>
12211
12212    
12212<script>
12213        function initAmBundlePackCompareOnProductView() {
12214            return {
12215                addToCompare: function () {
12216                    const productId = 1;
12217                    const formKey = hyva.getFormKey();
12218                    const postUrl = BASE_URL + 'catalog/product_compare/add/';
12219
12220                    fetch(postUrl, {
12221                        "headers": {
12222                            "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
12223                        },
12224                        "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(),
12225                        "method": "POST",
12226                        "mode": "cors",
12227                        "credentials": "include"
12228                    }).then(function (response) {
12229                        if (response.redirected) {
12230                            window.location.href = response.url;
12231                        }
12232                    }).catch(function (error) {
12233                        typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
12234                            [{
12235                                type: "error",
12236                                text: error
12237                            }], 5000
12238                        );
12239                    });
12240                }
12241            };
12242        }
12243        window.addEventListener('alpine:init', () => Alpine.data('initAmBundlePackCompareOnProductView', initAmBundlePackCompareOnProductView), {once: true})
12244    </script>
vendor: 1 bytes, line 12244
12244
12245<script>
12246    'use strict';
12247
12248    function initAmRelatedSplide() {
12249        return {
12250            isLoading: true,
12251            sliderDefaultConfig: {
12252                perPage: Number(this.$el.dataset.slidesPerView),
12253                focus: 0,
12254                type: 'loop',
12255                breakpoints: {
12256                    1280: {
12257                        perPage: 3
12258                    },
12259                    992: {
12260                        perPage: 2
12261                    },
12262                    576: {
12263                        perPage: 1
12264                    }
12265                },
12266                classes: {
12267                    arrow: 'splide__arrow bg-neutral-700! [&_svg]:fill-white! size-8! top-1/2! -translate-y-1/2! absolute!',
12268                    prev: 'splide__arrow--prev left-0!',
12269                    next: 'splide__arrow--next right-0!',
12270                    pagination: 'splide__pagination flex! lg:gap-5!',
12271                    page: 'splide__pagination__page hover:bg-neutral-700! bg-stone-300! size-2! [&.is-active]:transform-none! [&.is-active]:bg-neutral-700!',
12272                }
12273            },
12274            init() {
12275                window.addEventListener('amsplide-loaded', () => {
12276                    this.initializeSplide();
12277                }, { once: true });
12278                window.dispatchEvent(new CustomEvent('load-amsplide'));
12279                this.$watch('isLoading', (isLoading) => {
12280                    !isLoading && this.$nextTick(this.lazyloadCallback);
12281                });
12282            },
12283            initializeSplide() {
12284                const splideContainer = this.$refs.splideContainer;
12285                const splideInstance = new Splide(splideContainer, this.adjustPageItemsConfig(this.sliderDefaultConfig));
12286
12287                splideInstance.on('moved', this.lazyloadCallback);
12288                splideInstance.mount();
12289                this.isLoading = false;
12290            },
12291            adjustPageItemsConfig: function (config) {
12292                const slideCount = Number(this.$el.dataset.itemsCount);
12293                const breakpointsData = Object.entries(config.breakpoints)
12294                    .map(([breakpoint, option]) =>
12295                        [
12296                            breakpoint,
12297                            { ...config.breakpoints?.[breakpoint], ...this.getItemsPerPageConfig(option, slideCount) }
12298                        ]
12299                    );
12300
12301                return {
12302                    ...config,
12303                    ...this.getItemsPerPageConfig(config, slideCount),
12304                    breakpoints: {
12305                        ...Object.fromEntries(breakpointsData)
12306                    }
12307                }
12308            },
12309            getItemsPerPageConfig: function (config, slideCount) {
12310                const { perPage } = config;
12311                if (!perPage) {
12312                    return config;
12313                }
12314                const shouldHideControls = perPage >= slideCount;
12315                const itemsPerPage = shouldHideControls ? slideCount : perPage;
12316
12317                return {
12318                    perPage: itemsPerPage,
12319                    clones: shouldHideControls ? 0 : 2 * itemsPerPage,
12320                    pagination: !shouldHideControls,
12321                    arrows: !shouldHideControls,
12322                    drag: !shouldHideControls,
12323                    ...(shouldHideControls && { width: 'fit-content' })
12324                }
12325            },
12326            isNotLoading() {
12327                return !this.isLoading;
12328            },
12329            lazyloadCallback: function () {
12330                window.amlazycallback?.();
12331            }
12332        };
12333    }
12334
12335    window.addEventListener(
12336        'alpine:init',
12337        () => Alpine.data('initAmRelatedSplide', initAmRelatedSplide),
12338        { once: true }
12339    );
12340</script>
12340
12341
12342<script>
12343    'use strict';
12344    (() => {
12345        function _calculateStrength({elementID, valid}) {
12346            const password = document.getElementById(elementID),
12347                emailElm = document.getElementById('email_address');
12348            let displayScore;
12349            // Display score is based on combination of whether password is empty, valid, and zxcvbn strength
12350            if (!password || !password.value) {
12351                displayScore = 0;
12352            } else {
12353                // We should only perform this check in case there is an email field on screen
12354                if (emailElm && password.value && emailElm.value &&
12355                    password.value.toLowerCase() === emailElm.value.toLowerCase()) {
12356                    displayScore = 1;
12357                } else {
12358                    const zxcvbnScore = zxcvbn(password.value).score;
12359                    displayScore = valid && zxcvbnScore > 0 ? zxcvbnScore : 1;
12360                }
12361            }
12362
12363            _displayStrength(displayScore);
12364        }
12365
12366        function _displayStrength(displayScore) {
12367            let strengthLabel = '',
12368                className;
12369
12370            switch (displayScore) {
12371                case 0:
12372                    strengthLabel = "Ninguna\u0020contrase\u00F1a";
12373                    className = 'password-none';
12374                    break;
12375
12376                case 1:
12377                    strengthLabel = "D\u00E9bil";
12378                    className = 'password-weak';
12379                    break;
12380
12381                case 2:
12382                    strengthLabel = "Medio";
12383                    className = 'password-medium';
12384                    break;
12385
12386                case 3:
12387                    strengthLabel = "Fuerte";
12388                    className = 'password-strong';
12389                    break;
12390
12391                case 4:
12392                    strengthLabel = "Muy\u0020fuerte";
12393                    className = 'password-very-strong';
12394                    break;
12395            }
12396            const meterElm = document.getElementById('password-strength-meter-container'),
12397                meterLabelElm = document.getElementById('password-strength-meter-label');
12398            meterElm.className = '';
12399            meterElm.classList.add(className);
12400            meterLabelElm.textContent = strengthLabel;
12401        }
12402
12403        let loading = false;
12404        const callbacks = [];
12405
12406        function loadZxcvbn(cb) {
12407            callbacks.push(cb);
12408            if (loading) return;
12409            loading = true;
12410
12411            const script = document.createElement('script');
12412            script.type = 'text/javascript';
12413            script.src = 'https\u003A\u002F\u002Fwww.mueblesbonitos.com\u002Fstatic\u002Ffrontend\u002FMb\u002FHyva2\u002Fes_ES\u002Fjs\u002Fzxcvbn.js';
12414            script.async = true;
12415            script.onload = () => callbacks.forEach(cb => cb());
12416            document.head.appendChild(script);
12417        }
12418
12419        window.addEventListener('password-validate', function (evt) {
12420            const meterElm = document.getElementById('password-strength-meter-container'),
12421                meterLabelElm = document.getElementById('password-strength-meter-label');
12422            if (meterElm && meterLabelElm) {
12423                if (evt.detail && evt.detail.elementID) {
12424                    const cb = () => _calculateStrength(evt.detail);
12425                    window.zxcvbn ? cb() : loadZxcvbn(cb)
12426                }
12427            }
12428        });
12429
12430
12431        document.addEventListener('DOMContentLoaded', () => {
12432            hyva && hyva.formValidation && hyva.formValidation.addRule('password-strength', function(value, options, field, context) {
12433                let counter = 0;
12434                const minCharacterSets = options.minCharacterSets !== undefined ?  options.minCharacterSets : 1;
12435                if (value.match(/\d+/)) {
12436                    counter++;
12437                }
12438
12439                if (value.match(/[a-z]+/)) {
12440                    counter++;
12441                }
12442
12443                if (value.match(/[A-Z]+/)) {
12444                    counter++;
12445                }
12446
12447                if (value.match(/[^a-zA-Z0-9]+/)) {
12448                    counter++;
12449                }
12450
12451                queueMicrotask(() => {
12452                    window.dispatchEvent(new CustomEvent('password-validate', { detail: {
12453                            elementID: field.element.id || 'password',
12454                            valid: field.state.valid
12455                        }}));
12456                });
12457
12458                if (counter < minCharacterSets) {
12459                    const missing = minCharacterSets - counter;
12460                    return hyva.str('La\u0020contrase\u00F1a\u0020debe\u0020incluir\u0020al\u0020menos\u0020\u00251\u0020o\u0020m\u00E1s\u0020de\u0020los\u0020siguientes\u003A\u0020may\u00FAsculas\u0020\u0028A\u002DZ\u0029,\u0020min\u00FAsculas\u0020\u0028a\u002Dz\u0029,\u0020n\u00FAmero\u0020y\u0020s\u00EDmbolo.', missing);
12461                }
12462                return true;
12463            });
12464        })
12465    })();
12466
12467</script>
vendor: 1 bytes, line 12467
12467
12468<script type="text/json" id="default-section-data">
12469    {"messages":[],"customer":[],"compare-products":[],"last-ordered-items":[],"cart":[],"directory-data":{"ES":{"name":"Espa\u00f1a","regions":{"130":{"code":"A Coru\u0441a","name":"A Coru\u00f1a"},"131":{"code":"Alava","name":"Alava"},"132":{"code":"Albacete","name":"Albacete"},"133":{"code":"Alicante","name":"Alicante"},"134":{"code":"Almeria","name":"Almeria"},"135":{"code":"Asturias","name":"Asturias"},"136":{"code":"Avila","name":"Avila"},"137":{"code":"Badajoz","name":"Badajoz"},"138":{"code":"Baleares","name":"Baleares"},"139":{"code":"Barcelona","name":"Barcelona"},"140":{"code":"Burgos","name":"Burgos"},"141":{"code":"Caceres","name":"Caceres"},"142":{"code":"Cadiz","name":"Cadiz"},"143":{"code":"Cantabria","name":"Cantabria"},"144":{"code":"Castellon","name":"Castellon"},"145":{"code":"Ceuta","name":"Ceuta"},"146":{"code":"Ciudad Real","name":"Ciudad Real"},"147":{"code":"Cordoba","name":"Cordoba"},"148":{"code":"Cuenca","name":"Cuenca"},"149":{"code":"Girona","name":"Girona"},"150":{"code":"Granada","name":"Granada"},"151":{"code":"Guadalajara","name":"Guadalajara"},"152":{"code":"Guipuzcoa","name":"Guipuzcoa"},"153":{"code":"Huelva","name":"Huelva"},"154":{"code":"Huesca","name":"Huesca"},"155":{"code":"Jaen","name":"Jaen"},"156":{"code":"La Rioja","name":"La Rioja"},"157":{"code":"Las Palmas","name":"Las Palmas"},"158":{"code":"Leon","name":"Leon"},"159":{"code":"Lleida","name":"Lleida"},"160":{"code":"Lugo","name":"Lugo"},"161":{"code":"Madrid","name":"Madrid"},"162":{"code":"Malaga","name":"Malaga"},"163":{"code":"Melilla","name":"Melilla"},"164":{"code":"Murcia","name":"Murcia"},"165":{"code":"Navarra","name":"Navarra"},"166":{"code":"Ourense","name":"Ourense"},"167":{"code":"Palencia","name":"Palencia"},"168":{"code":"Pontevedra","name":"Pontevedra"},"169":{"code":"Salamanca","name":"Salamanca"},"170":{"code":"Santa Cruz de Tenerife","name":"Santa Cruz de Tenerife"},"171":{"code":"Segovia","name":"Segovia"},"172":{"code":"Sevilla","name":"Sevilla"},"173":{"code":"Soria","name":"Soria"},"174":{"code":"Tarragona","name":"Tarragona"},"175":{"code":"Teruel","name":"Teruel"},"176":{"code":"Toledo","name":"Toledo"},"177":{"code":"Valencia","name":"Valencia"},"178":{"code":"Valladolid","name":"Valladolid"},"179":{"code":"Vizcaya","name":"Vizcaya"},"180":{"code":"Zamora","name":"Zamora"},"181":{"code":"Zaragoza","name":"Zaragoza"}}},"data_id":1791444297},"captcha":[],"instant-purchase":[],"loggedAsCustomer":[],"persistent":[],"review":[],"payments":[],"wishlist":{"items":[]},"amfacebook-pixel":[],"hyva_checkout":[],"multisafepay-payment-request":[],"recently_viewed_product":[],"recently_compared_product":[],"product_data_storage":[],"paypal-billing-agreement":[],"paypal-buyer-country":[]}</script>
12469
12470    
12470<script>
12471    const AmAuthPopupReloadContent = function () {
12472        const customerMenuSelector = '\u0023customer\u002Dmenu\u0020\u007E\u0020nav';
12473
12474        return {
12475            contentUpdaters: [],
12476
12477            initContentUpdaters() {
12478                window.addEventListener('amsl-register-content-updater', (event) => {
12479                    event.stopPropagation();
12480                    if (typeof event.detail === 'function') {
12481                        this.registerContentUpdater(event.detail);
12482                    }
12483                }, true)
12484            },
12485
12486            reloadContent() {
12487                return Promise.all([
12488                    this.reloadHeader(),
12489                    ...this.contentUpdaters.map(updater => updater())
12490                ]).then(this.updateFormKey);
12491            },
12492
12493            registerContentUpdater(updater) {
12494                this.contentUpdaters.push(updater);
12495            },
12496
12497            async reloadHeader() {
12498                const response = await fetch(
12499                    `${BASE_URL}amsociallogin_hyva\u002Fheader\u002Fupdate?isAjax=1`,
12500                    {
12501                        method: 'GET',
12502                        headers: {
12503                            'Content-type': 'application/json'
12504                        }
12505                    }
12506                );
12507
12508                const result = await response.json();
12509                const {customer_menu_html: customerMenuHtml} = result;
12510                const container = document.createElement('div');
12511                container.innerHTML = customerMenuHtml;
12512                const currentMenu = document.querySelector(customerMenuSelector);
12513                const newMenu = container.querySelector(customerMenuSelector);
12514
12515                if (currentMenu && newMenu) {
12516                    currentMenu.replaceWith(newMenu);
12517                }
12518            },
12519
12520            updateFormKey() {
12521                const formKeyInputs = document.querySelectorAll('input[name="form_key"]');
12522                formKeyInputs.forEach(input => input.value = hyva.getFormKey());
12523            }
12524        }
12525    }
12526</script>
vendor: 1 bytes, line 12526
12526
12527<script>
12528        const AmAuthPopupRedirect = function () {
12529        const redirectTimeout = 2000;
12530        const redirectUrl = 'https://www.mueblesbonitos.com/customer/account/';
12531
12532        return {
12533            processRedirect(forceRedirectUrl) {
12534                if (forceRedirectUrl) {
12535                    setTimeout(() => {
12536                        this.resetSessionCookie();
12537                        window.location.assign(forceRedirectUrl);
12538                    }, redirectTimeout);
12539                    return;
12540                }
12541                                    this.reloadViaAjax();
12542                                                            },
12543
12544            reloadCustomerData() {
12545                this.resetSessionCookie();
12546                window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
12547            },
12548
12549            resetSessionCookie() {
12550                hyva.setCookie('mage-cache-sessid', '', -1, true);
12551            },
12552
12553            reloadPage() {
12554                                setTimeout(() => {
12555                    this.resetSessionCookie();
12556                    window.location.reload(true)
12557                }, redirectTimeout)
12558            },
12559
12560            reloadViaAjax() {
12561                window.addEventListener('private-content-loaded', () => {
12562                    this.reloadContent().then(() => {
12563                                                window.dispatchEvent(
12564                            new CustomEvent('amsl-content-updated')
12565                        );
12566                    }).catch(
12567                        (error) => {
12568                            console.error(error);
12569                            this.reloadPage();
12570                        }
12571                    );
12572                }, {once: true});
12573                this.reloadCustomerData();
12574                                window.dispatchEvent(
12575                    new CustomEvent('amsl-popup-ajax-login-success')
12576                );
12577            }
12578        }
12579    }
12580</script>
vendor: 1 bytes, line 12580
12580
12581<script>
12582    const AmAuthPopupNotification = function () {
12583        const modalName = 'amsl\u002Dpopup\u002Dnotification';
12584
12585        return {
12586            ...AmAuthPopupModal(modalName),
12587            notification: '',
12588
12589            initialize() {
12590                this.initModalSettings();
12591            },
12592
12593            // x-on:amsl-popup-show-notification.window="onShowNotification"
12594            onShowNotification(event) {
12595                this.showNotification(event && event.detail);
12596            },
12597
12598            showNotification(messages) {
12599                if (!messages) {
12600                    return;
12601                }
12602
12603                this.notification = Array.isArray(messages) ? messages.join('<br>') : messages;
12604
12605                window.dispatchEvent(new CustomEvent('amsl-hide-popup'));
12606
12607                this.show(modalName);
12608            },
12609
12610            // Para el botón de cerrar del contenido: x-on:click="closeNotification"
12611            closeNotification() {
12612                this.hide();
12613            },
12614
12615            hasNotification() {
12616                return !!this.notification;
12617            }
12618        }
12619    }
12620
12621    ;(() => {
12622        // Durante la carga de la página: esperar a alpine:init (todos los scripts ya definidos).
12623        // Si el script llega tarde (p.ej. dentro de un <template x-if>), registrar directamente.
12624        const register = () => Alpine.data('AmAuthPopupNotification', AmAuthPopupNotification);
12625        (document.readyState === 'loading' || !window.Alpine)
12626            ? window.addEventListener('alpine:init', register, {once: true})
12627            : register();
12628    })();
12629</script>
vendor: 1 bytes, line 12629
12629
12630<script>
12631    const AmAuthPopupModal = function (modalName) {
12632        const canCloseByOverlayClick = true;
12633
12634        return {
12635            ...hyva.modal(),
12636            animationDuration: 500,
12637
12638            initModalSettings() {
12639                if (!canCloseByOverlayClick) {
12640                    this.restrictOverlayClick();
12641                }
12642            },
12643
12644            restrictOverlayClick() {
12645                document.addEventListener('click', (event) => {
12646                    const modal = this.$refs[modalName];
12647                    const isVisible = this.opened[modalName];
12648                    if (isVisible && !modal.contains(event.target) && !modal.hasAttribute('x-no-overlay')) {
12649                        event.stopPropagation();
12650                    }
12651                }, {capture: true});
12652            }
12653        }
12654    }
12655</script>
12655
12656        
12656<script>
12657    function AmSocialLogin() {
12658        return {
12659            socialErrorMessage: '',
12660            isPopupEnabled: '1',
12661
12662            initializeSocialLogin() {
12663                this.initContentUpdaters();
12664            },
12665
12666            socialLoginClick(event) {
12667                const form = event.currentTarget;
12668
12669                if (this.isPopupEnabled) {
12670                    form.target = '_blank';
12671                    form.action = form.action + '&isAjax=true';
12672                }
12673
12674                const channel = new BroadcastChannel('amSocialLoginData');
12675                channel.addEventListener('message', this.onMessageEvent.bind(this));
12676
12677                event.stopPropagation();
12678                event.preventDefault();
12679                form.submit();
12680
12681                return false;
12682            },
12683
12684            onSocialResponse(data) {
12685                const isSuccessfulResult = data.result === 1;
12686
12687                if (isSuccessfulResult) {
12688                    window.dispatchEvent(
12689                        new CustomEvent(
12690                            'amsl-popup-show-notification',
12691                            {
12692                                detail: data.messages
12693                            }
12694                        )
12695                    );
12696                    this.processRedirect();
12697                } else {
12698                    const redirectData = data?.redirect_data;
12699
12700                    this.socialErrorMessage = data.messages.pop();
12701                    setTimeout(() => {
12702                        this.socialErrorMessage = '';
12703                    }, 5000);
12704
12705                    if (this.shouldCustomUrlRedirectWithError(redirectData)) {
12706                        return this.processRedirect(redirectData?.url);
12707                    }
12708
12709                    if (redirectData?.redirectWithError) {
12710                        this.processRedirect();
12711                    }
12712                }
12713            },
12714
12715            // Helper CSP: x-if="hasSocialError"
12716            hasSocialError() {
12717                return !!this.socialErrorMessage;
12718            },
12719
12720            shouldCustomUrlRedirectWithError(redirectData) {
12721                return (
12722                    redirectData &&
12723                    redirectData.redirect &&
12724                    redirectData.redirectWithError &&
12725                    redirectData.url
12726                );
12727            },
12728
12729            onMessageEvent(event) {
12730                if (event.origin !== window.location.origin) {
12731                    return;
12732                }
12733
12734                const data = JSON.parse(event.data);
12735                if (data['redirect_data']) {
12736                    this.onSocialResponse(data);
12737                }
12738            },
12739
12740            ...AmAuthPopupRedirect(),
12741            ...AmAuthPopupReloadContent()
12742        }
12743    }
12744
12745    ;(() => {
12746        // Durante la carga de la página: esperar a alpine:init (todos los scripts ya definidos).
12747        // Si el script llega tarde (p.ej. dentro de un <template x-if>), registrar directamente.
12748        const register = () => Alpine.data('AmSocialLogin', AmSocialLogin);
12749        (document.readyState === 'loading' || !window.Alpine)
12750            ? window.addEventListener('alpine:init', register, {once: true})
12751            : register();
12752    })();
12753</script>
12753
12754
12755                    
12755<script>
12756    const AmAuthPopup = function () {
12757        const TAB_ID_LOGIN = 'amsl\u002Dlogin';
12758        const TAB_ID_REGISTER = 'amsl\u002Dregister';
12759        const TAB_ID_FORGOT = 'amsl\u002Dforgot';
12760        const IS_KNOWN_CUSTOMER = false;
12761        const modalName = 'social\u002Dlogin\u002Dpopup';
12762        let componentInitialized = false;
12763
12764        const reCaptchaStatusBySection = {
12765            login: '1',
12766            register: '1',
12767            forgotPassword: '1',
12768        }
12769
12770        const reCaptchaStatusFor = section => reCaptchaStatusBySection[section];
12771
12772        return {
12773            isGuestCheckoutAllowed: true,
12774            isAccountForgotPasswordPage: false,
12775            activeTab: TAB_ID_LOGIN,
12776            tabs: [TAB_ID_LOGIN, TAB_ID_REGISTER],
12777            socialIconsExpansionState: {
12778                [TAB_ID_LOGIN]: false,
12779                [TAB_ID_REGISTER]: false
12780            },
12781            isLoading: false,
12782            modalName,
12783            isLogged: false,
12784            socialIconsExpanded: false,
12785
12786            initializeAuthPopup(privateData) {
12787                if (privateData?.data?.customer?.firstname && !IS_KNOWN_CUSTOMER) {
12788                    componentInitialized = false;
12789                    this.reloadExpiredCustomerData();
12790                    return;
12791                }
12792
12793                if (componentInitialized) {
12794                    return;
12795                }
12796
12797                componentInitialized = true;
12798
12799                const origShow = this.show;
12800                const origHide = this.hide;
12801                this.show = (name, event, activeTabName) => {
12802                    origShow.call(this, name, event);
12803                    this.activeTab = activeTabName || TAB_ID_LOGIN;
12804                }
12805                this.hide = (...args) => {
12806                    origHide.call(this, args);
12807                    setTimeout(() => {
12808                        this.clearForms();
12809                        this.clearFormMessages();
12810                    }, this.animationDuration + 1)
12811                }
12812
12813                this.initModalSettings();
12814                this.bindLinksEvents(privateData);
12815                this.initContentUpdaters();
12816                if (!this.isGuestCheckoutAllowed) {
12817                    this.bindAuthenticationEvent(privateData);
12818                }
12819            },
12820
12821            bindAuthenticationEvent(privateData) {
12822                window.addEventListener('toggle-authentication', (event) => {
12823                    event.stopPropagation();
12824
12825                    if (!this.isLoggedIn(privateData)) {
12826                        this.show(
12827                            this.modalName,
12828                            event
12829                        );
12830                    } else {
12831                        window.location.assign(event.detail.url)
12832                    }
12833                }, true)
12834            },
12835
12836            bindLinksEvents(privateData) {
12837                if (!this.isLoggedIn(privateData)) {
12838                    this.bindOpeningEvents();
12839                    this.bindForgotLinkEvent();
12840                    requestAnimationFrame(() => {
12841                        this.processForms();
12842                    })
12843                } else {
12844                    this.initLogout();
12845                }
12846            },
12847
12848            bindOpeningEvents() {
12849                const accountLinks = document.querySelectorAll(`#header nav a[href^="${BASE_URL}customer/account"], .columns a[href^="${BASE_URL}customer/account"]`) || [];
12850
12851                accountLinks.forEach(elem => {
12852                    const isRegisterLink = /\/create\/?(\?.+)?(\#.+)*/.test(elem.href);
12853                    elem.removeAttribute('onclick');
12854                    elem.setAttribute('aria-haspopup', 'dialog');
12855                    elem.addEventListener('click', (event) => {
12856                        event.preventDefault();
12857                        this.show(
12858                            this.modalName,
12859                            event,
12860                            isRegisterLink ? TAB_ID_REGISTER : TAB_ID_LOGIN
12861                        );
12862                    })
12863                });
12864
12865                if (reCaptchaStatusFor('register')) {
12866                    this.moveRecaptchaElement('.recaptcha-create-wrapper');
12867                }
12868
12869                if (reCaptchaStatusFor('login')) {
12870                    this.moveRecaptchaElement('.recaptcha-login-wrapper');
12871                }
12872            },
12873
12874            bindForgotLinkEvent() {
12875                const modalContainer = this.$el || this.$root;
12876                const forgotLinks = modalContainer.querySelectorAll(
12877                    `a[href^="${BASE_URL}customer/account/forgotpassword"]`
12878                ) || [];
12879
12880                forgotLinks.forEach((element) => {
12881                    element.addEventListener('click', (event) => {
12882                        event.preventDefault();
12883                        element.setAttribute('aria-haspopup', 'dialog');
12884                        this.activeTab = TAB_ID_FORGOT;
12885                    })
12886                })
12887
12888                if (reCaptchaStatusFor('forgotPassword') && !this.isAccountForgotPasswordPage) {
12889                    this.moveRecaptchaElement('.recaptcha-forgot-wrapper');
12890                }
12891            },
12892
12893            isLoggedIn(privateData) {
12894                try {
12895                    privateData = privateData?.data ?? JSON.parse(hyva.getBrowserStorage()?.['mage-cache-storage'] || '{}');
12896                    this.isLogged = !!(privateData.customer && privateData.customer.firstname);
12897                } catch (error) {
12898                    console.error('Error parsing privateData:', error);
12899                    this.isLogged = false;
12900                }
12901                return this.isLogged;
12902            },
12903
12904            showOnExternalEvent(event) {
12905                const eventData = event.detail || {};
12906                const message = eventData?.message;
12907                const tabName = eventData?.tabName || TAB_ID_LOGIN;
12908
12909                this.show(this.modalName, event, tabName);
12910                if (message) {
12911                    this.setFormMessages(tabName, [message]);
12912                }
12913            },
12914
12915            canShowAllSocialIcons() {
12916                return this.socialIconsExpansionState[this.activeTab];
12917            },
12918
12919            showAllSocialIcons() {
12920                this.socialIconsExpanded = true;
12921                this.socialIconsExpansionState[this.activeTab] = true;
12922            },
12923
12924            setLoading(isLoading) {
12925                const formButtons = this.$refs[this.modalName].querySelectorAll('[type="submit"]');
12926                formButtons.forEach(button => {
12927                    if (isLoading) {
12928                        button.setAttribute('disabled', 'disabled')
12929                    } else {
12930                        button.removeAttribute('disabled');
12931                    }
12932                })
12933                this.isLoading = isLoading;
12934            },
12935
12936            reloadExpiredCustomerData() {
12937                const sections = ['mage-cache-storage', 'private_content_version', 'mage-cache-timeout'];
12938                sections.forEach(section => localStorage.removeItem(section));
12939
12940                hyva.setCookie('mage-cache-sessid', '', -1);
12941                window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
12942            },
12943
12944            moveRecaptchaElement(element) {
12945                const captchaElement = document.querySelector(element);
12946                if (!captchaElement) {
12947                    return;
12948                }
12949
12950                const container = captchaElement.closest('.amsl-form').querySelector('.actions-toolbar');
12951                container.prepend(captchaElement);
12952            },
12953
12954            onKeypress(event) {
12955                const activeTabIndex = this.tabs.indexOf(this.activeTab);
12956
12957                if (activeTabIndex < 0 || event.code === 'Tab') {
12958                    return;
12959                }
12960
12961                switch (event.code) {
12962                    case 'Enter':
12963                    case 'Space':
12964                        this.activeTab = event.target.id.replace('tab-', '');
12965                        break;
12966
12967                    case 'ArrowRight':
12968                        this.activeTab = this.tabs[(activeTabIndex + 1) % this.tabs.length]
12969                        break;
12970
12971                    case 'ArrowLeft':
12972                        this.activeTab = this.tabs[(activeTabIndex + this.tabs.length - 1) % this.tabs.length]
12973                        break;
12974
12975                    case 'End':
12976                        this.activeTab = this.tabs[this.tabs.length - 1]
12977                        break;
12978
12979                    case 'Home':
12980                        this.activeTab = this.tabs[0]
12981                        break;
12982                }
12983
12984                document.getElementById('tab-' + this.activeTab).focus();
12985            },
12986
12987            /* ================================================================
12988             * Helpers CSP (Mb/Hyva2): Alpine CSP solo admite nombres de
12989             * propiedades/métodos en el HTML, sin argumentos ni operadores.
12990             * ================================================================ */
12991
12992            // Eventos del contenedor (modals/authentication-popup.phtml)
12993            onPrivateContentLoaded(event) {
12994                this.initializeAuthPopup(event && event.detail);
12995            },
12996            onHidePopup() {
12997                this.hide(this.modalName);
12998            },
12999            onContentUpdated() {
13000                this.bindLinksEvents();
13001            },
13002            closePopup() {
13003                this.hide();
13004            },
13005
13006            // Pestañas
13007            isLoginTab() {
13008                return this.activeTab === TAB_ID_LOGIN;
13009            },
13010            isRegisterTab() {
13011                return this.activeTab === TAB_ID_REGISTER;
13012            },
13013            isForgotTab() {
13014                return this.activeTab === TAB_ID_FORGOT;
13015            },
13016            isNotForgotTab() {
13017                return this.activeTab !== TAB_ID_FORGOT;
13018            },
13019            selectLoginTab() {
13020                this.activeTab = TAB_ID_LOGIN;
13021            },
13022            selectRegisterTab() {
13023                this.activeTab = TAB_ID_REGISTER;
13024            },
13025            tabClasses(tabId) {
13026                const active = this.activeTab === tabId;
13027                return {
13028                    '-active border-primary text-blue-800 hover:bg-transparent': active,
13029                    'border-transparent text-primary-lighter hover:bg-gray-100': !active
13030                };
13031            },
13032            loginTabClasses() {
13033                return this.tabClasses(TAB_ID_LOGIN);
13034            },
13035            registerTabClasses() {
13036                return this.tabClasses(TAB_ID_REGISTER);
13037            },
13038
13039            // Mensajes de cada formulario
13040            hasLoginMessages() {
13041                return this.formMessages.has(TAB_ID_LOGIN);
13042            },
13043            loginMessages() {
13044                return this.formMessages.get(TAB_ID_LOGIN) || [];
13045            },
13046            hasRegisterMessages() {
13047                return this.formMessages.has(TAB_ID_REGISTER);
13048            },
13049            registerMessages() {
13050                return this.formMessages.get(TAB_ID_REGISTER) || [];
13051            },
13052            hasForgotMessages() {
13053                return this.formMessages.has(TAB_ID_FORGOT);
13054            },
13055            forgotMessages() {
13056                return this.formMessages.get(TAB_ID_FORGOT) || [];
13057            },
13058
13059            // Estado de sesión y botones sociales
13060            isNotLogged() {
13061                return !this.isLogged;
13062            },
13063            socialButtonsClasses() {
13064                return {'-show-all': this.canShowAllSocialIcons()};
13065            },
13066            cannotShowAllSocialIcons() {
13067                return !this.canShowAllSocialIcons();
13068            },
13069            // Valores por defecto (AmSocialLogin los sobrescribe al hacer spread)
13070            socialErrorMessage: '',
13071            hasSocialError() {
13072                return !!this.socialErrorMessage;
13073            },
13074
13075            ...AmAuthPopupModal(modalName),
13076            ...AmAuthPopupForms(),
13077            ...AmAuthPopupRedirect(),
13078            ...AmAuthPopupReloadContent(),
13079            ...AmAuthPopupLogout(),
13080            ...(typeof AmSocialLogin === 'function' ? AmSocialLogin() : {})
13081        }
13082    }
13083
13084    ;(() => {
13085        // Durante la carga de la página: esperar a alpine:init (todos los scripts ya definidos).
13086        // Si el script llega tarde (p.ej. dentro de un <template x-if>), registrar directamente.
13087        const register = () => Alpine.data('AmAuthPopup', AmAuthPopup);
13088        (document.readyState === 'loading' || !window.Alpine)
13089            ? window.addEventListener('alpine:init', register, {once: true})
13090            : register();
13091    })();
13092</script>
vendor: 1 bytes, line 13092
13092
13093<script>
13094    (function () {
13095        const resetPasswordForms = document.querySelectorAll('form[action*="/forgotpasswordpost"]');
13096        resetPasswordForms.forEach(form => {
13097                        form.classList.add('form','password', 'forget');
13098        });
13099    })();
13100
13101        const AmAuthPopupForms = function () {
13102        const TAB_ID_LOGIN = 'amsl\u002Dlogin';
13103        const TAB_ID_REGISTER = 'amsl\u002Dregister';
13104        const TAB_ID_FORGOT = 'amsl\u002Dforgot';
13105        const formsConfig = JSON.parse(`\u007B\u0022amsl\u002Dlogin\u0022\u003A\u007B\u0022formType\u0022\u003A\u0022amsl\u002Dlogin\u0022,\u0022formId\u0022\u003A\u0022customer\u002Dlogin\u002Dform\u0022,\u0022successMessage\u0022\u003A\u0022You\u0020have\u0020successfully\u0020logged\u0020in.\u0022,\u0022submitUrlReplacement\u0022\u003A\u0022amsociallogin\u005C\u002Faccount\u0022\u007D,\u0022amsl\u002Dregister\u0022\u003A\u007B\u0022formType\u0022\u003A\u0022amsl\u002Dregister\u0022,\u0022formId\u0022\u003A\u0022accountcreate\u0022,\u0022successMessage\u0022\u003A\u0022Thank\u0020you\u0020for\u0020registering\u0020with\u0020us.\u0022,\u0022submitUrlReplacement\u0022\u003A\u0022amsociallogin\u005C\u002Faccount\u0022\u007D,\u0022amsl\u002Dforgot\u0022\u003A\u007B\u0022formType\u0022\u003A\u0022amsl\u002Dforgot\u0022,\u0022formId\u0022\u003A\u0022user_forgotpassword\u0022,\u0022customSubmitUrl\u0022\u003A\u0022customer\u005C\u002Faccount\u005C\u002Fforgotpasswordpost\u0022\u007D\u007D`);
13106
13107        return {
13108            formMessages: new Map(),
13109
13110            processForms() {
13111                Object.values(formsConfig).forEach((formOptions) => {
13112                    this.processForm(formOptions);
13113                })
13114            },
13115
13116            processForm(formOptions) {
13117                const { formId } = formOptions;
13118                const formElement = document.querySelector(`#social-login-popup #${formId}`);
13119
13120                if (formElement) {
13121                    this.bindFormSubmit(formElement, formOptions);
13122                }
13123            },
13124
13125            bindFormSubmit(formElement, formOptions) {
13126                const { formType, successMessage, submitUrlReplacement, customSubmitUrl } = formOptions;
13127
13128                let submitUrl = formElement.action;
13129                if (submitUrlReplacement) {
13130                    submitUrl = submitUrl.replace('customer/account', submitUrlReplacement);
13131                }
13132
13133                if (customSubmitUrl) {
13134                    let baseUrl = 'https://www.mueblesbonitos.com/';
13135                    submitUrl = baseUrl + customSubmitUrl;
13136                }
13137
13138                
13139                formElement.submit = () => {
13140                    this.clearFormMessages();
13141                    this.setLoading(true);
13142
13143                    this.formAjaxSubmit(
13144                        formElement,
13145                        submitUrl
13146                    ).then((result) => {
13147                        if (!result.errors.length) {
13148                            this.hide(this.modalName);
13149                            const notification = result.success || successMessage;
13150                            if (notification) {
13151                                window.dispatchEvent(
13152                                    new CustomEvent(
13153                                        'amsl-popup-show-notification',
13154                                        {
13155                                            detail: notification
13156                                        }
13157                                    )
13158                                );
13159                            }
13160                        }
13161                        if (result.errors.length) {
13162                            this.setFormMessages(formType, result.errors);
13163                            return;
13164                        }
13165                        this.processRedirect();
13166                    }).finally(() => {
13167                        this.setLoading(false);
13168                    })
13169                }
13170            },
13171
13172            async formAjaxSubmit(form, url) {
13173                let errors = [];
13174                let success = '';
13175
13176                try {
13177                    await fetch(url, {
13178                        method: 'POST',
13179                        body: new FormData(form)
13180                    });
13181
13182                    const messages = this.extractMageMessages();
13183                    const errorMessages = messages.filter(({ type }) => type === 'error');
13184                    const successMessages = messages.filter(({ type }) => type === 'success');
13185
13186                    errors = errorMessages.map(({ text }) => text);
13187                    if (successMessages.length) {
13188                        success = successMessages.pop().text || '';
13189                    }
13190                } catch (error) {
13191                    console.error(error);
13192                    errors.push('Sorry,\u0020something\u0020went\u0020wrong.\u0020Please\u0020try\u0020again\u0020later.');
13193                }
13194
13195                return { errors, success };
13196            },
13197
13198            extractMageMessages() {
13199                const messagesCookie = hyva.getCookie('mage-messages');
13200                const messages = messagesCookie
13201                    ? JSON.parse(decodeURIComponent(messagesCookie).replace(/\+/g, ' '))
13202                    : [];
13203                hyva.setCookie('mage-messages','', -1, true);
13204
13205                return messages;
13206            },
13207
13208            clearFormMessages() {
13209                this.formMessages = new Map();
13210            },
13211
13212            setFormMessages(formType, messages) {
13213                const formMessages = new Map(this.formMessages);
13214
13215                formMessages.set(formType, messages);
13216                this.formMessages = formMessages;
13217            },
13218
13219            clearForms() {
13220                const forms = this.$refs[this.modalName].querySelectorAll('form') || [];
13221                forms.forEach((form) => form.reset());
13222            }
13223        }
13224    }
13225</script>
vendor: 1 bytes, line 13225
13225
13226<script>
13227    const AmAuthPopupLogout = function () {
13228        return {
13229            initLogout() {
13230                const logoutLinks = document.querySelectorAll(`a[href*="customer/account/logout"]`) || [];
13231
13232                logoutLinks.forEach(elem => {
13233                    elem.addEventListener('click', (event) => {
13234                        event.preventDefault();
13235                        this.sendLogOut()
13236                    })
13237                })
13238            },
13239
13240            sendLogOut() {
13241                fetch(BASE_URL + "customer/account/logout", {
13242                    method: 'GET',
13243                    credentials: "include"
13244                }).then(response => {
13245                    window.dispatchEvent(
13246                        new CustomEvent(
13247                            'amsl-popup-show-notification',
13248                            {
13249                                detail: 'Ha\u0020cerrado\u0020sesi\u00F3n\u0020correctamente.'
13250                            }
13251                        )
13252                    );
13253                    this.processRedirect(this.isInAccountSection() ? BASE_URL : '');
13254                })
13255                .catch(error => {
13256                    console.error(error);
13257                    this.processRedirect();
13258                })
13259            },
13260
13261            isInAccountSection() {
13262                return document.querySelector('body').classList.contains('account');
13263            }
13264        }
13265    }
13266</script>
13266
13267        <div x-data="AmAuthPopup"
13268            x-on:private-content-loaded.window="onPrivateContentLoaded"
13269            x-on:amsl-show-popup.window="showOnExternalEvent"
13270            x-on:amsl-hide-popup.window="onHidePopup"
13271            x-on:amsl-content-updated.window="onContentUpdated"
13272        >
13273            <div x-cloak    data-dialog-ref-name="social-login-popup"
13274    x-bind="overlay"
13275    class="fixed inset-0 bg-black/50 z-50">
13276    <div class="fixed flex justify-center items-center text-left z-40 amsl-popup-modal p-6 inset-0">
13277        <div x-ref="social-login-popup" role="dialog" aria-modal="true"
13278                                                     aria-labelledby="social-login-popup"
13279                         class="inline-block bg-white shadow-xl rounded-lg p-10 max-h-screen overflow-auto overscroll-y-contain">
13280                <div id="social-login-popup"
13281        class="amsl-popup-block relative focus:outline-none focus-within:outline-none
13282            -social-right"
13283        role="dialog"
13284        aria-labelledby="amsl-popup-dialog"
13285        tabindex="0"
13286        x-on:click.stop
13287    >
13288        <button type="button"
13289            class="amsl-close absolute right-0 top-0 -mt-2 text-gray-400 hover:text-blue-800 transform md:translate-x-full"
13290            title="Cerrar"
13291            aria-label="Cerrar"
13292            role="button"
13293            x-on:click="closePopup"
13294        >
13295            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" role="img">
13296  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
13297<title>x</title></svg>
13298        </button>
13299        <h2 class="amsl-dialog-title sr-only" id="amsl-popup-dialog">
13300            Login and Registration Form        </h2>
13301        <div class="amsl-tabs-wrapper"
13302            title="Login and Registration Form"
13303        >
13304            <ul class="amsl-tablist flex space-x-4"
13305                role="tablist"
13306                x-on:keydown="onKeypress"
13307                x-show="isNotForgotTab"
13308            >
13309                <li class="amsl-title"
13310                    id="tab-amsl-login"
13311                    role="tab" aria-controls="amsl-login-content"
13312                    tabindex="0"
13313                >
13314                    <span class="amsl-link block p-4 text-lg cursor-pointer border-b"
13315                        data-toggle="switch"
13316                        x-on:click.prevent="selectLoginTab"
13317                        :class="loginTabClasses"
13318                    >
13319                        Iniciar Sesión                    </span>
13320                </li>
13321                <li class="amsl-title"
13322                    id="tab-amsl-register"
13323                    role="tab" aria-controls="amsl-register-content"
13324                    tabindex="0"
13325                >
13326                    <span class="amsl-link block p-4 text-lg cursor-pointer border-b"
13327                        x-on:click.prevent="selectRegisterTab"
13328                        :class="registerTabClasses"
13329                    >
13330                        Regístrate                    </span>
13331                </li>
13332            </ul>
13333            <div id="amsl-login-content"
13334                x-show="isLoginTab"
13335                x-cloak
13336                role="tabpanel"
13337                aria-labelledby="tab-amsl-login"
13338            >
13339                <template x-if="hasLoginMessages">
13340                    <div class="mt-4">
13341                        <template x-for="message in loginMessages" :key="message">
13342                            <div class="message error">
13343                                <span x-html="message"></span>
13344                            </div>
13345                        </template>
13346                    </div>
13347                </template>
13348                <div class="amsl-content amsl-login-content mt-6 amsl-position-variations                        "
13349                >
13350                    <template x-if="isNotLogged">
13351                        <div class="amsl-form">
13352                            <style>
13353    /* ---------- Tokens ---------- */
13354    .mb-login {
13355        --mb-primary: #35515E;
13356        --mb-soft: #F4F8F9;
13357        --mb-border: #d6dfe3;
13358        --mb-text: #1f2d33;
13359        --mb-muted: #5f7179;
13360        --mb-radius: 0.75rem;
13361
13362    }
13363
13364    /* ---------- Contenedor ---------- */
13365    .mb-login {
13366        max-width: 40rem;
13367        margin: 0 auto;
13368        padding: 0 1rem;
13369        color: var(--mb-text);
13370        box-sizing: border-box;
13371    }
13372    @media (min-width: 768px) {
13373        .mb-login__card {
13374            background: #fff; border: 1px solid var(--mb-border);
13375            border-radius: var(--mb-radius); padding: 1.5rem;
13376        }
13377    }
13378    .mb-login__title {
13379        font-size: 1.5rem; font-weight: 700; color: var(--mb-primary);
13380        margin: 0 0 1rem;
13381    }
13382
13383    .mb-notice {
13384        background: var(--mb-soft);
13385        border-left: 4px solid var(--mb-primary);
13386        border-radius: 0 0.5rem 0.5rem 0;
13387        padding: 0.875rem 1rem;
13388        margin-bottom: 1.25rem;
13389        font-size: 0.9rem;
13390        line-height: 1.5;
13391        color: var(--mb-primary);
13392    }
13393    .mb-notice a { font-weight: 700; text-decoration: underline;
13393 color: inherit; }
13394
13395    .mb-login__lead { text-align: center; font-size: 1rem; line-height: 1.5; margin: 0.25rem 0 1.25rem; }
13396    .mb-login__hint { color: var(--mb-muted); font-size: 0.9rem; margin: 0 0 1rem; }
13397
13398    .mb-entry { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 0.5rem; }
13399    .mb-back {
13400        display: inline-flex; align-items: center; gap: 0.35rem;
13401        background: none; border: 0; padding: 0; margin: 0 0 1rem;
13402        font-size: 0.875rem; color: var(--mb-primary); text-decoration: underline; cursor: pointer;
13403    }
13404
13405    /* ---------- Campos ---------- */
13406    .mb-login .field { margin-bottom: 1rem; }
13407    .mb-login .field .label { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.35rem; }
13408    .mb-login .form-input {
13409        width: 100%;
13410        min-height: 3rem;
13411        font-size: 16px; /* evita el zoom automático en iOS */
13412        border: 1px solid var(--mb-border);
13413        border-radius: 0.5rem;
13414        padding: 0.65rem 0.875rem;
13415        background: #fff;
13416    }
13417    .mb-login .form-input:focus {
13418        border-color: var(--mb-primary);
13419        box-shadow: 0 0 0 3px rgba(53, 81, 94, 0.15);
13420        outline: none;
13421    }
13422    .mb-password { position: relative; }
13423    .mb-password .form-input { padding-right: 3rem; }
13424    .mb-password__toggle {
13425        position: absolute; top: 0; right: 0; height: 3rem; width: 3rem;
13426        display: flex; align-items: center; justify-content: center;
13427        color: var(--mb-muted);
13428    }
13429
13430    /* ---------- Botones ---------- */
13431    .mb-submit {
13432        width: 100%; min-height: 3.25rem; font-size: 1.05rem; font-weight: 700;
13433        justify-content: center; border-radius: 0.5rem;
13434    }
13435    .mb-forgot { display: block; text-align: center; margin-top: 1rem; font-size: 0.9rem; color: var(--mb-muted); text-decoration: underline; }
13436    .mb-forgot:hover { color: var(--mb-primary); }
13437    .mb-error {
13438        display: flex; align-items: center; gap: 0.5rem; margin-top: 1rem;
13439        background: #fef2f2; border: 1px solid #fee2e2; color: #b91c1c;
13440        border-radius: 0.5rem; padding: 0.75rem; font-size: 0.9rem;
13441    }
13442
13443    /* ---------- Nuevo cliente: visible pero secundario ---------- */
13444    .mb-new { display: none; }
13445    .mb-new.is-moved {
13446        display: block;
13447        margin-top: 1.25rem; padding-top: 1.25rem;
13448        border-top: 1px solid var(--mb-border);
13449        text-align: center;
13450    }
13451    #mb-newcustomer-slot .btn,
13452    #mb-newcustomer-slot .action.create,
13453    #mb-newcustomer-slot .action.primary,
13454    #mb-newcustomer-slot a.primary,
13455    #mb-newcustomer-slot button {
13456        display: flex !important; align-items: center; justify-content: center;
13457        width: 100%; min-height: 3rem; margin-top: 0.75rem;
13458        background: var(--mb-soft) !important; color: var(--mb-primary) !important;
13459        border: 1.5px solid var(--mb-primary) !important; border-radius: 0.5rem !important;
13460        box-shadow: none !important; font-size: 1rem; font-weight: 700;
13461        text-decoration: none;
13462        transition: background-color .15s, color .15s;
13463    }
13464    #mb-newcustomer-slot .btn:hover,
13465    #mb-newcustomer-slot .action.create:hover,
13466    #mb-newcustomer-slot .action.primary:hover,
13467    #mb-newcustomer-slot a.primary:hover,
13468    #mb-newcustomer-slot button:hover {
13469        background: var(--mb-primary) !important; color: #fff !important;
13470    }
13471    #mb-newcustomer-slot .btn *,
13472    #mb-newcustomer-slot a.primary *,
13473    #mb-newcustomer-slot button * { color: inherit !important; }
13474    /* El bloque movido pierde su "card" para integrarse */
13475    #mb-newcustomer-slot > * {
13476        background: none !important; border: 0 !important; box-shadow: none !important;
13477        padding: 0 !important; margin: 0 !important; height: auto !important;
13478    }
13479    #mb-newcustomer-slot h2,
13480    #mb-newcustomer-slot h3,
13481    #mb-newcustomer-slot .block-title {
13482        font-size: 1rem !important; font-weight: 700; color: var(--mb-primary);
13483        border: 0 !important; padding: 0 !important; margin: 0 0 0.5rem !important;
13484    }
13485    #mb-newcustomer-slot p,
13486    #mb-newcustomer-slot li { font-size: 0.9rem; color: var(--mb-muted); }
13487
13488    /* ---------- Amasty Social Login (se mueve al hueco #mb-social-slot) ---------- */
13489    #mb-social-slot .amsl-social-wrapper,
13490    #mb-social-slot .amsl-login-page,
13491    #mb-social-slot .amsl-social-login {
13492        max-width: none; margin: 0; padding: 0; border: 0; background: none;
13493    }
13494    #maincontent .amsl-separator,
13495    #maincontent .amsl-title,
13496    #mb-social-slot .amsl-separator,
13497    #mb-social-slot .amsl-title { display: none; }
13498    #mb-social-slot .amsl-buttons { display: flex; flex-direction: column; gap: 0.75rem; width: 100%; }
13499    #mb-social-slot .amsl-button-wrapper { width: 100% !important; max-width: none !important; margin: 0 !important; }
13500    #mb-social-slot .amsl-button {
13501        position: relative;
13502        width: 100% !important; max-width: none !important; margin: 0 !important;
13503        min-height: 3.25rem; padding: 0.5rem 3rem !important;
13504        display: flex !important; align-items: center; justify-content: center;
13505        font-size: 1rem !important; font-weight: 500;
13506        background: #fff !important; color: var(--mb-text) !important;
13507        border: 1px solid var(--mb-text) !important; border-radius: 0.5rem !important;
13508        box-shadow: none !important;
13509    }
13510    #mb-social-slot .amsl-button:hover { background: var(--mb-soft) !important; }
13511    #mb-social-slot .mb-social-orig { display: none !important; }
13512    #mb-social-slot .mb-social-label {
13513        display: inline !important; color: var(--mb-text) !important;
13514        font-size: 1rem; font-weight: 500; line-height: 1.2;
13515        visibility: visible !important; opacity: 1 !important; position: static !important;
13516        width: auto !important; height: auto !important; text-indent: 0 !important;
13517    }
13518    #mb-social-slot .amsl-button > img,
13519    #mb-social-slot .amsl-button > svg,
13520    #mb-social-slot .amsl-button [class*="icon"] {
13521        position: absolute; left: 1rem; top: 50%; transform: translateY(-50%);
13522        width: 22px; height: 22px;
13523        display: block !important; visibility: visible !important; opacity: 1 !important;
13524    }
13525    #mb-social-slot .amsl-button [class*="icon"] svg,
13526    #mb-social-slot .amsl-button [class*="icon"] img { width: 100%; height: 100%; display: block; }
13527
13528    /* ---------- Campo email (clase propia: el popup oculta .field.email) ---------- */
13529    .mb-login .mb-field-email { display: block; }
13530
13531    /* ---------- Popup Ajax de Amasty: mismo aspecto que la página ---------- */
13532    .amsl-popup-block .amsl-content.amsl-position-variations { display: block !important; }
13533    .amsl-popup-block .amsl-content .amsl-separator,
13534    .amsl-popup-block .amsl-content > .amsl-social-wrapper { display: none !important; }
13535    .amsl-popup-block .amsl-form { width: 100% !important; max-width: none !important; }
13536    .amsl-popup-block .mb-login,
13537    .amsl-popup-block .mb-register { max-width: 32rem; padding: 0; }
13538    .amsl-popup-block .mb-login__card { border: 0 !important; padding: 0 !important; background: none !important; }
13539    .amsl-popup-block .mb-login__title { display: none; }
13540    /* Aviso legal de reCAPTCHA duplicado que añade Amasty fuera del formulario */
13541    .amsl-popup-block .amsl-form > .recaptcha-wrapper { display: none !important; }
13542</style>
13543
13544<div class="mb-login" x-data="mbLoginPanel" data-open="false">
13545    <div class="mb-login__card">
13546        <h2 class="mb-login__title" id="am-block-customer-login-heading">
13547            Ya soy cliente        </h2>
13548
13549        <!-- Pantalla de entrada: social login + email -->
13550        <div x-show="isEmailClosed" x-transition.opacity>
13551
13552            <div class="mb-entry">
13553                <!-- Aquí se recoloca el bloque de Amasty Social Login -->
13554                <div id="mb-social-slot"></div>
13555
13556                <button type="button"
13557                        class="btn btn-primary mb-submit"
13558                        aria-controls="mb-email-panel"
13559                        :aria-expanded="emailExpanded"
13560                        @click="openEmail">
13561                    Continuar con email                </button>
13562            </div>
13563
13564            <!-- Nuevo cliente: aquí se recoloca el bloque "Crear cuenta" de la página (con el mensaje VIP) -->
13565            <div class="mb-new">
13566                <div id="mb-newcustomer-slot"></div>
13567            </div>
13568        </div>
13569
13570        <!-- Panel desplegable: login con email -->
13571        <div id="mb-email-panel" x-show="isEmailOpen" x-transition x-cloak aria-labelledby="am-block-customer-login-heading">
13572            <button type="button" class="mb-back" @click="closeEmail">
13573                <span aria-hidden="true">&larr;</span>
13574                <span>Otras opciones de acceso</span>
13575            </button>
13576
13577            <!-- Aviso clientes de la web anterior (solo al elegir email) -->
13578           <!--  <div class="mb-notice">
13579                ¡Hemos actualizado nuestra web! Si tenías cuenta antes de abril de 2026, pulsa en ¿Has olvidado tu contraseña? para actualizarla. Si lo haces y no recibes el email, significa que no estás registrado: simplemente crea una cuenta nueva. Si tienes dudas,                <a href="mailto:info2&#x40;mueblesbonitos.com?subject=Dudas sobre el acceso o registro">escríbenos aquí.</a>
13580            </div> -->
13581
13582            <p class="mb-login__hint">
13583                Si ya tienes una cuenta, inicia sesión con tu email.            </p>
13584
13585            <form class="form form-login"
13586                  action="https://www.mueblesbonitos.com/customer/account/loginPost/"
13587                  method="post"
13588                  x-data="initCustomerLoginForm"
13589                  @submit.prevent="submitForm"
13590                  id="customer-login-form">
13591                <input name="form_key" type="hidden" value="GoQ6wnK4Gflfjncs" />                <fieldset class="fieldset login">
13592                    <legend class="sr-only">Ya soy cliente</legend>
13593
13594                    <div class="field mb-field-email required">
13595                        <label class="label" for="email">
13596                            <span>Email</span>
13597                        </label>
13598                        <div class="control">
13599                            <input name="login[username]"
13600                                   class="form-input"
13601                                   required
13602                                   value=""
13603                                   autocomplete="off"
13604                                   id="email"
13605                                   type="email"
13606                                   inputmode="email"
13607                                   autocapitalize="off"
13608                                   spellcheck="false"
13609                                   placeholder="tu&#x40;email.com"
13610                                   title="Email">
13611                        </div>
13612                    </div>
13613
13614                    <div class="field password required">
13615                        <label for="am-pass" class="label">
13616                            <span>Contraseña</span>
13617                        </label>
13618                        <div class="control mb-password">
13619                            <input name="login[password]"
13620                                   class="form-input"
13621                                   required
13622                                   type="password"
13623                                   :type="pwType"
13624                                   autocomplete="off"
13625                                   id="am-pass"
13626                                   title="Contrase&#xF1;a">
13627                            <button type="button"
13628                                    class="mb-password__toggle"
13629                                    :aria-pressed="pwPressed"
13630                                    @click="togglePw"
13631                                    :aria-label="pwLabel">
13632                                <span x-show="pwIsHidden"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
13633  <path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/>
13634  <path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
13635</svg>
13636</span>
13637                                <span x-show="pwIsVisible" x-cloak><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
13638  <path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/>
13639  <path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/>
13640</svg>
13641</span>
13642                            </button>
13643                        </div>
13644                    </div>
13645
13646                    <div class="control">
13647    <input type="hidden"
13648           value=""
13649           name="g-recaptcha-response"
13650    >
13651</div>
13652                    
13653                                        <div class="actions-toolbar">
13654                        <button type="submit"
13655                                class="btn btn-primary mb-submit"
13656                                name="send"
13657                            >
13658                            <span>Entrar a mi cuenta</span>
13659                        </button>
13660                    </div>
13661
13662                    <a class="mb-forgot" rel="nofollow" href="https://www.mueblesbonitos.com/customer/account/forgotpassword/">
13663                        <span>¿Has olvidado tu contraseña?</span>
13664                    </a>
13665
13666                    <template x-if="displayErrorMessage">
13667                        <p class="mb-error">
13668                            <span class="inline-block w-5 h-5 shrink-0">
13669                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="20" height="20" aria-hidden="true">
13670  <path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
13671</svg>
13672                            </span>
13673                            <template x-for="errorMessage in errorMessages">
13674                                <span x-html="errorMessage"></span>
13675                            </template>
13676                        </p>
13677                    </template>
13678                </fieldset>
13679            </form>
13680
13681            <div class="mt-3 text-xs text-center" style="color: var(--mb-muted)">
13682                <p class="prose my-4 text-sm">
13683    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
13684</p>
13685            </div>
13686        </div>
13687    </div>
13688
13689    
13689<script>
13690        (function () {
13691            // Bloque .mb-login al que pertenece este script (puede haber otro en el popup de Amasty)
13692            const root = document.currentScript && document.currentScript.closest('.mb-login');
13693            if (!root) return;
13694            // Dentro del popup de Amasty: los botones sociales están en la misma pestaña (.amsl-content)
13695            const popupContent = root.closest('.amsl-popup-block') ? root.closest('.amsl-content') : null;
13696
13697            const labels = {
13698                google: 'Continuar\u0020con\u0020Google',
13699                facebook: 'Continuar\u0020con\u0020Facebook',
13700                apple: 'Continuar\u0020con\u0020Apple',
13701                twitter: 'Continuar\u0020con\u0020X',
13702                linkedin: 'Continuar\u0020con\u0020LinkedIn',
13703                amazon: 'Continuar\u0020con\u0020Amazon',
13704                paypal: 'Continuar\u0020con\u0020PayPal'
13705            };
13706            const outsidePopup = (el) => !el.closest('.amsl-popup-block');
13707            const wrapText = (node) => {
13708                const w = document.createElement('span');
13709                w.className = 'mb-social-orig';
13710                node.replaceWith(w);
13711                w.appendChild(node);
13712            };
13713            const addLabels = () => {
13714                root.querySelectorAll('#mb-social-slot .amsl-button').forEach((btn) => {
13715                    if (btn.querySelector('.mb-social-label')) return;
13716                    const hint = (btn.className + ' ' + (btn.getAttribute('href') || '') + ' ' +
13717                        (btn.getAttribute('title') || '') + ' ' + (btn.dataset.amslType || '') + ' ' +
13718                        (btn.parentElement ? btn.parentElement.className : '')).toLowerCase();
13719                    const key = Object.keys(labels).find((k) => hint.includes(k));
13720                    if (!key) return;
13721                    // Ocultamos solo el texto original de Amasty, nunca el elemento que lleva el logo
13722                    btn.querySelectorAll('*').forEach((el) => {
13723                        if (el.closest('svg') || el.tagName === 'IMG') return;
13724                        if (el.querySelector('svg, img')) return;
13725                        const cs = getComputedStyle(el);
13726                        const before = getComputedStyle(el, '::before');
13727                        const hasIcon = (cs.backgroundImage && cs.backgroundImage !== 'none') ||
13728                            (cs.maskImage && cs.maskImage !== 'none') ||
13729                            (before.content && before.content !== 'none' && before.content !== 'normal');
13730                        const ownText = Array.from(el.childNodes)
13731                            .filter((n) => n.nodeType === 3)
13732                            .map((n) => n.textContent).join('').trim();
13733                        if (!ownText) return;
13734                        if (hasIcon) {
13735                            Array.from(el.childNodes).forEach((n) => {
13736                                if (n.nodeType === 3 && n.textContent.trim()) wrapText(n);
13737                            });
13738                        } else {
13739                            el.classList.add('mb-social-orig');
13740                        }
13741                    });
13742                    Array.from(btn.childNodes).forEach((n) => {
13743                        if (n.nodeType === 3 && n.textContent.trim()) wrapText(n);
13744                    });
13745                    const label = document.createElement('span');
13746                    label.className = 'mb-social-label';
13747                    label.textContent = labels[key];
13748                    btn.appendChild(label);
13749                });
13750            };
13751            const move = () => {
13752                const slot = root.querySelector('#mb-social-slot');
13753                if (!slot) return;
13754                if (popupContent) {
13755                    const popupButtons = Array.from(popupContent.querySelectorAll('.amsl-buttons'))
13756                        .find((el) => !slot.contains(el));
13757                    if (popupButtons) slot.appendChild(popupButtons);
13758                    addLabels();
13759                    return;
13760                }
13761                // Solo buscamos el bloque de Amasty dentro del contenido principal (nunca en la cabecera ni en el popup)
13762                const main = document.getElementById('maincontent') || document.querySelector('main') || document.body;
13763                const buttons = Array.from(main.querySelectorAll('.amsl-buttons'))
13764                    .find((el) => !slot.contains(el) && outsidePopup(el) && !el.closest('header, .page-header, #header'));
13765                if (buttons) {
13766                    let social = buttons;
13767                    const wrapper = buttons.closest('.amsl-social-login, .amsl-social-wrapper, .amsl-login-page');
13768                    if (wrapper && main.contains(wrapper) && !wrapper.contains(slot) && outsidePopup(wrapper) &&
13769                        !wrapper.querySelector('header, .page-header, nav, form')) {
13770                        social = wrapper;
13771                    }
13772                    slot.appendChild(social);
13773                }
13774                addLabels();
13775            };
13776            const moveNewCustomer = () => {
13777                const slot = root.querySelector('#mb-newcustomer-slot');
13778                const login = root;
13779                if (!slot || slot.children.length) return;
13780                const main = document.getElementById('maincontent') || document.querySelector('main') || document.body;
13781                const safe = (el) => el && !el.contains(login) && !login.contains(el) && outsidePopup(el) &&
13782                    !el.closest('header, .page-header, #header, nav') &&
13783                    !el.querySelector('form, header, nav');
13784
13785                let block = null;
13786                // 1) Clases estándar del bloque de nuevo cliente
13787                const byClass = Array.from(main.querySelectorAll('.block-new-customer, .block.new-customer, .customer-new'))
13788                    .find(outsidePopup);
13789                if (byClass) block = byClass.closest('.card') || byClass;
13790                // 2) Enlace a la página de registro (sea cual sea la URL traducida del registro)
13791                if (!safe(block)) {
13792                    const createUrl = "https:\/\/www.mueblesbonitos.com\/customer\/account\/create\/";
13793                    const link = Array.from(main.querySelectorAll('a[href]')).find((a) =>
13794                        !login.contains(a) && outsidePopup(a) && !a.closest('header, .page-header, #header, nav') &&
13795                        (a.href.indexOf('customer/account/create') !== -1 || a.href.split('?')[0] === createUrl.split('?')[0]));
13796                    if (link) block = link.closest('.card') || link.parentElement;
13797                }
13798                // 3) La otra columna de la rejilla del login
13799                if (!safe(block)) {
13800                    let node = login;
13801                    while (node.parentElement && node.parentElement !== main) {
13802                        const parent = node.parentElement;
13803                        const display = getComputedStyle(parent).display;
13804                        if ((display === 'grid' || display === 'flex') && parent.children.length > 1) {
13805                            block = Array.from(parent.children).find((c) => c !== node && c.querySelector('a, button'));
13806                            break;
13807                        }
13808                        node = parent;
13809                    }
13810                }
13811                if (!safe(block)) return;
13812
13813                const parent = block.parentElement;
13814                slot.appendChild(block);
13815                slot.parentElement.classList.add('is-moved');
13816                // La rejilla de 2 columnas se queda con una sola: que ocupe todo el ancho
13817                if (parent && getComputedStyle(parent).display === 'grid') {
13818                    parent.style.gridTemplateColumns = 'minmax(0, 1fr)';
13819                }
13820            };
13821            const init = () => { move(); if (!popupContent) moveNewCustomer(); };
13822            init();
13823            window.addEventListener('DOMContentLoaded', init);
13824        })();
13825
13826        // Panel "Continuar con email" / "Otras opciones de acceso"
13827        function mbLoginPanel() {
13828            return {
13829                emailOpen: false,
13830                init() {
13831                    this.emailOpen = this.$el.dataset.open === 'true';
13832                },
13833                isEmailOpen() {
13834                    return this.emailOpen;
13835                },
13836                isEmailClosed() {
13837                    return !this.emailOpen;
13838                },
13839                emailExpanded() {
13840                    return this.emailOpen ? 'true' : 'false';
13841                },
13842                openEmail() {
13843                    this.emailOpen = true;
13844                    this.$nextTick(() => {
13845                        const f = this.$root.querySelector('[name="login[username]"]');
13846                        f && f.focus();
13847                    });
13848                },
13849                closeEmail() {
13850                    this.emailOpen = false;
13851                }
13852            }
13853        }
13854
13855        function initCustomerLoginForm() {
13856            return {
13857                errors: 0,
13858                hasCaptchaToken: 0,
13859                pwVisible: false,
13860                displayErrorMessage: false,
13861                errorMessages: [],
13862                togglePw() {
13863                    this.pwVisible = !this.pwVisible;
13864                },
13865                pwType() {
13866                    return this.pwVisible ? 'text' : 'password';
13867                },
13868                pwPressed() {
13869                    return this.pwVisible ? 'true' : 'false';
13870                },
13871                pwIsHidden() {
13872                    return !this.pwVisible;
13873                },
13874                pwIsVisible() {
13875                    return this.pwVisible;
13876                },
13877                pwLabel() {
13878                    return this.pwVisible
13879                        ? 'Ocultar\u0020contrase\u00F1a'
13880                        : 'Mostrar\u0020Contrase\u00F1a';
13881                },
13882                setErrorMessages(messages) {
13883                    this.errorMessages = [messages];
13884                    this.displayErrorMessage = this.errorMessages.length;
13885                },
13886                submitForm() {
13887                    // $form = este formulario (página o popup). No usar el id: puede estar duplicado.
13888                    const $form = this.$root;
13889                                        // Exactamente un campo g-recaptcha-response dentro del formulario
13890                    // (si hay dos, el token no se guarda; si no hay ninguno, se envía sin token)
13891                    const tokenInputs = $form.querySelectorAll('[name="g-recaptcha-response"]');
13892                    tokenInputs.forEach((input, i) => { if (i > 0) input.remove(); });
13893                    if (!tokenInputs.length) {
13894                        const input = document.createElement('input');
13895                        input.type = 'hidden';
13896                        input.name = 'g-recaptcha-response';
13897                        $form.appendChild(input);
13898                    }
13899                        if (!this.hasCaptchaToken) {
13900        this.errors = 1;
13901
13902
13903        const executeGreCaptcha = () => {
13904            grecaptcha.ready(() => {
13905                grecaptcha.execute(
13906                    '6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3',
13907                    {action: 'submit'}
13908                ).then((token) => {
13909                    const tokenElement = $form['g\u002Drecaptcha\u002Dresponse'];
13910
13911                    if (tokenElement && token && token.length > 0) {
13912                        $form['g\u002Drecaptcha\u002Dresponse'].value = token;
13913                        this.errors = 0;
13914                        this.hasCaptchaToken = 1;
13915                        (this.submitForm || $form.submit).call(this);
13916                    } else {
13917                        this.errors = 1;
13918                        const error = tokenElement
13919                            ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'
13920                            : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.';
13921                        if (this.setErrorMessages) {
13922                            this.setErrorMessages([error])
13923                            this.displayErrorMessage = true;
13924                        } else {
13925                            window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000);
13926                        }
13927                    }
13928                }).catch(exception => {
13929                    console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`)
13930                });
13931            })
13932        }
13933
13934        if (window.grecaptcha) {
13935            executeGreCaptcha();
13936        } else {
13937            const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3";
13938            const script = document.createElement('script');
13939            script.setAttribute('type', 'text/javascript');
13940            script.setAttribute('src', recaptchaUrl);
13941            document.head.appendChild(script);
13942
13943            script.addEventListener("load", executeGreCaptcha, false);
13944        }
13945    }
13946                                        if (this.errors === 0) {
13947                        $form.submit();
13948                    }
13949                }
13950            }
13951        }
13952
13953        ;(() => {
13954            const register = () => {
13955                Alpine.data('mbLoginPanel', mbLoginPanel);
13956                Alpine.data('initCustomerLoginForm', initCustomerLoginForm);
13957            };
13958            (document.readyState === 'loading' || !window.Alpine)
13959                ? window.addEventListener('alpine:init', register, {once: true})
13960                : register();
13961        })();
13962    </script>
13962
13963    </div>
13964
13965                                                            <div class="recaptcha-login-wrapper recaptcha-wrapper w-full">
13966                                    <div class="control">
13967    <input type="hidden"
13968           value=""
13969           name="g-recaptcha-response"
13970    >
13971</div>
13972                                </div>
13973                                                                                        <div class="recaptcha-login-wrapper recaptcha-wrapper w-full">
13974                                    <p class="prose my-4 text-sm">
13975    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
13976</p>
13977                                </div>
13978                                                    </div>
13979                    </template>
13980                        <span class="amsl-separator bg-gray-500 hidden text-secondary text-sm font-bold relative w-0.5">
13981        <span
13982            class="amsl-icon absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2
13983                border border-gray-500 rounded-full bg-white overflow-hidden w-8 h-8
13984                min-w-8 flex items-center justify-center pb-[3px]"
13985        >o bien</span>
13986    </span>
13987    <div class="amsl-social-wrapper"
13988            >
13989        <div class="amsl-title text-base font-medium text-gray-70 mb-2">
13990            Inicia sesión con tus redes sociales        </div>
13991        <div class="amsl-title text-base font-medium text-gray-70 mb-2 -short">
13992            Iniciar Sesión con        </div>
13993        <div class="amsl-social-login ">
13994            <template x-if="hasSocialError">
13995                <p class="amsl-error -social message error mb-4" x-text="socialErrorMessage"></p>
13996            </template>
13997            <div class="amsl-buttons flex flex-wrap justify-center gap-7"
13998                                    :class="socialButtonsClasses"
13999                                >
14000                                                        <div
14001                        class="amsl-button-wrapper
14002                            "
14003                    >
14004                        <form method="POST"
14005                              action="https://www.mueblesbonitos.com/amsociallogin/social/login/?type=google"
14006                              class="amsl-button-form"
14007                              aria-label="Sign in with Google"
14008                              x-on:submit="socialLoginClick"
14009                        >
14010                            <input name="form_key" type="hidden" value="lYvGLDMwoyHIBAad" />                            <button
14011                                type="submit"
14012                                class="amsl-button rounded-full overflow-hidden bg-white
14013                                shadow-md hover:shadow-lg transition-amsl-social-button
14014                                block w-16 h-16 p-4                                -google&#x20;"
14015                                title="Sign in with Google"
14016                            >
14017                                <span
14018                                    class="amsl-social-icon pointer-events-none
14019                                        "                                    role="img"
14020                                    aria-label="Sign in with Google"
14021                                >
14022                                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:v="https://vecta.io/nano" viewBox="0 0 31 33" fill="none" width="24" height="24" role="img"><path d="M1.125 10.662c-.726 1.85-1.1 3.841-1.023 5.869-.061 3.005.825 5.947 2.383 8.465l4.781-3.654c-.261-.501-.478-1.03-.643-1.586-.625-1.678-.712-3.469-.371-5.174l-5.127-3.92z" fill="#fbbc05"/><path d="M15.832.502l-.775.045c-6.14.075-11.7 4.435-13.93 10.115l5.125 3.918c.711-3.552 3.289-6.733 6.809-7.75 3.23-1.155 6.557.145 9.322 1.85 1.399-1.331 2.71-2.751 3.998-4.189C23.437 1.989 19.706.395 15.832.502zm.016 13.736v.041l.047-.041c-.016 0-.031 0-.047 0z" fill="#ea4335"/><path d="M23.387 14.219c-2.298-.001-4.595.006-6.891.01l-.648.496.008 4.953 9.035.107c-.76 2.645-2.493 5.106-5.121 6.061-4.56 2.039-10.247-.148-12.514-4.533l-4.777 3.662c1.906 3.086 4.822 5.537 8.256 6.682 5.873 2.003 13.093.505 17.002-4.602 2.853-3.577 3.502-8.348 3.193-12.805l-7.543-.031z" fill="#34a853"/><path d="M23.385 14.219c-2.514-.001-5.026.006-7.537.01l.008 5.449 9.035.107c-.69 2.401-2.185 4.647-4.42 5.756l4.959 3.84c.852-.669 1.63-1.442 2.307-2.326 2.853-3.577 3.502-8.348 3.193-12.805l-7.545-.031z" fill="#4285f4"/><title>google</title></svg>
14023                                </span>
14024                                                            </button>
14025                        </form>
14026                    </div>
14027                                                        <div
14028                        class="amsl-button-wrapper
14029                            "
14030                    >
14031                        <form method="POST"
14032                              action="https://www.mueblesbonitos.com/amsociallogin/social/login/?type=facebook"
14033                              class="amsl-button-form"
14034                              aria-label="Sign in with Facebook"
14035                              x-on:submit="socialLoginClick"
14036                        >
14037                            <input name="form_key" type="hidden" value="lYvGLDMwoyHIBAad" />                            <button
14038                                type="submit"
14039                                class="amsl-button rounded-full overflow-hidden bg-white
14040                                shadow-md hover:shadow-lg transition-amsl-social-button
14041                                block w-16 h-16 p-4                                -facebook&#x20;"
14042                                title="Sign in with Facebook"
14043                            >
14044                                <span
14045                                    class="amsl-social-icon pointer-events-none
14046                                        "                                    role="img"
14047                                    aria-label="Sign in with Facebook"
14048                                >
14049                                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 38" fill="none" width="24" height="24" role="img"><path d="M12.37 37.28V20.668h5.576l.835-6.474H12.37V10.06c0-1.875.52-3.152 3.209-3.152l3.428-.002v-5.79c-.593-.08-2.628-.256-4.996-.256-4.943 0-8.327 3.017-8.327 8.558v4.775H.094v6.475h5.59V37.28h6.686z" fill="currentColor"/><title>facebook</title></svg>
14050                                </span>
14051                                                            </button>
14052                        </form>
14053                    </div>
14054                            </div>
14055                    </div>
14056    </div>
14057
14058            
14058<script>
14059    function AmSocialLogin() {
14060        return {
14061            socialErrorMessage: '',
14062            isPopupEnabled: '1',
14063
14064            initializeSocialLogin() {
14065                this.initContentUpdaters();
14066            },
14067
14068            socialLoginClick(event) {
14069                const form = event.currentTarget;
14070
14071                if (this.isPopupEnabled) {
14072                    form.target = '_blank';
14073                    form.action = form.action + '&isAjax=true';
14074                }
14075
14076                const channel = new BroadcastChannel('amSocialLoginData');
14077                channel.addEventListener('message', this.onMessageEvent.bind(this));
14078
14079                event.stopPropagation();
14080                event.preventDefault();
14081                form.submit();
14082
14083                return false;
14084            },
14085
14086            onSocialResponse(data) {
14087                const isSuccessfulResult = data.result === 1;
14088
14089                if (isSuccessfulResult) {
14090                    window.dispatchEvent(
14091                        new CustomEvent(
14092                            'amsl-popup-show-notification',
14093                            {
14094                                detail: data.messages
14095                            }
14096                        )
14097                    );
14098                    this.processRedirect();
14099                } else {
14100                    const redirectData = data?.redirect_data;
14101
14102                    this.socialErrorMessage = data.messages.pop();
14103                    setTimeout(() => {
14104                        this.socialErrorMessage = '';
14105                    }, 5000);
14106
14107                    if (this.shouldCustomUrlRedirectWithError(redirectData)) {
14108                        return this.processRedirect(redirectData?.url);
14109                    }
14110
14111                    if (redirectData?.redirectWithError) {
14112                        this.processRedirect();
14113                    }
14114                }
14115            },
14116
14117            // Helper CSP: x-if="hasSocialError"
14118            hasSocialError() {
14119                return !!this.socialErrorMessage;
14120            },
14121
14122            shouldCustomUrlRedirectWithError(redirectData) {
14123                return (
14124                    redirectData &&
14125                    redirectData.redirect &&
14126                    redirectData.redirectWithError &&
14127                    redirectData.url
14128                );
14129            },
14130
14131            onMessageEvent(event) {
14132                if (event.origin !== window.location.origin) {
14133                    return;
14134                }
14135
14136                const data = JSON.parse(event.data);
14137                if (data['redirect_data']) {
14138                    this.onSocialResponse(data);
14139                }
14140            },
14141
14142            ...AmAuthPopupRedirect(),
14143            ...AmAuthPopupReloadContent()
14144        }
14145    }
14146
14147    ;(() => {
14148        // Durante la carga de la página: esperar a alpine:init (todos los scripts ya definidos).
14149        // Si el script llega tarde (p.ej. dentro de un <template x-if>), registrar directamente.
14150        const register = () => Alpine.data('AmSocialLogin', AmSocialLogin);
14151        (document.readyState === 'loading' || !window.Alpine)
14152            ? window.addEventListener('alpine:init', register, {once: true})
14153            : register();
14154    })();
14155</script>
14155
14156                </div>
14157            </div>
14158            <div id="amsl-register-content"
14159                x-show="isRegisterTab"
14160                x-cloak
14161                role="tabpanel"
14162                aria-labelledby="tab-amsl-register"
14163            >
14164                <template x-if="hasRegisterMessages">
14165                    <div class="mt-4">
14166                        <template x-for="message in registerMessages" :key="message">
14167                            <div class="message error">
14168                                <span x-html="message"></span>
14169                            </div>
14170                        </template>
14171                    </div>
14172                </template>
14173                <div class="amsl-content amsl-register-content mt-6">
14174                    <template x-if="isNotLogged">
14175                        <div class="amsl-form mb-12">
14176                            <style>
14177    /* ---------- Tokens ---------- */
14178    /* También en .mb-register: en el popup Ajax no existe .customer-account-create */
14179    .customer-account-create,
14180    .mb-register {
14181        --mb-primary: #35515E;
14182        --mb-primary-hover: #2a414b;
14183        --mb-soft: #F4F8F9;
14184        --mb-border: #d6dfe3;
14185        --mb-text: #1f2d33;
14186        --mb-muted: #5f7179;
14187        --mb-radius: 0.75rem;
14188    }
14189
14190    /* ---------- Contenedor general ---------- */
14191    .mb-register {
14192        max-width: 40rem;
14193        margin: 0 auto;
14194        padding: 0 1rem;
14195        color: var(--mb-text);
14196        box-sizing: border-box;
14197    }
14198
14199    .mb-notice {
14200        background: var(--mb-soft);
14201        border-left: 4px solid var(--mb-primary);
14202        border-radius: 0 0.5rem 0.5rem 0;
14203        padding: 0.875rem 1rem;
14204        margin-bottom: 1.25rem;
14205        font-size: 0.9rem;
14206        line-height: 1.5;
14207        color: var(--mb-primary);
14208    }
14209    .mb-notice a { font-weight: 700; text-decoration: underline; color: inherit; }
14210
14211    /* ---------- Bloques (sin "cards" pesadas en móvil) ---------- */
14212    .mb-section { border: 0; padding: 0; margin: 0 0 1.5rem; min-width: 0; }
14213    .mb-section__title {
14214        display: flex; align-items: center; gap: 0.5rem;
14215        font-size: 1rem; font-weight: 700; margin-bottom: 0.75rem;
14216        color: var(--mb-primary);
14217    }
14218    .mb-consents { margin-top: 1.25rem; }
14219    @media (min-width: 768px) {
14220        .mb-section {
14221            background: #fff; border: 1px solid var(--mb-border);
14222            border-radius: var(--mb-radius); padding: 1.5rem;
14223        }
14224    }
14225
14226    /* ---------- Campos ---------- */
14227    .mb-register .field { margin-bottom: 1rem; }
14228    .mb-register .field .label { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.35rem; }
14229    .mb-register .form-input,
14230    .mb-register .form-select,
14231    .mb-register input[type="text"],
14232    .mb-register input[type="email"],
14233    .mb-register input[type="tel"],
14234    .mb-register input[type="password"],
14235    .mb-register select {
14236        width: 100%;
14237        min-height: 3rem;
14238        font-size: 16px; /* evita el zoom automático en iOS */
14239        border: 1px solid var(--mb-border);
14240        border-radius: 0.5rem;
14241        padding: 0.65rem 0.875rem;
14242        background: #fff;
14243    }
14244    .mb-register .form-input:focus,
14245    .mb-register .form-select:focus {
14246        border-color: var(--mb-primary);
14247        box-shadow: 0 0 0 3px rgba(53, 81, 94, 0.15);
14248        outline: none;
14249    }
14250    /* Nombre y apellidos lado a lado a partir de ~480px */
14251    @media (min-width: 480px) {
14252        .mb-register .field-name-firstname,
14253        .mb-register .field-name-lastname { display: inline-block; width: calc(50% - 0.375rem); vertical-align: top; }
14254        .mb-register .field-name-firstname { margin-right: 0.5rem; }
14255    }
14256
14257    /* ---------- Contraseña con ojo dentro del campo ---------- */
14258    .mb-password { position: relative; }
14259    .mb-password .form-input { padding-right: 3rem; }
14260    .mb-password__toggle {
14261        position: absolute; top: 0; right: 0; height: 3rem; width: 3rem;
14262        display: flex; align-items: center; justify-content: center;
14263        color: var(--mb-muted);
14264    }
14265    .mb-hint { font-size: 0.8rem; color: var(--mb-muted); margin-top: 0.35rem; }
14266    .mb-register .password-strength-meter { font-size: 0.8rem; color: var(--mb-muted); margin-top: 0.35rem; }
14267
14268    /* ---------- Consentimientos ---------- */
14269    .mb-check { display: flex; gap: 0.75rem; align-items: flex-start; margin-bottom: 0.875rem; }
14270    .mb-check input { width: 1.25rem; height: 1.25rem; margin-top: 0.1rem; flex-shrink: 0; accent-color: var(--mb-primary); }
14271    .mb-check label { font-size: 0.9rem; line-height: 1.4; }
14272    .mb-check a { color: var(--mb-primary); text-decoration: underline; }
14273
14274    /* ---------- Botón ---------- */
14275    .mb-submit {
14276        width: 100%; min-height: 3.25rem; font-size: 1.05rem; font-weight: 700;
14277        justify-content: center; border-radius: 0.5rem;
14278    }
14279    .mb-register__footer { text-align: center; margin-top: 1rem; font-size: 0.9rem; color: var(--mb-muted); }
14280    .mb-register__footer a { color: var(--mb-primary); font-weight: 600; text-decoration: underline; }
14281
14282    /* ---------- Pantalla de entrada (tipo Sklum) ---------- */
14283    .mb-register__lead {
14284        text-align: center; color: var(--mb-text); font-size: 1rem; line-height: 1.5;
14285        margin: 0.75rem 0 1.25rem;
14286    }
14287    .mb-entry { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1.25rem; }
14288    .mb-social-note { font-size: 0.8rem; color: var(--mb-muted); text-align: center; margin: 0.25rem 0 0; }
14289    .mb-social-note a { color: var(--mb-primary); text-decoration: underline; }
14290    .mb-back {
14291        display: inline-flex; align-items: center; gap: 0.35rem;
14292        background: none; border: 0; padding: 0; margin: 0.25rem 0 1rem;
14293        font-size: 0.875rem; color: var(--mb-primary); text-decoration: underline; cursor: pointer;
14294    }
14295
14296    /* ---------- Amasty Social Login (se mueve debajo de "Continuar con email") ----------
14297       Revisa en el inspector que las clases coinciden con tu versión del módulo. */
14298    #mb-social-slot .amsl-social-wrapper,
14299    #mb-social-slot .amsl-login-page,
14300    #mb-social-slot .amsl-social-login {
14301        max-width: none; margin: 0; padding: 0; border: 0; background: none;
14302    }
14303    #maincontent .amsl-separator,
14304    #maincontent .amsl-title,
14305    #mb-social-slot .amsl-separator,
14306    #mb-social-slot .amsl-title { display: none; }
14307    #mb-social-slot .amsl-buttons {
14308        display: flex; flex-direction: column; gap: 0.75rem; width: 100%;
14309    }
14310    #mb-social-slot .amsl-button-wrapper {
14311        width: 100% !important; max-width: none !important; margin: 0 !important;
14312    }
14313    #mb-social-slot .amsl-button {
14314        position: relative;
14315        width: 100% !important; max-width: none !important; margin: 0 !important;
14316        min-height: 3.25rem; padding: 0.5rem 3rem !important;
14317        display: flex !important; align-items: center; justify-content: center;
14318        font-size: 1rem !important; font-weight: 500;
14319        background: #fff !important; color: var(--mb-text) !important;
14320        border: 1px solid var(--mb-text) !important; border-radius: 0.5rem !important;
14321        box-shadow: none !important;
14322    }
14323    #mb-social-slot .amsl-button:hover { background: var(--mb-soft) !important; }
14324    /* Textos de los botones sociales (Amasty a veces los pinta en blanco o solo muestra el icono) */
14325    #mb-social-slot .mb-social-orig { display: none !important; }
14326    #mb-social-slot .mb-social-label {
14327        display: inline !important; color: var(--mb-text) !important;
14328        font-size: 1rem; font-weight: 500; line-height: 1.2;
14329        visibility: visible !important; opacity: 1 !important; position: static !important;
14330        width: auto !important; height: auto !important; text-indent: 0 !important;
14331    }
14332    /* Icono anclado a la izquierda, como Sklum */
14333    #mb-social-slot .amsl-button > img,
14334    #mb-social-slot .amsl-button > svg,
14335    #mb-social-slot .amsl-button [class*="icon"] {
14336        position: absolute; left: 1rem; top: 50%; transform: translateY(-50%);
14337        width: 22px; height: 22px;
14338        display: block !important; visibility: visible !important; opacity: 1 !important;
14339    }
14340    #mb-social-slot .amsl-button [class*="icon"] svg,
14341    #mb-social-slot .amsl-button [class*="icon"] img { width: 100%; height: 100%; display: block; }
14342
14343    /* ---------- Popup Ajax de Amasty: mismo aspecto que la página ---------- */
14344    .amsl-popup-block .mb-register__footer { display: none; } /* ya está la pestaña "Iniciar sesión" */
14345    .amsl-popup-block .mb-register__lead { display: none; } /* igual que el login: sin texto de entrada */
14346    .amsl-popup-block .mb-section { border: 0 !important; padding: 0 !important; background: none !important; }
14347    .amsl-popup-block .amsl-form > .recaptcha-wrapper { display: none !important; }
14348</style>
14349
14350<div class="mb-register" x-data="mbRegisterPanel" data-open="false">
14351
14352    <!-- Pantalla de entrada: email + login social -->
14353    <div x-show="isEmailClosed" x-transition.opacity>
14354        <p class="mb-register__lead">
14355            Crea tu cuenta en un momento con tu email o con tu cuenta de Google.        </p>
14356
14357        <div class="mb-entry">
14358            <!-- Aquí se recoloca el bloque de Amasty Social Login -->
14359            <div id="mb-social-slot"></div>
14360
14361            <button type="button"
14362                    class="btn btn-primary mb-submit"
14363                    aria-controls="mb-email-panel"
14364                    :aria-expanded="emailExpanded"
14365                    @click="openEmail">
14366                Continuar con email            </button>
14367
14368            <p class="mb-social-note">
14369                Al registrarte aceptas nuestra                <a href="https://www.mueblesbonitos.com/privacidad/" target="_blank" rel="noopener">Política de privacidad</a>
14370            </p>
14371        </div>
14372    </div>
14373    
14373<script>
14374        (function () {
14375            // Bloque .mb-register de este script (puede haber otro en el popup de Amasty)
14376            const root = document.currentScript && document.currentScript.closest('.mb-register');
14377            if (!root) return;
14378            // Dentro del popup de Amasty: los botones sociales están en la misma pestaña (.amsl-content)
14379            const popupContent = root.closest('.amsl-popup-block') ? root.closest('.amsl-content') : null;
14380            const move = () => {
14381                const slot = root.querySelector('#mb-social-slot');
14382                if (!slot) return;
14383                if (popupContent) {
14384                    const popupButtons = Array.from(popupContent.querySelectorAll('.amsl-buttons'))
14385                        .find((el) => !slot.contains(el));
14386                    if (popupButtons) slot.appendChild(popupButtons);
14387                    addLabels();
14388                    return;
14389                }
14390                // Solo buscamos el bloque de Amasty dentro del contenido principal (nunca en la cabecera)
14391                const main = document.getElementById('maincontent') || document.querySelector('main') || document.body;
14392                const buttons = Array.from(main.querySelectorAll('.amsl-buttons'))
14393                    .find((el) => !slot.contains(el) && !el.closest('.amsl-popup-block') && !el.closest('header, .page-header, #header'));
14394                if (buttons) {
14395                    let social = buttons;
14396                    const wrapper = buttons.closest('.amsl-social-login, .amsl-social-wrapper, .amsl-login-page');
14397                    // Solo usamos el contenedor si es pequeño: no contiene nuestro hueco ni la cabecera
14398                    if (wrapper && main.contains(wrapper) && !wrapper.contains(slot) &&
14399                        !wrapper.querySelector('header, .page-header, nav, form')) {
14400                        social = wrapper;
14401                    }
14402                    slot.appendChild(social);
14403                }
14404                addLabels();
14405            };
14406            const labels = {
14407                google: 'Continuar\u0020con\u0020Google',
14408                facebook: 'Continuar\u0020con\u0020Facebook',
14409                apple: 'Continuar\u0020con\u0020Apple',
14410                twitter: 'Continuar\u0020con\u0020X',
14411                linkedin: 'Continuar\u0020con\u0020LinkedIn',
14412                amazon: 'Continuar\u0020con\u0020Amazon',
14413                paypal: 'Continuar\u0020con\u0020PayPal'
14414            };
14415            const addLabels = () => {
14416                root.querySelectorAll('#mb-social-slot .amsl-button').forEach((btn) => {
14417                    if (btn.querySelector('.mb-social-label')) return;
14418                    const hint = (btn.className + ' ' + (btn.getAttribute('href') || '') + ' ' +
14419                        (btn.getAttribute('title') || '') + ' ' + (btn.dataset.amslType || '') + ' ' +
14420                        (btn.parentElement ? btn.parentElement.className : '')).toLowerCase();
14421                    const key = Object.keys(labels).find((k) => hint.includes(k));
14422                    if (!key) return;
14423                    // Ocultamos solo el texto original de Amasty, nunca el elemento que lleva el logo
14424                    // (svg, img, fondo o ::before), para no perder el icono.
14425                    btn.querySelectorAll('*').forEach((el) => {
14426                        if (el.closest('svg') || el.tagName === 'IMG') return;
14427                        if (el.querySelector('svg, img')) return;
14428                        const cs = getComputedStyle(el);
14429                        const before = getComputedStyle(el, '::before');
14430                        const hasIcon = (cs.backgroundImage && cs.backgroundImage !== 'none') ||
14431                            (cs.maskImage && cs.maskImage !== 'none') ||
14432                            (before.content && before.content !== 'none' && before.content !== 'normal');
14433                        const ownText = Array.from(el.childNodes)
14434                            .filter((n) => n.nodeType === 3)
14435                            .map((n) => n.textContent).join('').trim();
14436                        if (!ownText) return;
14437                        if (hasIcon) {
14438                            // El texto comparte elemento con el icono: lo ocultamos sin tocar el icono
14439                            Array.from(el.childNodes).forEach((n) => {
14440                                if (n.nodeType === 3 && n.textContent.trim()) {
14441                                    const w = document.createElement('span');
14442                                    w.className = 'mb-social-orig';
14443                                    n.replaceWith(w);
14444                                    w.appendChild(n);
14445                                }
14446                            });
14447                        } else {
14448                            el.classList.add('mb-social-orig');
14449                        }
14450                    });
14451                    // Texto suelto directamente dentro del botón
14452                    Array.from(btn.childNodes).forEach((n) => {
14453                        if (n.nodeType === 3 && n.textContent.trim()) {
14454                            const w = document.createElement('span');
14455                            w.className = 'mb-social-orig';
14456                            n.replaceWith(w);
14457                            w.appendChild(n);
14458                        }
14459                    });
14460                    const label = document.createElement('span');
14461                    label.className = 'mb-social-label';
14462                    label.textContent = labels[key];
14463                    btn.appendChild(label);
14464                });
14465            };
14466            move();
14467            window.addEventListener('DOMContentLoaded', move);
14468        })();
14469    </script>
14469
14470    
14471    <!-- Panel desplegable: formulario de registro con email -->
14472    <div id="mb-email-panel" x-show="isEmailOpen" x-transition x-cloak>
14473        <button type="button" class="mb-back" @click="closeEmail">
14474            <span aria-hidden="true">&larr;</span>
14475            <span>Otras opciones de registro</span>
14476        </button>
14477
14478    
14479    <form class="form create account form-create-account"
14480          action="https://www.mueblesbonitos.com/customer/account/createpost/"
14481          x-data="mbRegisterForm"
14482                    id="accountcreate"
14483          @submit.prevent="submitForm"
14484          method="post"
14485          enctype="multipart/form-data"
14486          autocomplete="off"
14487          novalidate>
14488        <input name="form_key" type="hidden" value="GoQ6wnK4Gflfjncs" />                <div class="control">
14489    <input type="hidden"
14490           value=""
14491           name="g-recaptcha-response"
14492    >
14493</div>
14494        <input type="hidden" name="success_url" value="">
14495        <input type="hidden" name="error_url" value="">
14496
14497        <!-- Un único bloque: Tus datos -->
14498        <fieldset class="mb-section">
14499            <legend class="mb-section__title">
14500                <span>Tus datos</span>
14501            </legend>
14502
14503                <div class="field field-reserved w-full field-name-firstname required">
14504        <label class="label" for="firstname">
14505            <span>
14506                Nombre            </span>
14507        </label>
14508        <div class="control">
14509            <input type="text" id="firstname"
14510                   name="firstname"
14511                   value=""
14512                   required
14513                   title="Nombre"
14514                   class="form-input w-full required-entry"
14515                   @input.debounce="onChange"
14516                 required            >
14517        </div>
14518    </div>
14519    <div class="field field-reserved w-full field-name-lastname required">
14520        <label class="label" for="lastname">
14521            <span>
14522                Apellido            </span>
14523        </label>
14524        <div class="control">
14525            <input type="text" id="lastname"
14526                   name="lastname"
14527                   required
14528                   value=""
14529                   title="Apellido"
14530                   class="form-input w-full required-entry"
14531                   @input.debounce="onChange"
14532                 required            >
14533        </div>
14534    </div>
14535
14536                        
14537                        
14538                        
14539            
14540            <div class="field field-reserved required">
14541                <label for="am-email-address" class="label">
14542                    <span>Email</span>
14543                </label>
14544                <div class="control">
14545                    <input type="email"
14546                           name="email"
14547                           id="am-email-address"
14548                           autocomplete="email"
14549                           inputmode="email"
14550                           autocapitalize="off"
14551                           spellcheck="false"
14552                           required
14553                           placeholder="tu&#x40;email.com"
14554                           value=""
14555                           title="Email"
14556                           class="form-input w-full"
14557                           @input.debounce="onChange">
14558                </div>
14559            </div>
14560
14561            <div class="field field-reserved required">
14562                <label for="password" class="label">
14563                    <span>Contraseña</span>
14564                </label>
14565                <div class="control mb-password">
14566                    <div class="sr-only" aria-live="polite">
14567                        <span x-text="pwStatus"></span>
14568                    </div>
14569                    <input :type="pwType"
14570                           type="password"
14571                           id="password"
14572                           name="password"
14573                           title="Contrase&#xF1;a"
14574                           minlength="8"
14575                           class="form-input w-full"
14576                           required
14577                           aria-describedby="password-hint"
14578                           data-validate='{"password-strength": {"minCharacterSets": 3}}'
14579                           @input.debounce="onChange"
14580                           autocomplete="off">
14581                    <button type="button"
14582                            class="mb-password__toggle"
14583                            :aria-pressed="pwPressed"
14584                            @click="togglePw"
14585                            :aria-label="pwLabel">
14586                        <span x-show="pwIsHidden"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
14587  <path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/>
14588  <path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
14589</svg>
14590</span>
14591                        <span x-show="pwIsVisible" x-cloak><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
14592  <path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/>
14593  <path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/>
14594</svg>
14595</span>
14596                    </button>
14597                </div>
14598                <p id="password-hint" class="mb-hint">
14599                    Mínimo 8 caracteres. Combina mayúsculas, minúsculas, números o símbolos.                </p>
14600                <div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite">
14601                    <div id="password-strength-meter" class="password-strength-meter">
14602                        Nivel de Seguridad de Contraseña:
14603                        <span id="password-strength-meter-label" data-role="password-strength-meter-label">
14604                            Ninguna contraseña                        </span>
14605                    </div>
14606                </div>
14607            </div>
14608
14609            <div class="field field-reserved required">
14610                <label for="password-confirmation" class="label">
14611                    <span>Confirmar Contraseña</span>
14612                </label>
14613                <div class="control mb-password">
14614                    <div class="sr-only" aria-live="polite">
14615                        <span x-text="pwConfirmStatus"></span>
14616                    </div>
14617                    <input :type="pwConfirmType"
14618                           type="password"
14619                           name="password_confirmation"
14620                           id="password-confirmation"
14621                           title="Confirmar&#x20;Contrase&#xF1;a"
14622                           data-validate='{"equalTo": "password"}'
14623                           @input.debounce="onChange"
14624                           required
14625                           class="form-input w-full"
14626                           autocomplete="off">
14627                    <button type="button"
14628                            class="mb-password__toggle"
14629                            :aria-pressed="pwConfirmPressed"
14630                            @click="togglePwConfirm"
14631                            :aria-label="pwConfirmLabel">
14632                        <span x-show="pwConfirmIsHidden"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
14633  <path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/>
14634  <path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
14635</svg>
14636</span>
14637                        <span x-show="pwConfirmIsVisible" x-cloak><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
14638  <path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/>
14639  <path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/>
14640</svg>
14641</span>
14642                    </button>
14643                </div>
14644            </div>
14645
14646        
14647        <!-- Consentimientos + envío -->
14648        <div class="mb-consents">
14649                            <div class="mb-check field choice newsletter">
14650                    <input type="checkbox" name="is_subscribed" value="1" id="is_subscribed"
14651                           title="Darse&#x20;de&#x20;Alta&#x20;para&#x20;Bolet&#xED;n&#x20;de&#x20;Noticias"
14652                                                      class="checkbox">
14653                    <label for="is_subscribed">
14654                        Quiero recibir novedades y ofertas exclusivas por email                    </label>
14655                </div>
14656                            
14657            <div class="mb-check field choice required">
14658                <input type="checkbox" name="privacy" id="privacy" required class="checkbox">
14659                <label for="privacy">
14660                    He leído y acepto la                    <a href="https://www.mueblesbonitos.com/privacidad/" target="_blank" rel="noopener">Política de privacidad</a>
14661                </label>
14662            </div>
14663
14664            
14665            <button type="submit"
14666                    class="action submit primary btn btn-primary mb-submit"
14667                    title="Crear&#x20;una&#x20;Cuenta"
14668                    >
14669                <span>Crear una Cuenta</span>
14670            </button>
14671
14672            <div class="mt-3 text-xs text-center" style="color: var(--mb-muted)">
14673                <p class="prose my-4 text-sm">
14674    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
14675</p>
14676            </div>
14677        </div>
14678        </fieldset>
14679    </form>
14680    </div><!-- /#mb-email-panel -->
14681
14682    <p class="mb-register__footer">
14683        ¿Ya tienes cuenta?        <a href="https://www.mueblesbonitos.com/customer/account/login/">Inicia sesión</a>
14684    </p>
14685</div>
14686
14687<script>
14688    function mbRegisterPanel() {
14689        return {
14690            emailOpen: false,
14691            init() {
14692                this.emailOpen = this.$el.dataset.open === 'true';
14693            },
14694            isEmailOpen() {
14695                return this.emailOpen;
14696            },
14697            isEmailClosed() {
14698                return !this.emailOpen;
14699            },
14700            emailExpanded() {
14701                return this.emailOpen ? 'true' : 'false';
14702            },
14703            openEmail() {
14704                this.emailOpen = true;
14705                this.$nextTick(() => {
14706                    const f = this.$root.querySelector('[name="firstname"]');
14707                    f && f.focus();
14708                });
14709            },
14710            closeEmail() {
14711                this.emailOpen = false;
14712                window.scrollTo({ top: 0, behavior: 'smooth' });
14713            }
14714        }
14715    }
14716
14717    function mbRegisterForm() {
14718        return Object.assign(hyva.formValidation(this.$el), mbRegisterFormMethods());
14719    }
14720
14721    function mbRegisterFormMethods() {
14722        const labels = {
14723            show: 'Mostrar\u0020Contrase\u00F1a',
14724            hide: 'Ocultar\u0020contrase\u00F1a',
14725            pwShown: 'Se\u0020muestra\u0020la\u0020contrase\u00F1a',
14726            pwHidden: 'Contrase\u00F1a\u0020oculta',
14727            confirmShown: 'Confirm\u0020password\u0020shown',
14728            confirmHidden: 'Confirmar\u0020contrase\u00F1a\u0020oculta'
14729        };
14730
14731        return {
14732            errors: 0,
14733            hasCaptchaToken: 0,
14734            pwVisible: false,
14735            pwConfirmVisible: false,
14736
14737            // Contraseña
14738            togglePw() { this.pwVisible = !this.pwVisible; },
14739            pwType() { return this.pwVisible ? 'text' : 'password'; },
14740            pwPressed() { return this.pwVisible ? 'true' : 'false'; },
14741            pwLabel() { return this.pwVisible ? labels.hide : labels.show; },
14742            pwStatus() { return this.pwVisible ? labels.pwShown : labels.pwHidden; },
14743            pwIsHidden() { return !this.pwVisible; },
14744            pwIsVisible() { return this.pwVisible; },
14745
14746            // Confirmar contraseña
14747            togglePwConfirm() { this.pwConfirmVisible = !this.pwConfirmVisible; },
14748            pwConfirmType() { return this.pwConfirmVisible ? 'text' : 'password'; },
14749            pwConfirmPressed() { return this.pwConfirmVisible ? 'true' : 'false'; },
14750            pwConfirmLabel() { return this.pwConfirmVisible ? labels.hide : labels.show; },
14751            pwConfirmStatus() { return this.pwConfirmVisible ? labels.confirmShown : labels.confirmHidden; },
14752            pwConfirmIsHidden() { return !this.pwConfirmVisible; },
14753            pwConfirmIsVisible() { return this.pwConfirmVisible; },
14754
14755            submitForm() {
14756                this.validate()
14757                    .then(() => {
14758                        // Do not rename $form, the variable is expected to be declared in the recaptcha output
14759                        const $form = this.$root;
14760                                                // Exactamente un campo g-recaptcha-response dentro del formulario
14761                        const tokenInputs = $form.querySelectorAll('[name="g-recaptcha-response"]');
14762                        tokenInputs.forEach((input, i) => { if (i > 0) input.remove(); });
14763                        if (!tokenInputs.length) {
14764                            const input = document.createElement('input');
14765                            input.type = 'hidden';
14766                            input.name = 'g-recaptcha-response';
14767                            $form.appendChild(input);
14768                        }
14769                            if (!this.hasCaptchaToken) {
14770        this.errors = 1;
14771
14772
14773        const executeGreCaptcha = () => {
14774            grecaptcha.ready(() => {
14775                grecaptcha.execute(
14776                    '6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3',
14777                    {action: 'submit'}
14778                ).then((token) => {
14779                    const tokenElement = $form['g\u002Drecaptcha\u002Dresponse'];
14780
14781                    if (tokenElement && token && token.length > 0) {
14782                        $form['g\u002Drecaptcha\u002Dresponse'].value = token;
14783                        this.errors = 0;
14784                        this.hasCaptchaToken = 1;
14785                        (this.submitForm || $form.submit).call(this);
14786                    } else {
14787                        this.errors = 1;
14788                        const error = tokenElement
14789                            ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'
14790                            : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.';
14791                        if (this.setErrorMessages) {
14792                            this.setErrorMessages([error])
14793                            this.displayErrorMessage = true;
14794                        } else {
14795                            window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000);
14796                        }
14797                    }
14798                }).catch(exception => {
14799                    console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`)
14800                });
14801            })
14802        }
14803
14804        if (window.grecaptcha) {
14805            executeGreCaptcha();
14806        } else {
14807            const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3";
14808            const script = document.createElement('script');
14809            script.setAttribute('type', 'text/javascript');
14810            script.setAttribute('src', recaptchaUrl);
14811            document.head.appendChild(script);
14812
14813            script.addEventListener("load", executeGreCaptcha, false);
14814        }
14815    }
14816                        
14817                        if (this.errors === 0) {
14818                            $form.submit();
14819                        }
14820                    })
14821                    .catch((invalid) => {
14822                        if (invalid.length > 0) {
14823                            invalid[0].focus();
14824                            invalid[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
14825                        }
14826                    });
14827            },
14828                    }
14829    }
14830
14831    const mbRegisterAddRules = () => {
14832        hyva.formValidation.addRule('telephone', (value, options) => {
14833            const phoneNumber = value.trim().replace(' ', '');
14834            if (phoneNumber && phoneNumber.length < (options.minlength || 3)) {
14835                return 'El\u0020n\u00FAmero\u0020de\u0020tel\u00E9fono\u0020es\u0020demasiad
14835o\u0020corto.';
14836            }
14837            return true;
14838        });
14839
14840        const postCodeSpecs = {"AD":{"pattern_1":{"example":"AD100","pattern":"^AD\\d{3}$"}},"AM":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"AR":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"},"pattern_2":{"example":"A1234BCD","pattern":"^[a-zA-z]{1}[0-9]{4}[a-zA-z]{3}$"}},"AS":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"AT":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"AU":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"AX":{"pattern_1":{"example":"22123","pattern":"^22\\d{3}$"}},"AZ":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"},"pattern_2":{"example":"123456","pattern":"^[0-9]{6}$"}},"BA":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"BB":{"pattern_1":{"example":"BB12345","pattern":"^(BB\\d{5})?$"}},"BD":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"BE":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"BG":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"BH":{"pattern_1":{"example":"323","pattern":"^((1[0-2]|[1-9])\\d{2})?$"}},"BM":{"pattern_1":{"example":"MA 02","pattern":"^[A-Z]{2}[ ]?[A-Z0-9]{2}$"}},"BN":{"pattern_1":{"example":"AB1234","pattern":"^[a-zA-z]{2}[0-9]{4}$"}},"BR":{"pattern_1":{"example":"12345678","pattern":"^[0-9]{8}$"},"pattern_2":{"example":"12345-678","pattern":"^[0-9]{5}\\-[0-9]{3}$"}},"BY":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"CA":{"pattern_1":{"example":"A1B 2C3","pattern":"^[a-zA-z]{1}[0-9]{1}[a-zA-z]{1}\\s[0-9]{1}[a-zA-z]{1}[0-9]{1}$"},"pattern_2":{"example":"A1B2C3","pattern":"^[a-zA-z]{1}[0-9]{1}[a-zA-z]{1}[0-9]{1}[a-zA-z]{1}[0-9]{1}$"},"pattern_3":{"example":"A1B","pattern":"^[a-zA-z]{1}[0-9]{1}[a-zA-z]{1}$"}},"CC":{"pattern_1":{"example":"6799","pattern":"^6799$"}},"CH":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"CK":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"CL":{"pattern_1":{"example":"1234567","pattern":"^\\d{7}$"}},"CN":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"CR":{"pattern_1":{"example":"12345 or 123-1234","pattern":"^\\d{4,5}|\\d{3}-\\d{4}$"}},"CS":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"CU":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"CV":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"CX":{"pattern_1":{"example":"6798","pattern":"^6798$"}},"CY":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"CZ":{"pattern_1":{"example":"123 45","pattern":"^[0-9]{3}\\s[0-9]{2}$"}},"DE":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"DK":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"DO":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"DZ":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"EC":{"pattern_1":{"example":"A1234B or AB123456 or 123456","pattern":"^([A-Z]\\d{4}[A-Z]|(?:[A-Z]{2})?\\d{6})?$"}},"EE":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"EG":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"ES":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"ET":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"FI":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"FK":{"pattern_1":{"example":"FIQQ 1ZZ","pattern":"^FIQQ 1ZZ$"}},"FM":{"pattern_1":{"example":"96941","pattern":"^(9694[1-4])([ \\-]\\d{4})?$"}},"FO":{"pattern_1":{"example":"123","pattern":"^\\d{3}$"}},"FR":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"GB":{"pattern_1":{"example":"AB12 3CD","pattern":"^[a-zA-Z]{2}[0-9]{2}\\s?[0-9]{1}[a-zA-Z]{2}$"},"pattern_2":{"example":"A1B 2CD","pattern":"^[a-zA-Z]{1}[0-9]{1}[a-zA-Z]{1}\\s?[0-9]{1}[a-zA-Z]{2}$"},"pattern_3":{"example":"AB1 2CD","pattern":"^[a-zA-Z]{2}[0-9]{1}\\s?[0-9]{1}[a-zA-Z]{2}$"},"pattern_4":{"example":"AB1C 2DF","pattern":"^[a-zA-Z]{2}[0-9]{1}[a-zA-Z]{1}\\s?[0-9]{1}[a-zA-Z]{2}$"},"pattern_5":{"example":"A12 3BC","pattern":"^[a-zA-Z]{1}[0-9]{2}\\s?[0-9]{1}[a-zA-Z]{2}$"},"pattern_6":{"example":"A1 2BC","pattern":"^[a-zA-Z]{1}[0-9]{1}\\s?[0-9]{1}[a-zA-Z]{2}$"}},"GE":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"GF":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"GG":{"pattern_1":{"example":"GY10 2AB","pattern":"^[gG][yY]([1-9]|10)\\s?[0-9]{1}[a-zA-Z]{2}$"}},"GH":{"pattern_1":{"example":"GA18400","pattern":"^[A-Z][A-Z0-9]\\d{3,5}$"}},"GL":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"GN":{"pattern_1":{"example":"123","pattern":"^\\d{3}$"}},"GP":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"GR":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"GS":{"pattern_1":{"example":"SIQQ 1ZZ","pattern":"^SIQQ 1ZZ$"}},"GT":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"GU":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"GW":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"HM":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"HN":{"pattern_1":{"example":"12345","pattern":"^(?:\\d{5})?$"}},"HR":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"HT":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"HU":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"IC":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"ID":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"IL":{"pattern_1":{"example":"6687865","pattern":"^[0-9]{7}$"}},"IM":{"pattern_1":{"example":"IM1 1AD","pattern":"^IM\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$"}},"IN":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"IO":{"pattern_1":{"example":"BBND 1ZZ","pattern":"^BBND 1ZZ$"}},"IS":{"pattern_1":{"example":"123","pattern":"^[0-9]{3}$"}},"IQ":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"IT":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}}
14840,"JE":{"pattern_1":{"example":"JE2 4PJ","pattern":"^[jJ][eE][1-5]{1}\\s?[0-9]{1}[a-zA-Z]{2}$"}},"JO":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"JP":{"pattern_1":{"example":"123-4567","pattern":"^[0-9]{3}-[0-9]{4}$"},"pattern_2":{"example":"1234567","pattern":"^[0-9]{7}$"}},"KE":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"KG":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"KR":{"pattern_1":{"example":"123-456","pattern":"^[0-9]{3}-[0-9]{3}$"},"pattern_2":{"example":"12345","pattern":"^[0-9]{5}$"}},"KH":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"KW":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"KZ":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"LA":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"LB":{"pattern_1":{"example":"1234 5678","pattern":"^(\\d{4}([ ]?\\d{4})?)?$"}},"LI":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"LK":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"LT":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"LU":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"LV":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"MA":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"MC":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"MD":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"ME":{"pattern_1":{"example":"81101","pattern":"^8\\d{4}$"}},"MG":{"pattern_1":{"example":"123","pattern":"^[0-9]{3}$"}},"MH":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"MK":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"MN":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"MP":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"MS":{"pattern_1":{"example":"MSR1250","pattern":"^MSR\\s?\\d{4}$"}},"MQ":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"MT":{"pattern_1":{"example":"ABC 1234","pattern":"^[a-zA-Z]{3}\\s[0-9]{4}$"},"pattern_2":{"example":"ABC 123","pattern":"^[a-zA-Z]{3}\\s[0-9]{3}$"},"pattern_3":{"example":"ABC 12","pattern":"^[a-zA-Z]{3}\\s[0-9]{2}$"}},"MU":{"pattern_1":{"example":"A1201 or 80110","pattern":"^([AR]|[0-9])\\d{4,5}$"}},"MV":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"},"pattern_2":{"example":"1234","pattern":"^[0-9]{4}$"}},"MX":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"MY":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"NC":{"pattern_1":{"example":"98800","pattern":"^988\\d{2}$"}},"NE":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"NF":{"pattern_1":{"example":"2899","pattern":"^2899$"}},"NG":{"pattern_1":{"example":"123456","pattern":"^(\\d{6})?$"}},"NI":{"pattern_1":{"example":"22500","pattern":"^\\d{5}$"}},"NL":{"pattern_1":{"example":"1234 AB\/1234AB","pattern":"^[1-9][0-9]{3}\\s?[a-zA-Z]{2}$"},"pattern_2":{"example":"1234","pattern":"^[1-9][0-9]{3}$"}},"NO":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"NP":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"NZ":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"OM":{"pattern_1":{"example":"PC 123 or 123","pattern":"^(PC )?\\d{3}$"}},"PA":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"PF":{"pattern_1":{"example":"98701","pattern":"^987\\d{2}$"}},"PG":{"pattern_1":{"example":"123","pattern":"^\\d{3}$"}},"PH":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"PK":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"PL":{"pattern_1":{"example":"12-345","pattern":"^[0-9]{2}-[0-9]{3}$"}},"PM":{"pattern_1":{"example":"97500","pattern":"^9[78]5\\d{2}$"}},"PN":{"pattern_1":{"example":"PCRN 1ZZ","pattern":"^PCRN 1ZZ$"}},"PR":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"PT":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"},"pattern_2":{"example":"1234-567","pattern":"^[0-9]{4}-[0-9]{3}$"}},"PW":{"pattern_1":{"example":"96939 or 96940","pattern":"^(?:96939|96940)$"}}
14840,"PY":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"RE":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"RO":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"RS":{"pattern_1":{"example":"123456","pattern":"^\\d{6}$"}},"RU":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"SA":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"SE":{"pattern_1":{"example":"123 45","pattern":"^[0-9]{3}\\s[0-9]{2}$"}},"SG":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"SI":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"SK":{"pattern_1":{"example":"123 45","pattern":"^[0-9]{3}\\s[0-9]{2}$"}},"SH":{"pattern_1":{"example":"ASCN 1ZZ","pattern":"^(ASCN|STHL) 1ZZ$"}},"SJ":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"SM":{"pattern_1":{"example":"47890","pattern":"^4789\\d$"}},"SN":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"SO":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"SZ":{"pattern_1":{"example":"A123","pattern":"^[a-zA-Z]{1}[0-9]{3}$"}},"TC":{"pattern_1":{"example":"TKCA 1ZZ","pattern":"^TKCA 1ZZ$"}},"TH":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"TJ":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"TM":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"TN":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"TR":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"TT":{"pattern_1":{"example":"120110","pattern":"^\\d{6}$"}},"TW":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"},"pattern_2":{"example":"123","pattern":"^[0-9]{3}$"}},"UA":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"US":{"pattern_1":{"example":"12345-6789","pattern":"^[0-9]{5}\\-[0-9]{4}$"},"pattern_2":{"example":"12345","pattern":"^[0-9]{5}$"}},"UY":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"UZ":{"pattern_1":{"example":"123456","pattern":"^[0-9]{6}$"}},"VA":{"pattern_1":{"example":"00120","pattern":"^00120$"}},"VE":{"pattern_1":{"example":"1234","pattern":"^\\d{4}$"}},"VI":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"WF":{"pattern_1":{"example":"98601","pattern":"^986\\d{2}$"}},"XK":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}},"XY":{"pattern_1":{"example":"12345","pattern":"^[0-9]{5}$"}},"YT":{"pattern_1":{"example":"97601","pattern":"^976\\d{2}$"}},"ZA":{"pattern_1":{"example":"1234","pattern":"^[0-9]{4}$"}},"ZM":{"pattern_1":{"example":"12345","pattern":"^\\d{5}$"}}};
14841
14842        hyva.formValidation.addRule('postcode', (postCode, options, field, context) => {
14843            context.removeMessages(field, 'postcode-warning')
14844            const countryId = (context.fields['country_id'] && context.fields['country_id'].element.value),
14845                validatedPostCodeExamples = [],
14846                countryPostCodeSpecs = countryId && postCodeSpecs ? postCodeSpecs[countryId] : false;
14847
14848            if (!postCode || !countryPostCodeSpecs) return true;
14849
14850            for (const postCodeSpec of Object.values(countryPostCodeSpecs)) {
14851                if (new RegExp(postCodeSpec.pattern).test(postCode)) return true;
14852                validatedPostCodeExamples.push(postCodeSpec.example);
14853            }
14854            if (validatedPostCodeExamples.length) {
14855                context.addMessages(field, 'postcode-warning', [
14856                    'El\u0020C\u00F3digo\u0020Postal\u0020proporcionado\u0020parece\u0020no\u0020ser\u0020v\u00E1lido.',
14857                    '\u0020Ejemplo\u003A\u0020' + validatedPostCodeExamples.join('; ') + '. ',
14858                    'Si\u0020cree\u0020que\u0020es\u0020el\u0020correcto,\u0020puede\u0020ignorar\u0020este\u0020aviso.'
14859                ]);
14860            }
14861            return true;
14862        });
14863    };
14864    document.readyState === 'loading'
14865        ? window.addEventListener('DOMContentLoaded', mbRegisterAddRules)
14866        : mbRegisterAddRules();
14867
14868    ;(() => {
14869        const register = () => {
14870            Alpine.data('mbRegisterPanel', mbRegisterPanel);
14871            Alpine.data('mbRegisterForm', mbRegisterForm);
14872        };
14873        (document.readyState === 'loading' || !window.Alpine)
14874            ? window.addEventListener('alpine:init', register, {once: true})
14875            : register();
14876    })();
14877</script>
14877
14878
14879                                                            <div class="recaptcha-create-wrapper recaptcha-wrapper w-full">
14880                                    <div class="control">
14881    <input type="hidden"
14882           value=""
14883           name="g-recaptcha-response"
14884    >
14885</div>
14886                                </div>
14887                                                                                        <div class="recaptcha-create-wrapper recaptcha-wrapper w-full">
14888                                    <p class="prose my-4 text-sm">
14889    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
14890</p>
14891                                </div>
14892                                                    </div>
14893                    </template>
14894                        <span class="amsl-separator bg-gray-500 hidden text-secondary text-sm font-bold relative w-0.5">
14895        <span
14896            class="amsl-icon absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2
14897                border border-gray-500 rounded-full bg-white overflow-hidden w-8 h-8
14898                min-w-8 flex items-center justify-center pb-[3px]"
14899        >o bien</span>
14900    </span>
14901    <div class="amsl-social-wrapper"
14902            >
14903        <div class="amsl-title text-base font-medium text-gray-70 mb-2">
14904            Inicia sesión con tus redes sociales        </div>
14905        <div class="amsl-title text-base font-medium text-gray-70 mb-2 -short">
14906            Iniciar Sesión con        </div>
14907        <div class="amsl-social-login ">
14908            <template x-if="hasSocialError">
14909                <p class="amsl-error -social message error mb-4" x-text="socialErrorMessage"></p>
14910            </template>
14911            <div class="amsl-buttons flex flex-wrap justify-center gap-7"
14912                                    :class="socialButtonsClasses"
14913                                >
14914                                                        <div
14915                        class="amsl-button-wrapper
14916                            "
14917                    >
14918                        <form method="POST"
14919                              action="https://www.mueblesbonitos.com/amsociallogin/social/login/?type=google"
14920                              class="amsl-button-form"
14921                              aria-label="Sign in with Google"
14922                              x-on:submit="socialLoginClick"
14923                        >
14924                            <input name="form_key" type="hidden" value="lYvGLDMwoyHIBAad" />                            <button
14925                                type="submit"
14926                                class="amsl-button rounded-full overflow-hidden bg-white
14927                                shadow-md hover:shadow-lg transition-amsl-social-button
14928                                block w-16 h-16 p-4                                -google&#x20;"
14929                                title="Sign in with Google"
14930                            >
14931                                <span
14932                                    class="amsl-social-icon pointer-events-none
14933                                        "                                    role="img"
14934                                    aria-label="Sign in with Google"
14935                                >
14936                                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:v="https://vecta.io/nano" viewBox="0 0 31 33" fill="none" width="24" height="24" role="img"><path d="M1.125 10.662c-.726 1.85-1.1 3.841-1.023 5.869-.061 3.005.825 5.947 2.383 8.465l4.781-3.654c-.261-.501-.478-1.03-.643-1.586-.625-1.678-.712-3.469-.371-5.174l-5.127-3.92z" fill="#fbbc05"/><path d="M15.832.502l-.775.045c-6.14.075-11.7 4.435-13.93 10.115l5.125 3.918c.711-3.552 3.289-6.733 6.809-7.75 3.23-1.155 6.557.145 9.322 1.85 1.399-1.331 2.71-2.751 3.998-4.189C23.437 1.989 19.706.395 15.832.502zm.016 13.736v.041l.047-.041c-.016 0-.031 0-.047 0z" fill="#ea4335"/><path d="M23.387 14.219c-2.298-.001-4.595.006-6.891.01l-.648.496.008 4.953 9.035.107c-.76 2.645-2.493 5.106-5.121 6.061-4.56 2.039-10.247-.148-12.514-4.533l-4.777 3.662c1.906 3.086 4.822 5.537 8.256 6.682 5.873 2.003 13.093.505 17.002-4.602 2.853-3.577 3.502-8.348 3.193-12.805l-7.543-.031z" fill="#34a853"/><path d="M23.385 14.219c-2.514-.001-5.026.006-7.537.01l.008 5.449 9.035.107c-.69 2.401-2.185 4.647-4.42 5.756l4.959 3.84c.852-.669 1.63-1.442 2.307-2.326 2.853-3.577 3.502-8.348 3.193-12.805l-7.545-.031z" fill="#4285f4"/><title>google</title></svg>
14937                                </span>
14938                                                            </button>
14939                        </form>
14940                    </div>
14941                                                        <div
14942                        class="amsl-button-wrapper
14943                            "
14944                    >
14945                        <form method="POST"
14946                              action="https://www.mueblesbonitos.com/amsociallogin/social/login/?type=facebook"
14947                              class="amsl-button-form"
14948                              aria-label="Sign in with Facebook"
14949                              x-on:submit="socialLoginClick"
14950                        >
14951                            <input name="form_key" type="hidden" value="lYvGLDMwoyHIBAad" />                            <button
14952                                type="submit"
14953                                class="amsl-button rounded-full overflow-hidden bg-white
14954                                shadow-md hover:shadow-lg transition-amsl-social-button
14955                                block w-16 h-16 p-4                                -facebook&#x20;"
14956                                title="Sign in with Facebook"
14957                            >
14958                                <span
14959                                    class="amsl-social-icon pointer-events-none
14960                                        "                                    role="img"
14961                                    aria-label="Sign in with Facebook"
14962                                >
14963                                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 38" fill="none" width="24" height="24" role="img"><path d="M12.37 37.28V20.668h5.576l.835-6.474H12.37V10.06c0-1.875.52-3.152 3.209-3.152l3.428-.002v-5.79c-.593-.08-2.628-.256-4.996-.256-4.943 0-8.327 3.017-8.327 8.558v4.775H.094v6.475h5.59V37.28h6.686z" fill="currentColor"/><title>facebook</title></svg>
14964                                </span>
14965                                                            </button>
14966                        </form>
14967                    </div>
14968                            </div>
14969                    </div>
14970    </div>
14971
14972            
14972<script>
14973    function AmSocialLogin() {
14974        return {
14975            socialErrorMessage: '',
14976            isPopupEnabled: '1',
14977
14978            initializeSocialLogin() {
14979                this.initContentUpdaters();
14980            },
14981
14982            socialLoginClick(event) {
14983                const form = event.currentTarget;
14984
14985                if (this.isPopupEnabled) {
14986                    form.target = '_blank';
14987                    form.action = form.action + '&isAjax=true';
14988                }
14989
14990                const channel = new BroadcastChannel('amSocialLoginData');
14991                channel.addEventListener('message', this.onMessageEvent.bind(this));
14992
14993                event.stopPropagation();
14994                event.preventDefault();
14995                form.submit();
14996
14997                return false;
14998            },
14999
15000            onSocialResponse(data) {
15001                const isSuccessfulResult = data.result === 1;
15002
15003                if (isSuccessfulResult) {
15004                    window.dispatchEvent(
15005                        new CustomEvent(
15006                            'amsl-popup-show-notification',
15007                            {
15008                                detail: data.messages
15009                            }
15010                        )
15011                    );
15012                    this.processRedirect();
15013                } else {
15014                    const redirectData = data?.redirect_data;
15015
15016                    this.socialErrorMessage = data.messages.pop();
15017                    setTimeout(() => {
15018                        this.socialErrorMessage = '';
15019                    }, 5000);
15020
15021                    if (this.shouldCustomUrlRedirectWithError(redirectData)) {
15022                        return this.processRedirect(redirectData?.url);
15023                    }
15024
15025                    if (redirectData?.redirectWithError) {
15026                        this.processRedirect();
15027                    }
15028                }
15029            },
15030
15031            // Helper CSP: x-if="hasSocialError"
15032            hasSocialError() {
15033                return !!this.socialErrorMessage;
15034            },
15035
15036            shouldCustomUrlRedirectWithError(redirectData) {
15037                return (
15038                    redirectData &&
15039                    redirectData.redirect &&
15040                    redirectData.redirectWithError &&
15041                    redirectData.url
15042                );
15043            },
15044
15045            onMessageEvent(event) {
15046                if (event.origin !== window.location.origin) {
15047                    return;
15048                }
15049
15050                const data = JSON.parse(event.data);
15051                if (data['redirect_data']) {
15052                    this.onSocialResponse(data);
15053                }
15054            },
15055
15056            ...AmAuthPopupRedirect(),
15057            ...AmAuthPopupReloadContent()
15058        }
15059    }
15060
15061    ;(() => {
15062        // Durante la carga de la página: esperar a alpine:init (todos los scripts ya definidos).
15063        // Si el script llega tarde (p.ej. dentro de un <template x-if>), registrar directamente.
15064        const register = () => Alpine.data('AmSocialLogin', AmSocialLogin);
15065        (document.readyState === 'loading' || !window.Alpine)
15066            ? window.addEventListener('alpine:init', register, {once: true})
15067            : register();
15068    })();
15069</script>
15069
15070                </div>
15071            </div>
15072        </div>
15073
15074        <div class="amsl-tabs-wrapper -forgot"
15075            x-show="isForgotTab"
15076            title="Forgot Your Password Form"
15077            x-cloak
15078        >
15079            <ul class="amsl-tablist flex space-x-4" role="tablist">
15080                <li class="amsl-title"
15081                    id="tab-amsl-forgot"
15082                    role="tab" aria-controls="amsl-forgot-content"
15083                >
15084                    <span class="amsl-link block p-4 text-lg border-b -active border-primary text-blue-800 hover:bg-transparent"
15085                       @click.prevent
15086                    >
15087                        ¿Olvidó su Contraseña?                    </span>
15088                </li>
15089            </ul>
15090            <div id="amsl-forgot-content" role="tabpanel" aria-labelledby="tab-amsl-forgot">
15091                <template x-if="hasForgotMessages">
15092                    <div class="mt-4">
15093                        <template x-for="message in forgotMessages" :key="message">
15094                            <div class="message error">
15095                                <span x-html="message"></span>
15096                            </div>
15097                        </template>
15098                    </div>
15099                </template>
15100                <div class="amsl-content amsl-forgot-content mt-6">
15101                    <template x-if="isNotLogged">
15102                        <div class="amsl-form">
15103                            <div class="mb-12">
15104    <div class="w-full md:w-1/2 card my-8">
15105        <form action="https://www.mueblesbonitos.com/customer/account/forgotpasswordpost/"
15106              method="post"
15107              id="user_forgotpassword"
15108              x-data="initPasswordForm"
15109              @submit.prevent="submitForm">
15110            <input name="form_key" type="hidden" value="GoQ6wnK4Gflfjncs" />            <input type="hidden" name="formId" value="user_forgotpassword">
15111                        <div class="control">
15112    <input type="hidden"
15113           value=""
15114           name="g-recaptcha-response"
15115    >
15116</div>
15117            <fieldset class="fieldset">
15118                <fieldset class="mb-8">
15119                    Por favor, introduce tu dirección de correo electrónico a continuación para recibir un enlace de restablecimiento de contraseña.                </fieldset>
15120                <div class="field email required">
15121                    <label for="email_address" class="label">
15122                        <span>Email</span>
15123                    </label>
15124                    <div class="control">
15125                        <input type="email"
15126                               name="email"
15127                               alt="email"
15128                               id="email_address"
15129                               class="form-input w-full"
15130                               autocomplete="off"
15131                               required
15132                               value="">
15133                    </div>
15134                </div>
15135                                <p class="prose my-4 text-sm">
15136    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
15137</p>
15138            </fieldset>
15139            <div class="actions-toolbar">
15140                <div class="primary">
15141                    <button type="submit" class="action submit primary disabled:opacity-75"
15142                                            >
15143                        <span>Restablecer mi contraseña</span>
15144                    </button>
15145                </div>
15146                <div class="secondary">
15147                    <a class="action back"
15148                       href="https://www.mueblesbonitos.com/customer/account/login/referer/aHR0cHM6Ly93d3cubXVlYmxlc2Jvbml0b3MuY29tL3NhbG9u/"><span>Volver</span></a>
15149                </div>
15150            </div>
15151        </form>
15152        
15152<script>
15153            function initPasswordForm() {
15154                return {
15155                    errors: 0,
15156                    hasCaptchaToken: 0,
15157                    submitForm() {
15158                        // Do not rename $form, the variable is expected to be declared in the recaptcha output
15159                        const $form = this.$root;
15160                                                // Exactamente un campo g-recaptcha-response dentro del formulario
15161                        const tokenInputs = $form.querySelectorAll('[name="g-recaptcha-response"]');
15162                        tokenInputs.forEach((input, i) => { if (i > 0) input.remove(); });
15163                        if (!tokenInputs.length) {
15164                            const input = document.createElement('input');
15165                            input.type = 'hidden';
15166                            input.name = 'g-recaptcha-response';
15167                            $form.appendChild(input);
15168                        }
15169                            if (!this.hasCaptchaToken) {
15170        this.errors = 1;
15171
15172
15173        const executeGreCaptcha = () => {
15174            grecaptcha.ready(() => {
15175                grecaptcha.execute(
15176                    '6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3',
15177                    {action: 'submit'}
15178                ).then((token) => {
15179                    const tokenElement = $form['g\u002Drecaptcha\u002Dresponse'];
15180
15181                    if (tokenElement && token && token.length > 0) {
15182                        $form['g\u002Drecaptcha\u002Dresponse'].value = token;
15183                        this.errors = 0;
15184                        this.hasCaptchaToken = 1;
15185                        (this.submitForm || $form.submit).call(this);
15186                    } else {
15187                        this.errors = 1;
15188                        const error = tokenElement
15189                            ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'
15190                            : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.';
15191                        if (this.setErrorMessages) {
15192                            this.setErrorMessages([error])
15193                            this.displayErrorMessage = true;
15194                        } else {
15195                            window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000);
15196                        }
15197                    }
15198                }).catch(exception => {
15199                    console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`)
15200                });
15201            })
15202        }
15203
15204        if (window.grecaptcha) {
15205            executeGreCaptcha();
15206        } else {
15207            const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LdhDJUsAAAAAFXlSOEYil6koVeIFlWUTvMii4H3";
15208            const script = document.createElement('script');
15209            script.setAttribute('type', 'text/javascript');
15210            script.setAttribute('src', recaptchaUrl);
15211            document.head.appendChild(script);
15212
15213            script.addEventListener("load", executeGreCaptcha, false);
15214        }
15215    }
15216                        
15217                        if (this.errors === 0) {
15218                            $form.submit();
15219                        }
15220                    }
15221                }
15222            }
15223
15224            ;(() => {
15225        // Durante la carga de la página: esperar a alpine:init (todos los scripts ya definidos).
15226        // Si el script llega tarde (p.ej. dentro de un <template x-if>), registrar directamente.
15227        const register = () => Alpine.data('initPasswordForm', initPasswordForm);
15228        (document.readyState === 'loading' || !window.Alpine)
15229            ? window.addEventListener('alpine:init', register, {once: true})
15230            : register();
15231    })();
15232        </script>
15232
15233            </div>
15234</div>
15235                                                                                                <div class="recaptcha-forgot-wrapper recaptcha-wrapper w-full">
15236                                        <div class="control">
15237    <input type="hidden"
15238           value=""
15239           name="g-recaptcha-response"
15240    >
15241</div>
15242                                    </div>
15243                                                                                                    <div class="recaptcha-forgot-wrapper recaptcha-wrapper w-full">
15244                                        <p class="prose my-4 text-sm">
15245    <em>Este formulario está protegido por reCAPTCHA: se aplican la <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Política de privacidad</a> y las <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Condiciones del servicio</a> <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">de Google</a>.</em>
15246</p>
15247                                    </div>
15248                                                                                    </div>
15249                    </template>
15250                </div>
15251            </div>
15252        </div>
15253    </div>
15254        </div>
15255    </div>
15256    </div>
15257        </div>
15258        <div x-data="AmAuthPopupNotification"
15259        x-init="initialize"
15260        x-on:amsl-popup-show-notification.window="onShowNotification"
15261    >
15262        <div x-cloak    data-dialog-ref-name="amsl-popup-notification"
15263    x-bind="overlay"
15264    class="fixed inset-0 bg-black/50 z-50">
15265    <div class="fixed flex justify-center items-center text-left z-40 amsl-popup-notification text-green-600 px-2 min-w-[300px] inset-0">
15266        <div x-ref="amsl-popup-notification" role="dialog" aria-modal="true"
15267                                                  class="inline-block bg-white shadow-xl rounded-lg p-10 max-h-screen overflow-auto overscroll-y-contain">
15268            <div class="relative">
15269    <button
15270        type="button"
15271        class="amsl-close absolute left-full bottom-full transform translate-x-2
15272            -translate-y-2 text-gray-400 hover:text-blue-800"
15273        x-on:click="closeNotification"
15274        title="Cerrar"
15275        aria-label="Cerrar"
15276        role="button"
15277    >
15278        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" role="img">
15279  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
15280<title>x</title></svg>
15281    </button>
15282    <template x-if="hasNotification">
15283        <div x-html="notification"></div>
15284    </template>
15285</div>
15286        </div>
15287    </div>
15288    </div>
15289    </div>
15290</div></body>
15291</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.