{
  "version": 3,
  "sources": ["/cdn/shop/t/94/assets/section-combo-page-cro.js?rev=20260720-mobile-performance-1"],
  "sourcesContent": ["\r\n\r\n\r\n// class ComboPage {\r\n//   constructor() {\r\n//     this.combo = [];\r\n//     this.maxSlots = 3;\r\n//     this.minimumItems = 3;\r\n//     this.discountPercentage = 20;\r\n//     this.tierPrice = 0;\r\n//     this.currentTierId = null;\r\n//     this.discountCode = '';\r\n//     this.footer = document.querySelector('.combo-footer');\r\n//     this.checkoutBtn = document.querySelector('.combo-checkout-btn');\r\n//     this.totalPriceEl = document.querySelector('.js-combo-total');\r\n//     this.totalLabelEl = document.querySelector('.js-combo-total-label');\r\n//     this.slotsContainer = document.querySelector('.combo-slots');\r\n//     this.isCheckingOut = false;\r\n//     this.init();\r\n//   }\r\n\r\n//   async init() {\r\n//     // 1. Fetch current cart and sync combo state (Replacing the cart clear logic to prevent replacement)\r\n//     await this.syncWithCart();\r\n\r\n//     this.bindAtbButtons(document);\r\n\r\n//     this.setupInfiniteScroll();\r\n//     this.setupFilterListeners();\r\n\r\n//     if (this.checkoutBtn) {\r\n//       this.checkoutBtn.addEventListener('click', (e) => {\r\n//         e.preventDefault();\r\n//         this.handleCheckout();\r\n//       });\r\n//     }\r\n\r\n//     document.querySelectorAll('.js-tier-tab').forEach(btn => {\r\n//       btn.addEventListener('click', (e) => this.handleTabClick(e.currentTarget));\r\n//     });\r\n\r\n//     this.applyTierSettings(this.getActiveTierElement());\r\n//     this.updateUI();\r\n//     this.watchCartForComboDiscount();\r\n\r\n//     // Load real filters from collection URL for each tier (filters only available on collection pages)\r\n//     document.querySelectorAll('.js-combo-tier').forEach(tier => this.loadFiltersForTier(tier));\r\n\r\n//     // Auto-select a product if redirected from PDP via ?autoselect=handle\r\n//     this.handleAutoSelect();\r\n//   }\r\n\r\n//   async syncWithCart() {\r\n//     try {\r\n//       const res = await fetch('/cart.js');\r\n//       const cart = await res.json();\r\n//       this.setGlobalCartCount(cart.item_count);\r\n\r\n//       // Filter items that belong to the combo\r\n//       this.combo = cart.items\r\n//         .filter(item => item.properties && item.properties._combo === 'true')\r\n//         .map(item => ({\r\n//           productId: String(item.product_id),\r\n//           variantId: String(item.variant_id),\r\n//           price: item.price,\r\n//           image: item.image,\r\n//           title: item.product_title,\r\n//           handle: item.handle\r\n//         }));\r\n\r\n//       // Try to identify the tier from the first item found to lock it\r\n//       if (this.combo.length > 0) {\r\n//         const firstId = this.combo[0].variantId;\r\n//         const btn = document.querySelector(`.js-atb-btn[data-variant-id=\"${firstId}\"]`);\r\n//         if (btn) {\r\n//           const tier = btn.closest('.combo-tier');\r\n//           if (tier) this.currentTierId = tier.dataset.tierId;\r\n//         }\r\n//       }\r\n//     } catch (e) {\r\n//       console.error('Failed to sync with cart', e);\r\n//     }\r\n//   }\r\n\r\n//   handleAutoSelect() {\r\n//     const params = new URLSearchParams(window.location.search);\r\n//     const handle = params.get('autoselect');\r\n//     if (!handle) return;\r\n\r\n//     // If already in combo, don't trigger another click (which would remove it)\r\n//     if (this.combo.some(item => item.handle === handle)) {\r\n//       const cleanUrl = window.location.pathname;\r\n//       window.history.replaceState({}, '', cleanUrl);\r\n//       return;\r\n//     }\r\n\r\n//     // Clean the URL so a page refresh doesn't re-trigger\r\n//     const cleanUrl = window.location.pathname;\r\n//     window.history.replaceState({}, '', cleanUrl);\r\n\r\n//     // Try immediately (product cards may already be rendered)\r\n//     if (this._tryAutoSelect(handle)) return;\r\n\r\n//     // Cards may still be loading \u2014 watch for DOM changes\r\n//     const observer = new MutationObserver(() => {\r\n//       if (this._tryAutoSelect(handle)) {\r\n//         observer.disconnect();\r\n//       }\r\n//     });\r\n//     observer.observe(document.querySelector('.combo-content') || document.body, {\r\n//       childList: true,\r\n//       subtree: true\r\n//     });\r\n\r\n//     // Stop watching after 8 seconds regardless\r\n//     setTimeout(() => observer.disconnect(), 8000);\r\n//   }\r\n\r\n//   _tryAutoSelect(handle) {\r\n//     const btn = document.querySelector(`.js-atb-btn[data-handle=\"${handle}\"]`);\r\n//     if (!btn) return false;\r\n\r\n//     // Scroll to the product card\r\n//     btn.closest('.combo-card-wrapper')?.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n\r\n//     // Brief highlight animation\r\n//     const card = btn.closest('.combo-card-wrapper');\r\n//     if (card) {\r\n//       card.style.transition = 'box-shadow 0.4s ease';\r\n//       card.style.boxShadow = '0 0 0 3px #543e3a';\r\n//       setTimeout(() => { card.style.boxShadow = ''; }, 2000);\r\n//     }\r\n\r\n//     // Click the Add To Box button\r\n//     setTimeout(() => btn.click(), 400);\r\n//     return true;\r\n//   }\r\n\r\n//   bindAtbButtons(container) {\r\n//     container.querySelectorAll('.js-atb-btn').forEach(btn => {\r\n//       if (btn.dataset.comboBound === 'true') return;\r\n//       btn.dataset.comboBound = 'true';\r\n//       btn.addEventListener('click', (e) => this.handleAtbClick(e.currentTarget));\r\n//     });\r\n//   }\r\n\r\n//   syncAddToBoxButtons(scope = document) {\r\n//     scope.querySelectorAll('.js-atb-btn').forEach(btn => {\r\n//       const isAdded = this.combo.some(item => item.variantId === btn.dataset.variantId);\r\n//       btn.classList.toggle('is-added', isAdded);\r\n//       btn.textContent = isAdded ? 'Added To Box' : 'Add To Box';\r\n//     });\r\n//   }\r\n\r\n//   buildLoadMoreUrl(tier, nextPage, overrideParams = null) {\r\n//     const collectionHandle = tier.dataset.collectionHandle;\r\n//     const tagFilter = tier.dataset.tagFilter;\r\n\r\n//     if (!collectionHandle) return '';\r\n\r\n//     let path = `/collections/${collectionHandle}`;\r\n\r\n//     if (tagFilter) {\r\n//       path += `/${encodeURIComponent(tagFilter)}`;\r\n//     }\r\n\r\n//     let searchParams = '';\r\n//     if (overrideParams !== null) {\r\n//       // Use explicitly provided params (e.g. from a clear-filter link href)\r\n//       searchParams = overrideParams;\r\n//     } else {\r\n//       // Read from the facet form inputs\r\n//       const facetForm = tier.querySelector('aside.facets-wrapper facet-filters-form form');\r\n//       if (facetForm) {\r\n//         searchParams = new URLSearchParams(new FormData(facetForm)).toString();\r\n//       }\r\n//     }\r\n\r\n//     const separator = searchParams ? '&' : '';\r\n//     return `${path}?view=combo-products&page=${nextPage}${separator}${searchParams}`;\r\n//   }\r\n\r\n//   setupInfiniteScroll() {\r\n//     const options = {\r\n//       root: null,\r\n//       rootMargin: '0px 0px 300px 0px', // Trigger 300px before sentinel enters viewport\r\n//       threshold: 0\r\n//     };\r\n\r\n//     this.sentinelObserver = new IntersectionObserver((entries) => {\r\n//       entries.forEach(entry => {\r\n//         if (!entry.isIntersecting) return;\r\n//         const sentinel = entry.target;\r\n//         if (sentinel.dataset.allLoaded === 'true') return;\r\n//         if (sentinel.dataset.loading === 'true') return;\r\n//         this.loadMoreForSentinel(sentinel);\r\n//       });\r\n//     }, options);\r\n\r\n//     document.querySelectorAll('.js-infinite-sentinel').forEach(sentinel => {\r\n//       if (sentinel.dataset.allLoaded !== 'true') {\r\n//         this.sentinelObserver.observe(sentinel);\r\n//       }\r\n//     });\r\n//   }\r\n\r\n//   async loadMoreForSentinel(sentinel, isReset = false) {\r\n//     const tier = sentinel.closest('.js-combo-tier');\r\n//     const grid = tier?.querySelector('.js-combo-grid');\r\n//     const nextPage = isReset ? 1 : parseInt(sentinel.dataset.nextPage || '2', 10);\r\n\r\n//     if (!tier || !grid) return;\r\n\r\n//     sentinel.dataset.loading = 'true';\r\n//     sentinel.classList.add('is-loading');\r\n\r\n//     if (isReset) {\r\n//       grid.classList.add('is-loading-grid');\r\n//     }\r\n\r\n//     const requestUrl = this.buildLoadMoreUrl(tier, nextPage, sentinel._clearParams ?? null);\r\n//     delete sentinel._clearParams; // Clear after use so subsequent loads read from form\r\n//     if (!requestUrl) {\r\n//       sentinel.dataset.allLoaded = 'true';\r\n//       this.sentinelObserver.unobserve(sentinel);\r\n//       return;\r\n//     }\r\n\r\n//     try {\r\n//       const response = await fetch(requestUrl, {\r\n//         headers: { 'X-Requested-With': 'XMLHttpRequest' }\r\n//       });\r\n\r\n//       if (!response.ok) throw new Error('Failed to load more combo products.');\r\n\r\n//       const html = await response.text();\r\n//       const parser = new DOMParser();\r\n//       const doc = parser.parseFromString(html, 'text/html');\r\n//       const cards = doc.querySelectorAll('.combo-card-wrapper');\r\n//       const meta = doc.querySelector('.combo-ajax-meta');\r\n//       const facetsPayload = doc.getElementById('combo-facets-payload');\r\n\r\n//       // Inject real filters from collection AJAX response (filters only available on collection URLs)\r\n//       if (facetsPayload && isReset) {\r\n//         const asideWrapper = tier.querySelector('aside.facets-wrapper');\r\n//         if (asideWrapper) {\r\n//           asideWrapper.innerHTML = facetsPayload.innerHTML;\r\n//           this.setupFilterListeners();\r\n//         }\r\n//       }\r\n\r\n//       if (cards.length) {\r\n//         if (isReset) {\r\n//           grid.innerHTML = '';\r\n//           grid.classList.remove('is-loading-grid');\r\n//         }\r\n//         const fragment = document.createDocumentFragment();\r\n//         cards.forEach(card => fragment.appendChild(card));\r\n//         grid.appendChild(fragment);\r\n//         this.bindAtbButtons(grid);\r\n//         this.syncAddToBoxButtons(grid);\r\n//       } else if (isReset) {\r\n//         grid.innerHTML = '<p class=\"combo-no-results\">No products found matching these filters.</p>';\r\n//         grid.classList.remove('is-loading-grid');\r\n//       }\r\n\r\n//       const hasMore = meta?.dataset.hasMore === 'true' && cards.length > 0;\r\n//       if (hasMore) {\r\n//         sentinel.dataset.nextPage = String(nextPage + 1);\r\n//         sentinel.dataset.loading = 'false';\r\n//         sentinel.classList.remove('is-loading');\r\n//         sentinel.dataset.allLoaded = 'false';\r\n//         this.sentinelObserver.observe(sentinel);\r\n//       } else {\r\n//         sentinel.dataset.allLoaded = 'true';\r\n//         sentinel.classList.remove('is-loading');\r\n//         this.sentinelObserver.unobserve(sentinel);\r\n//       }\r\n//     } catch (error) {\r\n//       console.error(error);\r\n//       sentinel.dataset.loading = 'false';\r\n//       sentinel.classList.remove('is-loading');\r\n//       if (isReset) grid.classList.remove('is-loading-grid');\r\n//     }\r\n//   }\r\n\r\n//   // Fetch filter HTML from the collection directly to get exact Swatches and Settings\r\n//   async loadFiltersForTier(tier) {\r\n//     const collectionHandle = tier.dataset.collectionHandle;\r\n//     const blockId = tier.dataset.tierId || tier.id || Math.random().toString(36).substr(2, 9);\r\n//     if (!collectionHandle) return;\r\n//     const asideWrapper = tier.querySelector('aside.facets-wrapper');\r\n//     if (!asideWrapper) return;\r\n\r\n//     try {\r\n//       // Fetch the raw collection page to get exact, fully-configured filter DOM with Swatches\r\n//       const url = `/collections/${collectionHandle}`;\r\n//       const response = await fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });\r\n//       if (!response.ok) return;\r\n//       const html = await response.text();\r\n//       const doc = new DOMParser().parseFromString(html, 'text/html');\r\n\r\n//       const realAside = doc.querySelector('aside.facets-wrapper');\r\n//       if (realAside) {\r\n//         // Prevent ID collisions since we might load multiple tiers\r\n//         let asideHtml = realAside.innerHTML;\r\n//         asideHtml = asideHtml.replace(/FacetFiltersForm/g, 'FacetFiltersForm-' + blockId);\r\n//         asideHtml = asideHtml.replace(/SortBy/g, 'SortBy-' + blockId);\r\n\r\n//         asideWrapper.innerHTML = asideHtml;\r\n//         this.setupFilterListeners();\r\n//       }\r\n//     } catch (e) {\r\n//       console.warn('Could not load filters for tier:', collectionHandle, e);\r\n//     }\r\n//   }\r\n\r\n//   setupFilterListeners() {\r\n//     const self = this;\r\n//     const filterDebounce = this.debounce((tier) => {\r\n//       const sentinel = tier.querySelector('.js-infinite-sentinel');\r\n//       if (sentinel) self.loadMoreForSentinel(sentinel, true);\r\n//     }, 500);\r\n\r\n//     document.querySelectorAll('.js-combo-tier').forEach(tier => {\r\n//       // Target facet form inside the standard aside.facets-wrapper\r\n//       const facetForm = tier.querySelector('aside.facets-wrapper facet-filters-form');\r\n//       if (facetForm) {\r\n//         facetForm.addEventListener('input', () => filterDebounce(tier));\r\n//         const sortSelect = facetForm.querySelector('select[name=\"sort_by\"]');\r\n//         if (sortSelect) {\r\n//           sortSelect.addEventListener('change', () => filterDebounce(tier));\r\n//         }\r\n//       }\r\n//     });\r\n\r\n//     // Handle facet-remove (\u00D7 on active filter chip) and Clear all\r\n//     document.addEventListener('click', (e) => {\r\n//       const clearLink = e.target.closest('facet-remove a, a.active-facets__button--clear');\r\n//       if (clearLink && clearLink.closest('.js-combo-tier')) {\r\n//         e.preventDefault();\r\n//         const tier = clearLink.closest('.js-combo-tier');\r\n//         const sentinel = tier.querySelector('.js-infinite-sentinel');\r\n//         if (!sentinel) return;\r\n\r\n//         // Read the clean params from the clear link's own href\r\n//         const href = clearLink.getAttribute('href') || '';\r\n//         const hrefSearch = href.includes('?') ? href.split('?')[1] : '';\r\n//         const cleanParams = new URLSearchParams(hrefSearch);\r\n//         cleanParams.delete('view');\r\n//         cleanParams.delete('page');\r\n\r\n//         sentinel.dataset.nextPage = '1';\r\n//         sentinel.dataset.allLoaded = 'false';\r\n//         sentinel._clearParams = cleanParams.toString();\r\n//         this.loadMoreForSentinel(sentinel, true);\r\n//       }\r\n//     });\r\n//   }\r\n\r\n//   debounce(fn, wait) {\r\n//     let timeout;\r\n//     return (...args) => {\r\n//       clearTimeout(timeout);\r\n//       timeout = setTimeout(() => fn.apply(this, args), wait);\r\n//     };\r\n//   }\r\n\r\n//   getTierById(tierId) {\r\n//     return document.querySelector(`.js-combo-tier[data-tier-id=\"${tierId}\"]`);\r\n//   }\r\n\r\n//   getActiveTierElement() {\r\n//     if (this.currentTierId) {\r\n//       return this.getTierById(this.currentTierId);\r\n//     }\r\n\r\n//     return document.querySelector('.js-combo-tier.is-active') || document.querySelector('.js-combo-tier');\r\n//   }\r\n\r\n//   applyTierSettings(tier) {\r\n//     if (!tier) return;\r\n\r\n//     const maxSlots = parseInt(tier.dataset.maxSlots || '3', 10);\r\n//     const minimumItems = parseInt(tier.dataset.minItems || '3', 10);\r\n//     const discountPercentage = parseFloat(tier.dataset.discountPercentage || '20');\r\n//     const tierPrice = parseInt(tier.dataset.tierPrice || '0', 10);\r\n\r\n//     this.maxSlots = Number.isFinite(maxSlots) && maxSlots > 0 ? maxSlots : 3;\r\n//     this.minimumItems = Number.isFinite(minimumItems) && minimumItems > 0\r\n//       ? Math.min(minimumItems, this.maxSlots)\r\n//       : Math.min(3, this.maxSlots);\r\n//     this.discountPercentage = Number.isFinite(discountPercentage) && discountPercentage > 0 ? discountPercentage : 20;\r\n//     this.tierPrice = Number.isFinite(tierPrice) ? tierPrice : 0;\r\n//     this.discountCode = tier.dataset.discountCode || '';\r\n//   }\r\n\r\n//   handleTabClick(tab) {\r\n//     if (tab.disabled) return;\r\n//     const targetId = tab.dataset.target;\r\n\r\n//     document.querySelectorAll('.js-tier-tab').forEach(t => t.classList.remove('is-active'));\r\n//     tab.classList.add('is-active');\r\n\r\n//     const targetTier = this.getTierById(targetId);\r\n//     document.querySelectorAll('.js-combo-tier').forEach(tier => {\r\n//       if (tier.dataset.tierId === targetId) {\r\n//         tier.classList.add('is-active');\r\n//       } else {\r\n//         tier.classList.remove('is-active');\r\n//       }\r\n//     });\r\n\r\n//     if (!this.currentTierId || this.currentTierId === targetId) {\r\n//       this.applyTierSettings(targetTier);\r\n//       this.updateUI();\r\n//     }\r\n//   }\r\n\r\n//   async handleAtbClick(btn) {\r\n//     const tier = btn.closest('.combo-tier');\r\n//     const tierId = tier.dataset.tierId;\r\n//     const variantId = btn.dataset.variantId;\r\n\r\n//     if (this.currentTierId && this.currentTierId !== tierId) {\r\n//       alert('Please complete or clear your current combo before switching tiers.');\r\n//       return;\r\n//     }\r\n\r\n//     const productId = btn.dataset.productId;\r\n//     const price = parseInt(btn.dataset.price, 10);\r\n//     const image = btn.dataset.image;\r\n//     const title = btn.dataset.title;\r\n\r\n//     const index = this.combo.findIndex(item => item.variantId === variantId);\r\n\r\n//     if (index > -1) {\r\n//       const removedItem = this.combo[index];\r\n//       this.combo.splice(index, 1);\r\n//       btn.classList.remove('is-added');\r\n//       btn.textContent = 'Add To Box';\r\n//       if (this.combo.length === 0) this.currentTierId = null;\r\n//       this.adjustGlobalCartCount(-1);\r\n//       this.updateUI();\r\n\r\n//       try {\r\n//         const remRes = await fetch('/cart/change.json', {\r\n//           method: 'POST',\r\n//           headers: { 'Content-Type': 'application/json' },\r\n//           body: JSON.stringify({ id: variantId, quantity: 0 })\r\n//         });\r\n\r\n//         if (!remRes.ok) {\r\n//           throw new Error('Failed to remove combo item.');\r\n//         }\r\n//       } catch (error) {\r\n//         console.error(error);\r\n//         this.combo.splice(index, 0, removedItem);\r\n//         this.currentTierId = tierId;\r\n//         btn.classList.add('is-added');\r\n//         btn.textContent = 'Added To Box';\r\n//         this.adjustGlobalCartCount(1);\r\n//         this.updateUI();\r\n//         alert('Could not update the box. Please try again.');\r\n//       }\r\n//     } else {\r\n//       this.applyTierSettings(tier);\r\n//       const tierSlots = this.maxSlots;\r\n\r\n//       if (this.combo.length < tierSlots) {\r\n//         btn.disabled = true;\r\n//         btn.textContent = 'Adding...';\r\n\r\n//         try {\r\n//           this.currentTierId = tierId;\r\n//           this.combo.push({ productId, variantId, price, image, title });\r\n//           btn.classList.add('is-added');\r\n//           btn.textContent = 'Added To Box';\r\n//           this.adjustGlobalCartCount(1);\r\n//           this.updateUI();\r\n\r\n//           const addRes = await fetch('/cart/add.json', {\r\n//             method: 'POST',\r\n//             headers: { 'Content-Type': 'application/json' },\r\n//             body: JSON.stringify({ items: [{ id: variantId, quantity: 1, properties: { '_combo': 'true' } }] })\r\n//           });\r\n\r\n//           if (!addRes.ok) {\r\n//             throw new Error('Could not add item to cart.');\r\n//           }\r\n//         } catch (e) {\r\n//           console.error(e);\r\n//           this.combo = this.combo.filter(item => item.variantId !== variantId);\r\n//           btn.classList.remove('is-added');\r\n//           btn.textContent = 'Add To Box';\r\n//           if (this.combo.length === 0) this.currentTierId = null;\r\n//           this.adjustGlobalCartCount(-1);\r\n//           this.updateUI();\r\n//           alert('Could not add item to cart. Please try again.');\r\n//         } finally {\r\n//           btn.disabled = false;\r\n//         }\r\n//       } else {\r\n//         alert(`You can only add up to ${tierSlots} items for this combo.`);\r\n//       }\r\n//     }\r\n//   }\r\n\r\n//   updateUI() {\r\n//     if (!this.currentTierId) {\r\n//       this.applyTierSettings(this.getActiveTierElement());\r\n//     }\r\n\r\n//     document.querySelectorAll('.combo-tier').forEach(tier => {\r\n//       if (this.currentTierId && tier.dataset.tierId !== this.currentTierId) {\r\n//         tier.classList.add('is-disabled');\r\n//       } else {\r\n//         tier.classList.remove('is-disabled');\r\n//       }\r\n//     });\r\n\r\n//     document.querySelectorAll('.js-tier-tab').forEach(tab => {\r\n//       if (this.currentTierId && tab.dataset.target !== this.currentTierId) {\r\n//         tab.disabled = true;\r\n//       } else {\r\n//         tab.disabled = false;\r\n//       }\r\n//     });\r\n\r\n//     this.syncAddToBoxButtons();\r\n\r\n//     this.slotsContainer.innerHTML = '';\r\n//     for (let i = 0; i < this.maxSlots; i++) {\r\n//       const item = this.combo[i];\r\n//       const slot = document.createElement('div');\r\n//       slot.className = 'combo-slot' + (item ? '' : ' combo-slot--empty');\r\n\r\n//       if (item) {\r\n//         slot.innerHTML = `\r\n//           <img src=\"${item.image}\" alt=\"${item.title}\">\r\n//           <span class=\"combo-slot__remove\" data-variant-id=\"${item.variantId}\">\u00D7</span>\r\n//         `;\r\n//         slot.querySelector('.combo-slot__remove').addEventListener('click', (e) => {\r\n//           this.removeItem(e.target.dataset.variantId);\r\n//         });\r\n//       } else {\r\n//         slot.innerHTML = `<span class=\"add-piece\">ADD<br>Item ${i + 1}</span>`;\r\n//       }\r\n//       this.slotsContainer.appendChild(slot);\r\n//     }\r\n\r\n//     const subtotal = this.combo.reduce((acc, item) => acc + item.price, 0);\r\n//     const qualifiesForDiscount = this.combo.length >= this.minimumItems;\r\n//     const discountAmount = qualifiesForDiscount\r\n//       ? Math.round((subtotal * this.discountPercentage) / 100)\r\n//       : 0;\r\n//     const finalPriceToDisplay = subtotal - discountAmount;\r\n//     const totalRow = document.querySelector('.js-total-row');\r\n\r\n//     this.updateProgress(subtotal, qualifiesForDiscount);\r\n\r\n//     if (qualifiesForDiscount) {\r\n//       const formattedPrice = this.formatMoney(finalPriceToDisplay);\r\n//       const formattedSubtotal = this.formatMoney(subtotal);\r\n//       if (this.totalPriceEl) {\r\n//         this.totalPriceEl.innerHTML = `${formattedPrice}<span class=\"combo-summary__compare\">${formattedSubtotal}</span>`;\r\n//       }\r\n//       if (this.totalLabelEl) {\r\n//         this.totalLabelEl.textContent = `Total (${this.discountPercentage}% OFF) -`;\r\n//       }\r\n//       if (totalRow) totalRow.style.display = 'flex';\r\n//       this.checkoutBtn.disabled = false;\r\n//       this.checkoutBtn.textContent = 'GO TO CART';\r\n\r\n//       // Save discount state for cart popup banner\r\n//       sessionStorage.setItem('comboDiscount', JSON.stringify({\r\n//         subtotal,\r\n//         discountAmount,\r\n//         finalPrice: finalPriceToDisplay,\r\n//         discountPercentage: this.discountPercentage\r\n//       }));\r\n//       this.injectComboDiscountBanner();\r\n//     } else {\r\n//       if (this.totalPriceEl) this.totalPriceEl.textContent = '---';\r\n//       if (this.totalLabelEl) this.totalLabelEl.textContent = 'Total -';\r\n//       if (totalRow) totalRow.style.display = 'none';\r\n//       this.checkoutBtn.disabled = true;\r\n//       this.checkoutBtn.textContent = this.buildDisabledCtaLabel();\r\n\r\n//       // Clear discount state\r\n//       sessionStorage.removeItem('comboDiscount');\r\n//       this.injectComboDiscountBanner();\r\n//     }\r\n//   }\r\n\r\n//   watchCartForComboDiscount() {\r\n//     const self = this;\r\n\r\n//     // Watch product list area \u2013 fires when generateCart() re-renders items\r\n//     const cartContent = document.querySelector('.js-mini-cart-content');\r\n//     if (cartContent) {\r\n//       new MutationObserver(() => {\r\n//         requestAnimationFrame(() => self.injectComboDiscountBanner());\r\n//       }).observe(cartContent, { childList: true });\r\n//     }\r\n\r\n//     // Watch cart total text \u2013 fires when updateElements() refreshes the price\r\n//     const cartTotalEl = document.querySelector('.js-cart-total');\r\n//     if (cartTotalEl) {\r\n//       new MutationObserver(() => {\r\n//         requestAnimationFrame(() => self.injectComboDiscountBanner());\r\n//       }).observe(cartTotalEl, { childList: true, subtree: true, characterData: true });\r\n//     }\r\n//   }\r\n\r\n//   injectComboDiscountBanner() {\r\n//     // Remove any stale banner first\r\n//     document.querySelectorAll('.combo-cart-discount-banner').forEach(el => el.remove());\r\n\r\n//     const raw = sessionStorage.getItem('comboDiscount');\r\n//     if (!raw) return;\r\n\r\n//     const { subtotal, discountAmount, finalPrice, discountPercentage } = JSON.parse(raw);\r\n\r\n//     const bottomTotal = document.querySelector('.bottom-total');\r\n//     if (!bottomTotal) return;\r\n\r\n//     // Override the Shopify-rendered total with discounted price\r\n//     const cartTotalEl = document.querySelector('.js-cart-total');\r\n//     if (cartTotalEl && !cartTotalEl.dataset.comboOverridden) {\r\n//       cartTotalEl.dataset.comboOverridden = 'true';\r\n//       cartTotalEl.innerHTML = this.formatMoney(finalPrice);\r\n//       setTimeout(() => { delete cartTotalEl.dataset.comboOverridden; }, 100);\r\n//     }\r\n\r\n//     // Build and inject the banner above the total row\r\n//     const banner = document.createElement('div');\r\n//     banner.className = 'combo-cart-discount-banner';\r\n//     banner.innerHTML = `\r\n//       <div class=\"combo-cart-discount-row\">\r\n//         <span class=\"combo-cart-badge\">\uD83C\uDF81 COMBO ${discountPercentage}% OFF</span>\r\n//         <span class=\"combo-cart-saving\">You save ${this.formatMoney(discountAmount)}</span>\r\n//       </div>\r\n//       <div class=\"combo-cart-original\">\r\n//         Original: <s>${this.formatMoney(subtotal)}</s> \u2192 <strong>${this.formatMoney(finalPrice)}</strong>\r\n//       </div>\r\n//     `;\r\n//     bottomTotal.parentNode.insertBefore(banner, bottomTotal);\r\n//   }\r\n\r\n//   updateProgress(subtotal, qualifiesForDiscount) {\r\n//     document.querySelectorAll('.combo-progress-wrapper').forEach(wrapper => {\r\n//       const fill = wrapper.querySelector('.combo-progress-fill');\r\n//       const text = wrapper.querySelector('.combo-progress-text');\r\n\r\n//       if (fill) {\r\n//         fill.style.width = '0%';\r\n//         fill.style.background = '#228be6';\r\n//       }\r\n\r\n//       if (text) {\r\n//         text.textContent = `Add ${this.minimumItems} items to unlock ${this.discountPercentage}% OFF.`;\r\n//       }\r\n//     });\r\n\r\n//     const activeTier = this.getActiveTierElement();\r\n//     if (!activeTier) return;\r\n\r\n//     const progressText = activeTier.querySelector('.combo-progress-text');\r\n//     const progressFill = activeTier.querySelector('.combo-progress-fill');\r\n//     if (!progressText || !progressFill) return;\r\n\r\n//     const progressTarget = Math.max(this.minimumItems, 1);\r\n//     const percent = Math.min((this.combo.length / progressTarget) * 100, 100);\r\n//     progressFill.style.width = `${percent}%`;\r\n\r\n//     if (qualifiesForDiscount) {\r\n//       const remainingSlots = Math.max(this.maxSlots - this.combo.length, 0);\r\n//       const extraCopy = remainingSlots > 0\r\n//         ? ` Add ${remainingSlots} more item${remainingSlots === 1 ? '' : 's'} and keep the discount.`\r\n//         : '';\r\n//       progressText.textContent = `${this.discountPercentage}% OFF unlocked on ${this.formatMoney(subtotal)}.${extraCopy}`;\r\n//       progressFill.style.background = '#00b84c';\r\n//       return;\r\n//     }\r\n\r\n//     const remainingToUnlock = Math.max(this.minimumItems - this.combo.length, 0);\r\n//     progressText.textContent = `Add ${remainingToUnlock} more item${remainingToUnlock === 1 ? '' : 's'} to unlock ${this.discountPercentage}% OFF.`;\r\n//   }\r\n\r\n//   buildDisabledCtaLabel() {\r\n//     const remaining = Math.max(this.minimumItems - this.combo.length, 0);\r\n\r\n//     if (remaining <= 0) {\r\n//       return 'GO TO CART';\r\n//     }\r\n\r\n//     if (this.combo.length === 0) {\r\n//       return `ADD ${this.minimumItems} ITEMS`;\r\n//     }\r\n\r\n//     return `ADD ${remaining} MORE`;\r\n//   }\r\n\r\n//   async removeItem(variantId) {\r\n//     const index = this.combo.findIndex(item => item.variantId === variantId);\r\n//     if (index > -1) {\r\n//       const [removedItem] = this.combo.splice(index, 1);\r\n//       const btn = document.querySelector(`.js-atb-btn[data-variant-id=\"${variantId}\"]`);\r\n//       if (btn) {\r\n//         btn.classList.remove('is-added');\r\n//         btn.textContent = 'Add To Box';\r\n//       }\r\n//       if (this.combo.length === 0) this.currentTierId = null;\r\n//       this.adjustGlobalCartCount(-1);\r\n//       this.updateUI();\r\n\r\n//       try {\r\n//         const remRes = await fetch('/cart/change.json', {\r\n//           method: 'POST',\r\n//           headers: { 'Content-Type': 'application/json' },\r\n//           body: JSON.stringify({ id: variantId, quantity: 0 })\r\n//         });\r\n\r\n//         if (!remRes.ok) {\r\n//           throw new Error('Failed to remove combo item.');\r\n//         }\r\n//       } catch (error) {\r\n//         console.error(error);\r\n//         this.combo.splice(index, 0, removedItem);\r\n//         if (btn) {\r\n//           btn.classList.add('is-added');\r\n//           btn.textContent = 'Added To Box';\r\n//         }\r\n//         if (!this.currentTierId) {\r\n//           this.currentTierId = this.getActiveTierElement()?.dataset.tierId || null;\r\n//         }\r\n//         this.adjustGlobalCartCount(1);\r\n//         this.updateUI();\r\n//         alert('Could not update the box. Please try again.');\r\n//       }\r\n//     }\r\n//   }\r\n\r\n//   setGlobalCartCount(itemCount) {\r\n//     document.querySelectorAll('.js-cart-count').forEach(el => {\r\n//       el.textContent = itemCount;\r\n//       el.classList.toggle('hide', itemCount <= 0);\r\n//     });\r\n//   }\r\n\r\n//   adjustGlobalCartCount(delta) {\r\n//     const currentCountEl = document.querySelector('.js-cart-count');\r\n//     const currentCount = currentCountEl ? parseInt(currentCountEl.textContent || '0', 10) : 0;\r\n//     const nextCount = Math.max((Number.isFinite(currentCount) ? currentCount : 0) + delta, 0);\r\n//     this.setGlobalCartCount(nextCount);\r\n//   }\r\n\r\n//   async updateGlobalCartCount() {\r\n//     try {\r\n//       const res = await fetch('/cart.js');\r\n//       const cart = await res.json();\r\n//       this.setGlobalCartCount(cart.item_count);\r\n//     } catch (e) {\r\n//       console.error('Failed to update cart count', e);\r\n//     }\r\n//   }\r\n\r\n//   formatMoney(cents) {\r\n//     return '\u20B9' + (cents / 100).toLocaleString('en-IN', {\r\n//       minimumFractionDigits: 0,\r\n//       maximumFractionDigits: 2\r\n//     });\r\n//   }\r\n\r\n//   async handleCheckout() {\r\n//     if (this.combo.length < this.minimumItems) return;\r\n\r\n//     this.isCheckingOut = true;\r\n//     this.checkoutBtn.disabled = true;\r\n//     this.checkoutBtn.textContent = 'OPENING CART...';\r\n\r\n//     if (window.theme && theme.miniCart) {\r\n//       theme.miniCart.generateCart();\r\n//       theme.miniCart.updateElements();\r\n//       const miniCartEl = document.querySelector('.js-mini-cart');\r\n//       if (miniCartEl) {\r\n//         miniCartEl.classList.add('active');\r\n//         document.querySelector('.mini-cart-content').parentElement.classList.add('active');\r\n//       } else {\r\n//         window.location.href = '/cart';\r\n//       }\r\n//     } else {\r\n//       const cartIcon = document.querySelector('.js-toggle-cart, .site-header__cart, .header__icon--cart, a[href=\"/cart\"]');\r\n//       if (cartIcon) {\r\n//         cartIcon.click();\r\n//       } else {\r\n//         window.location.href = '/cart';\r\n//       }\r\n//     }\r\n\r\n//     setTimeout(() => {\r\n//       this.isCheckingOut = false;\r\n//       this.checkoutBtn.disabled = false;\r\n//       this.checkoutBtn.textContent = 'GO TO CART';\r\n//     }, 1500);\r\n//   }\r\n// }\r\n\r\n// document.addEventListener('DOMContentLoaded', () => {\n//   window.comboPage = new ComboPage();\n// });\n\nvar KPComboPersonalization = (() => {\n  const stateVersion = 1;\n  const maximumRecentLimit = 6;\n  const maximumControlledLimit = 60;\n  const maximumPromotedLimit = 6;\n  const defaultConfig = {\n    promotedEnabled: false,\n    promotedHandles: [],\n    recentEnabled: true,\n    recentLimit: 6,\n    curatedEnabled: true,\n    quotas: {\n      necklaces: 9,\n      bracelets: 3,\n      earrings: 3,\n      gifts: 0\n    },\n    maxPriceCents: 700000,\n    avoidPrevious: true,\n    shortfallBehavior: 'fill-then-reuse',\n    remainderOrder: 'recommended'\n  };\n\n  const emptyState = () => ({\n    version: stateVersion,\n    recent: [],\n    previousControlled: [],\n    updatedAt: 0\n  });\n\n  const normalizeHandle = value => String(value || '').trim();\n\n  const normalizeState = value => {\n    const source = value && typeof value === 'object' ? value : {};\n    const recentSeen = new Set();\n    const recent = Array.isArray(source.recent) ? source.recent : [];\n    const normalizedRecent = recent\n      .map(entry => {\n        const handle = normalizeHandle(typeof entry === 'string' ? entry : entry?.handle);\n        const viewedAt = Number(typeof entry === 'string' ? 0 : entry?.viewedAt) || 0;\n        return { handle, viewedAt };\n      })\n      .filter(entry => {\n        if (!entry.handle || recentSeen.has(entry.handle)) return false;\n        recentSeen.add(entry.handle);\n        return true;\n      })\n      .sort((a, b) => b.viewedAt - a.viewedAt)\n      .slice(0, maximumRecentLimit);\n\n    const previousSeen = new Set();\n    const previousControlled = (Array.isArray(source.previousControlled) ? source.previousControlled : [])\n      .map(normalizeHandle)\n      .filter(handle => {\n        if (!handle || previousSeen.has(handle)) return false;\n        previousSeen.add(handle);\n        return true;\n      })\n      .slice(0, maximumControlledLimit);\n\n    return {\n      version: stateVersion,\n      recent: normalizedRecent,\n      previousControlled,\n      updatedAt: Number(source.updatedAt) || 0\n    };\n  };\n\n  const readState = (storage, key) => {\n    try {\n      if (!storage || typeof storage.getItem !== 'function') {\n        return { available: false, state: emptyState() };\n      }\n      const raw = storage.getItem(key);\n      if (!raw) return { available: true, state: emptyState() };\n      const parsed = JSON.parse(raw);\n      if (Number(parsed?.version) !== stateVersion) {\n        return { available: true, state: emptyState() };\n      }\n      return { available: true, state: normalizeState(parsed) };\n    } catch (error) {\n      return { available: false, state: emptyState() };\n    }\n  };\n\n  const writeState = (storage, key, state) => {\n    try {\n      if (!storage || typeof storage.setItem !== 'function') return false;\n      storage.setItem(key, JSON.stringify(normalizeState(state)));\n      return true;\n    } catch (error) {\n      return false;\n    }\n  };\n\n  const recordRecent = (state, handle, viewedAt = Date.now()) => {\n    const normalized = normalizeState(state);\n    const normalizedHandle = normalizeHandle(handle);\n    if (!normalizedHandle) return normalized;\n    const recent = normalized.recent.filter(entry => entry.handle !== normalizedHandle);\n    recent.unshift({ handle: normalizedHandle, viewedAt: Number(viewedAt) || Date.now() });\n    return normalizeState({\n      ...normalized,\n      recent,\n      updatedAt: Number(viewedAt) || Date.now()\n    });\n  };\n\n  const shuffle = (items, random = Math.random) => {\n    const shuffled = [...items];\n    for (let index = shuffled.length - 1; index > 0; index -= 1) {\n      const swapIndex = Math.floor(random() * (index + 1));\n      [shuffled[index], shuffled[swapIndex]] = [shuffled[swapIndex], shuffled[index]];\n    }\n    return shuffled;\n  };\n\n  const categoryBucket = category => {\n    if (category === 'necklaces') return 'necklaces';\n    if (category === 'bracelets') return 'bracelets';\n    if (category === 'studs' || category === 'drop-earrings') return 'earrings';\n    if (category === 'gifts') return 'gifts';\n    return 'other';\n  };\n\n  const clampInteger = (value, minimum, maximum, fallback) => {\n    const parsed = Number.parseInt(value, 10);\n    if (!Number.isFinite(parsed)) return fallback;\n    return Math.min(Math.max(parsed, minimum), maximum);\n  };\n\n  const normalizeConfig = options => {\n    const source = options && typeof options === 'object' ? options : {};\n    const sourceQuotas = source.quotas && typeof source.quotas === 'object' ? source.quotas : {};\n    const shortfallBehaviors = new Set(['fill-then-reuse', 'fresh-only', 'strict']);\n    const remainderOrders = new Set(['recommended', 'catalog', 'random']);\n    const parsedMaxPrice = Number.parseInt(source.maxPriceCents, 10);\n    const promotedSeen = new Set();\n    const promotedSource = Array.isArray(source.promotedHandles)\n      ? source.promotedHandles\n      : String(source.promotedHandles || '').split('|');\n    const promotedHandles = promotedSource\n      .map(normalizeHandle)\n      .filter(handle => {\n        if (!handle || promotedSeen.has(handle)) return false;\n        promotedSeen.add(handle);\n        return true;\n      })\n      .slice(0, maximumPromotedLimit);\n    return {\n      promotedEnabled: source.promotedEnabled === true,\n      promotedHandles,\n      recentEnabled: source.recentEnabled === undefined\n        ? defaultConfig.recentEnabled\n        : source.recentEnabled === true,\n      recentLimit: clampInteger(\n        source.recentLimit,\n        1,\n        maximumRecentLimit,\n        defaultConfig.recentLimit\n      ),\n      curatedEnabled: source.curatedEnabled === undefined\n        ? defaultConfig.curatedEnabled\n        : source.curatedEnabled === true,\n      quotas: {\n        necklaces: clampInteger(sourceQuotas.necklaces, 0, 15, defaultConfig.quotas.necklaces),\n        bracelets: clampInteger(sourceQuotas.bracelets, 0, 15, defaultConfig.quotas.bracelets),\n        earrings: clampInteger(sourceQuotas.earrings, 0, 15, defaultConfig.quotas.earrings),\n        gifts: clampInteger(sourceQuotas.gifts, 0, 15, defaultConfig.quotas.gifts)\n      },\n      maxPriceCents: Number.isFinite(parsedMaxPrice)\n        ? Math.min(Math.max(parsedMaxPrice, 100000), 950000)\n        : defaultConfig.maxPriceCents,\n      avoidPrevious: source.avoidPrevious === undefined\n        ? defaultConfig.avoidPrevious\n        : source.avoidPrevious === true,\n      shortfallBehavior: shortfallBehaviors.has(source.shortfallBehavior)\n        ? source.shortfallBehavior\n        : defaultConfig.shortfallBehavior,\n      remainderOrder: remainderOrders.has(source.remainderOrder)\n        ? source.remainderOrder\n        : defaultConfig.remainderOrder\n    };\n  };\n\n  const buildOrder = (items, state, options = {}) => {\n    const random = typeof options.random === 'function' ? options.random : Math.random;\n    const config = normalizeConfig(options);\n    const controlledLimit = config.curatedEnabled\n      ? Object.values(config.quotas).reduce((total, count) => total + count, 0)\n      : 0;\n    const normalizedState = normalizeState(state);\n    const uniqueItems = [];\n    const itemByHandle = new Map();\n\n    for (const sourceItem of Array.isArray(items) ? items : []) {\n      const handle = normalizeHandle(sourceItem?.handle);\n      if (!handle || itemByHandle.has(handle)) continue;\n      const item = {\n        ...sourceItem,\n        handle,\n        category: String(sourceItem?.category || ''),\n        priceCents: Number(sourceItem?.priceCents) || 0,\n        available: sourceItem?.available !== false,\n        originalRank: clampInteger(sourceItem?.originalRank, 0, Number.MAX_SAFE_INTEGER, uniqueItems.length),\n        recommendedRank: clampInteger(sourceItem?.recommendedRank, 0, Number.MAX_SAFE_INTEGER, uniqueItems.length)\n      };\n      itemByHandle.set(handle, item);\n      uniqueItems.push(item);\n    }\n\n    const promotedHandles = config.promotedEnabled\n      ? config.promotedHandles.filter(handle => itemByHandle.get(handle)?.available)\n      : [];\n    const used = new Set(promotedHandles);\n    const recentHandles = config.recentEnabled\n      ? normalizedState.recent\n        .map(entry => entry.handle)\n        .filter(handle => itemByHandle.get(handle)?.available && !used.has(handle))\n        .slice(0, config.recentLimit)\n      : [];\n    recentHandles.forEach(handle => used.add(handle));\n    const previousControlled = config.avoidPrevious\n      ? new Set(normalizedState.previousControlled)\n      : new Set();\n    const controlledHandles = [];\n    const freshEligible = uniqueItems.filter(item => {\n      return item.available\n        && item.priceCents < config.maxPriceCents\n        && !used.has(item.handle)\n        && !previousControlled.has(item.handle);\n    });\n\n    const takeFromPool = (pool, count) => {\n      for (const item of shuffle(pool.filter(candidate => !used.has(candidate.handle)), random)) {\n        if (controlledHandles.length >= controlledLimit || count <= 0) break;\n        used.add(item.handle);\n        controlledHandles.push(item.handle);\n        count -= 1;\n      }\n    };\n\n    if (config.curatedEnabled) {\n      Object.entries(config.quotas).forEach(([bucket, count]) => {\n        takeFromPool(freshEligible.filter(item => categoryBucket(item.category) === bucket), count);\n      });\n    }\n\n    if (config.curatedEnabled && config.shortfallBehavior !== 'strict') {\n      takeFromPool(freshEligible, controlledLimit - controlledHandles.length);\n    }\n\n    if (\n      config.curatedEnabled\n      && config.shortfallBehavior === 'fill-then-reuse'\n      && controlledHandles.length < controlledLimit\n    ) {\n      const eligibleIncludingPrevious = uniqueItems.filter(item => {\n        return item.available && item.priceCents < config.maxPriceCents && !used.has(item.handle);\n      });\n      takeFromPool(eligibleIncludingPrevious, controlledLimit - controlledHandles.length);\n    }\n\n    const orderedHandles = [...promotedHandles, ...recentHandles, ...controlledHandles];\n    const orderedSet = new Set(orderedHandles);\n    let remainder = uniqueItems.filter(item => !orderedSet.has(item.handle));\n    if (config.remainderOrder === 'random') {\n      remainder = shuffle(remainder, random);\n    } else if (config.remainderOrder === 'catalog') {\n      remainder.sort((itemA, itemB) => itemA.originalRank - itemB.originalRank);\n    } else {\n      remainder.sort((itemA, itemB) => itemA.recommendedRank - itemB.recommendedRank);\n    }\n    remainder.forEach(item => {\n      orderedSet.add(item.handle);\n      orderedHandles.push(item.handle);\n    });\n\n    return {\n      orderedHandles,\n      promotedHandles,\n      recentHandles,\n      controlledHandles,\n      controlledShortfall: Math.max(controlledLimit - controlledHandles.length, 0),\n      config\n    };\n  };\n\n  return {\n    buildOrder,\n    emptyState,\n    normalizeConfig,\n    normalizeState,\n    readState,\n    recordRecent,\n    writeState\n  };\n})();\n\nvar ComboPage = class ComboPage {\n  constructor() {\n    document.body.classList.add('combo-page-active');\n    this.destroyed = false;\n    this.managedListeners = [];\n    this.managedObservers = [];\n    this.combo = [];\n    this.maxSlots = 3;\r\n    this.minimumItems = 3;\r\n    this.discountPercentage = 20;\r\n    this.tierPrice = 0;\r\n    this.currentTierId = null;\r\n    this.discountCode = '';\r\n    this.footer = document.querySelector('.combo-footer');\r\n    this.checkoutBtn = document.querySelector('.combo-checkout-btn');\n    this.totalPriceEl = document.querySelector('.js-combo-total');\n    this.totalLabelEl = document.querySelector('.js-combo-total-label');\n    this.totalCompareEl = document.querySelector('.js-combo-total-compare');\n    this.totalSavingEl = document.querySelector('.js-combo-total-saving');\n    this.potentialEl = document.querySelector('.js-combo-potential');\n    this.potentialSubtotalEl = document.querySelector('.js-combo-potential-subtotal');\n    this.potentialSavingEl = document.querySelector('.js-combo-potential-saving');\n    this.summaryCountEl = document.querySelector('.js-combo-summary-count');\n    this.summaryMessageEl = document.querySelector('.js-combo-summary-message');\n    this.slotsContainer = document.querySelector('.combo-slots');\n    this.productDialog = document.querySelector('[data-combo-product-dialog]');\n    this.confirmDialog = document.querySelector('[data-combo-confirm-dialog]');\n    this.celebration = document.querySelector('[data-combo-celebration]');\n    this.celebrationAmount = document.querySelector('[data-combo-celebration-amount]');\n    this.confettiContainer = document.querySelector('[data-combo-confetti]');\n    this.recommendationsSection = document.querySelector('[data-combo-recommendations-section]');\n    this.recommendationsContainer = document.querySelector('[data-combo-recommendations]');\n    this.recommendationsCopy = document.querySelector('[data-combo-recommendations-copy]');\n    this.visibleCountEl = document.querySelector('[data-combo-visible-count]');\n    this.visibleCountStatusEl = document.querySelector('[data-combo-count-status]');\n    this.visibleCountLoaderEl = document.querySelector('[data-combo-count-loader]');\n    this.selectionToggle = document.querySelector('[data-combo-selection-toggle]');\n    this.selectionPanel = document.querySelector('[data-combo-selection-panel]');\n    this.selectionList = document.querySelector('[data-combo-selection-list]');\n    this.statusPanel = document.querySelector('[data-combo-status]');\n    this.statusCopy = document.querySelector('[data-combo-status-copy]');\n    this.statusRetry = document.querySelector('[data-combo-status-retry]');\n    this.celebrationTimer = null;\n    this.dialogMediaAutoplayTimer = null;\n    this.dialogMediaAutoplayDirection = 1;\n    this.savingsAnimationFrame = null;\n    this.activeCuratedCategory = 'all';\n    this.activePriceFilter = 'all';\n    this.activeSort = 'recommended';\n    this.retryAction = null;\n    this.tierHydrationPromises = new WeakMap();\n    this.comboFacetClearBound = false;\n    this.isCheckingOut = false;\n    this.isCartSyncing = false;\n    this.isCartMutating = false;\n    this.cartSyncTimer = null;\n    this.lastCartSignature = '';\n    this.comboPage = document.querySelector('.combo-page--cro');\n    this.personalizationEnabled = this.comboPage?.dataset.personalizedRankingEnabled === 'true';\n    this.personalizationConfig = KPComboPersonalization.normalizeConfig({\n      promotedEnabled: this.comboPage?.dataset.promotedProductsEnabled === 'true',\n      promotedHandles: String(this.comboPage?.dataset.promotedProductHandles || '').split('|'),\n      recentEnabled: this.comboPage?.dataset.personalizationRecentEnabled !== 'false',\n      recentLimit: this.comboPage?.dataset.personalizationRecentLimit,\n      curatedEnabled: this.comboPage?.dataset.personalizationCuratedEnabled !== 'false',\n      quotas: {\n        necklaces: this.comboPage?.dataset.personalizationNecklaceSlots,\n        bracelets: this.comboPage?.dataset.personalizationBraceletSlots,\n        earrings: this.comboPage?.dataset.personalizationEarringSlots\n      },\n      maxPriceCents: Number.parseInt(this.comboPage?.dataset.personalizationMaxPriceRupees || '7000', 10) * 100,\n      avoidPrevious: this.comboPage?.dataset.personalizationAvoidPrevious !== 'false',\n      shortfallBehavior: this.comboPage?.dataset.personalizationShortfallBehavior,\n      remainderOrder: this.comboPage?.dataset.personalizationRemainderOrder\n    });\n    this.personalizationStorageKey = 'kp_combo_personalization_v1';\n    this.personalizationMemoryState = KPComboPersonalization.emptyState();\n    this.personalizedOrderRanks = null;\n    this.necklacePersonalizationEnabled = this.comboPage?.dataset.necklacePersonalizedRankingEnabled === 'true';\n    this.necklacePersonalizationConfig = KPComboPersonalization.normalizeConfig({\n      recentEnabled: this.comboPage?.dataset.necklaceRecentEnabled !== 'false',\n      recentLimit: this.comboPage?.dataset.necklaceRecentLimit,\n      curatedEnabled: this.comboPage?.dataset.necklaceCuratedEnabled !== 'false',\n      quotas: {\n        necklaces: this.comboPage?.dataset.necklaceCuratedSlots,\n        bracelets: 0,\n        earrings: 0\n      },\n      maxPriceCents: Number.parseInt(this.comboPage?.dataset.necklaceMaxPriceRupees || '7000', 10) * 100,\n      avoidPrevious: this.comboPage?.dataset.necklaceAvoidPrevious !== 'false',\n      shortfallBehavior: this.comboPage?.dataset.necklaceShortfallBehavior,\n      remainderOrder: this.comboPage?.dataset.necklaceRemainderOrder\n    });\n    this.necklacePersonalizationStorageKey = 'kp_combo_necklace_personalization_v1';\n    this.necklacePersonalizationMemoryState = KPComboPersonalization.emptyState();\n    this.necklacePersonalizedOrderRanks = null;\n    this.braceletPersonalizationEnabled = this.comboPage?.dataset.braceletPersonalizedRankingEnabled === 'true';\n    this.braceletPersonalizationConfig = KPComboPersonalization.normalizeConfig({\n      recentEnabled: this.comboPage?.dataset.braceletRecentEnabled !== 'false',\n      recentLimit: this.comboPage?.dataset.braceletRecentLimit,\n      curatedEnabled: this.comboPage?.dataset.braceletCuratedEnabled !== 'false',\n      quotas: {\n        necklaces: 0,\n        bracelets: this.comboPage?.dataset.braceletCuratedSlots,\n        earrings: 0\n      },\n      maxPriceCents: Number.parseInt(this.comboPage?.dataset.braceletMaxPriceRupees || '7000', 10) * 100,\n      avoidPrevious: this.comboPage?.dataset.braceletAvoidPrevious !== 'false',\n      shortfallBehavior: this.comboPage?.dataset.braceletShortfallBehavior,\n      remainderOrder: this.comboPage?.dataset.braceletRemainderOrder\n    });\n    this.braceletPersonalizationStorageKey = 'kp_combo_bracelet_personalization_v1';\n    this.braceletPersonalizationMemoryState = KPComboPersonalization.emptyState();\n    this.braceletPersonalizedOrderRanks = null;\n    this.additionalCategoryPersonalizations = {\n      studs: {\n        category: 'studs',\n        label: 'Studs',\n        enabled: this.comboPage?.dataset.studPersonalizedRankingEnabled === 'true',\n        config: KPComboPersonalization.normalizeConfig({\n          recentEnabled: this.comboPage?.dataset.studRecentEnabled !== 'false',\n          recentLimit: this.comboPage?.dataset.studRecentLimit,\n          curatedEnabled: this.comboPage?.dataset.studCuratedEnabled !== 'false',\n          quotas: {\n            necklaces: 0,\n            bracelets: 0,\n            earrings: this.comboPage?.dataset.studCuratedSlots,\n            gifts: 0\n          },\n          maxPriceCents: Number.parseInt(this.comboPage?.dataset.studMaxPriceRupees || '7000', 10) * 100,\n          avoidPrevious: this.comboPage?.dataset.studAvoidPrevious !== 'false',\n          shortfallBehavior: this.comboPage?.dataset.studShortfallBehavior,\n          remainderOrder: this.comboPage?.dataset.studRemainderOrder\n        }),\n        storageKey: 'kp_combo_stud_personalization_v1',\n        memoryState: KPComboPersonalization.emptyState(),\n        orderRanks: null,\n        eventName: 'stud_personalization_applied'\n      },\n      'drop-earrings': {\n        category: 'drop-earrings',\n        label: 'Drop Earrings',\n        enabled: this.comboPage?.dataset.dropEarringPersonalizedRankingEnabled === 'true',\n        config: KPComboPersonalization.normalizeConfig({\n          recentEnabled: this.comboPage?.dataset.dropEarringRecentEnabled !== 'false',\n          recentLimit: this.comboPage?.dataset.dropEarringRecentLimit,\n          curatedEnabled: this.comboPage?.dataset.dropEarringCuratedEnabled !== 'false',\n          quotas: {\n            necklaces: 0,\n            bracelets: 0,\n            earrings: this.comboPage?.dataset.dropEarringCuratedSlots,\n            gifts: 0\n          },\n          maxPriceCents: Number.parseInt(this.comboPage?.dataset.dropEarringMaxPriceRupees || '7000', 10) * 100,\n          avoidPrevious: this.comboPage?.dataset.dropEarringAvoidPrevious !== 'false',\n          shortfallBehavior: this.comboPage?.dataset.dropEarringShortfallBehavior,\n          remainderOrder: this.comboPage?.dataset.dropEarringRemainderOrder\n        }),\n        storageKey: 'kp_combo_drop_earring_personalization_v1',\n        memoryState: KPComboPersonalization.emptyState(),\n        orderRanks: null,\n        eventName: 'drop_earring_personalization_applied'\n      },\n      gifts: {\n        category: 'gifts',\n        label: 'Gifts',\n        enabled: this.comboPage?.dataset.giftPersonalizedRankingEnabled === 'true',\n        config: KPComboPersonalization.normalizeConfig({\n          recentEnabled: this.comboPage?.dataset.giftRecentEnabled !== 'false',\n          recentLimit: this.comboPage?.dataset.giftRecentLimit,\n          curatedEnabled: this.comboPage?.dataset.giftCuratedEnabled !== 'false',\n          quotas: {\n            necklaces: 0,\n            bracelets: 0,\n            earrings: 0,\n            gifts: this.comboPage?.dataset.giftCuratedSlots\n          },\n          maxPriceCents: Number.parseInt(this.comboPage?.dataset.giftMaxPriceRupees || '7000', 10) * 100,\n          avoidPrevious: this.comboPage?.dataset.giftAvoidPrevious !== 'false',\n          shortfallBehavior: this.comboPage?.dataset.giftShortfallBehavior,\n          remainderOrder: this.comboPage?.dataset.giftRemainderOrder\n        }),\n        storageKey: 'kp_combo_gift_personalization_v1',\n        memoryState: KPComboPersonalization.emptyState(),\n        orderRanks: null,\n        eventName: 'gift_personalization_applied'\n      }\n    };\n    this.hasAnyPersonalization = this.personalizationEnabled\n      || this.necklacePersonalizationEnabled\n      || this.braceletPersonalizationEnabled\n      || Object.values(this.additionalCategoryPersonalizations).some(definition => definition.enabled);\n    this.personalizationHydrationReady = false;\n    this.personalizationLifecycleBound = false;\n    this.pendingPersonalizationActivation = false;\n    this.productRequestTimeoutMs = 12000;\n    if (this.hasAnyPersonalization) this.comboPage?.classList.add('is-personalizing');\n    this.dispatchCopy = document.querySelector('[data-combo-dispatch-copy]');\n    this.offerExpiry = document.querySelector('[data-combo-offer-expiry]');\n    this.activeOfferExpiryCopy = '';\n    this.mobileViewportQuery = window.matchMedia('(max-width: 768px)');\n    this.mobileProgressiveCatalogEnabled = this.mobileViewportQuery.matches;\n    this.tierProductCatalogs = new WeakMap();\n    this.seedMobileProductCatalogs();\n    this.reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n    this.addManagedListener(this.mobileViewportQuery, 'change', () => this.updateUI());\n    this.addManagedListener(this.reducedMotionQuery, 'change', event => {\n      if (event.matches) {\n        this.stopDialogMediaAutoplay();\n        return;\n      }\n\n      if (this.productDialog && !this.productDialog.hidden) {\n        const media = this.productDialog.querySelector('[data-combo-product-dialog-media]');\n        const previousButton = this.productDialog.querySelector('[data-combo-product-media-previous]');\n        const nextButton = this.productDialog.querySelector('[data-combo-product-media-next]');\n        this.startDialogMediaAutoplay(media, previousButton, nextButton);\n      }\n    });\n    this.bindPersonalizationLifecycle();\n    this.initOfferTiming();\n    this.init();\n  }\n\n  addManagedListener(target, type, handler, options) {\n    if (!target?.addEventListener) return;\n    target.addEventListener(type, handler, options);\n    this.managedListeners.push({ target, type, handler, options });\n  }\n\n  addManagedObserver(observer) {\n    if (observer?.disconnect) this.managedObservers.push(observer);\n    return observer;\n  }\n\n  seedMobileProductCatalogs() {\n    if (!this.mobileProgressiveCatalogEnabled) return;\n    document.querySelectorAll('.js-combo-tier').forEach(tier => {\n      const catalog = this.getMobileProductCatalog(tier);\n      tier.querySelectorAll('.js-combo-grid > .combo-card-wrapper').forEach(card => {\n        this.addMobileCatalogCard(catalog, card, card.outerHTML);\n      });\n    });\n  }\n\n  getMobileProductCatalog(tier) {\n    if (!tier) return null;\n    let catalog = this.tierProductCatalogs.get(tier);\n    if (catalog) return catalog;\n\n    const grid = tier.querySelector('.js-combo-grid');\n    catalog = {\n      records: [],\n      recordsByHandle: new Map(),\n      filteredRecords: [],\n      renderedCount: 0,\n      initialCount: Math.max(Number.parseInt(grid?.dataset.initialCount || '24', 10), 1),\n      loadStep: Math.max(Number.parseInt(grid?.dataset.loadStep || tier.dataset.loadStep || '12', 10), 1),\n      hydrated: false\n    };\n    this.tierProductCatalogs.set(tier, catalog);\n    return catalog;\n  }\n\n  addMobileCatalogCard(catalog, card, html) {\n    if (!catalog || !card) return null;\n    const handle = card.dataset.comboProductHandle;\n    if (!handle || catalog.recordsByHandle.has(handle)) return catalog.recordsByHandle.get(handle) || null;\n\n    const dataset = { ...card.dataset };\n    dataset.comboOriginalIndex = String(catalog.records.length);\n    const record = { handle, dataset, html: String(html || card.outerHTML).trim() };\n    catalog.records.push(record);\n    catalog.recordsByHandle.set(handle, record);\n    return record;\n  }\n\n  createMobileCatalogCard(record) {\n    if (!record?.html) return null;\n    const template = document.createElement('template');\n    template.innerHTML = record.html;\n    const card = template.content.querySelector('.combo-card-wrapper');\n    if (!card) return null;\n\n    card.dataset.comboOriginalIndex = record.dataset.comboOriginalIndex;\n    card.querySelectorAll('[data-combo-bound], [data-combo-gallery-bound], [data-combo-quantity-bound]').forEach(element => {\n      element.removeAttribute('data-combo-bound');\n      element.removeAttribute('data-combo-gallery-bound');\n      element.removeAttribute('data-combo-quantity-bound');\n    });\n    return card;\n  }\n\n  getDiscoveryCards(tier = this.getActiveTierElement()) {\n    if (this.mobileProgressiveCatalogEnabled) {\n      const records = this.getMobileProductCatalog(tier)?.records || [];\n      if (records.length) return records;\n    }\n    return Array.from(tier?.querySelectorAll('.combo-card-wrapper') || []);\n  }\n\n  getProductRecord(handle, tier = this.getActiveTierElement()) {\n    if (!handle || !this.mobileProgressiveCatalogEnabled) return null;\n    return this.getMobileProductCatalog(tier)?.recordsByHandle.get(handle) || null;\n  }\n\n  getMountedProductCard(handle, tier = this.getActiveTierElement()) {\n    if (!handle || !tier) return null;\n    return Array.from(tier.querySelectorAll('.combo-card-wrapper'))\n      .find(card => card.dataset.comboProductHandle === handle) || null;\n  }\n\n  ensureProductCardMounted(handle, tier = this.getActiveTierElement()) {\n    const existingCard = this.getMountedProductCard(handle, tier);\n    if (existingCard || !this.mobileProgressiveCatalogEnabled || !tier) return existingCard;\n\n    const record = this.getProductRecord(handle, tier);\n    const grid = tier.querySelector('.js-combo-grid');\n    const card = this.createMobileCatalogCard(record);\n    if (!grid || !card) return null;\n\n    card.dataset.comboForcedMount = 'true';\n    grid.appendChild(card);\n    this.bindAtbButtons(card);\n    this.bindProductCardEnhancements(card);\n    this.syncAddToBoxButtons(card);\n    return card;\n  }\n\n  sortDiscoveryCards(cards) {\n    return [...cards].sort((cardA, cardB) => {\n      const priceA = Number.parseInt(cardA.dataset.comboProductPriceCents || '0', 10);\n      const priceB = Number.parseInt(cardB.dataset.comboProductPriceCents || '0', 10);\n      const titleA = cardA.dataset.comboProductTitle || '';\n      const titleB = cardB.dataset.comboProductTitle || '';\n      if (this.activeSort === 'price-ascending') return priceA - priceB;\n      if (this.activeSort === 'price-descending') return priceB - priceA;\n      if (this.activeSort === 'name-ascending') return titleA.localeCompare(titleB);\n      const personalizedRankA = this.getActivePersonalizedRank(cardA);\n      const personalizedRankB = this.getActivePersonalizedRank(cardB);\n      if (Number.isFinite(personalizedRankA) && Number.isFinite(personalizedRankB)) {\n        return personalizedRankA - personalizedRankB;\n      }\n      if (Number.isFinite(personalizedRankA)) return -1;\n      if (Number.isFinite(personalizedRankB)) return 1;\n      return this.compareRecommendedCards(cardA, cardB);\n    });\n  }\n\n  recordMatchesDiscovery(record) {\n    const categoryMatches = this.activeCuratedCategory === 'all'\n      || record.dataset.comboCategory === this.activeCuratedCategory;\n    return categoryMatches && this.cardMatchesPrice(record);\n  }\n\n  mountMobileCatalogRecords(tier, records, { replace = false } = {}) {\n    const grid = tier?.querySelector('.js-combo-grid');\n    if (!grid) return;\n    if (replace) grid.replaceChildren();\n\n    const fragment = document.createDocumentFragment();\n    records.forEach(record => {\n      const card = this.createMobileCatalogCard(record);\n      if (card) fragment.appendChild(card);\n    });\n    grid.appendChild(fragment);\n    this.bindAtbButtons(grid);\n    this.bindProductCardEnhancements(grid);\n    this.syncAddToBoxButtons(grid);\n  }\n\n  updateMobileCatalogSentinel(tier) {\n    const catalog = this.getMobileProductCatalog(tier);\n    const sentinel = tier?.querySelector('.js-infinite-sentinel');\n    if (!catalog || !sentinel) return;\n\n    if (!catalog.hydrated) {\n      sentinel.dataset.allLoaded = 'false';\n      this.sentinelObserver?.unobserve(sentinel);\n      return;\n    }\n\n    const hasMoreToRender = catalog.renderedCount < catalog.filteredRecords.length;\n    sentinel.dataset.allLoaded = hasMoreToRender ? 'false' : 'true';\n    if (hasMoreToRender) {\n      this.sentinelObserver?.observe(sentinel);\n    } else {\n      this.sentinelObserver?.unobserve(sentinel);\n    }\n  }\n\n  renderNextMobileCatalogBatch(tier) {\n    if (!this.mobileProgressiveCatalogEnabled || !tier) return false;\n    const catalog = this.getMobileProductCatalog(tier);\n    if (!catalog?.hydrated) return false;\n\n    const nextCount = Math.min(\n      catalog.renderedCount + catalog.loadStep,\n      catalog.filteredRecords.length\n    );\n    if (nextCount <= catalog.renderedCount) {\n      this.updateMobileCatalogSentinel(tier);\n      return true;\n    }\n\n    const nextRecords = catalog.filteredRecords.slice(catalog.renderedCount, nextCount);\n    this.mountMobileCatalogRecords(tier, nextRecords);\n    catalog.renderedCount = nextCount;\n    this.updateMobileCatalogSentinel(tier);\n    return true;\n  }\n\n  destroy() {\n    if (this.destroyed) return;\n    this.destroyed = true;\n    this.managedListeners.splice(0).forEach(({ target, type, handler, options }) => {\n      target.removeEventListener(type, handler, options);\n    });\n    this.managedObservers.splice(0).forEach(observer => observer.disconnect());\n    this.sentinelObserver?.disconnect();\n    window.clearInterval(this.offerTimingTimer);\n    window.clearInterval(this.dialogMediaAutoplayTimer);\n    window.clearTimeout(this.cartSyncTimer);\n    window.clearTimeout(this.celebrationTimer);\n    if (this.savingsAnimationFrame) window.cancelAnimationFrame(this.savingsAnimationFrame);\n    this.comboPage?.classList.remove('is-personalizing');\n  }\n\n  getComboUnitCount(items = this.combo) {\n    return items.reduce((total, item) => total + Number(item.quantity || 1), 0);\n  }\n\n  getComboSubtotal(items = this.combo) {\n    return items.reduce((total, item) => total + (item.price * Number(item.quantity || 1)), 0);\n  }\n\n  initOfferTiming() {\n    if (!this.comboPage) return;\n    this.updateOfferTiming();\n    this.offerTimingTimer = window.setInterval(() => this.updateOfferTiming(), 60000);\n  }\n\n  updateOfferTiming() {\n    if (this.dispatchCopy) {\n      const formatter = new Intl.DateTimeFormat('en-IN', {\n        timeZone: 'Asia/Kolkata',\n        weekday: 'short',\n        hour: '2-digit',\n        minute: '2-digit',\n        hourCycle: 'h23'\n      });\n      const parts = Object.fromEntries(formatter.formatToParts(new Date()).map(part => [part.type, part.value]));\n      const cutoffHour = Number.parseInt(this.comboPage.dataset.dispatchCutoffHour || '14', 10);\n      const currentMinutes = (Number.parseInt(parts.hour || '0', 10) * 60) + Number.parseInt(parts.minute || '0', 10);\n      const cutoffMinutes = cutoffHour * 60;\n\n      if (parts.weekday === 'Sun') {\n        this.dispatchCopy.textContent = 'Orders placed today dispatch Monday';\n      } else if (currentMinutes < cutoffMinutes) {\n        const remaining = cutoffMinutes - currentMinutes;\n        const hours = Math.floor(remaining / 60);\n        const minutes = remaining % 60;\n        const duration = [hours ? `${hours}h` : '', minutes ? `${minutes}m` : ''].filter(Boolean).join(' ');\n        this.dispatchCopy.textContent = `Order in ${duration || 'under 1m'} for dispatch today`;\n      } else {\n        this.dispatchCopy.textContent = 'Dispatches the next working day';\n      }\n    }\n\n    if (this.offerExpiry) {\n      const endDate = this.comboPage.dataset.comboOfferEndDate;\n      const expiresAt = endDate ? new Date(`${endDate}T23:59:59+05:30`) : null;\n      const active = expiresAt && !Number.isNaN(expiresAt.getTime()) && expiresAt.getTime() > Date.now();\n      this.offerExpiry.hidden = !active;\n      this.activeOfferExpiryCopy = '';\n      if (active) {\n        this.offerExpiry.dateTime = endDate;\n        const formattedEndDate = new Intl.DateTimeFormat('en-IN', {\n          day: 'numeric',\n          month: 'long',\n          timeZone: 'Asia/Kolkata'\n        }).format(expiresAt);\n        this.offerExpiry.textContent = `Offer ends ${formattedEndDate}`;\n        this.activeOfferExpiryCopy = `Offer valid till ${formattedEndDate}`;\n      }\n    }\n  }\n\r\n  async init() {\n    // 1. Fetch current cart and sync combo state (Replacing the cart clear logic to prevent replacement)\n    await this.syncWithCart({ render: false });\n    if (this.destroyed) return;\n\n    this.bindAtbButtons(document);\n    this.bindSuggestedComboButtons();\n    this.bindCuratedCategoryButtons();\n    this.bindCroControls();\n    this.restoreDiscoveryStateFromHistory();\n    this.bindProductCardEnhancements(document);\n    this.bindOverlayControls();\n\n    this.setupInfiniteScroll();\n    this.hasFacetControls = Boolean(document.querySelector('.js-combo-tier .facets-wrapper'));\n    if (this.breadcrumbFiltersEnabled()) {\n      this.setupBreadcrumbFilters();\n    } else {\n      sessionStorage.removeItem('combo_last_filter');\n    }\n\r\n    if (this.checkoutBtn) {\r\n      this.checkoutBtn.addEventListener('click', (e) => {\r\n        e.preventDefault();\r\n        this.handleCheckout();\r\n      });\r\n    }\r\n\r\n    document.querySelectorAll('.js-tier-tab').forEach(btn => {\r\n      btn.addEventListener('click', (e) => this.handleTabClick(e.currentTarget));\r\n    });\r\n\r\n    this.applyTierSettings(this.getActiveTierElement());\n\n    if (this.breadcrumbFiltersEnabled()) {\n      this.restoreLastFilter();\n    }\n\r\n    this.updateUI();\n    this.watchCartForComboDiscount();\n    this.bindCartSynchronization();\n    this.trackCroEvent('page_view', { selected_count: this.getComboUnitCount() });\n\r\n    // Load real filters from collection URL for each tier (filters only available on collection pages)\r\n    if (this.hasFacetControls) {\n      await Promise.all(\n        Array.from(document.querySelectorAll('.js-combo-tier')).map(tier => this.loadFiltersForTier(tier))\n      );\n    }\n    if (this.destroyed) return;\n\n    const hydrationResults = await this.hydrateAllTierProducts();\n    if (this.destroyed) return;\n    this.personalizationHydrationReady = hydrationResults.every(Boolean);\n    if (this.hasAnyPersonalization && this.personalizationHydrationReady) {\n      if (this.pendingPersonalizationActivation) {\n        this.activatePersonalizationLanding();\n      } else {\n        this.initializePersonalizedRanking();\n      }\n    }\n    this.bindPersonalizationLifecycle();\n    this.completeInitialCountLoading();\n\r\n    // Auto-select a product if redirected from PDP via ?autoselect=handle\r\n    this.handleAutoSelect();\r\n  }\r\n\r\n  comboCartSignature(cart) {\n    return (cart?.items || [])\n      .filter(item => String(item.properties?._combo) === 'true')\n      .map(item => `${item.key}:${item.quantity}`)\n      .sort()\n      .join('|');\n  }\n\n  applyCartState(cart, { render = true } = {}) {\n    this.setGlobalCartCount(cart.item_count);\n    this.lastCartSignature = this.comboCartSignature(cart);\n    const groupedItems = new Map();\n    (cart.items || [])\n      .filter(item => String(item.properties?._combo) === 'true')\n      .forEach(item => {\n        const variantId = String(item.variant_id);\n        const existing = groupedItems.get(variantId);\n        if (existing) {\n          existing.quantity += Number(item.quantity || 1);\n          existing.keys.push(item.key);\n          return;\n        }\n\n        groupedItems.set(variantId, {\n          productId: String(item.product_id),\n          variantId,\n          price: item.price,\n          image: item.image,\n          title: item.product_title,\n          handle: item.handle,\n          tierId: item.properties?._tier_id || '',\n          groupId: item.properties?._combo_group || 'kp-primary-combo',\n          quantity: Number(item.quantity || 1),\n          key: item.key,\n          keys: [item.key]\n        });\n      });\n    this.combo = Array.from(groupedItems.values());\n\n    const activeTierId = this.getActiveTierElement()?.dataset.tierId || null;\n    this.currentTierId = this.combo.length ? activeTierId : null;\n    if (render) this.updateUI();\n  }\n\n  async syncWithCart({ render = true, cart = null } = {}) {\n    if (this.isCartSyncing && !cart) return;\n    this.isCartSyncing = true;\n    try {\n      const nextCart = cart || await this.fetchCartState();\n      this.applyCartState(nextCart, { render });\n      return nextCart;\n    } catch (e) {\n      console.error('Failed to sync with cart', e);\n      return null;\n    } finally {\n      this.isCartSyncing = false;\n    }\n  }\n\n  scheduleCartSync() {\n    window.clearTimeout(this.cartSyncTimer);\n    this.cartSyncTimer = window.setTimeout(() => {\n      if (!this.isCartMutating) this.syncWithCart();\n    }, 120);\n  }\n\n  bindCartSynchronization() {\n    this.addManagedListener(window, 'pageshow', () => this.scheduleCartSync());\n    this.addManagedListener(window, 'focus', () => this.scheduleCartSync());\n    this.addManagedListener(document, 'visibilitychange', () => {\n      if (document.visibilityState === 'visible') this.scheduleCartSync();\n    });\n    this.addManagedListener(document, 'kp:cart-updated', event => {\n      const cart = event.detail?.cart;\n      if (cart && this.comboCartSignature(cart) !== this.lastCartSignature) {\n        this.syncWithCart({ cart });\n      }\n    });\n  }\n\n  emitCartUpdated(cart) {\n    document.dispatchEvent(new CustomEvent('kp:cart-updated', { detail: { cart } }));\n  }\n\n  // --- NEW INTEGRATED FILTER METHODS ---\n  breadcrumbFiltersEnabled() {\n    const comboPage = document.querySelector('.combo-page');\n    return comboPage?.dataset.enableBreadcrumbFilters === 'true';\n  }\n\n  setupBreadcrumbFilters() {\n    const breadcrumbs = document.querySelectorAll('.js-breadcrumb-container a[data-handle]');\n    breadcrumbs.forEach(link => {\n      link.addEventListener('click', async (e) => {\r\n        e.preventDefault();\r\n        const handle = link.dataset.handle;\r\n        this.applyFilter(handle);\r\n      });\r\n    });\r\n  }\r\n\r\n  async applyFilter(handle) {\r\n    const activeTier = this.getActiveTierElement();\r\n    if (!activeTier || !handle) return;\r\n    sessionStorage.setItem('combo_last_filter', handle);\r\n\r\n    const breadcrumbs = document.querySelectorAll('.js-breadcrumb-container a[data-handle]');\r\n    breadcrumbs.forEach(b => {\r\n      b.style.fontWeight = (b.dataset.handle === handle) ? '700' : '400';\r\n      b.style.textDecoration = (b.dataset.handle === handle) ? 'underline' : 'none';\r\n    });\r\n\r\n    const sentinel = activeTier.querySelector('.js-infinite-sentinel');\r\n    const grid = activeTier.querySelector('.js-combo-grid');\r\n    if (!sentinel || !grid) return;\r\n\r\n    grid.style.opacity = '0.5';\r\n    grid.classList.add('is-loading-grid');\r\n    activeTier.dataset.collectionHandle = handle;\r\n    sentinel.dataset.nextPage = '1';\r\n    sentinel.dataset.allLoaded = 'false';\r\n    sentinel._isBreadcrumbFilter = true;\r\n\r\n    const refreshed = await this.loadMoreForSentinel(sentinel, true);\n    if (refreshed && this.mobileProgressiveCatalogEnabled) {\n      await this.hydrateTierProducts(activeTier);\n    }\n    \r\n    sentinel._isBreadcrumbFilter = false;\r\n    grid.style.opacity = '1';\r\n    grid.classList.remove('is-loading-grid');\r\n    if (this.sentinelObserver) this.sentinelObserver.observe(sentinel);\r\n  }\r\n\r\n  restoreLastFilter() {\n    const lastFilter = sessionStorage.getItem('combo_last_filter');\n    if (lastFilter) this.applyFilter(lastFilter);\n  }\n  // --- END FILTER METHODS ---\r\n\r\n  handleAutoSelect() {\n    const params = new URLSearchParams(window.location.search);\n    const handle = params.get('autoselect') || sessionStorage.getItem('kpComboAutoSelect');\n    if (!handle) return;\n\n    sessionStorage.removeItem('kpComboAutoSelect');\n\r\n    // If already in combo, don't trigger another click (which would remove it)\r\n    if (this.combo.some(item => item.handle === handle)) {\r\n      const cleanUrl = window.location.pathname;\r\n      window.history.replaceState({}, '', cleanUrl);\r\n      return;\r\n    }\r\n\r\n    // Clean the URL so a page refresh doesn't re-trigger\r\n    const cleanUrl = window.location.pathname;\r\n    window.history.replaceState({}, '', cleanUrl);\r\n\r\n    // Try immediately (product cards may already be rendered)\r\n    if (this._tryAutoSelect(handle)) return;\r\n\r\n    // Cards may still be loading \u2014 watch for DOM changes\r\n    const observer = this.addManagedObserver(new MutationObserver(() => {\n      if (this._tryAutoSelect(handle)) {\n        observer.disconnect();\n      }\n    }));\n    observer.observe(document.querySelector('.combo-content') || document.body, {\r\n      childList: true,\r\n      subtree: true\r\n    });\r\n\r\n    // Stop watching after 8 seconds regardless\r\n    setTimeout(() => observer.disconnect(), 8000);\r\n  }\r\n\r\n  _tryAutoSelect(handle) {\n    const existingButton = document.querySelector(`.js-atb-btn[data-handle=\"${handle}\"]`);\n    const btn = existingButton || this.ensureProductCardMounted(handle)?.querySelector('.js-atb-btn');\n    if (!btn) return false;\n\r\n    // Scroll to the product card\r\n    btn.closest('.combo-card-wrapper')?.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n\r\n    // Brief highlight animation\r\n    const card = btn.closest('.combo-card-wrapper');\r\n    if (card) {\r\n      card.style.transition = 'box-shadow 0.4s ease';\r\n      card.style.boxShadow = '0 0 0 3px #543e3a';\r\n      setTimeout(() => { card.style.boxShadow = ''; }, 2000);\r\n    }\r\n\r\n    // Click the Add To Box button\r\n    setTimeout(() => btn.click(), 400);\r\n    return true;\r\n  }\r\n\r\n  bindAtbButtons(container) {\n    this.bindQuantityControls(container);\n    container.querySelectorAll('.js-atb-btn').forEach(btn => {\n      if (btn.dataset.comboBound === 'true') return;\n      btn.dataset.comboBound = 'true';\n      btn.addEventListener('click', (e) => this.handleAtbClick(e.currentTarget));\n    });\n  }\n\n  bindQuantityControls(container) {\n    container.querySelectorAll('[data-combo-quantity]').forEach(control => {\n      if (control.dataset.comboQuantityBound === 'true') return;\n      control.dataset.comboQuantityBound = 'true';\n      control.querySelector('[data-combo-quantity-decrease]')?.addEventListener('click', () => {\n        this.changeComboQuantity(control, -1);\n      });\n      control.querySelector('[data-combo-quantity-increase]')?.addEventListener('click', () => {\n        this.changeComboQuantity(control, 1);\n      });\n      this.syncQuantityControl(control, 1);\n    });\n  }\n\n  syncQuantityControl(control, quantity) {\n    const safeQuantity = Math.min(Math.max(Number(quantity || 1), 1), 10);\n    const card = control.closest('.combo-card-wrapper');\n    const button = card?.querySelector('.js-atb-btn');\n    if (button) button.dataset.quantity = String(safeQuantity);\n    const output = control.querySelector('[data-combo-quantity-value]');\n    if (output) output.textContent = String(safeQuantity);\n    const decrease = control.querySelector('[data-combo-quantity-decrease]');\n    const increase = control.querySelector('[data-combo-quantity-increase]');\n    if (decrease) decrease.disabled = safeQuantity <= 1;\n    if (increase) increase.disabled = safeQuantity >= 10;\n  }\n\n  findComboCartLine(cart, item) {\n    const matchingLines = (cart?.items || []).filter(line => {\n      const properties = line.properties || {};\n      return String(line.variant_id) === String(item.variantId)\n        && String(properties._combo) === 'true';\n    });\n\n    return matchingLines.find(line => line.key === item.key)\n      || matchingLines.find(line => !item.tierId || String(line.properties?._tier_id) === String(item.tierId))\n      || matchingLines[0]\n      || null;\n  }\n\n  async fetchCartState() {\n    const response = await fetch('/cart.js', {\n      headers: { Accept: 'application/json' },\n      cache: 'no-store'\n    });\n    if (!response.ok) throw new Error('Could not refresh the cart.');\n    return response.json();\n  }\n\n  async postCartLineQuantity(lineKey, quantity) {\n    return fetch('/cart/change.js', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n      body: JSON.stringify({ id: lineKey, quantity })\n    });\n  }\n\n  async addComboItemToCart(item) {\n    const root = window.Shopify?.routes?.root || '/';\n    const endpoint = `${root}cart/add.js`;\n    const payload = {\n      items: [{\n        id: item.variantId,\n        quantity: item.quantity,\n        properties: {\n          '_combo': 'true',\n          '_combo_group': item.groupId,\n          '_tier_id': item.tierId,\n          '_combo_source': 'combo-page'\n        }\n      }]\n    };\n\n    let lastError = null;\n    for (let attempt = 0; attempt < 2; attempt += 1) {\n      try {\n        const response = await fetch(endpoint, {\n          method: 'POST',\n          credentials: 'same-origin',\n          headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n          body: JSON.stringify(payload)\n        });\n\n        if (!response.ok) {\n          const errorPayload = await response.json().catch(() => ({}));\n          const error = new Error(errorPayload.description || errorPayload.message || 'Could not add item to cart.');\n          error.status = response.status;\n          throw error;\n        }\n\n        await response.json();\n        return this.fetchCartState();\n      } catch (error) {\n        lastError = error;\n\n        // A mobile connection can lose the response after Shopify has accepted\n        // the add. Confirm cart state before retrying so we never add twice.\n        const recoveredCart = await this.fetchCartState().catch(() => null);\n        const recoveredLine = recoveredCart?.items?.find(line => (\n          String(line.variant_id) === String(item.variantId)\n          && String(line.properties?._combo) === 'true'\n          && String(line.properties?._combo_group || '') === String(item.groupId)\n        ));\n        if (recoveredLine) return recoveredCart;\n\n        const retryable = !error.status || error.status === 429 || error.status >= 500;\n        if (attempt === 0 && retryable) {\n          await new Promise(resolve => window.setTimeout(resolve, 350));\n          continue;\n        }\n        break;\n      }\n    }\n\n    throw lastError || new Error('Could not add item to cart.');\n  }\n\n  async changeCartLineQuantity(item, quantity) {\n    let cart = await this.fetchCartState();\n    let matchingLines = (cart.items || []).filter(line => (\n      String(line.variant_id) === String(item.variantId)\n      && String(line.properties?._combo) === 'true'\n    ));\n\n    if (!matchingLines.length) {\n      if (quantity === 0) return cart;\n      throw new Error('Could not find this combo item in the cart.');\n    }\n\n    if (quantity === 0) {\n      for (const line of matchingLines) {\n        const response = await this.postCartLineQuantity(line.key, 0);\n        if (!response.ok) throw new Error('Could not remove this combo item.');\n        cart = await response.json();\n      }\n      this.setGlobalCartCount(cart.item_count);\n      return cart;\n    }\n\n    const preferredLine = matchingLines.find(line => line.key === item.key) || matchingLines[0];\n    for (const duplicate of matchingLines.filter(line => line.key !== preferredLine.key)) {\n      const response = await this.postCartLineQuantity(duplicate.key, 0);\n      if (!response.ok) throw new Error('Could not consolidate this combo item.');\n      cart = await response.json();\n    }\n\n    matchingLines = (cart.items || []).filter(line => (\n      String(line.variant_id) === String(item.variantId)\n      && String(line.properties?._combo) === 'true'\n    ));\n    const currentLine = matchingLines.find(line => line.key === preferredLine.key) || matchingLines[0];\n    if (!currentLine) throw new Error('Could not find this combo item in the cart.');\n    const response = await this.postCartLineQuantity(currentLine.key, quantity);\n    if (!response.ok) throw new Error('Could not update this combo item.');\n    cart = await response.json();\n    this.setGlobalCartCount(cart.item_count);\n    return cart;\n  }\n\n  async changeComboQuantity(control, delta) {\n    const card = control.closest('.combo-card-wrapper');\n    const button = card?.querySelector('.js-atb-btn');\n    if (!button) return;\n\n    const currentQuantity = Number(button.dataset.quantity || 1);\n    const nextQuantity = Math.min(Math.max(currentQuantity + delta, 1), 10);\n    if (nextQuantity === currentQuantity) return;\n\n    const item = this.combo.find(candidate => candidate.variantId === button.dataset.variantId);\n    if (!item) {\n      this.syncQuantityControl(control, nextQuantity);\n      return;\n    }\n\n    const previousQuantity = item.quantity;\n    const nextUnitCount = this.getComboUnitCount() - previousQuantity + nextQuantity;\n    if (nextQuantity > previousQuantity && nextUnitCount > this.maxSlots) {\n      this.showCroStatus(`This combo can include up to ${this.maxSlots} items.`);\n      return;\n    }\n\n    item.quantity = nextQuantity;\n    this.syncQuantityControl(control, nextQuantity);\n    this.adjustGlobalCartCount(nextQuantity - previousQuantity);\n    this.updateUI();\n\n    try {\n      const updatedCart = await this.changeCartLineQuantity(item, nextQuantity);\n      this.applyCartState(updatedCart);\n      this.emitCartUpdated(updatedCart);\n      this.clearCroStatus();\n      this.trackCroEvent('quantity_changed', {\n        product_handle: item.handle,\n        quantity: nextQuantity\n      });\n    } catch (error) {\n      await this.syncWithCart();\n      this.showCroStatus(error.message || 'Could not update quantity. Please try again.');\n    }\n  }\n\n  bindSuggestedComboButtons() {\n    document.querySelectorAll('[data-combo-suggestion]').forEach(button => {\n      if (button.dataset.comboSuggestionBound === 'true') return;\n      button.dataset.comboSuggestionBound = 'true';\n      button.addEventListener('click', () => this.applySuggestedCombo(button));\n    });\n  }\n\n  async applySuggestedCombo(button) {\n    const handles = (button.dataset.comboHandles || '')\n      .split(',')\n      .map(handle => handle.trim())\n      .filter(Boolean);\n\n    if (!handles.length) return;\n\n    button.disabled = true;\n    try {\n      for (const item of [...this.combo]) {\n        await this.removeItem(item.variantId);\n      }\n\n      for (const handle of handles) {\n        const existingButton = document.querySelector(`.js-atb-btn[data-handle=\"${handle}\"]`);\n        const addButton = existingButton || this.ensureProductCardMounted(handle)?.querySelector('.js-atb-btn');\n        if (addButton && !addButton.classList.contains('is-added')) {\n          await this.handleAtbClick(addButton);\n        }\n      }\n    } finally {\n      button.disabled = false;\n    }\n  }\n\n  bindCuratedCategoryButtons() {\n    document.querySelectorAll('.combo-curated-category').forEach(button => {\n      if (button.dataset.comboCategoryBound === 'true') return;\n      button.dataset.comboCategoryBound = 'true';\n      button.addEventListener('click', async () => {\n        const category = button.dataset.comboCategory || 'all';\n        const previousPriceFilter = this.activePriceFilter;\n        this.activeCuratedCategory = category;\n        this.setActivePriceFilter('all');\n        document.querySelectorAll('.combo-curated-category').forEach(categoryButton => {\n          categoryButton.classList.toggle('is-active', categoryButton === button);\n          categoryButton.setAttribute('aria-pressed', categoryButton === button ? 'true' : 'false');\n        });\n        await this.hydrateTierProducts(this.getActiveTierElement());\n        this.updateCategoryCounts();\n        this.filterCuratedCategory(category);\n        this.persistDiscoveryStateToHistory();\n        this.trackCroEvent('category_filter', {\n          category,\n          price_filter_reset: previousPriceFilter !== 'all'\n        });\n      });\n    });\n  }\n\n  bindCroControls() {\n    document.querySelectorAll('[data-combo-price-filter]').forEach(button => {\n      button.addEventListener('click', async () => {\n        this.setActivePriceFilter(button.dataset.comboPriceFilter || 'all');\n        await this.hydrateTierProducts(this.getActiveTierElement());\n        this.updateCategoryCounts();\n        this.applyCroDiscovery();\n        this.persistDiscoveryStateToHistory();\n        this.trackCroEvent('price_filter', { price_filter: this.activePriceFilter });\n      });\n    });\n\n    document.querySelector('[data-combo-sort]')?.addEventListener('change', async event => {\n      this.activeSort = event.currentTarget.value || 'recommended';\n      await this.hydrateTierProducts(this.getActiveTierElement());\n      this.applyCroDiscovery();\n      this.persistDiscoveryStateToHistory();\n      this.trackCroEvent('sort', { sort: this.activeSort });\n    });\n\n    this.selectionToggle?.addEventListener('click', () => {\n      if (!this.selectionPanel) return;\n      const shouldOpen = this.selectionPanel.hidden;\n      this.selectionPanel.hidden = !shouldOpen;\n      this.selectionToggle.setAttribute('aria-expanded', shouldOpen ? 'true' : 'false');\n    });\n\n    this.statusRetry?.addEventListener('click', async () => {\n      const retryAction = this.retryAction;\n      this.clearCroStatus();\n      if (retryAction) await retryAction();\n    });\n    document.querySelector('[data-combo-status-close]')?.addEventListener('click', () => this.clearCroStatus());\n\n    this.updateCategoryCounts();\n    this.applyCroDiscovery();\n  }\n\n  normalizeDiscoveryState(state) {\n    if (!state || typeof state !== 'object') return null;\n\n    const categories = ['all', 'necklaces', 'bracelets', 'studs', 'drop-earrings', 'gifts'];\n    const priceFilters = ['all', 'under-1200', '1200-2000', 'over-2000'];\n    const sorts = ['recommended', 'price-ascending', 'price-descending', 'name-ascending'];\n\n    return {\n      category: categories.includes(state.category) ? state.category : 'all',\n      priceFilter: priceFilters.includes(state.priceFilter) ? state.priceFilter : 'all',\n      sort: sorts.includes(state.sort) ? state.sort : 'recommended'\n    };\n  }\n\n  persistDiscoveryStateToHistory() {\n    const currentState = window.history.state && typeof window.history.state === 'object'\n      ? window.history.state\n      : {};\n    const discoveryState = this.normalizeDiscoveryState({\n      category: this.activeCuratedCategory,\n      priceFilter: this.activePriceFilter,\n      sort: this.activeSort\n    });\n\n    window.history.replaceState(\n      { ...currentState, kpComboDiscovery: discoveryState },\n      '',\n      window.location.href\n    );\n\n    try {\n      window.sessionStorage.setItem(\n        `kp_combo_discovery:${window.location.pathname}`,\n        JSON.stringify(discoveryState)\n      );\n    } catch (error) {\n      return;\n    }\n  }\n\n  restoreDiscoveryStateFromHistory() {\n    let storedState = null;\n    try {\n      storedState = JSON.parse(\n        window.sessionStorage.getItem(`kp_combo_discovery:${window.location.pathname}`) || 'null'\n      );\n    } catch (error) {\n      storedState = null;\n    }\n\n    const discoveryState = this.normalizeDiscoveryState(\n      window.history.state?.kpComboDiscovery || storedState\n    );\n    if (!discoveryState) return false;\n\n    this.activeCuratedCategory = discoveryState.category;\n    this.setActivePriceFilter(discoveryState.priceFilter);\n    this.activeSort = discoveryState.sort;\n\n    document.querySelectorAll('.combo-curated-category').forEach(button => {\n      const isActive = button.dataset.comboCategory === discoveryState.category;\n      button.classList.toggle('is-active', isActive);\n      button.setAttribute('aria-pressed', isActive ? 'true' : 'false');\n    });\n\n    const sortSelect = document.querySelector('[data-combo-sort]');\n    if (sortSelect) sortSelect.value = discoveryState.sort;\n    this.applyCroDiscovery();\n    return true;\n  }\n\n  compareRecommendedCards(cardA, cardB) {\n    const categoryPriority = {\n      necklaces: 0,\n      bracelets: 1,\n      studs: 2,\n      'drop-earrings': 3,\n      gifts: 4\n    };\n    const categoryRankA = categoryPriority[cardA.dataset.comboCategory] ?? 5;\n    const categoryRankB = categoryPriority[cardB.dataset.comboCategory] ?? 5;\n    if (categoryRankA !== categoryRankB) return categoryRankA - categoryRankB;\n    return Number.parseInt(cardA.dataset.comboOriginalIndex || '0', 10)\n      - Number.parseInt(cardB.dataset.comboOriginalIndex || '0', 10);\n  }\n\n  getPersonalizationStorage() {\n    try {\n      return window.localStorage;\n    } catch (error) {\n      return null;\n    }\n  }\n\n  readPersonalizationState() {\n    const result = KPComboPersonalization.readState(\n      this.getPersonalizationStorage(),\n      this.personalizationStorageKey\n    );\n    if (result.available) this.personalizationMemoryState = result.state;\n    return result.available ? result.state : this.personalizationMemoryState;\n  }\n\n  persistPersonalizationState(state) {\n    this.personalizationMemoryState = KPComboPersonalization.normalizeState(state);\n    KPComboPersonalization.writeState(\n      this.getPersonalizationStorage(),\n      this.personalizationStorageKey,\n      this.personalizationMemoryState\n    );\n  }\n\n  readNecklacePersonalizationState() {\n    const result = KPComboPersonalization.readState(\n      this.getPersonalizationStorage(),\n      this.necklacePersonalizationStorageKey\n    );\n    if (result.available) this.necklacePersonalizationMemoryState = result.state;\n    return result.available ? result.state : this.necklacePersonalizationMemoryState;\n  }\n\n  persistNecklacePersonalizationState(state) {\n    this.necklacePersonalizationMemoryState = KPComboPersonalization.normalizeState(state);\n    KPComboPersonalization.writeState(\n      this.getPersonalizationStorage(),\n      this.necklacePersonalizationStorageKey,\n      this.necklacePersonalizationMemoryState\n    );\n  }\n\n  readBraceletPersonalizationState() {\n    const result = KPComboPersonalization.readState(\n      this.getPersonalizationStorage(),\n      this.braceletPersonalizationStorageKey\n    );\n    if (result.available) this.braceletPersonalizationMemoryState = result.state;\n    return result.available ? result.state : this.braceletPersonalizationMemoryState;\n  }\n\n  persistBraceletPersonalizationState(state) {\n    this.braceletPersonalizationMemoryState = KPComboPersonalization.normalizeState(state);\n    KPComboPersonalization.writeState(\n      this.getPersonalizationStorage(),\n      this.braceletPersonalizationStorageKey,\n      this.braceletPersonalizationMemoryState\n    );\n  }\n\n  readAdditionalCategoryPersonalizationState(definition) {\n    const result = KPComboPersonalization.readState(\n      this.getPersonalizationStorage(),\n      definition.storageKey\n    );\n    if (result.available) definition.memoryState = result.state;\n    return result.available ? result.state : definition.memoryState;\n  }\n\n  persistAdditionalCategoryPersonalizationState(definition, state) {\n    definition.memoryState = KPComboPersonalization.normalizeState(state);\n    KPComboPersonalization.writeState(\n      this.getPersonalizationStorage(),\n      definition.storageKey,\n      definition.memoryState\n    );\n  }\n\n  recordRecentlyViewed(handle, category = '') {\n    if (!this.hasAnyPersonalization || !handle) return;\n    const viewedAt = Date.now();\n\n    if (this.personalizationEnabled && this.personalizationConfig.recentEnabled) {\n      const state = this.readPersonalizationState();\n      this.persistPersonalizationState(KPComboPersonalization.recordRecent(state, handle, viewedAt));\n    }\n\n    if (\n      this.necklacePersonalizationEnabled\n      && category === 'necklaces'\n      && this.necklacePersonalizationConfig.recentEnabled\n    ) {\n      const necklaceState = this.readNecklacePersonalizationState();\n      this.persistNecklacePersonalizationState(\n        KPComboPersonalization.recordRecent(necklaceState, handle, viewedAt)\n      );\n    }\n\n    if (\n      this.braceletPersonalizationEnabled\n      && category === 'bracelets'\n      && this.braceletPersonalizationConfig.recentEnabled\n    ) {\n      const braceletState = this.readBraceletPersonalizationState();\n      this.persistBraceletPersonalizationState(\n        KPComboPersonalization.recordRecent(braceletState, handle, viewedAt)\n      );\n    }\n\n    Object.values(this.additionalCategoryPersonalizations).forEach(definition => {\n      if (\n        !definition.enabled\n        || category !== definition.category\n        || !definition.config.recentEnabled\n      ) return;\n      const categoryState = this.readAdditionalCategoryPersonalizationState(definition);\n      this.persistAdditionalCategoryPersonalizationState(\n        definition,\n        KPComboPersonalization.recordRecent(categoryState, handle, viewedAt)\n      );\n    });\n  }\n\n  initializeNecklacePersonalizedRanking(items, globalState) {\n    if (!this.necklacePersonalizationEnabled) {\n      this.necklacePersonalizedOrderRanks = null;\n      return false;\n    }\n\n    try {\n      const necklaceItems = items.filter(item => item.category === 'necklaces');\n      if (!necklaceItems.length) {\n        this.necklacePersonalizedOrderRanks = null;\n        return false;\n      }\n\n      const necklaceHandles = new Set(necklaceItems.map(item => item.handle));\n      const necklaceState = this.readNecklacePersonalizationState();\n      const migratedRecent = globalState.recent.filter(entry => necklaceHandles.has(entry.handle));\n      const mergedState = KPComboPersonalization.normalizeState({\n        ...necklaceState,\n        recent: [...necklaceState.recent, ...migratedRecent]\n      });\n      const result = KPComboPersonalization.buildOrder(\n        necklaceItems,\n        mergedState,\n        this.necklacePersonalizationConfig\n      );\n      if (!result.orderedHandles.length) {\n        this.necklacePersonalizedOrderRanks = null;\n        return false;\n      }\n\n      this.necklacePersonalizedOrderRanks = new Map(\n        result.orderedHandles.map((handle, index) => [handle, index])\n      );\n      this.persistNecklacePersonalizationState({\n        ...mergedState,\n        previousControlled: this.necklacePersonalizationConfig.curatedEnabled\n          ? result.controlledHandles\n          : mergedState.previousControlled,\n        updatedAt: Date.now()\n      });\n      this.trackCroEvent('necklace_personalization_applied', {\n        recent_count: result.recentHandles.length,\n        controlled_count: result.controlledHandles.length,\n        controlled_shortfall: result.controlledShortfall,\n        remainder_order: result.config.remainderOrder\n      });\n      return true;\n    } catch (error) {\n      this.necklacePersonalizedOrderRanks = null;\n      console.warn('Necklace personalization fallback applied.', error);\n      return false;\n    }\n  }\n\n  initializeBraceletPersonalizedRanking(items, globalState) {\n    if (!this.braceletPersonalizationEnabled) {\n      this.braceletPersonalizedOrderRanks = null;\n      return false;\n    }\n\n    try {\n      const braceletItems = items.filter(item => item.category === 'bracelets');\n      if (!braceletItems.length) {\n        this.braceletPersonalizedOrderRanks = null;\n        return false;\n      }\n\n      const braceletHandles = new Set(braceletItems.map(item => item.handle));\n      const braceletState = this.readBraceletPersonalizationState();\n      const migratedRecent = globalState.recent.filter(entry => braceletHandles.has(entry.handle));\n      const mergedState = KPComboPersonalization.normalizeState({\n        ...braceletState,\n        recent: [...braceletState.recent, ...migratedRecent]\n      });\n      const result = KPComboPersonalization.buildOrder(\n        braceletItems,\n        mergedState,\n        this.braceletPersonalizationConfig\n      );\n      if (!result.orderedHandles.length) {\n        this.braceletPersonalizedOrderRanks = null;\n        return false;\n      }\n\n      this.braceletPersonalizedOrderRanks = new Map(\n        result.orderedHandles.map((handle, index) => [handle, index])\n      );\n      this.persistBraceletPersonalizationState({\n        ...mergedState,\n        previousControlled: this.braceletPersonalizationConfig.curatedEnabled\n          ? result.controlledHandles\n          : mergedState.previousControlled,\n        updatedAt: Date.now()\n      });\n      this.trackCroEvent('bracelet_personalization_applied', {\n        recent_count: result.recentHandles.length,\n        controlled_count: result.controlledHandles.length,\n        controlled_shortfall: result.controlledShortfall,\n        remainder_order: result.config.remainderOrder\n      });\n      return true;\n    } catch (error) {\n      this.braceletPersonalizedOrderRanks = null;\n      console.warn('Bracelet personalization fallback applied.', error);\n      return false;\n    }\n  }\n\n  initializeAdditionalCategoryPersonalizedRanking(items, globalState, definition) {\n    if (!definition.enabled) {\n      definition.orderRanks = null;\n      return false;\n    }\n\n    try {\n      const categoryItems = items.filter(item => item.category === definition.category);\n      if (!categoryItems.length) {\n        definition.orderRanks = null;\n        return false;\n      }\n\n      const categoryHandles = new Set(categoryItems.map(item => item.handle));\n      const categoryState = this.readAdditionalCategoryPersonalizationState(definition);\n      const migratedRecent = globalState.recent.filter(entry => categoryHandles.has(entry.handle));\n      const mergedState = KPComboPersonalization.normalizeState({\n        ...categoryState,\n        recent: [...categoryState.recent, ...migratedRecent]\n      });\n      const result = KPComboPersonalization.buildOrder(\n        categoryItems,\n        mergedState,\n        definition.config\n      );\n      if (!result.orderedHandles.length) {\n        definition.orderRanks = null;\n        return false;\n      }\n\n      definition.orderRanks = new Map(\n        result.orderedHandles.map((handle, index) => [handle, index])\n      );\n      this.persistAdditionalCategoryPersonalizationState(definition, {\n        ...mergedState,\n        previousControlled: definition.config.curatedEnabled\n          ? result.controlledHandles\n          : mergedState.previousControlled,\n        updatedAt: Date.now()\n      });\n      this.trackCroEvent(definition.eventName, {\n        recent_count: result.recentHandles.length,\n        controlled_count: result.controlledHandles.length,\n        controlled_shortfall: result.controlledShortfall,\n        remainder_order: result.config.remainderOrder\n      });\n      return true;\n    } catch (error) {\n      definition.orderRanks = null;\n      console.warn(`${definition.label} personalization fallback applied.`, error);\n      return false;\n    }\n  }\n\n  initializePersonalizedRanking() {\n    if (!this.hasAnyPersonalization) return false;\n\n    try {\n      this.updateCategoryCounts();\n      const cards = this.getDiscoveryCards();\n      if (!cards.length) return false;\n      const recommendedCards = [...cards].sort((cardA, cardB) => this.compareRecommendedCards(cardA, cardB));\n      const recommendedRanks = new Map(\n        recommendedCards.map((card, index) => [card.dataset.comboProductHandle, index])\n      );\n      const items = cards.map(card => ({\n        handle: card.dataset.comboProductHandle,\n        category: card.dataset.comboCategory,\n        priceCents: Number.parseInt(card.dataset.comboProductPriceCents || '0', 10),\n        available: card.dataset.comboProductAvailable !== 'false',\n        originalRank: Number.parseInt(card.dataset.comboOriginalIndex || '0', 10),\n        recommendedRank: recommendedRanks.get(card.dataset.comboProductHandle)\n      }));\n      const state = this.readPersonalizationState();\n      let bestComboPicksApplied = false;\n      if (this.personalizationEnabled) {\n        try {\n          const result = KPComboPersonalization.buildOrder(items, state, this.personalizationConfig);\n          if (result.orderedHandles.length) {\n            this.personalizedOrderRanks = new Map(\n              result.orderedHandles.map((handle, index) => [handle, index])\n            );\n            const latestState = this.readPersonalizationState();\n            this.persistPersonalizationState({\n              ...latestState,\n              previousControlled: this.personalizationConfig.curatedEnabled\n                ? result.controlledHandles\n                : latestState.previousControlled,\n              updatedAt: Date.now()\n            });\n            this.trackCroEvent('personalization_applied', {\n              promoted_count: result.promotedHandles.length,\n              recent_count: result.recentHandles.length,\n              controlled_count: result.controlledHandles.length,\n              controlled_shortfall: result.controlledShortfall,\n              remainder_order: result.config.remainderOrder\n            });\n            bestComboPicksApplied = true;\n          }\n        } catch (error) {\n          this.personalizedOrderRanks = null;\n          console.warn('Best Combo Picks personalization fallback applied.', error);\n        }\n      } else {\n        this.personalizedOrderRanks = null;\n      }\n\n      const necklaceApplied = this.initializeNecklacePersonalizedRanking(\n        items,\n        this.readPersonalizationState()\n      );\n      const braceletApplied = this.initializeBraceletPersonalizedRanking(\n        items,\n        this.readPersonalizationState()\n      );\n      const additionalCategoryApplied = Object.values(this.additionalCategoryPersonalizations)\n        .map(definition => this.initializeAdditionalCategoryPersonalizedRanking(\n          items,\n          this.readPersonalizationState(),\n          definition\n        ))\n        .some(Boolean);\n      this.applyCroDiscovery();\n      return bestComboPicksApplied || necklaceApplied || braceletApplied || additionalCategoryApplied;\n    } catch (error) {\n      this.personalizedOrderRanks = null;\n      this.necklacePersonalizedOrderRanks = null;\n      this.braceletPersonalizedOrderRanks = null;\n      Object.values(this.additionalCategoryPersonalizations).forEach(definition => {\n        definition.orderRanks = null;\n      });\n      console.warn('Combo personalization fallback applied.', error);\n      this.applyCroDiscovery();\n      return false;\n    }\n  }\n\n  activatePersonalizationLanding() {\n    if (!this.pendingPersonalizationActivation || document.visibilityState !== 'visible') return;\n    this.pendingPersonalizationActivation = false;\n    if (!this.personalizationHydrationReady) return;\n    this.comboPage?.classList.add('is-personalizing');\n    try {\n      this.initializePersonalizedRanking();\n    } finally {\n      this.comboPage?.classList.remove('is-personalizing');\n    }\n  }\n\n  bindPersonalizationLifecycle() {\n    if (!this.hasAnyPersonalization || this.personalizationLifecycleBound) return;\n    this.personalizationLifecycleBound = true;\n    this.addManagedListener(window, 'pageshow', event => {\n      if (!event.persisted) return;\n      this.pendingPersonalizationActivation = true;\n      this.activatePersonalizationLanding();\n    });\n    this.addManagedListener(document, 'visibilitychange', () => {\n      if (document.visibilityState === 'visible') this.activatePersonalizationLanding();\n    });\n  }\n\n  setActivePriceFilter(filter = 'all') {\n    this.activePriceFilter = filter;\n    document.querySelectorAll('[data-combo-price-filter]').forEach(filterButton => {\n      const isActive = filterButton.dataset.comboPriceFilter === filter;\n      filterButton.classList.toggle('is-active', isActive);\n      filterButton.setAttribute('aria-pressed', isActive ? 'true' : 'false');\n    });\n  }\n\n  cardMatchesPrice(card) {\n    const price = Number.parseInt(card.dataset.comboProductPriceCents || '0', 10);\n    if (!Number.isFinite(price)) return true;\n\n    if (this.activePriceFilter === 'under-1200') return price < 120000;\n    if (this.activePriceFilter === '1200-2000') return price >= 120000 && price <= 200000;\n    if (this.activePriceFilter === 'over-2000') return price > 200000;\n    return true;\n  }\n\n  updateCategoryCounts() {\n    const cards = this.getDiscoveryCards();\n    cards.forEach((card, index) => {\n      if (!card.dataset.comboOriginalIndex) card.dataset.comboOriginalIndex = String(index);\n    });\n  }\n\n  completeInitialCountLoading() {\n    if (this.visibleCountLoaderEl) this.visibleCountLoaderEl.hidden = true;\n    if (this.visibleCountStatusEl) this.visibleCountStatusEl.hidden = false;\n    this.comboPage?.classList.remove('is-personalizing');\n  }\n\n  getActivePersonalizedRank(card) {\n    const handle = card.dataset.comboProductHandle;\n    if (this.activeCuratedCategory === 'necklaces') {\n      return this.necklacePersonalizedOrderRanks?.get(handle);\n    }\n    if (this.activeCuratedCategory === 'bracelets') {\n      return this.braceletPersonalizedOrderRanks?.get(handle);\n    }\n    const additionalCategory = this.additionalCategoryPersonalizations?.[this.activeCuratedCategory];\n    if (additionalCategory) {\n      return additionalCategory.orderRanks?.get(handle);\n    }\n    if (this.activeCuratedCategory === 'all') {\n      return this.personalizedOrderRanks?.get(handle);\n    }\n    return undefined;\n  }\n\n  applyCroDiscovery() {\n    if (this.mobileProgressiveCatalogEnabled) {\n      let visibleCount = 0;\n      document.querySelectorAll('.js-combo-tier').forEach(tier => {\n        const catalog = this.getMobileProductCatalog(tier);\n        if (!catalog) return;\n        catalog.filteredRecords = this.sortDiscoveryCards(catalog.records)\n          .filter(record => this.recordMatchesDiscovery(record));\n        catalog.renderedCount = Math.min(catalog.initialCount, catalog.filteredRecords.length);\n        this.mountMobileCatalogRecords(\n          tier,\n          catalog.filteredRecords.slice(0, catalog.renderedCount),\n          { replace: true }\n        );\n        this.updateMobileCatalogSentinel(tier);\n        visibleCount += catalog.filteredRecords.length;\n      });\n\n      if (this.visibleCountEl) {\n        this.visibleCountEl.textContent = `${visibleCount} product${visibleCount === 1 ? '' : 's'}`;\n      }\n      return;\n    }\n\n    document.querySelectorAll('.js-combo-grid').forEach(grid => {\n      const cards = Array.from(grid.querySelectorAll(':scope > .combo-card-wrapper'));\n      const sortedCards = this.sortDiscoveryCards(cards);\n\n      sortedCards.forEach(card => grid.appendChild(card));\n    });\n\n    let visibleCount = 0;\n    document.querySelectorAll('.combo-card-wrapper').forEach(card => {\n      const categoryMatches = this.activeCuratedCategory === 'all'\n        || card.dataset.comboCategory === this.activeCuratedCategory;\n      const isVisible = categoryMatches && this.cardMatchesPrice(card);\n      card.hidden = !isVisible;\n      if (isVisible) visibleCount += 1;\n    });\n\n    if (this.visibleCountEl) {\n      this.visibleCountEl.textContent = `${visibleCount} product${visibleCount === 1 ? '' : 's'}`;\n    }\n  }\n\n  updateRecommendations() {\n    if (!this.recommendationsSection || !this.recommendationsContainer) return;\n    const selectedUnits = this.getComboUnitCount();\n    const remaining = Math.max(this.minimumItems - selectedUnits, 0);\n    if (selectedUnits === 0 || remaining === 0) {\n      this.recommendationsSection.hidden = true;\n      this.recommendationsContainer.replaceChildren();\n      return;\n    }\n\n    const selectedHandles = new Set(this.combo.map(item => item.handle));\n    const discoveryCards = this.getDiscoveryCards();\n    const discoveryCardsByHandle = new Map(\n      discoveryCards.map(card => [card.dataset.comboProductHandle, card])\n    );\n    const selectedCategories = new Set(this.combo.map(item => {\n      return discoveryCardsByHandle.get(item.handle)?.dataset.comboCategory;\n    }).filter(Boolean));\n\n    const candidates = discoveryCards\n      .filter(card => !selectedHandles.has(card.dataset.comboProductHandle))\n      .map(card => {\n        const weeklySelections = Number.parseInt(card.dataset.comboSelectionCount || '0', 10) || 0;\n        const originalRank = Number.parseInt(card.dataset.comboOriginalIndex || '0', 10);\n        const categoryBonus = selectedCategories.has(card.dataset.comboCategory) ? 0 : 10000;\n        return { card, score: categoryBonus + (weeklySelections * 100) - originalRank };\n      })\n      .sort((a, b) => b.score - a.score)\n      .slice(0, 4);\n\n    if (!candidates.length) {\n      this.recommendationsSection.hidden = true;\n      return;\n    }\n\n    this.recommendationsContainer.replaceChildren();\n    candidates.forEach(({ card: candidate }) => {\n      const card = typeof candidate.querySelector === 'function'\n        ? candidate\n        : this.getMountedProductCard(candidate.handle) || this.createMobileCatalogCard(candidate);\n      const sourceButton = card?.querySelector('.js-atb-btn');\n      const imageSource = card?.querySelector('.combo-card-gallery__track img');\n      if (!sourceButton || !imageSource) return;\n\n      const button = document.createElement('button');\n      button.type = 'button';\n      button.className = 'combo-cro-recommendation';\n      button.setAttribute('aria-label', `Add ${candidate.dataset.comboProductTitle} to combo`);\n\n      const image = document.createElement('img');\n      image.src = imageSource.currentSrc || imageSource.src;\n      image.alt = '';\n      image.width = 72;\n      image.height = 72;\n\n      const copy = document.createElement('span');\n      copy.className = 'combo-cro-recommendation__copy';\n      const title = document.createElement('strong');\n      title.textContent = candidate.dataset.comboProductTitle || '';\n      const prices = document.createElement('span');\n      prices.className = 'combo-cro-recommendation__prices';\n      const actualPrice = document.createElement('span');\n      actualPrice.className = 'combo-cro-recommendation__actual-price';\n      actualPrice.textContent = `Price ${candidate.dataset.comboProductPrice || ''}`;\n      const comboPrice = document.createElement('span');\n      comboPrice.className = 'combo-cro-recommendation__combo-price';\n      comboPrice.textContent = `Combo ${candidate.dataset.comboProductComboPrice || ''}`;\n      prices.append(actualPrice, comboPrice);\n      copy.append(title, prices);\n\n      const add = document.createElement('span');\n      add.className = 'combo-cro-recommendation__add';\n      add.setAttribute('aria-hidden', 'true');\n      add.textContent = 'Add';\n\n      button.append(image, copy, add);\n      button.addEventListener('click', async () => {\n        button.disabled = true;\n        try {\n          const mountedCard = typeof candidate.querySelector === 'function'\n            ? candidate\n            : this.ensureProductCardMounted(candidate.handle);\n          const actionButton = mountedCard?.querySelector('.js-atb-btn');\n          if (actionButton) await this.handleAtbClick(actionButton);\n        } finally {\n          if (button.isConnected) button.disabled = false;\n        }\n      });\n      this.recommendationsContainer.appendChild(button);\n    });\n\n    if (this.recommendationsCopy) {\n      this.recommendationsCopy.textContent = `Add ${remaining} more to unlock ${this.discountPercentage}% off`;\n    }\n    this.recommendationsSection.hidden = false;\n  }\n\n  guideToNextProduct() {\n    this.trackCroEvent('completion_cta', { remaining: Math.max(this.minimumItems - this.getComboUnitCount(), 0) });\n    const target = !this.recommendationsSection?.hidden\n      ? this.recommendationsSection\n      : document.querySelector('.combo-content');\n    target?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n    window.setTimeout(() => {\n      const nextButton = !this.recommendationsSection?.hidden\n        ? this.recommendationsSection.querySelector('.combo-cro-recommendation')\n        : document.querySelector('.combo-card-wrapper:not([hidden]) .js-atb-btn:not(.is-added)');\n      nextButton?.focus({ preventScroll: true });\n    }, 450);\n  }\n\n  renderSelectionPanel(items) {\n    if (!this.selectionList || !this.selectionToggle || !this.selectionPanel) return;\n    this.selectionList.replaceChildren();\n    this.selectionToggle.textContent = `View ${this.getComboUnitCount(items)} items`;\n\n    if (!items.length) {\n      this.selectionPanel.hidden = true;\n      this.selectionToggle.setAttribute('aria-expanded', 'false');\n      return;\n    }\n\n    items.forEach(item => {\n      const row = document.createElement('div');\n      row.className = 'combo-cro-selected-item';\n\n      const image = document.createElement('img');\n      image.src = item.image;\n      image.alt = '';\n      image.width = 46;\n      image.height = 46;\n\n      const copy = document.createElement('span');\n      copy.className = 'combo-cro-selected-item__copy';\n      const title = document.createElement('strong');\n      title.textContent = item.title;\n      const price = document.createElement('span');\n      price.textContent = `Qty ${item.quantity || 1} \u00B7 ${this.formatMoney(item.price * Number(item.quantity || 1))}`;\n      copy.append(title, price);\n\n      const remove = document.createElement('button');\n      remove.type = 'button';\n      remove.textContent = 'Remove';\n      remove.setAttribute('aria-label', `Remove ${item.title} from combo`);\n      remove.addEventListener('click', () => this.removeItem(item.variantId));\n\n      row.append(image, copy, remove);\n      this.selectionList.appendChild(row);\n    });\n  }\n\n  showCroStatus(message, retryAction = null) {\n    this.retryAction = retryAction;\n    if (this.statusCopy) this.statusCopy.textContent = message;\n    if (this.statusRetry) this.statusRetry.hidden = !retryAction;\n    if (this.statusPanel) this.statusPanel.hidden = false;\n\n    const dialogStatus = this.productDialog?.querySelector('[data-combo-product-dialog-status]');\n    if (dialogStatus && this.productDialog && !this.productDialog.hidden) {\n      dialogStatus.textContent = message;\n      dialogStatus.hidden = false;\n    }\n  }\n\n  clearCroStatus() {\n    this.retryAction = null;\n    if (this.statusPanel) this.statusPanel.hidden = true;\n    if (this.statusRetry) this.statusRetry.hidden = true;\n    const dialogStatus = this.productDialog?.querySelector('[data-combo-product-dialog-status]');\n    if (dialogStatus) {\n      dialogStatus.textContent = '';\n      dialogStatus.hidden = true;\n    }\n  }\n\n  trackCroEvent(name, detail = {}) {\n    const payload = {\n      event: `combo_cro_${name}`,\n      combo_selected_count: this.getComboUnitCount(),\n      ...detail\n    };\n    if (Array.isArray(window.dataLayer)) window.dataLayer.push(payload);\n    document.dispatchEvent(new CustomEvent('kp:combo-cro', { detail: payload }));\n  }\n\n  loadDeferredMedia(media) {\n    if (!media) return;\n    media.querySelectorAll('img[data-src]').forEach(image => {\n      image.src = image.dataset.src;\n      image.removeAttribute('data-src');\n    });\n  }\n\n  getCardGalleryMedia(track) {\n    const mediaTemplate = track?.querySelector('[data-combo-gallery-media]');\n    if (!mediaTemplate?.content) return [];\n    return Array.from(mediaTemplate.content.querySelectorAll('[data-combo-gallery-source]')).map(source => ({\n      src: source.dataset.src || '',\n      alt: source.dataset.alt || '',\n      width: Number.parseInt(source.dataset.width || '720', 10) || 720,\n      height: Number.parseInt(source.dataset.height || '720', 10) || 720\n    })).filter(item => item.src);\n  }\n\n  setCardGalleryMedia(track, index, previousButton, nextButton) {\n    const mediaItems = this.getCardGalleryMedia(track);\n    const image = track?.querySelector(':scope > img');\n    if (!image || !mediaItems.length) return;\n    const safeIndex = Math.max(0, Math.min(mediaItems.length - 1, index));\n    const mediaItem = mediaItems[safeIndex];\n    if (image.src !== mediaItem.src) image.src = mediaItem.src;\n    image.alt = mediaItem.alt;\n    image.width = mediaItem.width;\n    image.height = mediaItem.height;\n    track.dataset.comboGalleryIndex = String(safeIndex);\n    if (previousButton) {\n      previousButton.hidden = mediaItems.length < 2;\n      previousButton.disabled = safeIndex <= 0;\n    }\n    if (nextButton) {\n      nextButton.hidden = mediaItems.length < 2;\n      nextButton.disabled = safeIndex >= mediaItems.length - 1;\n    }\n  }\n\n  moveCardGalleryMedia(track, direction, previousButton, nextButton) {\n    const currentIndex = Number.parseInt(track?.dataset.comboGalleryIndex || '0', 10) || 0;\n    this.setCardGalleryMedia(track, currentIndex + direction, previousButton, nextButton);\n  }\n\n  bindProductCardEnhancements(container) {\n    container.querySelectorAll('[data-combo-card-gallery]').forEach(gallery => {\n      if (gallery.dataset.comboGalleryBound === 'true') return;\n      gallery.dataset.comboGalleryBound = 'true';\n\n      const card = gallery.closest('.combo-card-wrapper');\n      const track = gallery.querySelector('[data-combo-gallery-track]');\n      const previousButton = gallery.querySelector('[data-combo-gallery-previous]');\n      const nextButton = gallery.querySelector('[data-combo-gallery-next]');\n      let pointerStartX = 0;\n      let suppressClick = false;\n\n      const openDetails = trigger => this.openProductDialog(card, trigger);\n\n      if (track) {\n        track.addEventListener('pointerdown', event => {\n          pointerStartX = event.clientX;\n          suppressClick = false;\n        });\n        track.addEventListener('pointerup', event => {\n          const horizontalDistance = event.clientX - pointerStartX;\n          if (Math.abs(horizontalDistance) < 36) return;\n          suppressClick = true;\n          this.moveCardGalleryMedia(\n            track,\n            horizontalDistance < 0 ? 1 : -1,\n            previousButton,\n            nextButton\n          );\n        });\n        track.addEventListener('click', event => {\n          if (suppressClick) {\n            suppressClick = false;\n            event.preventDefault();\n            return;\n          }\n          event.preventDefault();\n          openDetails(track);\n        });\n        track.addEventListener('keydown', event => {\n          if (event.key !== 'Enter' && event.key !== ' ') return;\n          event.preventDefault();\n          openDetails(track);\n        });\n\n        previousButton?.addEventListener('click', event => {\n          event.preventDefault();\n          event.stopPropagation();\n          this.moveCardGalleryMedia(track, -1, previousButton, nextButton);\n        });\n        nextButton?.addEventListener('click', event => {\n          event.preventDefault();\n          event.stopPropagation();\n          this.moveCardGalleryMedia(track, 1, previousButton, nextButton);\n        });\n        this.setCardGalleryMedia(track, 0, previousButton, nextButton);\n      }\n\n      card?.querySelectorAll('.luxury-title, .product-card__name').forEach(link => {\n        link.addEventListener('click', event => {\n          event.preventDefault();\n          openDetails(link);\n        });\n      });\n    });\n  }\n\n  bindOverlayControls() {\n    if (this.productDialog) {\n      this.productDialog.querySelectorAll('[data-combo-product-close]').forEach(button => {\n        button.addEventListener('click', () => this.closeOverlay(this.productDialog));\n      });\n      const dialogMedia = this.productDialog.querySelector('[data-combo-product-dialog-media]');\n      const previousMediaButton = this.productDialog.querySelector('[data-combo-product-media-previous]');\n      const nextMediaButton = this.productDialog.querySelector('[data-combo-product-media-next]');\n      const syncDialogNavigation = () => this.syncMediaNavigation(dialogMedia, previousMediaButton, nextMediaButton);\n\n      dialogMedia?.addEventListener('scroll', syncDialogNavigation, { passive: true });\n      previousMediaButton?.addEventListener('click', event => {\n        event.preventDefault();\n        this.moveMedia(dialogMedia, -1, previousMediaButton, nextMediaButton);\n        this.startDialogMediaAutoplay(dialogMedia, previousMediaButton, nextMediaButton);\n      });\n      nextMediaButton?.addEventListener('click', event => {\n        event.preventDefault();\n        this.moveMedia(dialogMedia, 1, previousMediaButton, nextMediaButton);\n        this.startDialogMediaAutoplay(dialogMedia, previousMediaButton, nextMediaButton);\n      });\n      dialogMedia?.addEventListener('pointerdown', () => this.stopDialogMediaAutoplay());\n      dialogMedia?.addEventListener('pointerup', () => {\n        this.startDialogMediaAutoplay(dialogMedia, previousMediaButton, nextMediaButton);\n      });\n      dialogMedia?.addEventListener('pointercancel', () => {\n        this.startDialogMediaAutoplay(dialogMedia, previousMediaButton, nextMediaButton);\n      });\n      this.productDialog.querySelector('[data-combo-product-dialog-link]')?.addEventListener('click', event => {\n        const destination = event.currentTarget.dataset.productUrl;\n        if (!destination) {\n          event.preventDefault();\n          return;\n        }\n\n        event.preventDefault();\n        window.location.assign(destination);\n      });\n      this.productDialog.querySelector('[data-combo-product-dialog-add]')?.addEventListener('click', async event => {\n        const modalButton = event.currentTarget;\n        const handle = this.productDialog.dataset.productHandle;\n        const sourceButton = Array.from(document.querySelectorAll('.js-atb-btn'))\n          .find(button => button.dataset.handle === handle);\n        if (!sourceButton) return;\n\n        const wasAdded = sourceButton.classList.contains('is-added');\n        this.clearCroStatus();\n        modalButton.disabled = true;\n        await this.handleAtbClick(sourceButton);\n        modalButton.disabled = false;\n        const isAdded = sourceButton.classList.contains('is-added');\n        modalButton.textContent = isAdded\n          ? 'Added to combo'\n          : 'Add to combo';\n        if (wasAdded !== isAdded) {\n          setTimeout(() => this.closeOverlay(this.productDialog), 350);\n        }\n      });\n    }\n\n    if (this.confirmDialog) {\n      this.confirmDialog.querySelectorAll('[data-combo-confirm-close]').forEach(button => {\n        button.addEventListener('click', () => this.closeOverlay(this.confirmDialog));\n      });\n      this.confirmDialog.querySelector('[data-combo-confirm-submit]')?.addEventListener('click', () => {\n        this.completeCheckout();\n      });\n    }\n\n    this.addManagedListener(document, 'keydown', event => {\n      if (event.key !== 'Escape') return;\n      if (this.productDialog && !this.productDialog.hidden) this.closeOverlay(this.productDialog);\n      if (this.confirmDialog && !this.confirmDialog.hidden) this.closeOverlay(this.confirmDialog);\n    });\n  }\n\n  openProductDialog(card, trigger) {\n    if (!card || !this.productDialog) return;\n    this.stopDialogMediaAutoplay();\n    this.dialogMediaAutoplayDirection = 1;\n    this.clearCroStatus();\n    this.recordRecentlyViewed(\n      card.dataset.comboProductHandle || '',\n      card.dataset.comboCategory || ''\n    );\n    this.trackCroEvent('quick_view', { product_handle: card.dataset.comboProductHandle || '' });\n    this.lastDialogTrigger = trigger;\n    this.productDialog.dataset.productHandle = card.dataset.comboProductHandle || '';\n\n    const title = this.productDialog.querySelector('[data-combo-product-dialog-title]');\n    const price = this.productDialog.querySelector('[data-combo-product-dialog-price]');\n    const comboPrice = this.productDialog.querySelector('[data-combo-product-dialog-combo-price]');\n    const comboSaving = this.productDialog.querySelector('[data-combo-product-dialog-saving]');\n    const merchLabel = this.productDialog.querySelector('[data-combo-product-dialog-merch]');\n    const selectionCount = this.productDialog.querySelector('[data-combo-product-dialog-selection]');\n    const stock = this.productDialog.querySelector('[data-combo-product-dialog-stock]');\n    const specifications = this.productDialog.querySelector('[data-combo-product-dialog-specifications]');\n    const media = this.productDialog.querySelector('[data-combo-product-dialog-media]');\n    const previousMediaButton = this.productDialog.querySelector('[data-combo-product-media-previous]');\n    const nextMediaButton = this.productDialog.querySelector('[data-combo-product-media-next]');\n    const link = this.productDialog.querySelector('[data-combo-product-dialog-link]');\n    const addButton = this.productDialog.querySelector('[data-combo-product-dialog-add]');\n    const sourceButton = card.querySelector('.js-atb-btn');\n\n    if (title) title.textContent = card.dataset.comboProductTitle || '';\n    if (price) price.textContent = card.dataset.comboProductPrice || '';\n    if (comboPrice) comboPrice.textContent = card.dataset.comboProductComboPrice || '';\n    if (comboSaving) comboSaving.textContent = `Save ${card.dataset.comboProductSaving || ''}`;\n    if (merchLabel) {\n      merchLabel.textContent = card.dataset.comboMerchLabel || 'Easy to combine';\n    }\n    if (selectionCount) {\n      const weeklySelections = Number.parseInt(card.dataset.comboSelectionCount || '', 10);\n      if (Number.isFinite(weeklySelections) && weeklySelections > 0) {\n        selectionCount.textContent = `${weeklySelections.toLocaleString('en-IN')} times selected in combos this week`;\n        selectionCount.hidden = false;\n      } else {\n        selectionCount.textContent = '';\n        selectionCount.hidden = true;\n      }\n    }\n    if (stock) {\n      const stockCopy = card.dataset.comboProductStock || '';\n      stock.textContent = stockCopy;\n      stock.hidden = !stockCopy;\n      stock.classList.toggle('is-low', stockCopy.startsWith('Only '));\n    }\n    if (specifications) {\n      const specificationTemplate = card.querySelector('[data-combo-product-specifications]');\n      specifications.replaceChildren();\n      if (specificationTemplate?.content) {\n        specifications.appendChild(specificationTemplate.content.cloneNode(true));\n      }\n      specifications.scrollTop = 0;\n    }\n    if (link) {\n      const productUrl = card.dataset.comboProductUrl;\n      const destination = productUrl ? new URL(productUrl, window.location.origin).href : '';\n      link.href = destination || '#';\n      link.dataset.productUrl = destination;\n      link.setAttribute('aria-disabled', destination ? 'false' : 'true');\n    }\n    if (addButton) {\n      addButton.textContent = sourceButton?.classList.contains('is-added') ? 'Remove from combo' : 'Add to combo';\n    }\n\n    if (media) {\n      media.innerHTML = '';\n      const cardMedia = this.getCardGalleryMedia(card.querySelector('[data-combo-gallery-track]'));\n      cardMedia.forEach((sourceImage, index) => {\n        const image = document.createElement('img');\n        image.src = sourceImage.src;\n        image.alt = sourceImage.alt;\n        image.width = sourceImage.width;\n        image.height = sourceImage.height;\n        image.loading = index === 0 ? 'eager' : 'lazy';\n        media.appendChild(image);\n      });\n      media.scrollLeft = 0;\n    }\n\n    this.openOverlay(this.productDialog);\n    requestAnimationFrame(() => {\n      this.syncMediaNavigation(media, previousMediaButton, nextMediaButton);\n      this.startDialogMediaAutoplay(media, previousMediaButton, nextMediaButton);\n    });\n  }\n\n  moveMedia(media, direction, previousButton, nextButton) {\n    if (!media || !media.clientWidth) return;\n    const itemCount = media.children.length;\n    if (itemCount < 2) return;\n    const currentIndex = Math.round(media.scrollLeft / media.clientWidth);\n    const nextIndex = Math.max(0, Math.min(itemCount - 1, currentIndex + direction));\n    media.scrollLeft = nextIndex * media.clientWidth;\n    this.syncMediaNavigation(media, previousButton, nextButton);\n  }\n\n  syncMediaNavigation(media, previousButton, nextButton) {\n    if (!media) return;\n    const itemCount = media.children.length;\n    const hasMultipleImages = itemCount > 1;\n    const activeIndex = media.clientWidth\n      ? Math.round(media.scrollLeft / media.clientWidth)\n      : 0;\n\n    if (previousButton) {\n      previousButton.hidden = !hasMultipleImages;\n      previousButton.disabled = activeIndex <= 0;\n    }\n    if (nextButton) {\n      nextButton.hidden = !hasMultipleImages;\n      nextButton.disabled = activeIndex >= itemCount - 1;\n    }\n  }\n\n  stopDialogMediaAutoplay() {\n    if (!this.dialogMediaAutoplayTimer) return;\n    window.clearInterval(this.dialogMediaAutoplayTimer);\n    this.dialogMediaAutoplayTimer = null;\n  }\n\n  startDialogMediaAutoplay(media, previousButton, nextButton) {\n    this.stopDialogMediaAutoplay();\n    if (!media || media.children.length < 2 || this.reducedMotionQuery?.matches) return;\n\n    this.dialogMediaAutoplayTimer = window.setInterval(() => {\n      if (!this.productDialog || this.productDialog.hidden || document.hidden || !media.clientWidth) return;\n\n      const itemCount = media.children.length;\n      const currentIndex = Math.round(media.scrollLeft / media.clientWidth);\n      if (currentIndex >= itemCount - 1) this.dialogMediaAutoplayDirection = -1;\n      if (currentIndex <= 0) this.dialogMediaAutoplayDirection = 1;\n\n      const nextIndex = Math.max(\n        0,\n        Math.min(itemCount - 1, currentIndex + this.dialogMediaAutoplayDirection)\n      );\n      media.scrollTo({\n        left: nextIndex * media.clientWidth,\n        behavior: 'smooth'\n      });\n      this.syncMediaNavigation(media, previousButton, nextButton);\n    }, 3800);\n  }\n\n  openConfirmDialog() {\n    if (!this.confirmDialog || this.getComboUnitCount() < this.minimumItems) return;\n\n    const items = this.confirmDialog.querySelector('[data-combo-confirm-items]');\n    const saving = this.confirmDialog.querySelector('[data-combo-confirm-saving]');\n    const total = this.confirmDialog.querySelector('[data-combo-confirm-total]');\n    const subtotal = this.getComboSubtotal();\n    const discountAmount = Math.round((subtotal * this.discountPercentage) / 100);\n    this.trackCroEvent('confirm_opened', {\n      subtotal,\n      discount_amount: discountAmount\n    });\n\n    if (items) {\n      items.innerHTML = '';\n      this.combo.forEach(item => {\n        const row = document.createElement('div');\n        row.className = 'combo-confirm-item';\n\n        const image = document.createElement('img');\n        image.src = item.image;\n        image.alt = item.title;\n        image.width = 48;\n        image.height = 48;\n\n        const copy = document.createElement('div');\n        const name = document.createElement('strong');\n        const price = document.createElement('span');\n        name.textContent = item.title;\n        price.textContent = `Qty ${item.quantity || 1} \u00B7 ${this.formatMoney(item.price * Number(item.quantity || 1))}`;\n        copy.append(name, price);\n        row.append(image, copy);\n        items.appendChild(row);\n      });\n    }\n\n    if (saving) {\n      saving.textContent = `${this.discountPercentage}% unlocked \u00B7 You save ${this.formatMoney(discountAmount)}`;\n    }\n    if (total) total.textContent = this.formatMoney(subtotal - discountAmount);\n    this.openOverlay(this.confirmDialog);\n  }\n\n  openOverlay(overlay) {\n    if (!overlay) return;\n    overlay.hidden = false;\n    document.body.classList.add('combo-overlay-open');\n    requestAnimationFrame(() => overlay.classList.add('is-open'));\n    overlay.querySelector('.combo-overlay__close')?.focus({ preventScroll: true });\n  }\n\n  closeOverlay(overlay) {\n    if (!overlay || overlay.hidden) return;\n    if (overlay === this.productDialog) this.stopDialogMediaAutoplay();\n    overlay.classList.remove('is-open');\n    setTimeout(() => {\n      overlay.hidden = true;\n      if (![this.productDialog, this.confirmDialog].some(item => item && !item.hidden)) {\n        document.body.classList.remove('combo-overlay-open');\n      }\n      this.lastDialogTrigger?.focus?.({ preventScroll: true });\n    }, 180);\n  }\n\n  filterCuratedCategory(category = 'all') {\n    this.activeCuratedCategory = category;\n    this.applyCroDiscovery();\n  }\n\n  syncAddToBoxButtons(scope = document) {\n    scope.querySelectorAll('.js-atb-btn').forEach(btn => {\n      const selectedItem = this.combo.find(item => item.variantId === btn.dataset.variantId);\n      const isAdded = Boolean(selectedItem);\n      btn.classList.toggle('is-added', isAdded);\n      btn.textContent = isAdded\n        ? `Added${selectedItem?.quantity > 1 ? ` \u00B7 Qty ${selectedItem.quantity}` : ''}`\n        : 'Add to combo';\n      const quantityControl = btn.closest('.combo-card-wrapper')?.querySelector('[data-combo-quantity]');\n      if (quantityControl) this.syncQuantityControl(quantityControl, selectedItem?.quantity || Number(btn.dataset.quantity || 1));\n      const title = btn.dataset.title || 'product';\n      btn.setAttribute('aria-label', isAdded ? `Remove ${title} from combo` : `Add ${title} to combo`);\n    });\n  }\n\n  parseComboAjaxPayload(html) {\n    const shell = document.createElement('template');\n    shell.innerHTML = html;\n    const root = shell.content;\n    const cardTemplates = Array.from(root.querySelectorAll('template[data-combo-card-template]'));\n    const directCards = cardTemplates.length\n      ? []\n      : Array.from(root.querySelectorAll('.combo-card-wrapper'));\n    return {\n      root,\n      cardTemplates,\n      directCards,\n      meta: root.querySelector('.combo-ajax-meta'),\n      facetsPayload: root.querySelector('#combo-facets-payload')\n    };\n  }\n\r\n  buildLoadMoreUrl(tier, nextPage, overrideParams = null) {\r\n    const collectionHandle = tier.dataset.collectionHandle;\r\n    const sentinel = tier.querySelector('.js-infinite-sentinel');\r\n    const isBreadcrumbFilter = sentinel && sentinel._isBreadcrumbFilter === true;\r\n    const tagFilter = isBreadcrumbFilter ? '' : tier.dataset.tagFilter;\r\n\r\n    if (!collectionHandle) return '';\r\n\r\n    let path = `/collections/${collectionHandle}`;\r\n\r\n    if (tagFilter) {\r\n      path += `/${encodeURIComponent(tagFilter)}`;\r\n    }\r\n\r\n    let searchParams = '';\r\n    if (overrideParams !== null) {\r\n      // Use explicitly provided params (e.g. from a clear-filter link href)\r\n      searchParams = overrideParams;\r\n    } else if (!isBreadcrumbFilter) {\r\n      // Read from the facet form inputs\r\n      const facetForm = tier.querySelector('aside.facets-wrapper facet-filters-form form');\r\n      if (facetForm) {\r\n        searchParams = new URLSearchParams(new FormData(facetForm)).toString();\r\n      }\r\n    }\r\n\r\n    const separator = searchParams ? '&' : '';\r\n    return `${path}?view=combo-products-cro&page=${nextPage}${separator}${searchParams}`;\n  }\r\n\r\n  setupInfiniteScroll() {\r\n    const options = {\r\n      root: null,\r\n      rootMargin: '0px 0px 300px 0px', // Trigger 300px before sentinel enters viewport\r\n      threshold: 0\r\n    };\r\n\r\n    this.sentinelObserver = new IntersectionObserver((entries) => {\n      entries.forEach(entry => {\n        if (!entry.isIntersecting) return;\n        const sentinel = entry.target;\n        if (sentinel.dataset.hydrating === 'true') return;\n        if (sentinel.dataset.allLoaded === 'true') return;\n        if (sentinel.dataset.loading === 'true') return;\n        if (this.mobileProgressiveCatalogEnabled && sentinel.dataset.catalogHydrated === 'true') {\n          this.renderNextMobileCatalogBatch(sentinel.closest('.js-combo-tier'));\n          return;\n        }\n        this.loadMoreForSentinel(sentinel);\n      });\n    }, options);\r\n\r\n    document.querySelectorAll('.js-infinite-sentinel').forEach(sentinel => {\n      if (this.mobileProgressiveCatalogEnabled && sentinel.dataset.catalogHydrated !== 'true') return;\n      if (sentinel.dataset.allLoaded !== 'true') {\n        this.sentinelObserver.observe(sentinel);\n      }\r\n    });\n  }\n\n  async hydrateAllTierProducts() {\n    return Promise.all(\n      Array.from(document.querySelectorAll('.js-combo-tier')).map(tier => this.hydrateTierProducts(tier))\n    );\n  }\n\n  async hydrateTierProducts(tier) {\n    if (!tier) return false;\n    const mobileCatalog = this.mobileProgressiveCatalogEnabled\n      ? this.getMobileProductCatalog(tier)\n      : null;\n    if (mobileCatalog?.hydrated) return true;\n    const existingPromise = this.tierHydrationPromises.get(tier);\n    if (existingPromise) return existingPromise;\n\n    const hydrationPromise = (async () => {\n      const sentinel = tier.querySelector('.js-infinite-sentinel');\n      if (!sentinel) return false;\n\n      sentinel.dataset.hydrating = 'true';\n      if (this.mobileProgressiveCatalogEnabled) sentinel.dataset.catalogAllLoaded = 'false';\n      this.sentinelObserver?.unobserve(sentinel);\n      let completed = true;\n\n      try {\n        for (let pageGuard = 0; pageGuard < 100; pageGuard += 1) {\n          const allCatalogProductsLoaded = this.mobileProgressiveCatalogEnabled\n            ? sentinel.dataset.catalogAllLoaded === 'true'\n            : sentinel.dataset.allLoaded === 'true';\n          if (allCatalogProductsLoaded) break;\n          const loaded = await this.loadMoreForSentinel(sentinel);\n          if (!loaded) {\n            completed = false;\n            break;\n          }\n        }\n      } finally {\n        delete sentinel.dataset.hydrating;\n      }\n\n      if (mobileCatalog) {\n        mobileCatalog.hydrated = completed && sentinel.dataset.catalogAllLoaded === 'true';\n        sentinel.dataset.catalogHydrated = mobileCatalog.hydrated ? 'true' : 'false';\n      }\n      this.updateCategoryCounts();\n      this.applyCroDiscovery();\n      if (mobileCatalog?.hydrated) this.updateMobileCatalogSentinel(tier);\n      return completed;\n    })();\n\n    this.tierHydrationPromises.set(tier, hydrationPromise);\n    try {\n      return await hydrationPromise;\n    } finally {\n      this.tierHydrationPromises.delete(tier);\n    }\n  }\n\n  async loadMoreForSentinel(sentinel, isReset = false) {\n    const tier = sentinel.closest('.js-combo-tier');\n    const grid = tier?.querySelector('.js-combo-grid');\n    const nextPage = isReset ? 1 : parseInt(sentinel.dataset.nextPage || '2', 10);\n\n    if (!tier || !grid) return false;\n\n    const mobileCatalog = this.mobileProgressiveCatalogEnabled\n      ? this.getMobileProductCatalog(tier)\n      : null;\n    if (mobileCatalog?.hydrated && !isReset && sentinel.dataset.hydrating !== 'true') {\n      return this.renderNextMobileCatalogBatch(tier);\n    }\n\r\n    sentinel.dataset.loading = 'true';\r\n    sentinel.classList.add('is-loading');\r\n\r\n    if (isReset) {\n      grid.classList.add('is-loading-grid');\n      if (mobileCatalog) {\n        mobileCatalog.records = [];\n        mobileCatalog.recordsByHandle.clear();\n        mobileCatalog.filteredRecords = [];\n        mobileCatalog.renderedCount = 0;\n        mobileCatalog.hydrated = false;\n        sentinel.dataset.catalogHydrated = 'false';\n        sentinel.dataset.catalogAllLoaded = 'false';\n      }\n    }\n\r\n    const requestUrl = this.buildLoadMoreUrl(tier, nextPage, sentinel._clearParams ?? null);\n    delete sentinel._clearParams; // Clear after use so subsequent loads read from form\n    if (!requestUrl) {\n      sentinel.dataset.allLoaded = 'true';\n      sentinel.dataset.loading = 'false';\n      sentinel.classList.remove('is-loading');\n      grid.classList.remove('is-loading-grid');\n      this.sentinelObserver?.unobserve(sentinel);\n      return true;\n    }\r\n\r\n    const requestController = typeof AbortController === 'function' ? new AbortController() : null;\n    const requestTimeout = requestController\n      ? window.setTimeout(() => requestController.abort(), this.productRequestTimeoutMs)\n      : null;\n\n    try {\n      const response = await fetch(requestUrl, {\n        headers: { 'X-Requested-With': 'XMLHttpRequest' },\n        signal: requestController?.signal\n      });\n\r\n      if (!response.ok) throw new Error('Failed to load more combo products.');\n\n      const html = await response.text();\n      if (this.destroyed) return false;\n      const payload = this.parseComboAjaxPayload(html);\n      const { cardTemplates, directCards, meta, facetsPayload } = payload;\n      const hasMore = meta?.dataset.hasMore === 'true';\n\r\n      // Inject real filters from collection AJAX response (filters only available on collection URLs)\r\n      if (facetsPayload && isReset) {\n        const asideWrapper = tier.querySelector('aside.facets-wrapper');\n        if (asideWrapper) {\n          const blockId = tier.dataset.tierId || tier.id || 'combo-tier';\n          let asideHtml = facetsPayload.innerHTML;\n          asideHtml = asideHtml.replace(/FacetFiltersForm/g, 'FacetFiltersForm-' + blockId);\n          asideHtml = asideHtml.replace(/SortBy/g, 'SortBy-' + blockId);\n          asideWrapper.innerHTML = asideHtml;\n          this.setupFilterListeners();\n        }\n      }\n\r\n      if (isReset) {\n        grid.innerHTML = '';\n        grid.classList.remove('is-loading-grid');\n      }\n\n      if (mobileCatalog) {\n        cardTemplates.forEach(cardTemplate => {\n          const card = cardTemplate.content.querySelector('.combo-card-wrapper');\n          if (card) this.addMobileCatalogCard(mobileCatalog, card, cardTemplate.innerHTML);\n        });\n        directCards.forEach(card => this.addMobileCatalogCard(mobileCatalog, card, card.outerHTML));\n      } else {\n        const cards = cardTemplates.length\n          ? cardTemplates.map(cardTemplate => cardTemplate.content.querySelector('.combo-card-wrapper')).filter(Boolean)\n          : directCards;\n        const existingHandles = new Set(Array.from(grid.querySelectorAll('.combo-card-wrapper')).map(card => {\n          return card.dataset.comboProductHandle;\n        }));\n        const fragment = document.createDocumentFragment();\n        cards.forEach(card => {\n          const handle = card.dataset.comboProductHandle;\n          if (handle && existingHandles.has(handle)) return;\n          if (handle) existingHandles.add(handle);\n          fragment.appendChild(card);\n        });\n        grid.appendChild(fragment);\n        this.bindAtbButtons(grid);\n        this.bindProductCardEnhancements(grid);\n        this.syncAddToBoxButtons(grid);\n        this.updateCategoryCounts();\n      }\n\n      const loadedProductCount = mobileCatalog\n        ? mobileCatalog.records.length\n        : grid.querySelectorAll('.combo-card-wrapper').length;\n      if (!hasMore && loadedProductCount === 0) {\n        grid.innerHTML = '<p class=\"combo-no-results\">No products found matching these filters.</p>';\n        grid.classList.remove('is-loading-grid');\n      }\n\n      if (!this.mobileProgressiveCatalogEnabled || sentinel.dataset.hydrating !== 'true') {\n        this.filterCuratedCategory(this.activeCuratedCategory);\n      }\n\n      if (hasMore) {\n        sentinel.dataset.nextPage = String(nextPage + 1);\n        sentinel.dataset.loading = 'false';\n        sentinel.classList.remove('is-loading');\n        if (mobileCatalog) {\n          sentinel.dataset.catalogAllLoaded = 'false';\n        } else {\n          sentinel.dataset.allLoaded = 'false';\n          this.sentinelObserver?.observe(sentinel);\n        }\n      } else {\n        sentinel.dataset.loading = 'false';\n        sentinel.classList.remove('is-loading');\n        if (mobileCatalog) {\n          sentinel.dataset.catalogAllLoaded = 'true';\n        } else {\n          sentinel.dataset.allLoaded = 'true';\n          this.sentinelObserver?.unobserve(sentinel);\n        }\n      }\n      return true;\n    } catch (error) {\n      console.error(error);\n      sentinel.dataset.loading = 'false';\r\n      sentinel.classList.remove('is-loading');\n      if (isReset) grid.classList.remove('is-loading-grid');\n      this.showCroStatus('We could not load more products. Your selections are safe.', () => this.loadMoreForSentinel(sentinel, isReset));\n      return false;\n    } finally {\n      if (requestTimeout) window.clearTimeout(requestTimeout);\n    }\n  }\n\r\n  // Fetch filter HTML from the collection directly to get exact Swatches and Settings\r\n  async loadFiltersForTier(tier) {\r\n    const collectionHandle = tier.dataset.collectionHandle;\r\n    const blockId = tier.dataset.tierId || tier.id || Math.random().toString(36).substr(2, 9);\r\n    if (!collectionHandle) return;\r\n    const asideWrapper = tier.querySelector('aside.facets-wrapper');\r\n    if (!asideWrapper) return;\r\n\r\n    try {\r\n      const url = `/collections/${encodeURIComponent(collectionHandle)}?view=combo-products-cro&page=1`;\n      const response = await fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });\n      if (!response.ok) return;\n      const html = await response.text();\n      const doc = new DOMParser().parseFromString(html, 'text/html');\n\n      const facetsPayload = doc.getElementById('combo-facets-payload');\n      if (facetsPayload) {\n        // Prevent ID collisions since we might load multiple tiers\n        let asideHtml = facetsPayload.innerHTML;\n        asideHtml = asideHtml.replace(/FacetFiltersForm/g, 'FacetFiltersForm-' + blockId);\r\n        asideHtml = asideHtml.replace(/SortBy/g, 'SortBy-' + blockId);\r\n\r\n        asideWrapper.innerHTML = asideHtml;\r\n        this.setupFilterListeners();\r\n      }\r\n    } catch (e) {\r\n      console.warn('Could not load filters for tier:', collectionHandle, e);\r\n    }\r\n  }\r\n\r\n  setupFilterListeners() {\n    const self = this;\n    const filterDebounce = this.debounce(async (tier) => {\n      const sentinel = tier.querySelector('.js-infinite-sentinel');\n      if (!sentinel) return;\n      sentinel.dataset.nextPage = '1';\n      sentinel.dataset.allLoaded = 'false';\n      const refreshed = await self.loadMoreForSentinel(sentinel, true);\n      if (refreshed) await self.hydrateTierProducts(tier);\n    }, 500);\n\r\n    document.querySelectorAll('.js-combo-tier').forEach(tier => {\r\n      // Target facet form inside the standard aside.facets-wrapper\n      const facetForm = tier.querySelector('aside.facets-wrapper facet-filters-form');\n      if (facetForm && facetForm.dataset.comboFilterBound !== 'true') {\n        facetForm.dataset.comboFilterBound = 'true';\n        facetForm.addEventListener('input', () => filterDebounce(tier));\n        const sortSelect = facetForm.querySelector('select[name=\"sort_by\"]');\r\n        if (sortSelect) {\r\n          sortSelect.addEventListener('change', () => filterDebounce(tier));\r\n        }\r\n      }\r\n    });\r\n\r\n    // Handle facet-remove (\u00D7 on active filter chip) and Clear all\r\n    if (!this.comboFacetClearBound) {\n      this.comboFacetClearBound = true;\n      this.addManagedListener(document, 'click', async (e) => {\n        const clearLink = e.target.closest('facet-remove a, a.active-facets__button--clear');\n        if (clearLink && clearLink.closest('.js-combo-tier')) {\n          e.preventDefault();\n          const tier = clearLink.closest('.js-combo-tier');\n          const sentinel = tier.querySelector('.js-infinite-sentinel');\n          if (!sentinel) return;\n\n          const href = clearLink.getAttribute('href') || '';\n          const hrefSearch = href.includes('?') ? href.split('?')[1] : '';\n          const cleanParams = new URLSearchParams(hrefSearch);\n          cleanParams.delete('view');\n          cleanParams.delete('page');\n\n          sentinel.dataset.nextPage = '1';\n          sentinel.dataset.allLoaded = 'false';\n          sentinel._clearParams = cleanParams.toString();\n          const refreshed = await this.loadMoreForSentinel(sentinel, true);\n          if (refreshed) await this.hydrateTierProducts(tier);\n        }\n      });\n    }\n  }\n\r\n  debounce(fn, wait) {\r\n    let timeout;\r\n    return (...args) => {\r\n      clearTimeout(timeout);\r\n      timeout = setTimeout(() => fn.apply(this, args), wait);\r\n    };\r\n  }\r\n\r\n  getTierById(tierId) {\r\n    return document.querySelector(`.js-combo-tier[data-tier-id=\"${tierId}\"]`);\r\n  }\r\n\r\n  getActiveTierElement() {\r\n    if (this.currentTierId) {\r\n      return this.getTierById(this.currentTierId);\r\n    }\r\n\r\n    return document.querySelector('.js-combo-tier.is-active') || document.querySelector('.js-combo-tier');\r\n  }\r\n\r\n  applyTierSettings(tier) {\r\n    if (!tier) return;\r\n\r\n    const maxSlots = parseInt(tier.dataset.maxSlots || '3', 10);\r\n    const minimumItems = parseInt(tier.dataset.minItems || '3', 10);\r\n    const discountPercentage = parseFloat(tier.dataset.discountPercentage || '20');\r\n    const tierPrice = parseInt(tier.dataset.tierPrice || '0', 10);\r\n\r\n    this.maxSlots = Number.isFinite(maxSlots) && maxSlots > 0 ? maxSlots : 3;\r\n    this.minimumItems = Number.isFinite(minimumItems) && minimumItems > 0\r\n      ? Math.min(minimumItems, this.maxSlots)\r\n      : Math.min(3, this.maxSlots);\r\n    this.discountPercentage = Number.isFinite(discountPercentage) && discountPercentage > 0 ? discountPercentage : 20;\r\n    this.tierPrice = Number.isFinite(tierPrice) ? tierPrice : 0;\r\n    this.discountCode = tier.dataset.discountCode || '';\r\n  }\r\n\r\n  handleTabClick(tab) {\r\n    if (tab.disabled) return;\r\n    const targetId = tab.dataset.target;\r\n\r\n    document.querySelectorAll('.js-tier-tab').forEach(t => t.classList.remove('is-active'));\r\n    tab.classList.add('is-active');\r\n\r\n    const targetTier = this.getTierById(targetId);\r\n    document.querySelectorAll('.js-combo-tier').forEach(tier => {\r\n      if (tier.dataset.tierId === targetId) {\r\n        tier.classList.add('is-active');\r\n      } else {\r\n        tier.classList.remove('is-active');\r\n      }\r\n    });\r\n\r\n    if (!this.currentTierId || this.currentTierId === targetId) {\r\n      this.applyTierSettings(targetTier);\r\n      this.updateUI();\r\n    }\r\n  }\r\n\r\n  async handleAtbClick(btn) {\n    if (this.isCartMutating) return false;\n    await this.syncWithCart();\n    const tier = btn.closest('.combo-tier');\n    if (!tier) return false;\n    const tierId = tier.dataset.tierId;\n    const variantId = btn.dataset.variantId;\n\n    const productId = btn.dataset.productId;\n    const price = parseInt(btn.dataset.price, 10);\n    const image = btn.dataset.image;\n    const title = btn.dataset.title;\n    const handle = btn.dataset.handle;\n    const quantity = Math.min(Math.max(Number.parseInt(btn.dataset.quantity || '1', 10), 1), 10);\n\r\n    const index = this.combo.findIndex(item => item.variantId === variantId);\r\n\r\n    if (index > -1) {\r\n      const removedItem = this.combo[index];\r\n      this.combo.splice(index, 1);\n      btn.classList.remove('is-added');\n      btn.textContent = 'Add to combo';\n      if (this.combo.length === 0) this.currentTierId = null;\r\n      this.adjustGlobalCartCount(-Number(removedItem.quantity || 1));\n      this.updateUI();\r\n\r\n      try {\n        this.isCartMutating = true;\n        const updatedCart = await this.changeCartLineQuantity(removedItem, 0);\n        this.applyCartState(updatedCart);\n        this.emitCartUpdated(updatedCart);\n        this.clearCroStatus();\n        this.trackCroEvent('selection_removed', { product_handle: handle });\n        return true;\n      } catch (error) {\n        console.error(error);\n        await this.syncWithCart();\n        this.trackCroEvent('remove_failed', { product_handle: handle });\n        this.showCroStatus('We could not remove this product. Your combo is unchanged.', () => this.handleAtbClick(btn));\n        return false;\n      } finally {\n        this.isCartMutating = false;\n      }\n    } else {\r\n      this.applyTierSettings(tier);\r\n      const tierSlots = this.maxSlots;\n      const selectedUnits = this.getComboUnitCount();\n\r\n      if (selectedUnits + quantity <= tierSlots) {\n        const wasEligibleForDiscount = selectedUnits >= this.minimumItems;\n        btn.disabled = true;\n        btn.textContent = 'Adding...';\n\r\n        try {\r\n          this.currentTierId = tierId;\n          this.isCartMutating = true;\n          const addedItem = { productId, variantId, price, image, title, handle, tierId, groupId: 'kp-primary-combo', quantity, key: null };\n          this.combo.push(addedItem);\n          btn.classList.add('is-added');\n          btn.textContent = 'Added to combo';\n          this.adjustGlobalCartCount(quantity);\n          this.updateUI();\r\n\r\n          const updatedCart = await this.addComboItemToCart(addedItem);\n          this.applyCartState(updatedCart);\n          this.emitCartUpdated(updatedCart);\n          if (!wasEligibleForDiscount && this.getComboUnitCount() >= this.minimumItems) {\n            const eligibleSubtotal = this.getComboSubtotal();\n            const unlockedSavings = Math.round((eligibleSubtotal * this.discountPercentage) / 100);\n            this.showComboCelebration(unlockedSavings);\n          }\n          this.clearCroStatus();\n          this.trackCroEvent('selection_added', {\n            product_handle: handle,\n            discount_unlocked: this.getComboUnitCount() >= this.minimumItems,\n            quantity\n          });\n          return true;\n        } catch (e) {\n          console.error(e);\n          await this.syncWithCart();\n          this.trackCroEvent('add_failed', { product_handle: handle });\n          this.showCroStatus('We could not add this product. Your previous selections are safe.', () => this.handleAtbClick(btn));\n          return false;\n        } finally {\n          this.isCartMutating = false;\n          btn.disabled = false;\n        }\n      } else {\n        const availableUnits = Math.max(tierSlots - selectedUnits, 0);\n        this.showCroStatus(availableUnits > 0\n          ? `Only ${availableUnits} more ${availableUnits === 1 ? 'item fits' : 'items fit'} in this combo. Reduce the quantity to continue.`\n          : `This combo can include up to ${tierSlots} items. Remove one to choose another.`);\n        return false;\n      }\n    }\n    return false;\n  }\n\n  showComboCelebration(savingsAmount) {\n    if (!this.celebration || !this.celebrationAmount || savingsAmount <= 0) return;\n\n    window.clearTimeout(this.celebrationTimer);\n    if (this.savingsAnimationFrame) {\n      window.cancelAnimationFrame(this.savingsAnimationFrame);\n      this.savingsAnimationFrame = null;\n    }\n\n    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n    this.buildConfetti(reducedMotion ? 0 : 30);\n    this.celebrationAmount.textContent = reducedMotion ? this.formatMoney(savingsAmount) : this.formatMoney(0);\n    this.celebration.hidden = false;\n    this.celebration.classList.remove('is-active');\n    void this.celebration.offsetWidth;\n    this.celebration.classList.add('is-active');\n\n    if (!reducedMotion) this.animateSavingsAmount(savingsAmount);\n\n    this.celebrationTimer = window.setTimeout(() => {\n      this.celebration.classList.remove('is-active');\n      window.setTimeout(() => {\n        this.celebration.hidden = true;\n        if (this.confettiContainer) this.confettiContainer.innerHTML = '';\n      }, reducedMotion ? 0 : 220);\n    }, reducedMotion ? 1800 : 2700);\n  }\n\n  animateSavingsAmount(savingsAmount) {\n    const startedAt = window.performance.now();\n    const duration = 900;\n\n    const updateAmount = now => {\n      const progress = Math.min((now - startedAt) / duration, 1);\n      const easedProgress = 1 - Math.pow(1 - progress, 3);\n      this.celebrationAmount.textContent = this.formatMoney(Math.round(savingsAmount * easedProgress));\n\n      if (progress < 1) {\n        this.savingsAnimationFrame = window.requestAnimationFrame(updateAmount);\n      } else {\n        this.savingsAnimationFrame = null;\n      }\n    };\n\n    this.savingsAnimationFrame = window.requestAnimationFrame(updateAmount);\n  }\n\n  buildConfetti(pieceCount) {\n    if (!this.confettiContainer) return;\n    this.confettiContainer.innerHTML = '';\n    const colors = ['#c8a24a', '#543e3a', '#2d7a45', '#b86f52', '#f1d89a'];\n\n    for (let index = 0; index < pieceCount; index += 1) {\n      const piece = document.createElement('span');\n      const angle = (Math.PI * 2 * index) / pieceCount + (Math.random() * 0.35);\n      const distance = 120 + (Math.random() * 150);\n      const x = Math.cos(angle) * distance;\n      const y = (Math.sin(angle) * distance) + 70;\n      piece.className = index % 3 === 0 ? 'combo-confetti-piece is-round' : 'combo-confetti-piece';\n      piece.style.setProperty('--confetti-x', `${x.toFixed(1)}px`);\n      piece.style.setProperty('--confetti-y', `${y.toFixed(1)}px`);\n      piece.style.setProperty('--confetti-rotation', `${Math.round(360 + (Math.random() * 620))}deg`);\n      piece.style.setProperty('--confetti-delay', `${Math.round(Math.random() * 120)}ms`);\n      piece.style.backgroundColor = colors[index % colors.length];\n      this.confettiContainer.appendChild(piece);\n    }\n  }\n\n  updateUI() {\n    const tierOnPage = document.querySelector('.js-combo-tier');\n    const filteredCombo = this.combo;\n    const filteredUnits = this.getComboUnitCount(filteredCombo);\n\r\n    // Apply tier settings from current page if possible\r\n    if (tierOnPage) {\r\n       this.applyTierSettings(tierOnPage);\r\n    }\r\n\r\n    document.querySelectorAll('.combo-tier').forEach(tier => {\r\n      if (this.currentTierId && tier.dataset.tierId !== this.currentTierId) {\r\n        tier.classList.add('is-disabled');\r\n      } else {\r\n        tier.classList.remove('is-disabled');\r\n      }\r\n    });\r\n\r\n    document.querySelectorAll('.js-tier-tab').forEach(tab => {\r\n      if (this.currentTierId && tab.dataset.target !== this.currentTierId) {\r\n        tab.disabled = true;\r\n      } else {\r\n        tab.disabled = false;\r\n      }\r\n    });\r\n\r\n    this.syncAddToBoxButtons();\r\n    \r\n    // Safety check for slotsContainer (important for PDP)\r\n    if (this.slotsContainer) {\n      this.slotsContainer.innerHTML = '';\n      filteredCombo.forEach(item => {\n        const slot = document.createElement('div');\n        slot.className = 'combo-slot';\n\n        slot.innerHTML = `\n          <img src=\"${item.image}\" alt=\"${item.title}\">\n          ${item.quantity > 1 ? `<span class=\"combo-slot__quantity\">\u00D7${item.quantity}</span>` : ''}\n          <button type=\"button\" class=\"combo-slot__remove\" data-variant-id=\"${item.variantId}\" aria-label=\"Remove ${item.title}\">\u00D7</button>\n        `;\n        slot.querySelector('.combo-slot__remove').addEventListener('click', (e) => {\n          this.removeItem(e.target.dataset.variantId);\n        });\n        this.slotsContainer.appendChild(slot);\n      });\n\n      for (let i = filteredUnits; i < this.maxSlots; i++) {\n        const slot = document.createElement('div');\n        slot.className = 'combo-slot combo-slot--empty';\n        slot.innerHTML = `<span class=\"add-piece\">ADD<br>Item ${i + 1}</span>`;\n        this.slotsContainer.appendChild(slot);\n      }\n    }\n\n    const subtotal = this.getComboSubtotal(filteredCombo);\n    const qualifiesForDiscount = filteredUnits >= this.minimumItems;\n    const discountAmount = qualifiesForDiscount\n      ? Math.round((subtotal * this.discountPercentage) / 100)\n      : 0;\n    const potentialSaving = Math.round((subtotal * this.discountPercentage) / 100);\n    const finalPriceToDisplay = subtotal - discountAmount;\n    const totalRow = document.querySelector('.js-total-row');\n    const offerNote = document.querySelector('.js-combo-offer-note');\n\n    if (this.summaryCountEl) {\n      this.summaryCountEl.textContent = qualifiesForDiscount\n        ? `Your Combo: ${filteredUnits} items selected`\n        : `Your Combo: ${filteredUnits} of ${this.minimumItems} items selected`;\n    }\n    if (this.summaryMessageEl) {\n      if (qualifiesForDiscount) {\n        this.summaryMessageEl.textContent = `${this.discountPercentage}% unlocked`;\n      } else {\n        const remaining = Math.max(this.minimumItems - filteredUnits, 0);\n        this.summaryMessageEl.textContent = `Add ${remaining} more to unlock ${this.discountPercentage}% off`;\n      }\n    }\n\n    if (this.potentialEl) {\n      this.potentialEl.hidden = qualifiesForDiscount || filteredUnits === 0;\n    }\n    if (this.potentialSubtotalEl) {\n      this.potentialSubtotalEl.textContent = this.formatMoney(subtotal);\n    }\n    if (this.potentialSavingEl) {\n      this.potentialSavingEl.textContent = this.formatMoney(potentialSaving);\n    }\n    this.renderSelectionPanel(filteredCombo);\n    this.updateRecommendations();\n\n    this.updateProgress(subtotal, qualifiesForDiscount);\n\n    if (qualifiesForDiscount) {\n      const formattedPrice = this.formatMoney(finalPriceToDisplay);\n      const formattedSubtotal = this.formatMoney(subtotal);\n      const formattedSavings = this.formatMoney(discountAmount);\n      if (this.totalPriceEl) {\n        this.totalPriceEl.textContent = formattedPrice;\n      }\n      if (this.totalLabelEl) {\n        this.totalLabelEl.textContent = this.isMobileViewport()\n          ? 'Total'\n          : `Total (${this.discountPercentage}% OFF) -`;\n      }\n      if (this.totalCompareEl) {\n        this.totalCompareEl.textContent = formattedSubtotal;\n        this.totalCompareEl.removeAttribute('hidden');\n      }\n      if (this.totalSavingEl) {\n        this.totalSavingEl.textContent = `Save ${formattedSavings}`;\n        this.totalSavingEl.removeAttribute('hidden');\n      }\n      if (totalRow) totalRow.style.display = 'flex';\r\n      if (this.checkoutBtn) {\n        this.checkoutBtn.disabled = false;\n        this.checkoutBtn.textContent = 'VIEW COMBO IN CART';\n      }\n      if (offerNote) {\n        offerNote.textContent = [\n          `${this.discountPercentage}% instant discount unlocked.`,\n          this.activeOfferExpiryCopy ? `${this.activeOfferExpiryCopy}.` : ''\n        ].filter(Boolean).join(' ');\n      }\n\r\n      // Save discount state for cart popup banner\r\n      sessionStorage.setItem('comboDiscount', JSON.stringify({\r\n        subtotal,\r\n        discountAmount,\r\n        finalPrice: finalPriceToDisplay,\r\n        discountPercentage: this.discountPercentage\r\n      }));\r\n      this.injectComboDiscountBanner();\r\n    } else {\n      if (this.totalPriceEl) this.totalPriceEl.textContent = '---';\n      if (this.totalLabelEl) this.totalLabelEl.textContent = 'Total -';\n      if (this.totalCompareEl) {\n        this.totalCompareEl.textContent = '';\n        this.totalCompareEl.setAttribute('hidden', '');\n      }\n      if (this.totalSavingEl) {\n        this.totalSavingEl.textContent = '';\n        this.totalSavingEl.setAttribute('hidden', '');\n      }\n      if (totalRow) totalRow.style.display = 'none';\n      if (this.checkoutBtn) {\n        this.checkoutBtn.disabled = false;\n        this.checkoutBtn.textContent = this.buildDisabledCtaLabel();\n      }\n      if (offerNote) {\n        const remaining = Math.max(this.minimumItems - filteredUnits, 0);\n        offerNote.textContent = remaining === this.minimumItems\n          ? `Add ${this.minimumItems} products across categories to unlock ${this.discountPercentage}% instant discount.`\n          : `Add ${remaining} more product${remaining === 1 ? '' : 's'} to unlock ${this.discountPercentage}% instant discount.`;\n      }\n\r\n      // Clear discount state\r\n      sessionStorage.removeItem('comboDiscount');\r\n      this.injectComboDiscountBanner();\r\n    }\r\n\r\n    if (this.footer) {\n      if (filteredUnits > 0) {\n        this.footer.classList.add('is-visible');\n      } else {\n        this.footer.classList.remove('is-visible');\n      }\n      document.body.classList.toggle('combo-footer-visible', filteredUnits > 0);\n    }\n  }\r\n\r\n  watchCartForComboDiscount() {\n    const self = this;\r\n\r\n    // Watch product list area \u2013 fires when generateCart() re-renders items\r\n    const cartContent = document.querySelector('.js-mini-cart-content');\n    if (cartContent) {\n      const cartContentObserver = this.addManagedObserver(new MutationObserver(() => {\n        requestAnimationFrame(() => {\n          self.injectComboDiscountBanner();\n          self.scheduleCartSync();\n        });\n      }));\n      cartContentObserver.observe(cartContent, { childList: true });\n    }\n\r\n    // Watch cart total text \u2013 fires when updateElements() refreshes the price\r\n    const cartTotalEl = document.querySelector('.js-cart-total');\n    if (cartTotalEl) {\n      const cartTotalObserver = this.addManagedObserver(new MutationObserver(() => {\n        requestAnimationFrame(() => {\n          self.injectComboDiscountBanner();\n          if (!cartTotalEl.dataset.comboOverridden) self.scheduleCartSync();\n        });\n      }));\n      cartTotalObserver.observe(cartTotalEl, { childList: true, subtree: true, characterData: true });\n    }\r\n  }\r\n\r\n  injectComboDiscountBanner() {\r\n    // Remove any stale banner first\r\n    document.querySelectorAll('.combo-cart-discount-banner').forEach(el => el.remove());\r\n\r\n    const raw = sessionStorage.getItem('comboDiscount');\r\n    if (!raw) return;\r\n\r\n    const { subtotal, discountAmount, finalPrice, discountPercentage } = JSON.parse(raw);\r\n\r\n    const bottomTotal = document.querySelector('.bottom-total');\r\n    if (!bottomTotal) return;\r\n\r\n    // Override the Shopify-rendered total with discounted price\r\n    const cartTotalEl = document.querySelector('.js-cart-total');\r\n    if (cartTotalEl && !cartTotalEl.dataset.comboOverridden) {\r\n      cartTotalEl.dataset.comboOverridden = 'true';\r\n      cartTotalEl.innerHTML = this.formatMoney(finalPrice);\r\n      setTimeout(() => { delete cartTotalEl.dataset.comboOverridden; }, 100);\r\n    }\r\n\r\n    // Build and inject the banner above the total row\r\n    const banner = document.createElement('div');\r\n    banner.className = 'combo-cart-discount-banner';\r\n    banner.innerHTML = `\r\n      <div class=\"combo-cart-discount-row\">\r\n        <span class=\"combo-cart-badge\">\uD83C\uDF81 COMBO ${discountPercentage}% OFF</span>\r\n        <span class=\"combo-cart-saving\">You save ${this.formatMoney(discountAmount)}</span>\r\n      </div>\r\n      <div class=\"combo-cart-original\">\r\n        Original: <s>${this.formatMoney(subtotal)}</s> \u2192 <strong>${this.formatMoney(finalPrice)}</strong>\r\n      </div>\r\n    `;\r\n    bottomTotal.parentNode.insertBefore(banner, bottomTotal);\r\n  }\r\n\r\n  updateProgress(subtotal, qualifiesForDiscount) {\n    const selectedUnits = this.getComboUnitCount();\n    document.querySelectorAll('.combo-progress-wrapper').forEach(wrapper => {\r\n      const fill = wrapper.querySelector('.combo-progress-fill');\r\n      const text = wrapper.querySelector('.combo-progress-text');\r\n\r\n      if (fill) {\r\n        fill.style.width = '0%';\r\n        fill.style.background = '#228be6';\r\n      }\r\n\r\n      if (text) {\r\n        text.textContent = `Add ${this.minimumItems} items to unlock ${this.discountPercentage}% OFF.`;\r\n      }\r\n    });\r\n\r\n    const activeTier = this.getActiveTierElement();\r\n    if (!activeTier) return;\r\n\r\n    const progressText = activeTier.querySelector('.combo-progress-text');\r\n    const progressFill = activeTier.querySelector('.combo-progress-fill');\r\n    if (!progressText || !progressFill) return;\r\n\r\n    const progressTarget = Math.max(this.minimumItems, 1);\r\n    const percent = Math.min((selectedUnits / progressTarget) * 100, 100);\n    progressFill.style.width = `${percent}%`;\r\n\r\n    if (qualifiesForDiscount) {\r\n      const remainingSlots = Math.max(this.maxSlots - selectedUnits, 0);\n      const extraCopy = remainingSlots > 0\r\n        ? ` Add ${remainingSlots} more item${remainingSlots === 1 ? '' : 's'} and keep the discount.`\r\n        : '';\r\n      progressText.textContent = `${this.discountPercentage}% OFF unlocked on ${this.formatMoney(subtotal)}.${extraCopy}`;\r\n      progressFill.style.background = '#00b84c';\r\n      return;\r\n    }\r\n\r\n    const remainingToUnlock = Math.max(this.minimumItems - selectedUnits, 0);\n    progressText.textContent = `Add ${remainingToUnlock} more item${remainingToUnlock === 1 ? '' : 's'} to unlock ${this.discountPercentage}% OFF.`;\r\n  }\r\n\r\n  buildDisabledCtaLabel() {\n    const selectedUnits = this.getComboUnitCount();\n    const remaining = Math.max(this.minimumItems - selectedUnits, 0);\n\r\n    if (remaining <= 0) {\n      return 'CONFIRM COMBO';\n    }\n\n    if (selectedUnits === 0) {\n      return `CHOOSE ${this.minimumItems} ITEMS`;\n    }\n\n    if (remaining === 1) return 'CHOOSE FINAL PRODUCT';\n    return `CHOOSE ${remaining} MORE`;\n  }\n\n  isMobileViewport() {\n    return window.matchMedia('(max-width: 768px)').matches;\n  }\n\n  async removeItem(variantId) {\n    const index = this.combo.findIndex(item => item.variantId === variantId);\r\n    if (index > -1) {\r\n      const [removedItem] = this.combo.splice(index, 1);\r\n      const btn = document.querySelector(`.js-atb-btn[data-variant-id=\"${variantId}\"]`);\r\n      if (btn) {\n        btn.classList.remove('is-added');\n        btn.textContent = 'Add to combo';\n      }\r\n      if (this.combo.length === 0) this.currentTierId = null;\r\n      this.adjustGlobalCartCount(-Number(removedItem.quantity || 1));\n      this.updateUI();\r\n\r\n      try {\n        this.isCartMutating = true;\n        const updatedCart = await this.changeCartLineQuantity(removedItem, 0);\n        this.applyCartState(updatedCart);\n        this.emitCartUpdated(updatedCart);\n        this.clearCroStatus();\n        this.trackCroEvent('selection_removed', { product_handle: removedItem.handle });\n        return true;\n      } catch (error) {\n        console.error(error);\n        await this.syncWithCart();\n        this.trackCroEvent('remove_failed', { product_handle: removedItem.handle });\n        this.showCroStatus('We could not remove this product. Your combo is unchanged.', () => this.removeItem(variantId));\n        return false;\n      } finally {\n        this.isCartMutating = false;\n      }\n    }\n    return false;\n  }\n\r\n  setGlobalCartCount(itemCount) {\r\n    document.querySelectorAll('.js-cart-count').forEach(el => {\r\n      el.textContent = itemCount;\r\n      el.classList.toggle('hide', itemCount <= 0);\r\n    });\r\n  }\r\n\r\n  adjustGlobalCartCount(delta) {\r\n    const currentCountEl = document.querySelector('.js-cart-count');\r\n    const currentCount = currentCountEl ? parseInt(currentCountEl.textContent || '0', 10) : 0;\r\n    const nextCount = Math.max((Number.isFinite(currentCount) ? currentCount : 0) + delta, 0);\r\n    this.setGlobalCartCount(nextCount);\r\n  }\r\n\r\n  async updateGlobalCartCount() {\r\n    try {\r\n      const res = await fetch('/cart.js');\r\n      const cart = await res.json();\r\n      this.setGlobalCartCount(cart.item_count);\r\n    } catch (e) {\r\n      console.error('Failed to update cart count', e);\r\n    }\r\n  }\r\n\r\n  formatMoney(cents) {\r\n    return '\u20B9' + (cents / 100).toLocaleString('en-IN', {\r\n      minimumFractionDigits: 0,\r\n      maximumFractionDigits: 2\r\n    });\r\n  }\r\n\r\n  async handleCheckout() {\n    if (this.getComboUnitCount() < this.minimumItems) {\n      this.guideToNextProduct();\n      return;\n    }\n\n    this.openComboCart();\n  }\n\n  async openComboCart() {\n    this.checkoutBtn.disabled = true;\n    this.checkoutBtn.textContent = 'OPENING CART...';\n\n    try {\n      if (typeof window.KpOpenCartDrawer !== 'function') {\n        throw new Error('The side cart is not available yet. Please try again.');\n      }\n      await window.KpOpenCartDrawer();\n      this.clearCroStatus();\n    } catch (error) {\n      console.error('Could not open the side cart', error);\n      this.showCroStatus(error.message || 'Could not open the side cart. Please try again.', () => this.openComboCart());\n    }\n\n    window.setTimeout(() => {\n      this.isCheckingOut = false;\n      this.checkoutBtn.disabled = false;\n      this.checkoutBtn.textContent = 'VIEW COMBO IN CART';\n    }, 1200);\n  }\n\n  async completeCheckout() {\n    if (this.getComboUnitCount() < this.minimumItems || this.isCheckingOut) return;\n\n    this.isCheckingOut = true;\n    this.trackCroEvent('combo_confirmed', {\n      subtotal: this.getComboSubtotal()\n    });\n    const confirmButton = this.confirmDialog?.querySelector('[data-combo-confirm-submit]');\n    this.checkoutBtn.disabled = true;\n    this.checkoutBtn.textContent = 'OPENING CART...';\n    if (confirmButton) {\n      confirmButton.disabled = true;\n      confirmButton.textContent = 'Opening cart...';\n    }\n    this.closeOverlay(this.confirmDialog);\n\r\n    await this.openComboCart();\n\r\n    setTimeout(() => {\r\n      this.isCheckingOut = false;\n      this.checkoutBtn.disabled = false;\n      this.checkoutBtn.textContent = 'VIEW COMBO IN CART';\n      if (confirmButton) {\n        confirmButton.disabled = false;\n        confirmButton.textContent = 'Confirm & view cart';\n      }\n    }, 1500);\n  }\n};\n\nvar initializeComboPage = () => {\n  if (!window.comboPage) window.comboPage = new ComboPage();\n};\n\nif (typeof module !== 'undefined' && module.exports) {\n  module.exports = { ComboPage, KPComboPersonalization };\n}\n\nif (typeof document !== 'undefined') {\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', initializeComboPage, { once: true });\n  } else {\n    initializeComboPage();\n  }\n\n  if (window.Shopify?.designMode && !window.__kpComboEditorReloadBound) {\n    window.__kpComboEditorReloadBound = true;\n    document.addEventListener('shopify:section:load', event => {\n      const sectionElement = event.target instanceof Element ? event.target : null;\n      if (!sectionElement?.querySelector('.combo-page--cro')) return;\n      window.comboPage?.destroy?.();\n      window.comboPage = new ComboPage();\n    });\n  }\n}\n"],
  "mappings": "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",
  "names": ["cleanUrl", "response", "visibleCount"]
}
