{
  "version": 3,
  "sources": ["/cdn/shop/t/20/assets/custom.js?mdsv=20260719h"],
  "sourcesContent": ["/*\n  Add here your own custom javascript codes\n*/\ndocument.addEventListener('DOMContentLoaded', function () {\n    const toggleBtn = document.getElementById('toggleKitIdeal');\n    const list = document.getElementById('kitIdealList');\n\n    if(window.location.href.indexOf(\"products\") > -1) {\n    if (!toggleBtn || !list) return\n    toggleBtn.addEventListener('click', function () {\n      list.classList.toggle('expanded');\n      if (list.classList.contains('expanded')) {\n        toggleBtn.textContent = \"Voir moins\";\n      } else {\n        toggleBtn.textContent = \"Voir plus\";\n      }\n  });\n  }\n});\n\n// Product page: move kit manuals/guides above \"Contenu du kit\" on mobile without duplicating markup\n(function () {\n  const MOBILE_MQ = window.matchMedia ? window.matchMedia('(max-width: 1199px)') : null\n\n  function placeKitManualsGuides () {\n    const sections = document.querySelectorAll('.kit-manuals-guides--responsive')\n    sections.forEach(function (section) {\n      if (!(section instanceof HTMLElement)) return\n\n      const root = section.closest('.product-main')\n      if (!(root instanceof HTMLElement)) return\n\n      const anchor = root.querySelector('.kit-manuals-guides-anchor')\n      const mobileTarget = root.querySelector('.kit-manuals-guides-mobile-target')\n      if (!(anchor instanceof HTMLElement) || !(mobileTarget instanceof HTMLElement)) return\n\n      if (MOBILE_MQ && MOBILE_MQ.matches) {\n        if (section.parentElement !== mobileTarget) {\n          mobileTarget.appendChild(section)\n        }\n        return\n      }\n\n      if (section.previousElementSibling !== anchor || section.parentElement !== anchor.parentElement) {\n        anchor.insertAdjacentElement('afterend', section)\n      }\n    })\n  }\n\n  placeKitManualsGuides()\n  document.addEventListener('DOMContentLoaded', placeKitManualsGuides)\n  window.addEventListener('load', placeKitManualsGuides, { passive: true })\n  window.addEventListener('resize', placeKitManualsGuides, { passive: true })\n  document.addEventListener('shopify:section:load', function () {\n    placeKitManualsGuides()\n  })\n})();\n\n// Shopify Forms teaser: reduce the initial mobile preview size inside the app shadow DOM\n(function () {\n  const MOBILE_MQ = window.matchMedia ? window.matchMedia('(max-width: 767.98px)') : null\n  const STYLE_ATTR = 'data-mds-shopify-forms-mobile-teaser'\n  const CONTAINER_SELECTOR = [\n    '#app-embed',\n    '[id*=\"app-embed\"]',\n    '[id*=\"shopify-block\"][id*=\"forms\"]',\n    '[class*=\"shopify-form\"]',\n    'shopify-forms'\n  ].join(', ')\n  const CSS_TEXT = [\n    '@media (max-width: 767.98px) {',\n    '  [class*=\"teaser\"],',\n    '  [class*=\"Teaser\"],',\n    '  button[aria-expanded],',\n    '  [role=\"button\"][aria-expanded] {',\n    '    max-width: min(240px, calc(100vw - 1.5rem)) !important;',\n    '    min-height: 0 !important;',\n    '    padding: 0.625rem 0.875rem !important;',\n    '    font-size: 0.875rem !important;',\n    '    line-height: 1.25 !important;',\n    '    gap: 0.5rem !important;',\n    '    white-space: normal !important;',\n    '  }',\n    '  button[aria-expanded] *,',\n    '  [role=\"button\"][aria-expanded] * {',\n    '    font-size: inherit !important;',\n    '    line-height: inherit !important;',\n    '  }',\n    '  button[aria-expanded] p,',\n    '  [role=\"button\"][aria-expanded] p {',\n    '    margin: 0 !important;',\n    '  }',\n    '  button[aria-expanded] img,',\n    '  button[aria-expanded] svg,',\n    '  [role=\"button\"][aria-expanded] img,',\n    '  [role=\"button\"][aria-expanded] svg {',\n    '    width: 1rem !important;',\n    '    height: 1rem !important;',\n    '    max-width: 1rem !important;',\n    '    max-height: 1rem !important;',\n    '    flex: 0 0 1rem !important;',\n    '  }',\n    '}'\n  ].join('\\n')\n\n  function isMobileViewport () {\n    return !MOBILE_MQ || MOBILE_MQ.matches\n  }\n\n  function elementLooksLikeFormsHost (el) {\n    if (!(el instanceof Element)) return false\n\n    const tagName = (el.tagName || '').toLowerCase()\n    const id = (el.id || '').toLowerCase()\n    const className = typeof el.className === 'string' ? el.className.toLowerCase() : ''\n\n    if (tagName === 'shopify-forms') return true\n    if (tagName.includes('shopify') && tagName.includes('form')) return true\n    if (id.includes('forms') || id.includes('app-embed')) return true\n    if (className.includes('shopify-form') || className.includes('shopify forms')) return true\n\n    return !!el.closest(CONTAINER_SELECTOR)\n  }\n\n  function injectStyles (shadowRoot) {\n    if (!(shadowRoot instanceof ShadowRoot)) return\n    if (shadowRoot.querySelector('style[' + STYLE_ATTR + ']')) return\n\n    const style = document.createElement('style')\n    style.setAttribute(STYLE_ATTR, 'true')\n    style.textContent = CSS_TEXT\n    shadowRoot.appendChild(style)\n  }\n\n  function collectHosts (root) {\n    const hosts = new Set()\n    const scope = root && root.querySelectorAll ? root : document\n\n    scope.querySelectorAll(CONTAINER_SELECTOR).forEach(function (container) {\n      if (container.shadowRoot) hosts.add(container)\n      container.querySelectorAll('*').forEach(function (el) {\n        if (el.shadowRoot) hosts.add(el)\n      })\n    })\n\n    if (hosts.size > 0) return hosts\n\n    scope.querySelectorAll('*').forEach(function (el) {\n      if (el.shadowRoot && elementLooksLikeFormsHost(el)) {\n        hosts.add(el)\n      }\n    })\n\n    return hosts\n  }\n\n  function run (root) {\n    if (!isMobileViewport()) return\n\n    collectHosts(root).forEach(function (host) {\n      injectStyles(host.shadowRoot)\n    })\n  }\n\n  let rafId = 0\n  function schedule (root) {\n    if (rafId) window.cancelAnimationFrame(rafId)\n    rafId = window.requestAnimationFrame(function () {\n      rafId = 0\n      run(root)\n    })\n  }\n\n  schedule(document)\n  document.addEventListener('DOMContentLoaded', function () { schedule(document) })\n  window.addEventListener('load', function () { schedule(document) }, { passive: true })\n  document.addEventListener('shopify:section:load', function (e) {\n    schedule(e && e.target ? e.target : document)\n  })\n\n  if (MOBILE_MQ) {\n    const onViewportChange = function () { schedule(document) }\n    if (typeof MOBILE_MQ.addEventListener === 'function') {\n      MOBILE_MQ.addEventListener('change', onViewportChange)\n    } else if (typeof MOBILE_MQ.addListener === 'function') {\n      MOBILE_MQ.addListener(onViewportChange)\n    }\n  }\n\n  if (window.MutationObserver) {\n    const observer = new MutationObserver(function (mutations) {\n      for (const mutation of mutations) {\n        for (const node of mutation.addedNodes) {\n          if (!(node instanceof Element)) continue\n          schedule(node)\n          return\n        }\n      }\n    })\n\n    observer.observe(document.documentElement, { childList: true, subtree: true })\n  }\n})();\n\n// Article page (mobile): horizontal scroll only on tables via dedicated wrappers\n(function () {\n  const PAGE_CLASS = 'page-type-article'\n  const TABLE_SELECTOR = '.article-main .article-content.rte table'\n  const WRAPPER_CLASS = 'article-table-scroll'\n\n  function wrapTable (table) {\n    if (!(table instanceof HTMLTableElement)) return\n    const parent = table.parentElement\n    if (!parent || parent.classList.contains(WRAPPER_CLASS)) return\n\n    const wrapper = document.createElement('div')\n    wrapper.className = WRAPPER_CLASS\n    parent.insertBefore(wrapper, table)\n    wrapper.appendChild(table)\n  }\n\n  function initTableScroll (root) {\n    if (!document.body || !document.body.classList.contains(PAGE_CLASS)) return\n    const scope = root && root.querySelectorAll ? root : document\n    scope.querySelectorAll(TABLE_SELECTOR).forEach(wrapTable)\n  }\n\n  initTableScroll(document)\n\n  document.addEventListener('DOMContentLoaded', function () {\n    initTableScroll(document)\n  })\n\n  window.addEventListener('load', function () {\n    initTableScroll(document)\n  }, { passive: true })\n\n  document.addEventListener('shopify:section:load', function (e) {\n    initTableScroll(e && e.target ? e.target : document)\n  })\n})();\n\n// Smooth scroll to FAQ with dynamic offset for sticky header\n(function () {\n  function getTopOverlayHeight () {\n    let total = 0\n    // Primary sticky header\n    const header = document.getElementById('header-group')\n    if (header) {\n      const cs = window.getComputedStyle(header)\n      const stickyActive = cs && (cs.position === 'sticky' || cs.position === 'fixed')\n      if (stickyActive) total += header.offsetHeight || 0\n    }\n    // Shopify preview/admin bars (when present)\n    const previewBar = document.getElementById('preview-bar-iframe') || document.getElementById('shopify-preview-bar-iframe')\n    if (previewBar) total += (previewBar.getBoundingClientRect().height || previewBar.offsetHeight || 0)\n    // Optional announcement bars used by many themes\n    const announce = document.getElementById('shopify-section-announcement') || document.getElementById('announcement-bar')\n    if (announce) {\n      const csA = window.getComputedStyle(announce)\n      const stickyA = csA && (csA.position === 'sticky' || csA.position === 'fixed')\n      if (stickyA) total += announce.offsetHeight || 0\n    }\n    return total\n  }\n\n  function scrollToFaqAnchor (updateHash) {\n    const target = document.getElementById('collection-faq')\n    if (!target) return\n\n    const overlayOnly = getTopOverlayHeight()\n    const extra = overlayOnly > 0 ? 8 : 0 // add breathing space only when something overlays\n    const overlay = overlayOnly + extra\n    // Use CSS scroll-margin for one smooth, jitter-free scroll\n    target.style.scrollMarginTop = overlay + 'px'\n    target.scrollIntoView({ behavior: 'smooth', block: 'start' })\n\n    if (updateHash && history && history.pushState) {\n      history.pushState(null, '', '#collection-faq')\n    }\n  }\n\n  // Intercept clicks on any link to #collection-faq\n  document.addEventListener('click', function (e) {\n    const link = e.target.closest('a[href=\"#collection-faq\"]')\n    if (!link) return\n    const target = document.getElementById('collection-faq')\n    if (target) {\n      e.preventDefault()\n      // reflect destination and align perfectly using dynamic scroll-margin\n      scrollToFaqAnchor(true)\n    }\n    // if no target exists on page, let browser follow the hash normally\n  })\n\n  // If page loads with #collection-faq in URL, adjust after load\n  document.addEventListener('DOMContentLoaded', function () {\n    if (window.location.hash === '#collection-faq') {\n      // Wait a tick for layout to settle\n      setTimeout(function(){ scrollToFaqAnchor(false) }, 50)\n    }\n  })\n\n  // Also adjust if hash changes to #collection-faq later\n  window.addEventListener('hashchange', function () {\n    if (window.location.hash === '#collection-faq') {\n      setTimeout(function(){ scrollToFaqAnchor(false) }, 0)\n    }\n  })\n})();\n\n// Fiche produit : le badge d'avis sous le titre (jdgm-preview-badge) d\u00E9file par\n// d\u00E9faut vers le widget Judge.me complet, tout en bas apr\u00E8s la FAQ (\u00AB trop bas \u00BB).\n// On le redirige vers le titre de la section \u00AB Avis clients \u00BB (avis \u00E9pingl\u00E9s),\n// avec l'offset du header sticky pour atterrir pile sur le titre.\n(function () {\n  function getTopOverlayHeight () {\n    let total = 0\n    const header = document.getElementById('header-group')\n    if (header) {\n      const cs = window.getComputedStyle(header)\n      const stickyActive = cs && (cs.position === 'sticky' || cs.position === 'fixed')\n      if (stickyActive) total += header.offsetHeight || 0\n    }\n    const previewBar = document.getElementById('preview-bar-iframe') || document.getElementById('shopify-preview-bar-iframe')\n    if (previewBar) total += (previewBar.getBoundingClientRect().height || previewBar.offsetHeight || 0)\n    const announce = document.getElementById('shopify-section-announcement') || document.getElementById('announcement-bar')\n    if (announce) {\n      const csA = window.getComputedStyle(announce)\n      const stickyA = csA && (csA.position === 'sticky' || csA.position === 'fixed')\n      if (stickyA) total += announce.offsetHeight || 0\n    }\n    return total\n  }\n\n  // Cible pr\u00E9f\u00E9r\u00E9e : le titre \u00AB Avis clients \u00BB de la section d'avis \u00E9pingl\u00E9s,\n  // quand elle est visible. Sinon, repli sur le widget Judge.me complet (l'offset\n  // du header corrige alors le \u00AB trop bas \u00BB du scroll natif).\n  function getReviewsTarget () {\n    const pinned = document.querySelector('.pdp-pinned-reviews')\n    if (pinned && !pinned.hasAttribute('hidden')) {\n      return pinned.querySelector('.pdp-section-title') || pinned\n    }\n    return document.getElementById('judgeme_product_reviews')\n  }\n\n  function scrollToReviews () {\n    const target = getReviewsTarget()\n    if (!target) return\n    const overlay = getTopOverlayHeight()\n    const extra = overlay > 0 ? 12 : 8 // marge de respiration sous le header\n    target.style.scrollMarginTop = (overlay + extra) + 'px'\n    target.scrollIntoView({ behavior: 'smooth', block: 'start' })\n  }\n\n  // Capture : on passe AVANT le handler de clic natif de Judge.me sur le badge.\n  document.addEventListener('click', function (e) {\n    const badge = e.target.closest('.jdgm-preview-badge')\n    if (!badge) return\n    if (!getReviewsTarget()) return // pas de section d'avis : on laisse le comportement natif\n    e.preventDefault()\n    e.stopPropagation()\n    scrollToReviews()\n  }, true)\n})();\n\n// Collection/search product cards: on mobile/touch, do not trap the first tap on the image.\n// The image link should always navigate immediately.\n(function () {\n  const CARD_SELECTOR = '.page-type-collection .product-card--interactive-highlights, .page-type-search .product-card--interactive-highlights'\n  const MOBILE_MQ = window.matchMedia ? window.matchMedia('(max-width: 991.98px), (hover: none)') : null\n  const OPEN_CLASS = 'is-highlights-open'\n\n  function isMobileTouchMode () {\n    return !MOBILE_MQ || MOBILE_MQ.matches\n  }\n\n  function closeAllHighlights (exceptCard) {\n    document.querySelectorAll(CARD_SELECTOR + '.' + OPEN_CLASS).forEach(function (card) {\n      if (exceptCard && card === exceptCard) return\n      card.classList.remove(OPEN_CLASS)\n    })\n  }\n\n  document.addEventListener('click', function (event) {\n    if (!isMobileTouchMode()) {\n      closeAllHighlights()\n      return\n    }\n\n    const target = event.target instanceof Element ? event.target : null\n    if (!target) return\n\n    const card = target.closest(CARD_SELECTOR)\n\n    if (!card) {\n      closeAllHighlights()\n    }\n  })\n\n  window.addEventListener('resize', function () {\n    if (!isMobileTouchMode()) closeAllHighlights()\n  }, { passive: true })\n\n  document.addEventListener('shopify:section:load', function () {\n    if (!isMobileTouchMode()) closeAllHighlights()\n  })\n})();\n\n// Product card titles: fallback for browsers without line-clamp support\n(function () {\n  if (window.CSS && (CSS.supports('-webkit-line-clamp', '3') || CSS.supports('line-clamp', '3'))) {\n    return\n  }\n\n  const TITLE_SELECTOR = '.product-card-title'\n  const MAX_ITERATIONS = 18\n  const MIN_FONT_SIZE_PX = 6\n  const OBSERVED_FLAG = 'mdsTitleObserved'\n\n  function getLineHeightPx (computedStyle, fontSizePx) {\n    const raw = computedStyle.lineHeight\n    if (raw === 'normal') return fontSizePx * 1.2\n\n    const parsed = parseFloat(raw)\n    if (!Number.isFinite(parsed) || parsed <= 0) return fontSizePx * 1.2\n\n    // Some browsers may return a unitless number (e.g. \"1.4\") for line-height.\n    if (raw.endsWith('px')) return parsed\n    if (raw.endsWith('%')) return (parsed / 100) * fontSizePx\n    return parsed * fontSizePx\n  }\n\n  function isMoreThanThreeLines (el) {\n    const computed = window.getComputedStyle(el)\n    const fontSize = parseFloat(computed.fontSize)\n    if (!Number.isFinite(fontSize) || fontSize <= 0) return false\n\n    const lineHeight = getLineHeightPx(computed, fontSize)\n    if (!Number.isFinite(lineHeight) || lineHeight <= 0) return false\n\n    const paddingTop = parseFloat(computed.paddingTop) || 0\n    const paddingBottom = parseFloat(computed.paddingBottom) || 0\n    const contentHeight = el.scrollHeight - paddingTop - paddingBottom\n    return contentHeight > (lineHeight * 3 + 0.5)\n  }\n\n  function fitTitle (el) {\n    if (!(el instanceof HTMLElement)) return\n\n    el.style.removeProperty('font-size')\n    el.style.maxHeight = ''\n    el.style.overflow = ''\n\n    const computed = window.getComputedStyle(el)\n    const baseSize = parseFloat(computed.fontSize)\n    if (!Number.isFinite(baseSize) || baseSize <= 0) return\n\n    if (!isMoreThanThreeLines(el)) return\n\n    let low = MIN_FONT_SIZE_PX\n    let high = baseSize\n    let best = null\n\n    for (let i = 0; i < MAX_ITERATIONS; i++) {\n      const mid = (low + high) / 2\n      // Override Bootstrap utilities like `.fs-*` which use `!important`.\n      el.style.setProperty('font-size', mid + 'px', 'important')\n\n      if (isMoreThanThreeLines(el)) {\n        high = mid\n      } else {\n        best = mid\n        low = mid\n      }\n    }\n\n    if (best == null) {\n      el.style.setProperty('font-size', MIN_FONT_SIZE_PX + 'px', 'important')\n    } else {\n      el.style.setProperty('font-size', best + 'px', 'important')\n    }\n  }\n\n  function fitAll (root) {\n    const scope = root && root.querySelectorAll ? root : document\n    scope.querySelectorAll(TITLE_SELECTOR).forEach(fitTitle)\n  }\n\n  let rafId = 0\n  let isFitting = false\n  const resizeObserver = window.ResizeObserver\n    ? new ResizeObserver(function () { scheduleFit() })\n    : null\n\n  function observeTitles (root) {\n    if (!resizeObserver) return\n    const scope = root && root.querySelectorAll ? root : document\n    scope.querySelectorAll(TITLE_SELECTOR).forEach(function (el) {\n      if (!(el instanceof Element)) return\n      if (el.dataset && el.dataset[OBSERVED_FLAG]) return\n      if (el.dataset) el.dataset[OBSERVED_FLAG] = '1'\n      resizeObserver.observe(el)\n    })\n  }\n\n  function scheduleFit () {\n    if (isFitting) return\n    if (rafId) cancelAnimationFrame(rafId)\n    rafId = requestAnimationFrame(function () {\n      isFitting = true\n      try { fitAll(document) } finally { isFitting = false }\n    })\n  }\n\n  document.addEventListener('DOMContentLoaded', function () {\n    isFitting = true\n    try { fitAll(document) } finally { isFitting = false }\n    observeTitles(document)\n    // Run a second time after images/fonts/layout settle (swipers, etc.)\n    setTimeout(function () { isFitting = true; try { fitAll(document) } finally { isFitting = false } }, 250)\n    setTimeout(function () { isFitting = true; try { fitAll(document) } finally { isFitting = false } }, 1000)\n\n    // Some components (swiper, filters) update widths after init; retry briefly.\n    let tries = 0\n    const settleId = setInterval(function () {\n      tries++\n      scheduleFit()\n      if (tries >= 10) clearInterval(settleId)\n    }, 200)\n  })\n\n  window.addEventListener('resize', scheduleFit, { passive: true })\n  document.addEventListener('shopify:section:load', scheduleFit)\n  window.addEventListener('load', scheduleFit, { passive: true })\n\n  if (document.fonts && document.fonts.ready && typeof document.fonts.ready.then === 'function') {\n    document.fonts.ready.then(scheduleFit).catch(function () {})\n  }\n\n  // Catch product cards injected dynamically (recommendations, filters, etc.)\n  const observer = new MutationObserver(function (mutations) {\n    for (const mutation of mutations) {\n      for (const node of mutation.addedNodes) {\n        if (!(node instanceof Element)) continue\n        if (node.matches(TITLE_SELECTOR) || node.querySelector(TITLE_SELECTOR)) {\n          observeTitles(node)\n          scheduleFit()\n          return\n        }\n      }\n    }\n  })\n  observer.observe(document.documentElement, { childList: true, subtree: true })\n\n  // Manual trigger for debugging in console: `window.MDSFitProductCardTitles()`\n  window.MDSFitProductCardTitles = function () {\n    isFitting = true\n    try { fitAll(document) } finally { isFitting = false }\n  }\n\n  // Quick report for debugging in console: `window.MDSProductCardTitleReport()`\n  window.MDSProductCardTitleReport = function () {\n    return Array.from(document.querySelectorAll(TITLE_SELECTOR)).slice(0, 10).map(function (el) {\n      const cs = window.getComputedStyle(el)\n      const fontSize = cs.fontSize\n      const lineHeight = cs.lineHeight\n      const styleAttr = el.getAttribute('style') || ''\n      const paddingTop = parseFloat(cs.paddingTop) || 0\n      const paddingBottom = parseFloat(cs.paddingBottom) || 0\n      const contentHeight = el.scrollHeight - paddingTop - paddingBottom\n      const lineHeightPx = getLineHeightPx(cs, parseFloat(cs.fontSize) || 0)\n      const approxLines = lineHeightPx > 0 ? (contentHeight / lineHeightPx) : null\n      return {\n        text: (el.textContent || '').trim().slice(0, 80),\n        fontSize,\n        lineHeight,\n        approxLines,\n        scrollHeight: el.scrollHeight,\n        clientHeight: el.clientHeight,\n        styleAttr\n      }\n    })\n  }\n})();\n\n// Product cards (collection/search/home): quick \"add to cart\" icon button.\n// Adds the product's first available variant via the theme's <cart-container>,\n// using the minimum purchase quantity so products with a minimum order quantity\n// are added at their minimum instead of 1. The minimum is read from two sources\n// and the most restrictive wins:\n//   - data-min-quantity: theme-readable value (Shopify quantity_rule / metafield)\n//   - Pareto \"Order Limit\" rules exposed at runtime in window.omgLimitPurchase\n// Updates the count badge and opens the cart drawer; falls back to /cart/add.js.\n(function () {\n  // Read the effective minimum imposed by the Pareto (Order Limit) app for a\n  // given product. Pareto injects all of its rules into window.omgLimitPurchase.\n  // A rule applies either by product (product_list contains the product id) or by\n  // collection (collection_list intersects the product's collections). When more\n  // than one rule applies we keep the highest minimum (most restrictive).\n  function paretoMinQuantity (productId, collectionIdsCsv) {\n    try {\n      const cfg = window.omgLimitPurchase\n      if (!cfg || !Array.isArray(cfg.limits)) return 1\n      const pid = parseInt(productId, 10)\n      const collectionIds = String(collectionIdsCsv || '')\n        .split(',')\n        .map(function (s) { return parseInt(s, 10) })\n        .filter(function (n) { return !isNaN(n) })\n\n      let min = 1\n      for (let i = 0; i < cfg.limits.length; i++) {\n        const rule = cfg.limits[i]\n        if (!rule || rule.status !== 1 || rule.limit_type !== 'quantity') continue\n\n        let applies = false\n        if (!isNaN(pid) && Array.isArray(rule.product_list) && rule.product_list.indexOf(pid) !== -1) {\n          applies = true\n        } else if (Array.isArray(rule.collection_list)) {\n          for (let j = 0; j < collectionIds.length; j++) {\n            if (rule.collection_list.indexOf(collectionIds[j]) !== -1) { applies = true; break }\n          }\n        }\n\n        if (applies && typeof rule.min === 'number' && rule.min > min) min = rule.min\n      }\n      return min\n    } catch (err) {\n      return 1\n    }\n  }\n\n  // Expos\u00E9 pour le popup \u00AB Ajout\u00E9 au panier \u00BB (assets/cart-added-popup.js),\n  // qui applique la m\u00EAme r\u00E8gle Pareto au stepper de quantit\u00E9.\n  window.mdsParetoMinQuantity = paretoMinQuantity\n\n  document.addEventListener('click', async function (e) {\n    // .cap-upsell-add : boutons \u00AB + \u00BB du popup \u00AB Ajout\u00E9 au panier \u00BB\n    // (sections/cart-added-popup.liquid) \u2014 m\u00EAmes data-attributes, m\u00EAme logique.\n    const btn = e.target instanceof Element ? e.target.closest('.product-card-atc, .cap-upsell-add') : null\n    if (!btn) return\n\n    // Only the immediate-add button carries data-variant-id. Multi-variant / kit cards\n    // render an <a> link with no variant id \u2014 let it navigate to the product page normally.\n    const variantId = btn.dataset.variantId\n    if (!variantId) return\n\n    e.preventDefault()\n    if (btn.disabled || btn.classList.contains('is-loading')) return\n\n    // Minimum d'achat : on prend le plus restrictif entre la valeur lisible par le\n    // th\u00E8me (data-min-quantity) et la r\u00E8gle Pareto correspondant \u00E0 ce produit.\n    const themeMin = Math.max(1, parseInt(btn.dataset.minQuantity, 10) || 1)\n    const paretoMin = paretoMinQuantity(btn.dataset.productId, btn.dataset.collectionIds)\n    const minQty = Math.max(themeMin, paretoMin)\n\n    // D\u00E9sactiver l'\u00E9l\u00E9ment focalis\u00E9 le blur : on restaure le focus apr\u00E8s coup\n    // (important dans le popup \u00AB Ajout\u00E9 au panier \u00BB, dont le focus est pi\u00E9g\u00E9).\n    const hadFocus = document.activeElement === btn\n\n    btn.classList.add('is-loading')\n    btn.disabled = true\n\n    try {\n      const cart = document.querySelector('cart-container')\n      if (cart && typeof cart.add === 'function') {\n        const formData = new FormData()\n        formData.append('id', variantId)\n        formData.append('quantity', minQty)\n        await cart.add(formData)\n      } else {\n        const addUrl = (window.Shopify && window.Shopify.routes && window.Shopify.routes.cart_add_url) || '/cart/add'\n        const res = await fetch(addUrl + '.js', {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n          body: JSON.stringify({ id: variantId, quantity: minQty })\n        })\n        if (res.ok) {\n          const url = new URL(window.location.href)\n          url.searchParams.set('cart', 'true')\n          window.location.href = url.toString()\n        } else {\n          console.error('MDS: ajout au panier \u00E9chou\u00E9', res.status)\n        }\n      }\n    } catch (err) {\n      console.error('MDS: erreur ajout au panier', err)\n    } finally {\n      btn.classList.remove('is-loading')\n      btn.disabled = false\n      if (hadFocus) btn.focus()\n    }\n  })\n})();\n\n// Product page: tab switch without animation (instant) + mobile scroll alignment\n(function () {\n  const CONTAINER_SELECTOR = '[data-product-tabs]'\n  const RADIO_SELECTOR = '.product-tabs__radio'\n  const TAB_SELECTOR = '.product-tabs__tab'\n  const PANEL_SELECTOR = '.product-tabs__panel'\n  const DESKTOP_MQ = window.matchMedia ? window.matchMedia('(min-width: 769px)') : null\n  const REDUCED_MOTION_MQ = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)') : null\n  const MOBILE_SCROLL_DELAY_MS = 50\n  const MOBILE_SCROLL_EXTRA_OFFSET_PX = 16\n  const mobileScrollTimers = new WeakMap()\n\n  function isDesktop () {\n    return !DESKTOP_MQ || DESKTOP_MQ.matches\n  }\n\n  function prefersReducedMotion () {\n    return !!(REDUCED_MOTION_MQ && REDUCED_MOTION_MQ.matches)\n  }\n\n  function getTopOverlayHeight () {\n    let total = 0\n\n    const header = document.getElementById('header-group')\n    if (header) {\n      const headerStyle = window.getComputedStyle(header)\n      const headerIsSticky = headerStyle && (headerStyle.position === 'sticky' || headerStyle.position === 'fixed')\n      if (headerIsSticky) total += header.offsetHeight || 0\n    }\n\n    const previewBar = document.getElementById('preview-bar-iframe') || document.getElementById('shopify-preview-bar-iframe')\n    if (previewBar) total += (previewBar.getBoundingClientRect().height || previewBar.offsetHeight || 0)\n\n    const announcement = document.getElementById('shopify-section-announcement') || document.getElementById('announcement-bar')\n    if (announcement) {\n      const announcementStyle = window.getComputedStyle(announcement)\n      const announcementIsSticky = announcementStyle && (announcementStyle.position === 'sticky' || announcementStyle.position === 'fixed')\n      if (announcementIsSticky) total += announcement.offsetHeight || 0\n    }\n\n    return total\n  }\n\n  function scrollHeadingToTop (heading, smooth) {\n    if (!(heading instanceof Element)) return\n    const headingTop = heading.getBoundingClientRect().top + window.pageYOffset\n    const desiredTop = Math.max(0, headingTop - getTopOverlayHeight() - MOBILE_SCROLL_EXTRA_OFFSET_PX)\n    window.scrollTo({\n      top: desiredTop,\n      // 'instant' (pas 'auto') : Bootstrap pose scroll-behavior:smooth sur\n      // :root, et 'auto' h\u00E9rite de ce lissage \u2014 le saut doit \u00EAtre sec.\n      behavior: smooth && !prefersReducedMotion() ? 'smooth' : 'instant',\n    })\n  }\n\n  function maybeScrollMobileToTabHeading (container, radio) {\n    if (!(container instanceof Element)) return\n    if (!(radio instanceof Element)) return\n    if (isDesktop()) return\n\n    // Directement sur le titre de l'onglet tap\u00E9, SANS d\u00E9tour visible.\n    const heading = radio.nextElementSibling\n    if (!(heading instanceof Element)) return\n\n    // Alignement synchrone, avant le prochain rendu : quand un onglet\n    // ouvert plus haut se referme, l'utilisateur ne voit jamais l'\u00E9tat\n    // interm\u00E9diaire \u2014 donc pas de \u00AB page qui descend puis remonte \u00BB.\n    scrollHeadingToTop(heading, false)\n\n    const existingTimer = mobileScrollTimers.get(container)\n    if (existingTimer) window.clearTimeout(existingTimer)\n\n    // Passe de correction discr\u00E8te une fois la mise en page stabilis\u00E9e\n    // (images ou contenus charg\u00E9s tardivement).\n    const timerId = window.setTimeout(function () {\n      if (typeof radio.blur === 'function') radio.blur()\n      scrollHeadingToTop(heading, false)\n      mobileScrollTimers.delete(container)\n    }, MOBILE_SCROLL_DELAY_MS)\n\n    mobileScrollTimers.set(container, timerId)\n  }\n\n  function clearInlineMaxHeights (container) {\n    container.querySelectorAll(PANEL_SELECTOR).forEach(function (panel) {\n      if (!(panel instanceof HTMLElement)) return\n      panel.style.maxHeight = ''\n    })\n  }\n\n  function initContainer (container) {\n    if (!(container instanceof Element)) return\n    if (container.dataset && container.dataset.mdsTabsSmoothInit === '1') return\n    if (container.dataset) container.dataset.mdsTabsSmoothInit = '1'\n\n    // Panels may keep stale inline max-height from a previous version of this script.\n    clearInlineMaxHeights(container)\n\n    // Le HTML n'arrive avec AUCUNE radio coch\u00E9e : sur mobile l'accord\u00E9on\n    // doit \u00EAtre enti\u00E8rement repli\u00E9 d\u00E8s l'arriv\u00E9e (m\u00EAme sans JS). En desktop,\n    // la barre d'onglets doit avoir un onglet actif : on coche ici celui\n    // marqu\u00E9 data-default-tab par le Liquid.\n    function ensureDesktopDefaultTab () {\n      if (!isDesktop()) return\n      if (container.querySelector(RADIO_SELECTOR + ':checked')) return\n      const def = container.querySelector(RADIO_SELECTOR + '[data-default-tab]') ||\n        container.querySelector(RADIO_SELECTOR)\n      if (def instanceof HTMLInputElement) def.checked = true\n    }\n\n    ensureDesktopDefaultTab()\n\n    // Fen\u00EAtre repassant en desktop avec tout repli\u00E9 (rotation tablette\u2026)\n    if (DESKTOP_MQ && typeof DESKTOP_MQ.addEventListener === 'function') {\n      DESKTOP_MQ.addEventListener('change', function (ev) {\n        if (ev.matches) ensureDesktopDefaultTab()\n      })\n    }\n\n    container.addEventListener('change', function (e) {\n      const target = e.target\n      if (!(target instanceof Element)) return\n      if (!target.matches(RADIO_SELECTOR)) return\n      // Pas de d\u00E9filement quand on referme l'accord\u00E9on (radio d\u00E9coch\u00E9e)\n      if (target instanceof HTMLInputElement && !target.checked) return\n      maybeScrollMobileToTabHeading(container, target)\n    })\n\n    // Mobile: prevent native label->radio focus scrolling, then switch tab manually.\n    container.addEventListener('click', function (e) {\n      if (isDesktop()) return\n      const trigger = e.target && e.target.closest ? e.target.closest(TAB_SELECTOR + ', .product-tabs__heading') : null\n      if (!(trigger instanceof Element)) return\n\n      const label = trigger.matches(TAB_SELECTOR) ? trigger : trigger.querySelector(TAB_SELECTOR)\n      if (!(label instanceof Element)) return\n\n      const radioId = label.getAttribute('for')\n      if (!radioId) return\n\n      const radio = document.getElementById(radioId)\n      if (!(radio instanceof HTMLInputElement) || !radio.matches(RADIO_SELECTOR)) return\n\n      e.preventDefault()\n\n      // Accord\u00E9on mobile : re-taper l'en-t\u00EAte de l'onglet ouvert le referme.\n      // Impossible nativement avec des radios (non d\u00E9cochables), on d\u00E9coche\n      // en JS ; panneau et chevron suivent via les s\u00E9lecteurs :checked du CSS.\n      if (radio.checked) {\n        radio.checked = false\n        radio.dispatchEvent(new Event('change', { bubbles: true }))\n        return\n      }\n\n      radio.checked = true\n      radio.dispatchEvent(new Event('change', { bubbles: true }))\n    })\n  }\n\n  function initAll (root) {\n    const scope = root && root.querySelectorAll ? root : document\n    scope.querySelectorAll(CONTAINER_SELECTOR).forEach(initContainer)\n  }\n\n  document.addEventListener('DOMContentLoaded', function () {\n    initAll(document)\n  })\n\n  window.addEventListener('load', function () {\n    initAll(document)\n  }, { passive: true })\n\n  document.addEventListener('shopify:section:load', function (e) {\n    initAll(e && e.target ? e.target : document)\n  })\n})();\n\n// Judge.me: add a small \"verified\" badge next to the bottom widget review count text (e.g. \"4 avis\")\n(function () {\n  // Disabled: now handled via CSS in `assets/product.css` (works with revamped `jm-*` widget markup).\n  return\n  const WIDGET_ID = 'judgeme_product_reviews'\n  const BADGE_CLASS = 'mds-jdgm-verified-badge'\n\n  function ensureBadge (container) {\n    if (!(container instanceof Element)) return false\n    if (container.querySelector('.' + BADGE_CLASS)) return true\n\n    const badge = document.createElement('span')\n    badge.className = BADGE_CLASS\n    badge.setAttribute('aria-hidden', 'true')\n    badge.textContent = '\u2713'\n    container.appendChild(badge)\n    return true\n  }\n\n  function findLegacyCountEl (widget) {\n    const selectors = [\n      '.jdgm-rev-widg__summary-text',\n      '.jdgm-widget__summary-text',\n      '.jdgm-rev-widg__summary',\n      '.jdgm-widget__summary',\n    ]\n    for (const selector of selectors) {\n      const el = widget.querySelector(selector)\n      if (el) return el\n    }\n    return null\n  }\n\n  function findRevampedCountEl (widget) {\n    const root = widget.querySelector('[data-widget-container=\"review-widget\"]') || widget.querySelector('.jm-review-widget')\n    if (!root) return null\n\n    const candidates = root.querySelectorAll('.jm-average-rating-display .jm-text, .jm-review-widget__header .jm-text')\n    for (const el of candidates) {\n      if (!(el instanceof Element)) continue\n      const text = (el.textContent || '').trim()\n      if (!text) continue\n      if (!/\\d/.test(text)) continue\n      if (!/\\b(avis|review|reviews)\\b/i.test(text)) continue\n      return el\n    }\n    return null\n  }\n\n  function addBadgeIfNeeded () {\n    const widget =\n      document.getElementById(WIDGET_ID) ||\n      document.querySelector('[data-widget-container=\"review-widget\"]') ||\n      document.querySelector('.jm-review-widget')\n    if (!widget) return\n\n    const countEl = findRevampedCountEl(widget) || findLegacyCountEl(widget)\n    if (!countEl) return\n\n    // Avoid duplicating if Judge.me rerenders.\n    if (countEl.querySelector('.' + BADGE_CLASS)) return\n    ensureBadge(countEl)\n  }\n\n  function init () {\n    addBadgeIfNeeded()\n\n    const widget = document.getElementById(WIDGET_ID)\n    if (!window.MutationObserver) return\n\n    let raf = 0\n    const schedule = function () {\n      if (raf) return\n      raf = requestAnimationFrame(function () {\n        raf = 0\n        addBadgeIfNeeded()\n      })\n    }\n\n    if (widget) {\n      const mo = new MutationObserver(schedule)\n      mo.observe(widget, { childList: true, subtree: true })\n    }\n\n    // Fallback: if Judge.me mounts outside/replaces the wrapper, still try.\n    const docMo = new MutationObserver(schedule)\n    docMo.observe(document.documentElement, { childList: true, subtree: true })\n  }\n\n  document.addEventListener('DOMContentLoaded', init)\n  window.addEventListener('load', init, { passive: true })\n})();\n\n// Fiche produit : renomme le titre du widget Judge.me complet (tout en bas)\n// \u00AB Avis Clients \u00BB \u2192 \u00AB Tous les avis \u00BB. Ce texte vient du r\u00E9glage widget_title\n// de l'app Judge.me (non modifiable en Liquid), on le r\u00E9\u00E9crit donc apr\u00E8s rendu.\n// La section d'avis \u00E9pingl\u00E9s garde son propre titre \u00AB Avis clients \u00BB.\n(function () {\n  const WIDGET_ID = 'judgeme_product_reviews'\n  const NEW_TITLE = 'Tous les avis'\n  const OLD_TITLE = /^avis\\s+clients$/i\n  let inited = false\n\n  function renameTitle () {\n    const widget = document.getElementById(WIDGET_ID)\n    if (!widget) return\n    const candidates = widget.querySelectorAll('.jdgm-rev-widg__title, h1, h2, h3, [class*=\"title\"], [class*=\"heading\"]')\n    candidates.forEach(function (el) {\n      if (!(el instanceof Element)) return\n      // Ne pas toucher aux titres des avis individuels (un client pourrait\n      // avoir intitul\u00E9 son avis \u00AB Avis clients \u00BB).\n      if (el.closest('.jdgm-rev, .jm-review-item')) return\n      const text = (el.textContent || '').trim()\n      if (OLD_TITLE.test(text)) el.textContent = NEW_TITLE\n    })\n  }\n\n  function init () {\n    if (inited) return\n    const widget = document.getElementById(WIDGET_ID)\n    if (!widget) return\n    inited = true\n\n    renameTitle()\n    if (!window.MutationObserver) return\n\n    // Judge.me remplit le widget en asynchrone et peut re-rendre (pagination) :\n    // on r\u00E9-applique \u00E0 chaque mutation. Idempotent, donc pas de boucle.\n    let raf = 0\n    const mo = new MutationObserver(function () {\n      if (raf) return\n      raf = requestAnimationFrame(function () {\n        raf = 0\n        renameTitle()\n      })\n    })\n    mo.observe(widget, { childList: true, subtree: true, characterData: true })\n  }\n\n  document.addEventListener('DOMContentLoaded', init)\n  window.addEventListener('load', init, { passive: true })\n})();\n\n// Judge.me: rating histogram + click-to-filter (revamped `jm-*` widget + legacy fallback)\n(function () {\n  const WRAPPER_ID = 'judgeme_product_reviews'\n  const HIST_ATTR = 'data-mds-jm-rating-histogram'\n  const HIDDEN_CLASS = 'mds-jm-review-hidden'\n  const ACTIVE_CLASS = 'is-active'\n  const STAR_FULL = '\\u2605'\n  const STAR_EMPTY = '\\u2606'\n\n  function getWrapperEl () {\n    return document.getElementById(WRAPPER_ID)\n  }\n\n  function findWidgetRoot (wrapper) {\n    if (!wrapper) return null\n    return (\n      wrapper.querySelector('.jm-review-widget') ||\n      wrapper.querySelector('[data-widget-container=\"review-widget\"]') ||\n      wrapper.querySelector('.jdgm-review-widget') ||\n      null\n    )\n  }\n\n  function getProductId (wrapper) {\n    if (!wrapper) return null\n    const raw = wrapper.getAttribute('data-product-id') || wrapper.getAttribute('data-id')\n    if (!raw) return null\n    const num = parseInt(String(raw), 10)\n    return Number.isFinite(num) ? String(num) : null\n  }\n\n  function normalizeCounts (counts) {\n    const out = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n    if (!counts) return out\n    for (let i = 1; i <= 5; i++) {\n      const val = counts[i] ?? counts[String(i)]\n      const n = parseInt(String(val ?? 0), 10)\n      out[i] = Number.isFinite(n) ? n : 0\n    }\n    return out\n  }\n\n  function getCountsFromJdgmData (productId) {\n    try {\n      const jdgm = window.jdgm\n      if (!productId || !jdgm || !jdgm.data || !jdgm.data.reviewWidget) return null\n      const data = jdgm.data.reviewWidget[productId] || jdgm.data.reviewWidget[String(productId)]\n      if (!data) return null\n\n      // Cl\u00E9 V\u00C9RIFI\u00C9E sur le JSON live (2026-07-18) : \u00AB histogram \u00BB = tableau de\n      // { rating, frequency, percentage } couvrant TOUS les avis du produit\n      // (pas seulement la page 1 rendue dans le DOM).\n      if (Array.isArray(data.histogram) && data.histogram.length) {\n        const fromHistogram = {}\n        data.histogram.forEach(function (row) {\n          if (!row) return\n          const rating = parseInt(String(row.rating), 10)\n          if (rating >= 1 && rating <= 5) fromHistogram[rating] = row.frequency\n        })\n        return normalizeCounts(fromHistogram)\n      }\n\n      const candidate =\n        data.rating_distribution ||\n        data.ratingDistribution ||\n        data.rating_counts ||\n        data.ratingCounts ||\n        data.ratings_count ||\n        data.ratingsCount ||\n        data.distribution ||\n        null\n\n      if (Array.isArray(candidate) && candidate.length >= 5) {\n        return normalizeCounts({\n          1: candidate[0],\n          2: candidate[1],\n          3: candidate[2],\n          4: candidate[3],\n          5: candidate[4],\n        })\n      }\n\n      if (candidate && typeof candidate === 'object') {\n        return normalizeCounts(candidate)\n      }\n\n      return null\n    } catch (e) {\n      return null\n    }\n  }\n\n  function parseRatingFromAriaLabel (label) {\n    if (!label) return null\n    const m = String(label).match(/(\\d)\\s*(?:\\/|out of)\\s*5/i)\n    if (!m) return null\n    const n = parseInt(m[1], 10)\n    return n >= 1 && n <= 5 ? n : null\n  }\n\n  function getCountsFromDom (widgetRoot) {\n    const counts = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n    if (!widgetRoot) return counts\n\n    widgetRoot.querySelectorAll('.jm-review-item').forEach(function (item) {\n      if (!(item instanceof Element)) return\n      const star = item.querySelector('.jm-star-rating[aria-label]')\n      const rating = star ? parseRatingFromAriaLabel(star.getAttribute('aria-label')) : null\n      if (rating) counts[rating]++\n    })\n\n    widgetRoot.querySelectorAll('.jdgm-rev').forEach(function (item) {\n      if (!(item instanceof Element)) return\n      const scoreEl = item.querySelector('[data-score]')\n      const scoreRaw = scoreEl ? scoreEl.getAttribute('data-score') : null\n      const score = scoreRaw ? parseInt(String(scoreRaw), 10) : null\n      if (score && score >= 1 && score <= 5) counts[score]++\n    })\n\n    return counts\n  }\n\n  function ensureHistogramContainer (widgetRoot) {\n    if (!widgetRoot) return null\n\n    const header =\n      widgetRoot.querySelector('.jm-review-widget__header') ||\n      widgetRoot.querySelector('.jm-review-widget-minimal-header') ||\n      widgetRoot.querySelector('.jdgm-rev-widg__header') ||\n      widgetRoot\n\n    if (!header) return null\n\n    const existing = header.querySelector('[' + HIST_ATTR + ']')\n    if (existing) return existing\n\n    const container = document.createElement('div')\n    container.setAttribute(HIST_ATTR, '')\n    container.className = 'mds-jm-rating-histogram'\n    header.appendChild(container)\n    return container\n  }\n\n  function renderHistogramSkeleton (container) {\n    if (!container) return\n    if (container.dataset && container.dataset.mdsRendered === '1') return\n    if (container.dataset) container.dataset.mdsRendered = '1'\n\n    container.innerHTML = ''\n\n    for (let rating = 5; rating >= 1; rating--) {\n      const btn = document.createElement('button')\n      btn.type = 'button'\n      btn.className = 'mds-jm-rating-histogram__row'\n      btn.dataset.rating = String(rating)\n      btn.setAttribute('aria-pressed', 'false')\n\n      const stars = document.createElement('span')\n      stars.className = 'mds-jm-rating-histogram__stars'\n      stars.setAttribute('aria-hidden', 'true')\n      let starsText = ''\n      for (let i = 1; i <= 5; i++) starsText += i <= rating ? STAR_FULL : STAR_EMPTY\n      stars.textContent = starsText\n\n      const bar = document.createElement('span')\n      bar.className = 'mds-jm-rating-histogram__bar'\n      const fill = document.createElement('span')\n      fill.className = 'mds-jm-rating-histogram__fill'\n      bar.appendChild(fill)\n\n      const count = document.createElement('span')\n      count.className = 'mds-jm-rating-histogram__count'\n      count.textContent = '0'\n\n      btn.appendChild(stars)\n      btn.appendChild(bar)\n      btn.appendChild(count)\n\n      container.appendChild(btn)\n    }\n  }\n\n  function updateHistogram (container, counts) {\n    if (!container) return\n\n    const c = normalizeCounts(counts)\n    const max = Math.max(c[1], c[2], c[3], c[4], c[5], 0)\n\n    container.querySelectorAll('.mds-jm-rating-histogram__row').forEach(function (row) {\n      if (!(row instanceof HTMLElement)) return\n      const rating = parseInt(row.dataset.rating || '', 10)\n      if (!rating || rating < 1 || rating > 5) return\n\n      const n = c[rating] || 0\n      const pct = max > 0 ? Math.round((n / max) * 100) : 0\n\n      row.style.setProperty('--mds-fill', pct + '%')\n      const countEl = row.querySelector('.mds-jm-rating-histogram__count')\n      const next = String(n)\n      if (countEl && countEl.textContent !== next) countEl.textContent = next\n    })\n  }\n\n  function setActiveRow (container, ratingOrNull) {\n    if (!container) return\n    container.querySelectorAll('.mds-jm-rating-histogram__row').forEach(function (row) {\n      if (!(row instanceof HTMLElement)) return\n      const r = parseInt(row.dataset.rating || '', 10)\n      const active = ratingOrNull != null && r === ratingOrNull\n      row.classList.toggle(ACTIVE_CLASS, active)\n      row.setAttribute('aria-pressed', active ? 'true' : 'false')\n    })\n  }\n\n  function applyFilter (widgetRoot, ratingOrNull) {\n    if (!widgetRoot) return\n\n    widgetRoot.querySelectorAll('.jm-review-item').forEach(function (item) {\n      if (!(item instanceof HTMLElement)) return\n      if (ratingOrNull == null) {\n        item.classList.remove(HIDDEN_CLASS)\n        return\n      }\n      const star = item.querySelector('.jm-star-rating[aria-label]')\n      const rating = star ? parseRatingFromAriaLabel(star.getAttribute('aria-label')) : null\n      item.classList.toggle(HIDDEN_CLASS, rating !== ratingOrNull)\n    })\n\n    widgetRoot.querySelectorAll('.jdgm-rev').forEach(function (item) {\n      if (!(item instanceof HTMLElement)) return\n      if (ratingOrNull == null) {\n        item.classList.remove(HIDDEN_CLASS)\n        return\n      }\n      const scoreEl = item.querySelector('[data-score]')\n      const scoreRaw = scoreEl ? scoreEl.getAttribute('data-score') : null\n      const score = scoreRaw ? parseInt(String(scoreRaw), 10) : null\n      item.classList.toggle(HIDDEN_CLASS, score !== ratingOrNull)\n    })\n  }\n\n  function initHistogram (wrapper, widgetRoot) {\n    if (!wrapper || !widgetRoot) return\n\n    let currentRoot = widgetRoot\n    let currentContainer = ensureHistogramContainer(currentRoot)\n    if (!currentContainer) return\n\n    function removeDuplicateHistograms () {\n      wrapper.querySelectorAll('[' + HIST_ATTR + ']').forEach(function (el) {\n        if (el !== currentContainer) el.remove()\n      })\n    }\n\n    renderHistogramSkeleton(currentContainer)\n    removeDuplicateHistograms()\n\n    const productId = getProductId(wrapper)\n    let selectedRating = null\n\n    // Les donn\u00E9es globales (window.jdgm.data) peuvent arriver \u2014 ou \u00EAtre\n    // \u00E9cras\u00E9es \u2014 apr\u00E8s le montage du widget CDN : on m\u00E9morise les derniers\n    // comptages globaux valides pour ne jamais retomber sur le comptage DOM\n    // (qui ne voit que la page d'avis affich\u00E9e).\n    let dataCounts = null\n\n    const refresh = function () {\n      const fresh = getCountsFromJdgmData(productId)\n      if (fresh) dataCounts = fresh\n      const counts = dataCounts || getCountsFromDom(currentRoot)\n      updateHistogram(currentContainer, counts)\n      setActiveRow(currentContainer, selectedRating)\n      applyFilter(currentRoot, selectedRating)\n    }\n\n    // Donn\u00E9es inlin\u00E9es parfois ex\u00E9cut\u00E9es apr\u00E8s le premier rendu : on repasse.\n    ;[600, 1800, 4000].forEach(function (delay) {\n      setTimeout(refresh, delay)\n    })\n\n    if (!wrapper.dataset || wrapper.dataset.mdsJmHistogramClickInit !== '1') {\n      if (wrapper.dataset) wrapper.dataset.mdsJmHistogramClickInit = '1'\n      wrapper.addEventListener('click', function (e) {\n        const btn = e.target && e.target.closest ? e.target.closest('.mds-jm-rating-histogram__row') : null\n        if (!btn || !(btn instanceof HTMLElement)) return\n        if (!btn.closest('[' + HIST_ATTR + ']')) return\n        const rating = parseInt(btn.dataset.rating || '', 10)\n        if (!rating || rating < 1 || rating > 5) return\n\n        selectedRating = selectedRating === rating ? null : rating\n        refresh()\n      })\n    }\n\n    refresh()\n\n    if (window.MutationObserver) {\n      let raf = 0\n      const schedule = function () {\n        if (raf) return\n        raf = requestAnimationFrame(function () {\n          raf = 0\n          const nextRoot = findWidgetRoot(wrapper)\n          if (!nextRoot) return\n          currentRoot = nextRoot\n          const nextContainer = ensureHistogramContainer(currentRoot)\n          if (!nextContainer) return\n          currentContainer = nextContainer\n          renderHistogramSkeleton(currentContainer)\n          removeDuplicateHistograms()\n          refresh()\n        })\n      }\n      const mo = new MutationObserver(schedule)\n      mo.observe(wrapper, { childList: true, subtree: true })\n    }\n  }\n\n  function boot () {\n    const wrapper = getWrapperEl()\n    if (!wrapper) return\n    if (wrapper.dataset && wrapper.dataset.mdsJmHistogramInit === '1') return\n    if (wrapper.dataset && wrapper.dataset.mdsJmHistogramBooting === '1') return\n    if (wrapper.dataset) wrapper.dataset.mdsJmHistogramBooting = '1'\n\n    const widgetRoot = findWidgetRoot(wrapper)\n    if (widgetRoot) {\n      if (wrapper.dataset) wrapper.dataset.mdsJmHistogramInit = '1'\n      initHistogram(wrapper, widgetRoot)\n      return\n    }\n\n    // Widget may mount after DOMContentLoaded; observe briefly and retry.\n    if (!window.MutationObserver) return\n    if (wrapper.dataset && wrapper.dataset.mdsJmHistogramWaiting === '1') return\n    if (wrapper.dataset) wrapper.dataset.mdsJmHistogramWaiting = '1'\n\n    const mo = new MutationObserver(function () {\n      if (wrapper.dataset && wrapper.dataset.mdsJmHistogramInit === '1') return\n      const root = findWidgetRoot(wrapper)\n      if (!root) return\n      if (wrapper.dataset) wrapper.dataset.mdsJmHistogramInit = '1'\n      mo.disconnect()\n      initHistogram(wrapper, root)\n    })\n    mo.observe(wrapper, { childList: true, subtree: true })\n  }\n\n  document.addEventListener('DOMContentLoaded', boot)\n  window.addEventListener('load', boot, { passive: true })\n})();\n\n// Rich text: horizontal cards (text + image)\n(function () {\n  const ROOT_SELECTORS = [\n    '.article-main .article-content.rte',\n    '.page-content .description.rte',\n    '.product-info-section__content.rte',\n    '.product-info-section__content.description-content.rte'\n  ]\n  const CARD_CLASS = 'list-box-horizontal-card'\n  const CARD_TEXT_CLASS = 'list-box-horizontal-left'\n  const CARD_MEDIA_CLASS = 'list-box-horizontal-right'\n  const SKIP_CARD_CLASS = 'list-box-horizontal-skip'\n  const STANDALONE_IMAGE_CLASS = 'article-standalone-image'\n  const STANDALONE_IMAGE_WRAP_CLASS = 'article-standalone-image-wrap'\n  const LEGACY_CARD_CLASS = 'article-h-card'\n  const LEGACY_ROW_CLASS = 'article-inline-image-row'\n  const CANVA_SELECTOR = 'span[data-canva-clipboard]'\n  const EXCLUDED_CARD_H2_TITLES = new Set([\n    'panneaux a couches minces (thin film)',\n    'les panneaux solaires souples',\n    'les panneaux a demi-cellules (half-cut)'\n  ])\n\n  function isRejoignezNousPageRte (el) {\n    return !!(el instanceof HTMLElement && el.closest('.page-content--rejoinez-nous'))\n  }\n\n  function normalizeText (value) {\n    return String(value || '').replace(/\\u00a0/g, ' ').trim()\n  }\n\n  function normalizeHeadingKey (value) {\n    return normalizeText(value)\n      .toLowerCase()\n      .normalize('NFD')\n      .replace(/[\\u0300-\\u036f]/g, '')\n      .replace(/\\s+/g, ' ')\n  }\n\n  function isHeading (el) {\n    return !!(el instanceof HTMLElement && /^H[1-6]$/.test(el.tagName))\n  }\n\n  function sliceNodesFromLastHeading (nodes) {\n    if (!Array.isArray(nodes) || !nodes.length) return []\n    let lastHeadingIndex = -1\n    nodes.forEach(function (node, index) {\n      if (isHeading(node)) lastHeadingIndex = index\n    })\n    return lastHeadingIndex >= 0 ? nodes.slice(lastHeadingIndex) : nodes\n  }\n\n  function shouldExcludeHeadingFromCard (node) {\n    if (!(node instanceof HTMLElement)) return false\n    if (node.tagName !== 'H2') return false\n    return EXCLUDED_CARD_H2_TITLES.has(normalizeHeadingKey(node.textContent || ''))\n  }\n\n  function stripExcludedHeadingFromStart (nodes) {\n    if (!Array.isArray(nodes) || !nodes.length) return []\n    if (shouldExcludeHeadingFromCard(nodes[0])) return nodes.slice(1)\n    return nodes\n  }\n\n  function splitLeadingH2 (nodes) {\n    if (!Array.isArray(nodes) || !nodes.length) {\n      return []\n    }\n    const first = nodes[0]\n    if (first instanceof HTMLElement && first.tagName === 'H2') {\n      return nodes.slice(1)\n    }\n    return nodes\n  }\n\n  function paragraphTextWithoutMedia (p) {\n    if (!(p instanceof HTMLElement) || p.tagName !== 'P') return ''\n    const clone = p.cloneNode(true)\n    clone.querySelectorAll('img,br').forEach(function (node) { node.remove() })\n    return normalizeText(clone.textContent)\n  }\n\n  function nodeTextWithoutMedia (el) {\n    if (!(el instanceof HTMLElement)) return ''\n    const clone = el.cloneNode(true)\n    clone.querySelectorAll('img,br,' + CANVA_SELECTOR).forEach(function (node) { node.remove() })\n    return normalizeText(clone.textContent)\n  }\n\n  function removeCanvaArtifacts (root) {\n    if (!root || !root.querySelectorAll) return\n    root.querySelectorAll(CANVA_SELECTOR).forEach(function (el) { el.remove() })\n  }\n\n  function isTextDiv (el) {\n    if (!(el instanceof HTMLElement) || el.tagName !== 'DIV') return false\n    if (el.querySelector('img,video,iframe,table,figure')) return false\n    return nodeTextWithoutMedia(el) !== ''\n  }\n\n  function isImageOnlyBlock (el) {\n    if (!(el instanceof HTMLElement)) return false\n\n    if (el.tagName === 'IMG') {\n      const parent = el.parentElement\n      if (parent && parent.querySelectorAll('img').length === 1 && ['P', 'DIV', 'FIGURE', 'A'].includes(parent.tagName)) {\n        return false\n      }\n      return true\n    }\n\n    if (!['P', 'DIV', 'FIGURE', 'A'].includes(el.tagName)) return false\n    if (el.querySelectorAll('img').length !== 1) return false\n    if (nodeTextWithoutMedia(el) !== '') return false\n    return !el.querySelector('video,iframe,table,ul,ol,blockquote,h1,h2,h3,h4,h5,h6')\n  }\n\n  function isSpacerNode (el) {\n    if (!(el instanceof HTMLElement)) return false\n    if (!['P', 'DIV'].includes(el.tagName)) return false\n    if (isImageOnlyBlock(el)) return false\n    if (normalizeText(el.textContent) !== '') return false\n    return !el.querySelector('img,video,iframe,table,ul,ol,blockquote,h1,h2,h3,h4,h5,h6')\n  }\n\n  function isTextParagraph (el) {\n    if (!(el instanceof HTMLElement) || el.tagName !== 'P') return false\n    if (isImageOnlyBlock(el)) return false\n    return paragraphTextWithoutMedia(el) !== ''\n  }\n\n  function isCardTextNode (el) {\n    if (!(el instanceof HTMLElement)) return false\n    if (isTextParagraph(el) || isHeading(el)) return true\n    if (el.tagName === 'UL' || el.tagName === 'OL') return true\n    return isTextDiv(el)\n  }\n\n  function isManagedCardNode (el) {\n    if (!(el instanceof HTMLElement)) return false\n    return el.classList.contains(CARD_CLASS) ||\n      el.classList.contains(LEGACY_CARD_CLASS) ||\n      el.classList.contains(CARD_TEXT_CLASS) ||\n      el.classList.contains(CARD_MEDIA_CLASS)\n  }\n\n  function isArticleRteContainer (el) {\n    if (!(el instanceof HTMLElement)) return false\n    if (!document.body || !document.body.classList.contains('page-type-article')) return false\n    return !!el.closest('.article-main .article-content.rte')\n  }\n\n  function countConsecutiveLeadingSpacersBefore (node) {\n    let count = 0\n    let prev = node ? node.previousElementSibling : null\n    while (isSpacerNode(prev)) {\n      count += 1\n      prev = prev.previousElementSibling\n    }\n    return count\n  }\n\n  function shouldSkipCardForLeadingSpacers (container, imageNode) {\n    if (!isArticleRteContainer(container)) return false\n    return countConsecutiveLeadingSpacersBefore(imageNode) >= 2\n  }\n\n  function shouldAttachNextText (lastTextNode, nextParagraph) {\n    if (!(isTextParagraph(nextParagraph) || isTextDiv(nextParagraph))) return false\n    if (!lastTextNode) return true\n\n    const previousText = nodeTextWithoutMedia(lastTextNode)\n    const nextText = nodeTextWithoutMedia(nextParagraph)\n    const previousLooksComplete = /[.!?:;]\\s*$/.test(previousText)\n    const nextStartsLowercase = /^[a-z]/.test(nextText)\n\n    return !previousLooksComplete || nextStartsLowercase\n  }\n\n  function unwrapLegacyRows (rte) {\n    rte.querySelectorAll('.' + LEGACY_ROW_CLASS).forEach(function (row) {\n      if (!(row instanceof HTMLElement)) return\n      while (row.firstChild) {\n        row.parentNode.insertBefore(row.firstChild, row)\n      }\n      row.remove()\n    })\n  }\n\n  function splitMixedParagraph (p) {\n    if (!(p instanceof HTMLElement)) return null\n    if (!['P', 'DIV'].includes(p.tagName)) return null\n    if (p.closest('.' + CARD_CLASS + ', .' + LEGACY_CARD_CLASS)) return null\n\n    const images = p.querySelectorAll('img')\n    if (images.length !== 1) return null\n\n    const plainText = nodeTextWithoutMedia(p)\n    if (plainText === '') return null\n\n    const image = images[0]\n    const parentLink = image.parentElement\n    const imageNode = (\n      parentLink &&\n      parentLink.tagName === 'A' &&\n      parentLink.querySelectorAll('img').length === 1 &&\n      normalizeText(parentLink.textContent) === ''\n    )\n      ? parentLink\n      : image\n\n    const imageParagraph = document.createElement(p.tagName === 'P' ? 'p' : 'div')\n    imageParagraph.appendChild(imageNode.cloneNode(true))\n    p.insertAdjacentElement('afterend', imageParagraph)\n    imageNode.remove()\n    return imageParagraph\n  }\n\n  function normalizeMixedParagraphs (root) {\n    root.querySelectorAll('p, div').forEach(function (node) {\n      splitMixedParagraph(node)\n    })\n  }\n\n  function buildCardAroundImageParagraph (container, imageBlock) {\n    if (!(imageBlock instanceof HTMLElement) || imageBlock.parentElement !== container) return\n    if (imageBlock.closest('.' + CARD_CLASS + ', .' + LEGACY_CARD_CLASS)) return\n    if (shouldSkipCardForLeadingSpacers(container, imageBlock)) {\n      imageBlock.classList.add(SKIP_CARD_CLASS)\n      return\n    }\n\n    const beforeSpacers = []\n    const textNodes = []\n    let prev = imageBlock.previousElementSibling\n\n    // Collect all consecutive text nodes before the image.\n    while (prev && (isCardTextNode(prev) || isSpacerNode(prev))) {\n      if (isSpacerNode(prev)) {\n        beforeSpacers.unshift(prev)\n      } else {\n        textNodes.unshift(prev)\n      }\n      prev = prev.previousElementSibling\n    }\n\n    const selectedTextNodes = stripExcludedHeadingFromStart(sliceNodesFromLastHeading(textNodes))\n    const contentTextNodes = splitLeadingH2(selectedTextNodes)\n\n    const afterSpacers = []\n    let next = imageBlock.nextElementSibling\n    while (isSpacerNode(next)) {\n      afterSpacers.push(next)\n      next = next.nextElementSibling\n    }\n\n    let lastTextNode = contentTextNodes.length ? contentTextNodes[contentTextNodes.length - 1] : null\n    while (shouldAttachNextText(lastTextNode, next)) {\n      contentTextNodes.push(next)\n      lastTextNode = next\n      next = next.nextElementSibling\n      while (isSpacerNode(next)) {\n        afterSpacers.push(next)\n        next = next.nextElementSibling\n      }\n    }\n\n    if (!contentTextNodes.length) return\n\n    const card = document.createElement('div')\n    card.className = CARD_CLASS\n\n    const textWrap = document.createElement('div')\n    textWrap.className = CARD_TEXT_CLASS\n\n    const mediaWrap = document.createElement('div')\n    mediaWrap.className = CARD_MEDIA_CLASS\n\n    container.insertBefore(card, contentTextNodes[0])\n    card.appendChild(textWrap)\n    card.appendChild(mediaWrap)\n\n    contentTextNodes.forEach(function (node) {\n      if (node && node.parentElement === container) textWrap.appendChild(node)\n    })\n\n    const firstTextNode = contentTextNodes[0]\n    beforeSpacers.forEach(function (spacer) {\n      if (!(spacer && spacer.parentElement === container)) return\n      if (firstTextNode.compareDocumentPosition(spacer) & Node.DOCUMENT_POSITION_FOLLOWING) {\n        spacer.remove()\n      }\n    })\n\n    afterSpacers.forEach(function (spacer) {\n      if (spacer && spacer.parentElement === container) spacer.remove()\n    })\n\n    if (imageBlock.parentElement === container) {\n      mediaWrap.appendChild(imageBlock)\n    }\n  }\n\n  function buildCardFromDirectChildren (container) {\n    if (!(container instanceof HTMLElement)) return\n    if (isManagedCardNode(container)) return\n\n    const children = Array.from(container.children).filter(function (node) {\n      return node instanceof HTMLElement && !isManagedCardNode(node)\n    })\n    if (children.length < 2) return\n\n    let imageIndex = -1\n    for (let i = children.length - 1; i >= 0; i--) {\n      if (isImageOnlyBlock(children[i])) {\n        imageIndex = i\n        break\n      }\n    }\n    if (imageIndex <= 0) return\n\n    const imageNode = children[imageIndex]\n    if (shouldSkipCardForLeadingSpacers(container, imageNode)) {\n      imageNode.classList.add(SKIP_CARD_CLASS)\n      return\n    }\n\n    const before = children.slice(0, imageIndex)\n    const selectedBefore = stripExcludedHeadingFromStart(sliceNodesFromLastHeading(before))\n    const contentBefore = splitLeadingH2(selectedBefore)\n    const beforeHasText = contentBefore.some(isCardTextNode)\n    if (!beforeHasText) return\n\n    const beforeAllowed = contentBefore.every(function (node) {\n      return isCardTextNode(node) || isSpacerNode(node)\n    })\n    if (!beforeAllowed) return\n\n    const card = document.createElement('div')\n    card.className = CARD_CLASS\n\n    const textWrap = document.createElement('div')\n    textWrap.className = CARD_TEXT_CLASS\n\n    const mediaWrap = document.createElement('div')\n    mediaWrap.className = CARD_MEDIA_CLASS\n\n    container.insertBefore(card, contentBefore[0])\n    card.appendChild(textWrap)\n    card.appendChild(mediaWrap)\n\n    contentBefore.forEach(function (node) {\n      if (!node.parentElement || node.parentElement !== container) return\n      if (isSpacerNode(node)) {\n        node.remove()\n      } else {\n        textWrap.appendChild(node)\n      }\n    })\n\n    if (imageNode.parentElement === container) {\n      mediaWrap.appendChild(imageNode)\n    }\n  }\n\n  function markStandaloneArticleImages (root) {\n    if (!(root instanceof HTMLElement)) return\n    if (!document.body || !document.body.classList.contains('page-type-article')) return\n\n    root.querySelectorAll('.' + STANDALONE_IMAGE_WRAP_CLASS).forEach(function (el) {\n      el.classList.remove(STANDALONE_IMAGE_WRAP_CLASS)\n    })\n\n    root.querySelectorAll('img').forEach(function (img) {\n      if (!(img instanceof HTMLImageElement)) return\n      img.classList.remove(STANDALONE_IMAGE_CLASS)\n\n      if (img.closest('.' + CARD_CLASS + ', .' + LEGACY_CARD_CLASS)) return\n      if (img.closest('.img-wrapper')) return\n\n      img.classList.add(STANDALONE_IMAGE_CLASS)\n\n      const linkParent = img.parentElement && img.parentElement.tagName === 'A'\n        ? img.parentElement\n        : null\n      const wrap = (linkParent ? linkParent.parentElement : img.parentElement) || null\n      if (wrap instanceof HTMLElement && !wrap.closest('.' + CARD_CLASS + ', .' + LEGACY_CARD_CLASS)) {\n        wrap.classList.add(STANDALONE_IMAGE_WRAP_CLASS)\n      }\n    })\n  }\n\n  function buildCardsInRoot (root) {\n    if (isRejoignezNousPageRte(root)) return\n\n    removeCanvaArtifacts(root)\n    unwrapLegacyRows(root)\n    normalizeMixedParagraphs(root)\n\n    // First pass: handle wrappers with direct child blocks (common in rich-text/metafield markup).\n    const containers = [root].concat(Array.from(root.querySelectorAll('div, section, article, li, td, blockquote')))\n    containers.forEach(buildCardFromDirectChildren)\n\n    // Second pass: fallback around isolated image-only nodes.\n    const imageParagraphs = Array.from(root.querySelectorAll('p, div, figure, a, img')).filter(isImageOnlyBlock)\n    imageParagraphs.forEach(function (imageParagraph) {\n      const container = imageParagraph.parentElement\n      if (container) buildCardAroundImageParagraph(container, imageParagraph)\n    })\n\n    markStandaloneArticleImages(root)\n  }\n\n  // Disabled: keep the featured image in the hero area at the top of article pages.\n  // Previously this moved the hero image into the first rich-text card for text-only posts,\n  // which caused inconsistent layouts across articles.\n  function buildCardFromFeaturedImage (rte) {\n    return\n  }\n\n  function run (root) {\n    const scope = root && root.querySelectorAll ? root : document\n    removeCanvaArtifacts(scope)\n    ROOT_SELECTORS.forEach(function (selector) {\n      scope.querySelectorAll(selector).forEach(function (rte) {\n        buildCardsInRoot(rte)\n        buildCardFromFeaturedImage(rte)\n      })\n    })\n  }\n\n  run(document)\n  document.addEventListener('DOMContentLoaded', function () { run(document) })\n  window.addEventListener('load', function () { run(document) }, { passive: true })\n  document.addEventListener('shopify:section:load', function (e) {\n    run(e && e.target ? e.target : document)\n  })\n})();\n\n// Remove Canva clipboard artifacts accidentally pasted from Canva\n(function () {\n  const SELECTOR = 'span[data-canva-clipboard]'\n\n  function clean (root) {\n    const scope = root && root.querySelectorAll ? root : document\n    scope.querySelectorAll(SELECTOR).forEach(function (el) {\n      el.remove()\n    })\n  }\n\n  clean(document)\n  document.addEventListener('DOMContentLoaded', function () { clean(document) })\n  window.addEventListener('load', function () { clean(document) }, { passive: true })\n  document.addEventListener('shopify:section:load', function (e) {\n    clean(e && e.target ? e.target : document)\n  })\n\n  if (window.MutationObserver) {\n    const observer = new MutationObserver(function (mutations) {\n      for (const mutation of mutations) {\n        for (const node of mutation.addedNodes) {\n          if (!(node instanceof Element)) continue\n          if (node.matches(SELECTOR)) {\n            node.remove()\n            continue\n          }\n          clean(node)\n        }\n      }\n    })\n    observer.observe(document.documentElement, { childList: true, subtree: true })\n  }\n})();\n\n// Sous-menus du menu desktop : par d\u00E9faut align\u00E9s sur le bord gauche de leur\n// item. Quand la place manque avant le bord droit de la fen\u00EAtre (dernier item\n// d'une rang\u00E9e, fen\u00EAtres de 1200 \u00E0 ~1300 px), on bascule le sous-menu en\n// alignement droite (classe styl\u00E9e dans custom.css) pour qu'il reste\n// enti\u00E8rement visible au survol au lieu d'\u00EAtre rogn\u00E9 par l'overflow-x du body.\n(function () {\n  function alignDesktopSubmenus () {\n    const menus = document.querySelectorAll('#navbar-desktop .nav-desktop-menu .nav-item.dropdown > .dropdown-menu')\n    const viewport = document.documentElement.clientWidth\n    menus.forEach(function (menu) {\n      const item = menu.closest('.nav-item')\n      if (!item) return\n      menu.classList.remove('dropdown-menu--overflow-end')\n      if (!menu.offsetWidth) return\n      const itemLeft = item.getBoundingClientRect().left\n      if (itemLeft + menu.offsetWidth > viewport - 8) {\n        menu.classList.add('dropdown-menu--overflow-end')\n      }\n    })\n  }\n\n  let resizeTimer = null\n  window.addEventListener('resize', function () {\n    clearTimeout(resizeTimer)\n    resizeTimer = setTimeout(alignDesktopSubmenus, 150)\n  }, { passive: true })\n  document.addEventListener('DOMContentLoaded', alignDesktopSubmenus)\n  window.addEventListener('load', alignDesktopSubmenus, { passive: true })\n  document.addEventListener('shopify:section:load', alignDesktopSubmenus)\n})();\n\n/*\n  Compte \u00E0 rebours \u00AB Vente flash \u00BB \u2014 DEUX emplacements, un seul moteur :\n    - bandeau en bas de l'image des cartes produit (pages collection) ;\n    - bloc sous le prix de la fiche produit (fiches standard ET fiches kit).\n  Markup et conditions d'affichage : snippets/flash-sale-timer.liquid.\n  Un SEUL intervalle par page : \u00E0 chaque seconde on balaie les \u00E9l\u00E9ments\n  [data-flash-timer] pr\u00E9sents, ce qui couvre d'office les cartes ajout\u00E9es par\n  l'AJAX de la collection (filtres, tri, \u00AB Voir plus \u00BB) sans rien r\u00E9initialiser.\n  La date de fin (data-flash-end, sans fuseau) est lue en heure LOCALE du\n  visiteur, comme la banni\u00E8re d'\u00E9v\u00E9nement de la page Vente flash.\n  Offre termin\u00E9e ou date invalide : l'\u00E9l\u00E9ment est retir\u00E9, le reste est intact.\n*/\n;(function () {\n  let timer = null\n\n  const pad = (n) => String(n).padStart(2, '0')\n\n  // \u00AB 02j 14:05:33 \u00BB au-del\u00E0 de 24 h, \u00AB 14:05:33 \u00BB en dessous.\n  // S\u00E9parateur = espace demi-cadratin U+2002 (~2\u00D7 une espace normale) : les espaces\n  // cons\u00E9cutives seraient fusionn\u00E9es au rendu, U+2002 ne l'est pas. Pour resserrer\n  // ou \u00E9largir, changer ce caract\u00E8re (U+2009 fine, U+2003 cadratin).\n  const format = (seconds) => {\n    const days = Math.floor(seconds / 86400)\n    const rest = pad(Math.floor(seconds / 3600) % 24) + ':' + pad(Math.floor(seconds / 60) % 60) + ':' + pad(seconds % 60)\n    return days > 0 ? days + 'j\u2002' + rest : rest\n  }\n\n  const stop = () => {\n    if (timer) {\n      clearInterval(timer)\n      timer = null\n    }\n  }\n\n  const tick = () => {\n    const banners = document.querySelectorAll('[data-flash-timer]')\n    // Plus aucun bandeau (offres termin\u00E9es, collection sans produit flash) :\n    // inutile de garder un intervalle qui tourne dans le vide.\n    if (!banners.length) {\n      stop()\n      return\n    }\n\n    const now = Date.now()\n\n    banners.forEach(banner => {\n      const target = new Date(banner.dataset.flashEnd).getTime()\n\n      if (isNaN(target) || target - now <= 0) {\n        banner.remove()\n        return\n      }\n\n      const value = banner.querySelector('[data-flash-timer-value]')\n      if (value) value.textContent = format(Math.floor((target - now) / 1000))\n      banner.classList.add('is-ready')\n    })\n  }\n\n  const start = () => {\n    tick()\n    // Rien \u00E0 d\u00E9compter sur cette page : pas d'intervalle du tout.\n    if (!timer && document.querySelector('[data-flash-timer]')) {\n      timer = setInterval(tick, 1000)\n    }\n  }\n\n  start()\n  // Cartes inject\u00E9es par l'AJAX de la collection : elles affichent encore le\n  // gabarit \u00AB --:--:-- \u00BB et restent invisibles tant que .is-ready n'est pas pos\u00E9e.\n  window.addEventListener('kt.collection.loaded', start)\n  // Retour au premier plan : les intervalles sont brid\u00E9s en arri\u00E8re-plan, on\n  // recale l'affichage tout de suite au lieu d'attendre le prochain tick.\n  document.addEventListener('visibilitychange', () => {\n    if (!document.hidden) start()\n  })\n})()\n\n// Menu \u00AB compte \u00BB du header haut (maquette 3a, snippets/header-account).\n// L'ouverture au survol et au focus clavier est purement CSS. Ce script ne\n// couvre que ce que le CSS ne peut pas faire :\n//  - pointeur grossier (tablette tactile) : le premier appui ouvre le menu au\n//    lieu de partir droit sur /account, qui le rendrait inatteignable ;\n//  - fermeture par Echap ou par un appui en dehors ;\n//  - aria-expanded tenu a jour.\n;(function () {\n  const FINE_POINTER = window.matchMedia ? window.matchMedia('(hover: hover) and (pointer: fine)') : null\n  const WIDGET = '[data-header-account]'\n\n  const widgetOf = (node) => (node && node.closest ? node.closest(WIDGET) : null)\n  const toggleOf = (widget) => widget.querySelector('.header-account__toggle')\n\n  const expose = (widget, open) => {\n    const toggle = toggleOf(widget)\n    if (toggle) toggle.setAttribute('aria-expanded', open ? 'true' : 'false')\n  }\n\n  // .is-dismissed l'emporte sur :hover et :focus-within (CSS), encore vrais\n  // apres une fermeture explicite tant que le curseur ou le focus n'a pas\n  // quitte le widget \u2014 sans elle, Echap et le second appui rouvriraient le\n  // menu dans la foulee. Levee des que le pointeur ou le focus repart.\n  const close = (widget, dismiss) => {\n    widget.classList.remove('is-open')\n    if (dismiss) widget.classList.add('is-dismissed')\n    expose(widget, false)\n  }\n\n  const closeOthers = (except) => {\n    document.querySelectorAll(WIDGET).forEach((widget) => {\n      if (widget !== except) close(widget, false)\n    })\n  }\n\n  document.addEventListener('click', (event) => {\n    const toggle = event.target.closest && event.target.closest('.header-account__toggle')\n    const widget = toggle ? widgetOf(toggle) : null\n\n    if (!widget) {\n      closeOthers(null)\n      return\n    }\n\n    closeOthers(widget)\n    widget.classList.remove('is-dismissed')\n\n    // Pointeur fin : le survol a deja ouvert le menu, le clic suit le lien.\n    if (FINE_POINTER && FINE_POINTER.matches) return\n\n    if (widget.classList.contains('is-open')) {\n      // Second appui : on referme, sans partir sur /account \u2014 le compte reste\n      // accessible par l'entree \u00AB Mon compte \u00BB du menu.\n      event.preventDefault()\n      close(widget, true)\n      return\n    }\n\n    // Premier appui sur ecran tactile : ouvrir plutot que naviguer, sinon le\n    // menu serait inatteignable.\n    event.preventDefault()\n    widget.classList.add('is-open')\n    expose(widget, true)\n  })\n\n  document.addEventListener('keydown', (event) => {\n    if (event.key !== 'Escape') return\n    const widget = document.querySelector(WIDGET + '.is-open') || widgetOf(document.activeElement)\n    if (!widget || widget.classList.contains('is-dismissed')) return\n    close(widget, true)\n    const toggle = toggleOf(widget)\n    if (toggle) toggle.focus()\n  })\n\n  // Le pointeur quitte le widget : l'etat \u00AB ferme de force \u00BB n'a plus lieu\n  // d'etre, le prochain survol doit rouvrir normalement.\n  document.addEventListener('mouseout', (event) => {\n    const widget = widgetOf(event.target)\n    if (!widget || widget.contains(event.relatedTarget)) return\n    widget.classList.remove('is-dismissed')\n  })\n\n  // Au clavier c'est :focus-within (CSS) qui ouvre le menu : on aligne\n  // aria-expanded dessus. Delegation sur document \u2014 le header peut etre\n  // re-rendu par l'API Section Rendering (mise a jour du panier).\n  document.addEventListener('focusin', (event) => {\n    const focused = widgetOf(event.target)\n    document.querySelectorAll(WIDGET).forEach((widget) => {\n      const open = (widget === focused || widget.classList.contains('is-open')) &&\n        !widget.classList.contains('is-dismissed')\n      expose(widget, open)\n    })\n  })\n\n  document.addEventListener('focusout', (event) => {\n    const widget = widgetOf(event.target)\n    if (!widget) return\n    // focusout precede la prise de focus par la cible suivante.\n    setTimeout(() => {\n      if (widget.contains(document.activeElement)) return\n      widget.classList.remove('is-dismissed')\n      if (!widget.classList.contains('is-open')) expose(widget, false)\n    }, 0)\n  })\n})()\n"],
  "mappings": "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",
  "names": []
}
