{
  "version": 3,
  "sources": ["/cdn/shop/t/81/assets/pdp-clean-v4-reviews-v4.js?lly=laley-custom-20260808-release-v313"],
  "sourcesContent": ["/* ============================================================\n   Laley PDP Clean v4 \u2014 reviews\n   Modul\u00E6r PDP-runtime. Den gamle v3-monolitten er kun historisk arkiv.\n   Registrerer metoder p\u00E5 LaleyPDP.prototype via PDP.registerModule.\n   Krever pdp-clean-v4-core.js lastet f\u00F8rst (defer-rekkef\u00F8lge i product-clean-v3-1.liquid).\n   ============================================================ */\n(() => {\n  const PDP = window.LaleyPDPCleanV4;\n  if (!PDP || typeof PDP.registerModule !== 'function') {\n    console.error('[PDP] Kjerne mangler \u2014 hopper over modul: reviews');\n    return;\n  }\n  const { escapeHTML } = PDP.utils;\n\n  const readNumber = (values) => {\n    for (const value of values) {\n      if (value === undefined || value === null || value === '') continue;\n      const number = Number(String(value).replace(',', '.'));\n      if (Number.isFinite(number)) return number;\n    }\n    return null;\n  };\n\n  const parseReviewStateObject = (parsed) => {\n    if (!parsed || typeof parsed !== 'object') return null;\n    const aggregate = parsed.aggregateRating || parsed;\n    const ratingSource = parsed.reviewRating || aggregate;\n    const count = readNumber([\n      aggregate.reviewCount,\n      aggregate.rating_count,\n      aggregate.ratingCount,\n      parsed.reviewCount,\n      parsed.rating_count,\n      parsed.ratingCount,\n    ]) || 0;\n    const rating = readNumber([\n      aggregate.ratingValue,\n      aggregate.rating?.value,\n      ratingSource.ratingValue,\n      ratingSource.value,\n      ratingSource.rating?.value,\n      parsed.rating?.value,\n      parsed.rating,\n    ]) || 5;\n    if (count > 0) return { count, rating: Math.max(0, Math.min(5, rating)) };\n    return null;\n  };\n\n  const extractJsonObjectAfter = (text, marker) => {\n    const markerIndex = text.indexOf(marker);\n    if (markerIndex < 0) return null;\n    const start = text.indexOf('{', markerIndex);\n    if (start < 0) return null;\n    let depth = 0;\n    let inString = false;\n    let escaped = false;\n    for (let i = start; i < text.length; i += 1) {\n      const char = text[i];\n      if (inString) {\n        if (escaped) {\n          escaped = false;\n        } else if (char === '\\\\') {\n          escaped = true;\n        } else if (char === '\"') {\n          inString = false;\n        }\n        continue;\n      }\n      if (char === '\"') {\n        inString = true;\n      } else if (char === '{') {\n        depth += 1;\n      } else if (char === '}') {\n        depth -= 1;\n        if (depth === 0) return text.slice(start, i + 1);\n      }\n    }\n    return null;\n  };\n\n  const readStructuredDataReviewState = () => {\n    const scripts = document.querySelectorAll('script[type=\"application/ld+json\"]');\n    const findState = (value) => {\n      if (!value) return null;\n      if (Array.isArray(value)) {\n        for (const item of value) {\n          const state = findState(item);\n          if (state) return state;\n        }\n        return null;\n      }\n      if (typeof value !== 'object') return null;\n      const state = parseReviewStateObject(value);\n      if (state) return state;\n      if (value['@graph']) return findState(value['@graph']);\n      return null;\n    };\n    for (const script of scripts) {\n      try {\n        const state = findState(JSON.parse(script.textContent || '{}'));\n        if (state) return state;\n      } catch (e) {\n        // Ignore unrelated or malformed JSON-LD from apps.\n      }\n    }\n    return null;\n  };\n\n  const readKlaviyoMetafieldReviewState = () => {\n    const scripts = document.querySelectorAll('script#viewed_product, script');\n    for (const script of scripts) {\n      const text = script.textContent || '';\n      if (!text.includes('MetafieldReviews')) continue;\n      const json = extractJsonObjectAfter(text, 'MetafieldReviews');\n      if (!json) continue;\n      try {\n        const state = parseReviewStateObject(JSON.parse(json));\n        if (state) return state;\n      } catch (e) {\n        // Klaviyo owns this script shape; ignore and fall back to widget text.\n      }\n    }\n    return readStructuredDataReviewState();\n  };\n\n  const reviewStars = (rating) => {\n    const value = Number(String(rating || 5).replace(',', '.')) || 5;\n    const rounded = Math.max(0, Math.min(5, Math.round(value * 2) / 2));\n    const fullStars = Math.floor(rounded);\n    const halfStar = rounded % 1 >= 0.5;\n    const emptyStars = Math.max(0, 5 - fullStars - (halfStar ? 1 : 0));\n    return `${'\u2605'.repeat(fullStars)}${halfStar ? '\u00BD' : ''}${'\u2606'.repeat(emptyStars)}`;\n  };\n\n\n  const getProductId = (section) => (\n    section?.dataset?.productId\n    || document.querySelector('[data-pdp-section]')?.dataset?.productId\n    || ''\n  );\n  const nodeMatchesProduct = (node, productId) => {\n    if (!node || !productId) return true;\n    const ids = [\n      node.dataset?.productId,\n      node.dataset?.id,\n      node.getAttribute?.('data-product-id'),\n      node.getAttribute?.('data-id'),\n    ].filter(Boolean);\n    return !ids.length || ids.includes(productId);\n  };\n  const findProductScoped = (selector, section) => {\n    const productId = getProductId(section);\n    const local = section?.querySelector?.(selector);\n    if (local && nodeMatchesProduct(local, productId)) return local;\n    const exact = Array.from(document.querySelectorAll(selector))\n      .find((node) => nodeMatchesProduct(node, productId));\n    return exact || local || document.querySelector(selector);\n  };\n  const isReviewsSummaryRoot = (node) => Boolean(node?.closest?.('[data-pdp-reviews-summary]'));\n  const reviewWriteButtonClass = 'pdp-clean__reviews-write lly-action lly-action--secondary lly-action--compact';\n  const findReviewsSection = (section) => findProductScoped('[data-pdp-reviews-section]', section);\n  const findFullReviewsRoot = (section) => {\n    const productId = getProductId(section);\n    const local = section?.querySelector?.('#klaviyo-reviews-all');\n    if (local && nodeMatchesProduct(local, productId) && !isReviewsSummaryRoot(local)) return local;\n    return Array.from(document.querySelectorAll('#klaviyo-reviews-all'))\n      .find((node) => nodeMatchesProduct(node, productId) && !isReviewsSummaryRoot(node)) || null;\n  };\n  const findReviewsRoot = (section) => findFullReviewsRoot(section) || findProductScoped('#klaviyo-reviews-all', section);\n  const readReviewQuestionCount = (root) => {\n    const questionTab = Array.from(root?.querySelectorAll?.('[role=\"tab\"]') || [])\n      .find((tab) => /questions?|sp\u00F8rsm\u00E5l/i.test(tab.textContent || ''));\n    return Number(String(questionTab?.textContent || '').match(/\\d+/)?.[0] || 0);\n  };\n  const getReviewSourceId = (section) => getProductId(section);\n  const reviewsFallbackAllSelector = '[data-pdp-reviews-fallback-all]';\n  const removeElement = (node) => {\n    if (node?.parentNode) node.parentNode.removeChild(node);\n  };\n  const removeRootFallbackAll = (root) => {\n    root?.querySelectorAll?.(reviewsFallbackAllSelector).forEach(removeElement);\n  };\n  const findReviewFallbackAll = (root, section) => {\n    const scope = section || root?.parentElement;\n    return scope?.querySelector?.(reviewsFallbackAllSelector) || root?.querySelector?.(reviewsFallbackAllSelector);\n  };\n  const removeReviewFallbackAll = (root, section) => {\n    removeRootFallbackAll(root);\n    const scope = section || root?.parentElement;\n    scope?.querySelectorAll?.(reviewsFallbackAllSelector).forEach(removeElement);\n  };\n  const hasRenderedReviews = (root) => Boolean(root?.querySelector?.('#klaviyo-product-reviews-wrapper, .reviews_all_container, .kl_reviews__list, .kl_reviews__summary'))\n    && root.textContent.trim().length > 0;\n  const readRenderedKlaviyoReviewState = (root) => {\n    if (!root?.querySelector?.('.kl_reviews__summary')) return null;\n    const countCandidates = [\n      root.querySelector('.kl_reviews__summary__stars__count')?.textContent || '',\n      root.querySelector('.kl_reviews__list__tab small')?.textContent || '',\n      root.querySelector('.kl_reviews__list__tab')?.textContent || '',\n    ];\n    const countHit = countCandidates\n      .map((text) => String(text).match(/\\b(\\d+)\\b/))\n      .find(Boolean);\n    const displayedCount = Number(countHit?.[1] || 0);\n    const histogram = Array.from(root.querySelectorAll('.kl_reviews__histogram__bar--background[aria-label]'))\n      .map((node) => String(node.getAttribute('aria-label') || '').match(/(\\d+)\\s+(?:reviews?|anmeldelser?)\\s+(?:with|med)\\s+([1-5])\\s+(?:stars?|stjerner?)/i))\n      .filter(Boolean)\n      .map((match) => ({ count: Number(match[1]) || 0, stars: Number(match[2]) || 0 }));\n    const histogramCount = histogram.reduce((sum, row) => sum + row.count, 0);\n    const histogramRating = histogramCount > 0\n      ? histogram.reduce((sum, row) => sum + (row.count * row.stars), 0) / histogramCount\n      : 0;\n    const count = histogramCount || displayedCount;\n    const ratingCandidates = [\n      root.querySelector('.kl_reviews__summary__average_value')?.textContent || '',\n      root.querySelector('.kl_reviews__summary__average')?.getAttribute?.('aria-label') || '',\n      root.querySelector('.kl_reviews__summary__average')?.textContent || '',\n    ].join(' ');\n    const ratingHit = ratingCandidates.match(/([0-5](?:[.,]\\d+)?)/);\n    const displayedRating = Number(String(ratingHit?.[1] || 0).replace(',', '.')) || 0;\n    const rating = histogramRating || displayedRating;\n    return {\n      count: Number.isFinite(count) ? Math.max(0, count) : 0,\n      rating: Math.max(0, Math.min(5, rating)),\n    };\n  };\n  const namespaceRenderedKlaviyoIds = (root, sourceId) => {\n    if (!root || !sourceId) return;\n    const suffix = String(sourceId).replace(/[^A-Za-z0-9_-]/g, '-');\n    const replacements = new Map();\n    root.querySelectorAll('[id]').forEach((node) => {\n      const originalId = node.id || '';\n      const sharedId = originalId === 'reviewslist' || originalId.startsWith('kl_reviews_');\n      if (!sharedId || originalId.endsWith(`--${suffix}`)) return;\n      const namespacedId = `${originalId}--${suffix}`;\n      replacements.set(originalId, namespacedId);\n      node.id = namespacedId;\n    });\n    if (!replacements.size) return;\n    const referenceAttributes = ['aria-controls', 'aria-labelledby', 'aria-describedby', 'aria-owns', 'for', 'list'];\n    root.querySelectorAll(referenceAttributes.map((attribute) => `[${attribute}]`).join(',')).forEach((node) => {\n      referenceAttributes.forEach((attribute) => {\n        const value = node.getAttribute(attribute);\n        if (!value) return;\n        const next = value.split(/\\s+/).map((token) => replacements.get(token) || token).join(' ');\n        if (next !== value) node.setAttribute(attribute, next);\n      });\n    });\n  };\n  const isReviewHash = (hash) => {\n    const value = String(hash || '').toLowerCase();\n    return value === '#klaviyo-reviews-all'\n      || value === '#reviews'\n      || value === '#anmeldelser'\n      || value.indexOf('#anmeldelser-') === 0;\n  };\n  const anchorHasReviewHash = (node) => {\n    if (!node || node.tagName !== 'A') return false;\n    const href = node.getAttribute('href') || '';\n    if (!href || href.indexOf('#') < 0) return false;\n    try {\n      return isReviewHash(new URL(href, window.location.href).hash);\n    } catch (e) {\n      return isReviewHash(href.slice(href.indexOf('#')));\n    }\n  };\n  const shouldPreserveReviewHash = () => {\n    if (!isReviewHash(window.location.hash)) return false;\n    if (window.__laleyInitialReviewHashHandled) return false;\n    const preserveUntil = Number(window.__laleyPreserveReviewHashUntil || 0);\n    return preserveUntil && Date.now() < preserveUntil;\n  };\n  const clearReviewHash = (options = {}) => {\n    if (!isReviewHash(window.location.hash) || !window.history?.replaceState) return;\n    if (!options.force && shouldPreserveReviewHash()) return;\n    try {\n      window.history.replaceState(window.history.state, '', window.location.pathname + window.location.search);\n    } catch (e) {}\n  };\n  const reviewFallbackControl = (existing) => {\n    if (existing?.tagName === 'A') return existing;\n    const anchor = document.createElement('a');\n    if (existing?.parentNode) existing.parentNode.replaceChild(anchor, existing);\n    return anchor;\n  };\n  let klaviyoRenderLastAt = 0;\n  const callKlaviyoReviewRenderers = (force = false) => {\n    const now = Date.now();\n    if (!force && now - klaviyoRenderLastAt < 350) return false;\n    klaviyoRenderLastAt = now;\n    clearReviewHash();\n    let called = false;\n    [\n      window.klReviewsObject,\n      window.KlaviyoReviews,\n      window.klaviyoReviews,\n      window.klaviyoReviewsProductDesignMode,\n    ].forEach((candidate) => {\n      if (!candidate || (typeof candidate !== 'object' && typeof candidate !== 'function')) return;\n      ['renderWidgets', 'render', 'hydrate', 'init'].forEach((method) => {\n        if (typeof candidate[method] !== 'function') return;\n        try {\n          candidate[method]();\n          called = true;\n        } catch (e) {\n          // Klaviyo owns these globals; failed best-effort render calls are non-fatal.\n        }\n      });\n    });\n    document.dispatchEvent(new CustomEvent('laley:pdp:klaviyo-reviews-render', { bubbles: true }));\n    return called;\n  };\n  const isNearViewport = (el, margin = 900) => {\n    if (!el) return false;\n    const rect = el.getBoundingClientRect();\n    return rect.top < window.innerHeight + margin && rect.bottom > -margin;\n  };\n  const readReviewState = (section) => {\n    const block = section?.querySelector?.('[data-pdp-reviews-summary]');\n    const root = findReviewsRoot(section);\n    const attrCount = Number(block?.dataset.reviewCount || root?.dataset.reviewCount || 0);\n    const attrRating = Number(String(block?.dataset.reviewRating || root?.dataset.reviewRating || 5).replace(',', '.')) || 5;\n    if (attrCount > 0) return { count: attrCount, rating: Math.max(0, Math.min(5, attrRating)) };\n    return readKlaviyoMetafieldReviewState();\n  };\n\n  const setAttributeIfChanged = (el, name, value) => {\n    if (!el) return;\n    const next = String(value);\n    if (el.getAttribute(name) !== next) el.setAttribute(name, next);\n  };\n\n  const setTextIfChanged = (el, value) => {\n    if (!el) return;\n    const next = String(value);\n    if (el.textContent !== next) el.textContent = next;\n  };\n\n  const syncReviewCountDisplays = (section, value, rating) => {\n    const count = Number(String(value || '').match(/\\d+/)?.[0] || 0);\n    if (!Number.isFinite(count) || count < 1) return false;\n    const root = findReviewsRoot(section);\n    const reviewsSection = findReviewsSection(section);\n    const block = section?.querySelector?.('[data-pdp-reviews-summary]') || document.querySelector('[data-pdp-reviews-summary]');\n    const normalizedRating = Number(String(rating || block?.dataset.reviewRating || root?.dataset.reviewRating || 5).replace(',', '.')) || 5;\n    const displayCount = count;\n    const displayRating = normalizedRating;\n    const countWord = displayCount === 1 ? 'anmeldelse' : 'anmeldelser';\n\n    setAttributeIfChanged(root, 'data-review-count', count);\n    setAttributeIfChanged(root, 'data-review-rating', normalizedRating);\n    setAttributeIfChanged(reviewsSection, 'data-review-count', displayCount);\n    setAttributeIfChanged(reviewsSection, 'data-review-rating', displayRating);\n    reviewsSection?.classList.toggle('is-review-list-short', count < 5);\n    if (block) {\n      if (block.dataset.reviewCount !== String(displayCount)) block.dataset.reviewCount = String(displayCount);\n      if (block.dataset.reviewRating !== String(displayRating)) block.dataset.reviewRating = String(displayRating);\n      block.classList.add('has-reviews');\n      block.classList.remove('is-loading', 'is-empty', 'is-confirmed-empty');\n      const fallback = block.querySelector('[data-pdp-reviews-fallback]');\n      if (fallback) {\n        setAttributeIfChanged(fallback, 'aria-label', `${displayCount} ${countWord}`);\n        const spans = fallback.querySelectorAll('span');\n        const label = spans[spans.length - 1];\n        setTextIfChanged(label, `${displayCount} ${countWord}`);\n      }\n    }\n    return true;\n  };\n\n  const primeReviewFallback = (section) => {\n    const block = section?.querySelector?.('[data-pdp-reviews-summary]');\n    if (!block) return;\n    const root = findReviewsRoot(section);\n    const attrCount = Number(block.dataset.reviewCount || root?.dataset.reviewCount || 0);\n    const attrRating = Number(String(block.dataset.reviewRating || root?.dataset.reviewRating || 5).replace(',', '.')) || 5;\n    const state = attrCount > 0\n      ? { count: attrCount, rating: Math.max(0, Math.min(5, attrRating)) }\n      : readKlaviyoMetafieldReviewState();\n    if (!state?.count) return;\n\n    syncReviewCountDisplays(section, state.count, state.rating || 5);\n    block.classList.add('has-reviews');\n    block.classList.remove('is-loading', 'is-empty', 'is-confirmed-empty');\n\n    // V\u00C5R rad eier visningen permanent (Sondre juli-26): Klaviyo-raden\n    // skjules i CSS (beholdes usynlig som hydrerings-anker for kicket) \u2014\n    // dermed null dobbel-rad/CLS ved load, og alltid underline-typografien.\n    const existing = block.querySelector('[data-pdp-reviews-fallback]');\n    const fallback = reviewFallbackControl(existing);\n    fallback.setAttribute('href', '#anmeldelser');\n    fallback.removeAttribute('type');\n    fallback.className = 'pdp-clean__reviews-fallback';\n    fallback.setAttribute('data-pdp-reviews-fallback', '');\n    const countWord = Number(state.count) === 1 ? 'anmeldelse' : 'anmeldelser';\n    const nextHTML = `<span class=\"pdp-clean__reviews-fallback-stars\" aria-hidden=\"true\">${reviewStars(state.rating)}</span><span class=\"lly-link-underline\">${escapeHTML(state.count)} ${countWord}</span>`;\n    setAttributeIfChanged(fallback, 'aria-label', `${state.count} ${countWord}`);\n    if (fallback.innerHTML !== nextHTML) fallback.innerHTML = nextHTML;\n    if (!existing) block.prepend(fallback);\n  };\n\n  PDP.hooks.primeReviewFallback = primeReviewFallback;\n\n  PDP.registerModule('reviews', {\n    nudgeKlaviyoHydration() {\n      const fire = () => {\n        const variantForEvent = this.currentVariant || this.variantFromInput() || this.variants[0] || null;\n        document.dispatchEvent(new CustomEvent('variant:change', {\n          bubbles: true,\n          detail: {\n            variant: variantForEvent,\n            productId: this.section.dataset.productId,\n            sectionId: this.section.dataset.sectionId,\n          },\n        }));\n        // Theme-spesifikk event for kompatibilitet med Laley-tema\n        document.dispatchEvent(new CustomEvent('theme:variant:change', {\n          bubbles: true,\n          detail: { variant: variantForEvent, productId: this.section.dataset.productId },\n        }));\n        this.pokeKlaviyoReviews();\n      };\n      // One initial product event and one delayed pass cover Klaviyo's two normal\n      // load orders without keeping a retry loop alive below the fold.\n      fire();\n      const timer = window.setTimeout(fire, 1400);\n      this.timers.push(timer);\n    },\n\n    pokeKlaviyoReviews() {\n      const productId = this.section.dataset.productId;\n      if (!productId) return;\n      this.ensureReviewsMount?.();\n      const productHandle = this.section.dataset.productHandle || '';\n      const productUrl = this.section.dataset.productUrl || '';\n      const reviewSourceId = getReviewSourceId(this.section) || productId;\n      this.section.querySelectorAll('[data-pdp-reviews-summary]').forEach((el) => {\n        el.setAttribute('data-id', productId);\n        el.setAttribute('data-product-id', productId);\n        if (productHandle) el.setAttribute('data-product-handle', productHandle);\n        if (productUrl) el.setAttribute('data-product-url', productUrl);\n      });\n      const root = findFullReviewsRoot(this.section);\n      if (root) {\n        root.setAttribute('data-id', reviewSourceId);\n        root.setAttribute('data-product-id', reviewSourceId);\n        if (reviewSourceId === productId) {\n          if (productHandle) root.setAttribute('data-product-handle', productHandle);\n          if (productUrl) root.setAttribute('data-product-url', productUrl);\n        } else {\n          root.removeAttribute('data-product-handle');\n          root.removeAttribute('data-product-url');\n          root.removeAttribute('data-product-title');\n        }\n      }\n      callKlaviyoReviewRenderers();\n      document.dispatchEvent(new CustomEvent('laley:pdp:reviews-ready', {\n        bubbles: true,\n        detail: { productId, reviewSourceId, productHandle, sectionId: this.section.dataset.sectionId },\n      }));\n    },\n\n    ensureReviewsMount() {\n      const existing = findFullReviewsRoot(this.section);\n      if (existing) return existing;\n\n      const state = readReviewState(this.section);\n      if (!state?.count) return null;\n\n      const productId = this.section.dataset.productId;\n      const sectionId = this.section.dataset.sectionId || productId || 'reviews';\n      const sectionToken = String(sectionId).replace(/[^A-Za-z0-9_-]/g, '-');\n      const reviewsSection = document.createElement('section');\n      const reviewCount = Number(state.count) || 0;\n      const reviewStateClasses = reviewCount < 5 ? 'is-review-list-short' : '';\n      reviewsSection.className = `pdp-clean__reviews-section pdp-clean__reviews-section--standalone has-reviews${reviewStateClasses ? ` ${reviewStateClasses}` : ''}`;\n      reviewsSection.setAttribute('data-pdp-reviews-section', '');\n      reviewsSection.setAttribute('data-product-id', productId);\n      reviewsSection.setAttribute('data-review-count', String(state.count));\n      reviewsSection.setAttribute('data-review-rating', String(state.rating || 5));\n      reviewsSection.setAttribute('aria-labelledby', `pdp-reviews-title-${sectionToken}`);\n      const rating = Number(state.rating || 5) || 5;\n      const productHandle = this.section.dataset.productHandle || '';\n      const productUrl = this.section.dataset.productUrl || '';\n      reviewsSection.innerHTML = `\n        <div class=\"pdp-clean__reviews-head\" data-pdp-reviews-head>\n          <h2 class=\"pdp-clean__reviews-head-title lly-title\" id=\"pdp-reviews-title-${escapeHTML(sectionToken)}\">Anmeldelser</h2>\n          <button type=\"button\" class=\"${reviewWriteButtonClass}\" data-pdp-reviews-write>Skriv anmeldelse</button>\n        </div>\n        <div id=\"klaviyo-reviews-all\" class=\"klaviyo-reviews-all\" data-id=\"${escapeHTML(productId)}\" data-product-id=\"${escapeHTML(productId)}\" data-product-handle=\"${escapeHTML(productHandle)}\" data-product-url=\"${escapeHTML(productUrl)}\" data-review-count=\"${escapeHTML(state.count)}\" data-review-rating=\"${escapeHTML(rating)}\"></div>\n        <div class=\"pdp-clean__reviews-fallback-all\" data-pdp-reviews-fallback-all style=\"--lly-review-score: ${Math.max(0, Math.min(100, rating * 20))}%;\" aria-label=\"${escapeHTML(rating)} av 5, basert p\u00E5 ${escapeHTML(state.count)} ${Number(state.count) === 1 ? 'anmeldelse' : 'anmeldelser'}\">\n          <span class=\"pdp-clean__reviews-fallback-score\">${escapeHTML(rating)} <small>/ 5</small></span>\n          <span class=\"pdp-clean__reviews-fallback-stars\" aria-hidden=\"true\"></span>\n          <span class=\"pdp-clean__reviews-fallback-count\">${escapeHTML(state.count)} ${Number(state.count) === 1 ? 'anmeldelse' : 'anmeldelser'}</span>\n        </div>\n      `;\n\n      const host = this.section.closest('.shopify-section') || this.section;\n      host.insertAdjacentElement('afterend', reviewsSection);\n      return reviewsSection.querySelector('#klaviyo-reviews-all');\n    },\n\n    muteDocScroll() {\n      // July-26 cleanup: never monkeypatch native scroll APIs. Klaviyo hydration\n      // used to mute scrollTo/scrollIntoView, which could make the page feel\n      // locked near reviews after a hash or delayed widget render.\n    },\n\n    unmuteDocScroll() {\n      // Kept as a no-op compatibility hook for older helpers.\n    },\n\n    kickKlaviyoReviewsHydration() {\n      let root = this.ensureReviewsMount?.() || findReviewsRoot(this.section);\n      if (root && hasRenderedReviews(root)) {\n        removeReviewFallbackAll(root, findReviewsSection(this.section));\n        return true;\n      }\n\n      this.pokeKlaviyoReviews();\n      callKlaviyoReviewRenderers(true);\n      root = findReviewsRoot(this.section);\n      if (root && hasRenderedReviews(root)) {\n        removeReviewFallbackAll(root, findReviewsSection(this.section));\n        return true;\n      }\n      return false;\n    },\n\n    // \"7 reviews\" \u2192 \"7 anmeldelser\" \u2014 leser det FAKTISKE antallet fra Klaviyo-widgeten\n    // og bytter kun ordet (dynamisk, ikke hardkodet tall). Best-effort: virker der\n    // teksten er i light-DOM (ikke shadow-DOM).\n    bindReviewLabelLocale() {\n      const block = this.section.querySelector('[data-pdp-jump-reviews]');\n      if (!block) return;\n      const cacheKey = `laley:pdp:review-summary:${this.section.dataset.productId || 'unknown'}`;\n      const readCache = () => {\n        try {\n          const value = window.localStorage?.getItem(cacheKey);\n          if (!value) return null;\n          const parsed = JSON.parse(value);\n          const fresh = Date.now() - Number(parsed.ts || 0) < 1000 * 60 * 60 * 24 * 14;\n          return fresh && Number(parsed.count) > 0 ? parsed : null;\n        } catch (e) {\n          return null;\n        }\n      };\n      const writeCache = (state) => {\n        try {\n          window.localStorage?.setItem(cacheKey, JSON.stringify({ ...state, ts: Date.now() }));\n        } catch (e) {\n          // localStorage can be disabled in private mode; reviews still hydrate normally.\n        }\n      };\n      const readEmbeddedReviewState = () => readKlaviyoMetafieldReviewState();\n      const extractState = () => {\n        const root = findReviewsRoot(this.section);\n        const attrCount = Number(block.dataset.reviewCount || root?.dataset.reviewCount || 0);\n        const attrRating = Number(String(block.dataset.reviewRating || root?.dataset.reviewRating || 5).replace(',', '.')) || 5;\n        if (attrCount > 0) {\n          return { count: attrCount, rating: Math.max(0, Math.min(5, attrRating)) };\n        }\n\n        const embedded = readEmbeddedReviewState();\n        if (embedded?.count > 0) return embedded;\n\n        const candidates = [block.textContent || ''];\n        block.querySelectorAll('[aria-label], [title], [data-testid], [class]').forEach((el) => {\n          candidates.push(el.getAttribute('aria-label') || '');\n          candidates.push(el.getAttribute('title') || '');\n          candidates.push(el.getAttribute('data-testid') || '');\n          candidates.push(el.className || '');\n        });\n        const joined = candidates.join(' ');\n        const countHit = candidates\n          .map((text) => String(text).match(/(\\d+)\\s*(?:reviews?|anmeldelser?|anmeldelse)\\b/i))\n          .find(Boolean);\n        const ratingHit = joined.match(/([0-5](?:[.,]\\d+)?)\\s*(?:out of|av)\\s*5/i)\n          || joined.match(/rating[:\\s]+([0-5](?:[.,]\\d+)?)/i);\n        const count = Number(countHit?.[1] || 0);\n        const rating = Number(String(ratingHit?.[1] || 5).replace(',', '.')) || 5;\n        return { count, rating: Math.max(0, Math.min(5, rating)) };\n      };\n      const renderFallback = (state) => {\n        if (!state || Number(state.count) < 1) return;\n        // V\u00E5r rad eier visningen permanent \u2014 Klaviyo-raden er skjult i CSS\n        // og skal aldri erstatte fallbacken (dobbel rad/CLS ved load).\n        const existing = block.querySelector('[data-pdp-reviews-fallback]');\n        const fallback = reviewFallbackControl(existing);\n        fallback.setAttribute('href', '#anmeldelser');\n        fallback.removeAttribute('type');\n        fallback.className = 'pdp-clean__reviews-fallback';\n        fallback.setAttribute('data-pdp-reviews-fallback', '');\n        const countWord = Number(state.count) === 1 ? 'anmeldelse' : 'anmeldelser';\n        const nextHTML = `<span class=\"pdp-clean__reviews-fallback-stars\" aria-hidden=\"true\">${reviewStars(state.rating)}</span><span class=\"lly-link-underline\">${escapeHTML(state.count)} ${countWord}</span>`;\n        setAttributeIfChanged(fallback, 'aria-label', `${state.count} ${countWord}`);\n        if (fallback.innerHTML !== nextHTML) fallback.innerHTML = nextHTML;\n        if (!existing) block.prepend(fallback);\n      };\n      const syncCount = () => {\n        const state = extractState();\n        const cached = state.count > 0 ? state : readCache();\n        if (cached?.count > 0) {\n          renderFallback(cached);\n          block.classList.add('has-reviews');\n          block.classList.remove('is-loading', 'is-empty', 'is-confirmed-empty');\n          if (state.count > 0) writeCache(state);\n          return true;\n        }\n        return false;\n      };\n      const localize = () => {\n        const walker = document.createTreeWalker(block, NodeFilter.SHOW_TEXT, {\n          acceptNode(node) {\n            const parent = node.parentElement;\n            if (!parent) return NodeFilter.FILTER_REJECT;\n            if (/^(SCRIPT|STYLE|SVG|PATH|STOP)$/i.test(parent.tagName)) return NodeFilter.FILTER_REJECT;\n            return NodeFilter.FILTER_ACCEPT;\n          },\n        });\n        let node;\n        while ((node = walker.nextNode())) {\n          const t = node.nodeValue;\n          if (t && /\\breviews?\\b/i.test(t)) {\n            const nt = t.replace(/\\breviews\\b/gi, 'anmeldelser').replace(/\\breview\\b/gi, 'anmeldelse');\n            if (nt !== t) node.nodeValue = nt;\n          }\n        }\n        return syncCount();\n      };\n      let raf = null;\n      const schedule = () => {\n        if (raf) return;\n        raf = window.requestAnimationFrame(() => {\n          raf = null;\n          if (localize()) obs.disconnect();\n        });\n      };\n      const hasInitialState = localize();\n      const obs = new MutationObserver(schedule);\n      if (!hasInitialState) obs.observe(block, { childList: true, subtree: true, characterData: true });\n      const emptyTimer = window.setTimeout(() => {\n        if (syncCount()) {\n          obs.disconnect();\n          return;\n        }\n        block.classList.add('is-empty', 'is-confirmed-empty');\n        block.classList.remove('is-loading', 'has-reviews');\n        obs.disconnect();\n      }, 3000);\n      this.timers.push(emptyTimer);\n      this.unsubs.push(() => {\n        if (raf) window.cancelAnimationFrame(raf);\n        obs.disconnect();\n      });\n    },\n\n    bindReviewWidgetPolish() {\n      const root = this.ensureReviewsMount?.() || findReviewsRoot(this.section);\n      // The mount is deterministic: Liquid review metafields either let\n      // ensureReviewsMount create it now, or the product has no review surface.\n      // Never observe document.body and poll for a node the theme itself owns.\n      if (!root) return;\n      if (root.dataset.pdpReviewsPolishBound === 'true') return;\n      root.dataset.pdpReviewsPolishBound = 'true';\n\n      const section = findReviewsSection(this.section);\n      let visibilityReady = false;\n      let latestReviewCount = 0;\n      const summary = this.section.querySelector('[data-pdp-reviews-summary]');\n      const setCount = (value) => {\n        const count = Number(String(value || '').match(/\\d+/)?.[0] || 0);\n        if (!Number.isFinite(count) || count < 1) return;\n        latestReviewCount = count;\n        syncReviewCountDisplays(this.section, count);\n      };\n      setCount(root.dataset.reviewCount || summary?.dataset.reviewCount || '');\n\n      const translate = (value) => {\n        let text = String(value || '');\n        const trimmed = text.trim();\n        const exact = {\n          'Customer reviews': 'Kundeanmeldelser',\n          'WRITE A REVIEW': 'Skriv anmeldelse',\n          'Write a review': 'Skriv anmeldelse',\n          Reviews: 'Anmeldelser',\n          Review: 'Anmeldelse',\n          'SHOW MORE': 'Vis flere',\n          'Show more': 'Vis flere',\n          'Verified buyer': 'Verifisert kj\u00F8per',\n          'Most recent': 'Nyeste f\u00F8rst',\n          'Highest rating': 'H\u00F8yest vurdering',\n          'Lowest rating': 'Lavest vurdering',\n          'Most relevant': 'Mest relevant',\n          'All ratings': 'Alle vurderinger',\n          'With media': 'Med bilder',\n          'Search reviews': 'S\u00F8k i anmeldelser',\n          'Sort by:': 'Sorter etter:',\n          'Filter by:': 'Filtrer etter:',\n          'All variants': 'Alle varianter',\n          Questions: 'Sp\u00F8rsm\u00E5l',\n          Question: 'Sp\u00F8rsm\u00E5l',\n          'Ask a question': 'Still et sp\u00F8rsm\u00E5l',\n          'ASK A QUESTION': 'Still et sp\u00F8rsm\u00E5l',\n          Incentivized: 'Mottok insentiv',\n          Helpful: 'Nyttig',\n          'Was this helpful?': 'Var dette nyttig?',\n          'Product Reviews and Questions tabs': 'Faner for produktanmeldelser og sp\u00F8rsm\u00E5l',\n          'Write a review, opens in a new tab': 'Skriv anmeldelse, \u00E5pnes i ny fane',\n          'Skriv anmeldelse, opens in a new tab': 'Skriv anmeldelse, \u00E5pnes i ny fane',\n          'No matching reviews': 'Ingen anmeldelser matcher',\n          'No matching review': 'Ingen anmeldelser matcher',\n          'Try another search, or clear some filters': 'Pr\u00F8v et annet s\u00F8k eller fjern filtrene.',\n          'Clear all filters': 'Fjern alle filtre',\n          'Clear all filter': 'Fjern alle filtre',\n          'Clear all': 'Fjern filtre',\n          Search: 'S\u00F8k',\n        };\n        if (exact[trimmed]) return text.replace(trimmed, exact[trimmed]);\n\n        text = text\n          .replace(/\\bCustomer reviews\\b/g, 'Kundeanmeldelser')\n          .replace(/\\bWRITE A REVIEW\\b/g, 'Skriv anmeldelse')\n          .replace(/\\bWrite a review\\b/g, 'Skriv anmeldelse')\n          .replace(/\\bSHOW MORE\\b/g, 'Vis flere')\n          .replace(/\\bShow more\\b/g, 'Vis flere')\n          .replace(/\\bVerified buyer\\b/g, 'Verifisert kj\u00F8per')\n          .replace(/\\bIncentivized\\b/g, 'Mottok insentiv')\n          .replace(/\\bAsk a question\\b/gi, 'Still et sp\u00F8rsm\u00E5l')\n          .replace(/\\bAll variants\\b/gi, 'Alle varianter')\n          .replace(/Was this helpful\\?/gi, 'Var dette nyttig?')\n          .replace(/\\bStore replied\\b/gi, 'Laley svarte')\n          .replace(/\\bNo matching reviews?\\b/gi, 'Ingen anmeldelser matcher')\n          .replace(/\\bTry another search, or clear some filters\\b/gi, 'Pr\u00F8v et annet s\u00F8k eller fjern filtrene.')\n          .replace(/\\bClear all filters?\\b/gi, 'Fjern alle filtre')\n          .replace(/\\bClear all\\b/gi, 'Fjern filtre')\n          .replace(/\\b(\\d+)\\s+reviews\\b/gi, (_, count) => `${count} anmeldelser`)\n          .replace(/\\b1\\s+review\\b/gi, '1 anmeldelse')\n          .replace(/\\b1\\s+anmeldelser\\b/gi, '1 anmeldelse')\n          .replace(/\\b(\\d+)\\s+ratings\\b/gi, (_, count) => `${count} vurderinger`)\n          .replace(/\\b1\\s+rating\\b/gi, '1 vurdering')\n          .replace(/\\b(\\d+)\\s+stars\\b/gi, (_, count) => `${count} stjerner`)\n          .replace(/\\b1\\s+star\\b/gi, '1 stjerne')\n          .replace(/\\bAverage rating is ([\\d.,]+) (?:stars?|stjerner)\\b/gi, (_, rating) => `Gjennomsnittlig vurdering er ${rating} av 5 stjerner`)\n          .replace(/\\b(\\d+)\\s+anmeldelse(?:r)? with (\\d+)\\s+stjerner\\b/gi, (_, reviews, stars) => {\n            const reviewWord = Number(reviews) === 1 ? 'anmeldelse' : 'anmeldelser';\n            const starWord = Number(stars) === 1 ? 'stjerne' : 'stjerner';\n            return `${reviews} ${reviewWord} med ${stars} ${starWord}`;\n          })\n          .replace(/\\b1\\s+anmeldelse med 1\\s+stjerner\\b/gi, '1 anmeldelse med 1 stjerne')\n          .replace(/\\b(\\d+)\\s+anmeldelser med 1\\s+stjerner\\b/gi, (_, reviews) => `${reviews} anmeldelser med 1 stjerne`)\n          .replace(/\\bReviews (\\d+)\\b/gi, (_, count) => `Anmeldelser ${count}`)\n          .replace(/\\b(\\d+)[ -]star review\\b/gi, (_, count) => `${count}-stjerners anmeldelse`)\n          .replace(/\\b(?:an?|1)\\s+minute ago\\b/gi, 'for 1 minutt siden')\n          .replace(/\\b(\\d+)\\s+minutes ago\\b/gi, (_, count) => `for ${count} minutter siden`)\n          .replace(/\\b(?:an?|1)\\s+hour ago\\b/gi, 'for 1 time siden')\n          .replace(/\\b(\\d+)\\s+hours ago\\b/gi, (_, count) => `for ${count} timer siden`)\n          .replace(/\\byesterday\\b/gi, 'i g\u00E5r')\n          .replace(/\\b(?:a|1)\\s+day ago\\b/gi, 'for 1 dag siden')\n          .replace(/\\b(\\d+)\\s+days ago\\b/gi, (_, count) => `for ${count} dager siden`)\n          .replace(/\\b(?:a|1)\\s+month ago\\b/gi, 'for 1 m\u00E5ned siden')\n          .replace(/\\b(\\d+)\\s+months ago\\b/gi, (_, count) => `for ${count} m\u00E5neder siden`)\n          .replace(/\\b(?:a|1)\\s+year ago\\b/gi, 'for 1 \u00E5r siden')\n          .replace(/\\b(\\d+)\\s+years ago\\b/gi, (_, count) => `for ${count} \u00E5r siden`);\n        return text;\n      };\n\n      const syncCount = () => {\n        // Use Klaviyo's explicit count nodes only. Broad root text also contains\n        // histogram/filter numbers (5 stars, 4 stars, etc.) and can corrupt the\n        // PDP tab count.\n        const candidates = [\n          root.querySelector('.kl_reviews__list__tab')?.textContent || '',\n          root.querySelector('.kl_reviews__list__tab small')?.textContent || '',\n          root.querySelector('.kl_reviews__summary__stars__count')?.textContent || '',\n        ];\n        const hit = candidates\n          .map((text) => String(text).match(/\\b(\\d+)\\b/))\n          .find(Boolean);\n        if (hit) setCount(hit[1]);\n      };\n\n      const syncVisibility = () => {\n        if (!section) return;\n        const reviewItems = root.querySelectorAll('.kl_reviews__review_item, .kl_reviews__review__item, [class*=\"review_item\"], [class*=\"review__item\"]');\n        const hasRenderedWidget = hasRenderedReviews(root);\n        const explicitCount = [\n          root.dataset.reviewCount || '',\n          summary?.dataset.reviewCount || '',\n          root.querySelector('.kl_reviews__list__tab small')?.textContent || '',\n          root.querySelector('.kl_reviews__summary__stars__count')?.textContent || '',\n        ]\n          .map((text) => Number(String(text).match(/\\b(\\d+)\\b/)?.[1] || 0))\n          .find((count) => Number.isFinite(count) && count > 0) || 0;\n        const hasKnownReviews = latestReviewCount > 0 || explicitCount > 0;\n        // En rendret widget med NULL anmeldelser (\u00AB0 / 5\u00BB-summary) er en tom\n        // tilstand, ikke innhold \u2014 seksjonen skjules til f\u00F8rste anmeldelse\n        // finnes (Sondre juli-26: \u00ABno reviews yet\u00BB/0-histogram er anti-vibe).\n        if (reviewItems.length > 0 || (hasRenderedWidget && hasKnownReviews)) {\n          removeReviewFallbackAll(root, section);\n          section.classList.add('has-reviews');\n          section.classList.remove('is-loading', 'is-empty', 'is-confirmed-empty');\n          return;\n        }\n        if (hasRenderedWidget && !hasKnownReviews) {\n          section.classList.add('is-empty', 'is-confirmed-empty');\n          section.classList.remove('is-loading', 'has-reviews');\n          return;\n        }\n        if (hasKnownReviews) {\n          section.classList.add('has-reviews');\n          section.classList.remove('is-empty', 'is-confirmed-empty');\n          if (findReviewFallbackAll(root, section)) {\n            section.classList.remove('is-loading');\n          } else {\n            section.classList.add('is-loading');\n          }\n          return;\n        }\n        if (visibilityReady) {\n          section.classList.add('is-empty', 'is-confirmed-empty');\n          section.classList.remove('is-loading', 'has-reviews');\n        }\n      };\n\n      const syncPresentation = () => {\n        if (!section) return;\n        section.classList.toggle('has-review-qa', readReviewQuestionCount(root) > 0);\n\n        const normalize = (value) => String(value || '')\n          .replace(/\\s+/g, ' ')\n          .trim()\n          .toLocaleLowerCase('nb-NO');\n        const answersGrid = root.querySelector('.kl_reviews__answers_grid');\n        if (!answersGrid) return;\n\n        Array.from(answersGrid.children).forEach((card) => {\n          const question = card.querySelector(\n            '.kl_reviews__summary__custom_question__question--text, .kl_reviews__summary__custom_question__question--range'\n          );\n          const questionText = normalize(question?.textContent);\n          const isFit = questionText.includes('hvordan oppleves st\u00F8rrelsen');\n          const isSecondaryProfile = questionText.includes('vil du anbefale produktet')\n            || questionText.includes('hvor h\u00F8y er du');\n\n          card.classList.toggle('lly-review-fit-insight', isFit);\n          card.classList.toggle('lly-review-summary-hidden', isSecondaryProfile);\n          if (isSecondaryProfile) card.setAttribute('aria-hidden', 'true');\n          else card.removeAttribute('aria-hidden');\n          if (!isFit) return;\n\n          const range = card.querySelector('[role=\"img\"][aria-label]');\n          const label = range?.getAttribute('aria-label') || '';\n          const averageMatch = label.match(/average of\\s+([\\d.,]+)\\s+between\\s+([\\d.,]+).*?and\\s+([\\d.,]+)/i);\n          let fitState = 'normal';\n          if (averageMatch) {\n            const average = Number(averageMatch[1].replace(',', '.'));\n            const minimum = Number(averageMatch[2].replace(',', '.'));\n            const maximum = Number(averageMatch[3].replace(',', '.'));\n            const span = maximum - minimum;\n            const position = span > 0 ? (average - minimum) / span : 0.5;\n            if (position < 0.34) fitState = 'small';\n            else if (position > 0.66) fitState = 'large';\n          }\n          const resultText = {\n            small: 'Liten i st\u00F8rrelsen',\n            normal: 'Normal i st\u00F8rrelsen',\n            large: 'Stor i st\u00F8rrelsen',\n          }[fitState];\n\n          card.dataset.fitState = fitState;\n          card.setAttribute('aria-label', `Passform: ${resultText}`);\n          let insight = card.querySelector('[data-lly-review-fit-result]');\n          if (!insight) {\n            insight = document.createElement('div');\n            insight.className = 'lly-review-fit-insight__copy';\n            insight.dataset.llyReviewFitResult = '';\n            insight.innerHTML = '<strong class=\"lly-review-fit-insight__result\"></strong>';\n            card.prepend(insight);\n          } else if (\n            insight.children.length !== 1\n            || !insight.firstElementChild?.classList.contains('lly-review-fit-insight__result')\n          ) {\n            insight.innerHTML = '<strong class=\"lly-review-fit-insight__result\"></strong>';\n          }\n          const result = insight.querySelector('.lly-review-fit-insight__result');\n          if (result && result.textContent !== resultText) result.textContent = resultText;\n        });\n      };\n\n      let isPolishing = false;\n      let obs = null;\n      let isObservingReviews = false;\n      const reviewObserverOptions = {\n        childList: true,\n        subtree: true,\n        characterData: true,\n        attributes: true,\n        attributeFilter: ['aria-label', 'title', 'placeholder'],\n      };\n      const startReviewsObserver = () => {\n        if (!obs || isObservingReviews) return;\n        obs.observe(root, reviewObserverOptions);\n        isObservingReviews = true;\n      };\n      const stopReviewsObserver = () => {\n        if (!obs || !isObservingReviews) return;\n        obs.disconnect();\n        isObservingReviews = false;\n      };\n      const polish = () => {\n        if (isPolishing) return;\n        isPolishing = true;\n        stopReviewsObserver();\n\n        try {\n          namespaceRenderedKlaviyoIds(root, root.dataset.id || root.dataset.productId);\n          const walker = document.createTreeWalker(root, 4, {\n            acceptNode(node) {\n              const parent = node.parentElement;\n              if (!parent) return NodeFilter.FILTER_REJECT;\n              if (/^(SCRIPT|STYLE|SVG|PATH|STOP)$/i.test(parent.tagName)) return NodeFilter.FILTER_REJECT;\n              return NodeFilter.FILTER_ACCEPT;\n            },\n          });\n          let node;\n          while ((node = walker.nextNode())) {\n            const next = translate(node.nodeValue);\n            if (next !== node.nodeValue) node.nodeValue = next;\n          }\n\n          root.querySelectorAll('[aria-label], [title], [placeholder]').forEach((el) => {\n            ['aria-label', 'title', 'placeholder'].forEach((attr) => {\n              const value = el.getAttribute(attr);\n              if (!value) return;\n              const next = translate(value);\n              if (next !== value) el.setAttribute(attr, next);\n            });\n          });\n          syncCount();\n          syncVisibility();\n          syncPresentation();\n          document.dispatchEvent(new CustomEvent('laley:pdp:reviews-polished', {\n            bubbles: true,\n            detail: { productId: this.section.dataset.productId || '' },\n          }));\n        } finally {\n          window.requestAnimationFrame(() => {\n            isPolishing = false;\n            startReviewsObserver();\n          });\n        }\n      };\n\n      let polishTimer = null;\n      const schedule = () => {\n        if (isPolishing || polishTimer) return;\n        polishTimer = window.setTimeout(() => {\n          polishTimer = null;\n          polish();\n        }, 90);\n      };\n\n      polish();\n      const visibilityTimer = window.setTimeout(() => {\n        visibilityReady = true;\n        polish();\n      }, 3800);\n      obs = new MutationObserver(schedule);\n      startReviewsObserver();\n      let intersectionObserver = null;\n      if ('IntersectionObserver' in window && section) {\n        intersectionObserver = new IntersectionObserver((entries) => {\n          if (!entries.some((entry) => entry.isIntersecting)) return;\n          this.kickKlaviyoReviewsHydration();\n          polish();\n        }, { rootMargin: '720px 0px' });\n        intersectionObserver.observe(section);\n      }\n      this.unsubs.push(() => {\n        if (polishTimer) window.clearTimeout(polishTimer);\n        window.clearTimeout(visibilityTimer);\n        stopReviewsObserver();\n        intersectionObserver?.disconnect();\n      });\n    },\n\n    bindReviewsJump() {\n      if (this.section.dataset.pdpReviewsJumpDelegated === 'true') return;\n      this.section.dataset.pdpReviewsJumpDelegated = 'true';\n      const getTarget = () => {\n        const mountedRoot = this.ensureReviewsMount?.();\n        return (\n          findReviewsSection(this.section)\n          || mountedRoot?.closest?.('[data-pdp-reviews-section]')\n          || findFullReviewsRoot(this.section)\n          || mountedRoot\n        );\n      };\n      const getHeaderOffset = () => {\n        const headerVar = parseInt(window.getComputedStyle(document.documentElement).getPropertyValue('--HEADER-HEIGHT'), 10);\n        const header = Number.isFinite(headerVar) ? headerVar : (document.querySelector('header')?.offsetHeight || 0);\n        return Math.max(0, header + 12);\n      };\n      const scrollToTarget = (target, behavior = 'auto') => {\n        if (!target) return false;\n        const top = Math.max(0, target.getBoundingClientRect().top + window.scrollY - getHeaderOffset());\n        this.unmuteDocScroll();\n        const scroller = document.scrollingElement || document.documentElement;\n        try {\n          window.scrollTo({ top, behavior });\n        } catch (e) {\n          window.scrollTo(0, top);\n        }\n        // Direct assignment is the reliable path in Safari/Chrome when Klaviyo\n        // or gallery hydration has temporarily wrapped scroll APIs.\n        if (scroller) scroller.scrollTop = top;\n        return true;\n      };\n      let userScrollIntentAt = 0;\n      const markUserScrollIntent = (event) => {\n        if (event?.type === 'keydown') {\n          const scrollKeys = ['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End', ' '];\n          if (!scrollKeys.includes(event.key)) return;\n        }\n        userScrollIntentAt = Date.now();\n        this.unmuteDocScroll();\n      };\n      this.on(window, 'wheel', markUserScrollIntent, { passive: true, capture: true });\n      this.on(window, 'touchstart', markUserScrollIntent, { passive: true, capture: true });\n      this.on(window, 'touchmove', markUserScrollIntent, { passive: true, capture: true });\n      this.on(document, 'keydown', markUserScrollIntent, true);\n      this.on(window, 'laley:pdp:unmute-doc-scroll', () => this.unmuteDocScroll());\n\n      const jump = (event, options = {}) => {\n        if (event?.__laleySilentReviewHydrate) {\n          this.pokeKlaviyoReviews();\n          return;\n        }\n        // Only real customer intent may move the viewport. Klaviyo/app hydration\n        // can dispatch synthetic clicks; treating those as review jumps is what\n        // made the page feel pulled down or locked near reviews.\n        if (event && event.isTrusted === false) return;\n        if ((event?.type === 'pointerdown' || event?.type === 'mousedown') && event.button && event.button !== 0) return;\n        window.__laleyReviewJumpIntentAt = Date.now();\n        if (event) {\n          if (event.__laleyReviewsJumpHandled) return;\n          try {\n            Object.defineProperty(event, '__laleyReviewsJumpHandled', { value: true });\n          } catch (e) {\n            event.__laleyReviewsJumpHandled = true;\n          }\n          event.preventDefault();\n          event.stopPropagation();\n          event.stopImmediatePropagation?.();\n        }\n        const startedAt = options.startedAt || Date.now();\n        const wasUserInterrupted = () => userScrollIntentAt > startedAt;\n        this.activateReviewsTab?.();\n        this.unmuteDocScroll();\n        if (options.initialHash) window.__laleyInitialReviewHashHandled = true;\n        clearReviewHash({ force: true });\n        const runScroll = (behavior = 'auto') => {\n          if (wasUserInterrupted()) return false;\n          const target = getTarget();\n          if (!target) return false;\n          const moved = scrollToTarget(target, behavior);\n          if (moved) {\n            target.setAttribute('tabindex', '-1');\n            target.focus?.({ preventScroll: true });\n          }\n          return moved;\n        };\n        const targetIsAligned = () => {\n          const target = getTarget();\n          if (!target) return false;\n          return Math.abs(target.getBoundingClientRect().top - getHeaderOffset()) <= 24;\n        };\n        window.requestAnimationFrame(() => {\n          let attempts = 0;\n          const retryScroll = () => {\n            const moved = runScroll(options.behavior || 'auto');\n            this.pokeKlaviyoReviews();\n            const aligned = moved && targetIsAligned();\n            const keepCorrectingInitialHash = options.initialHash && attempts < 10;\n            if ((aligned && !keepCorrectingInitialHash) || attempts >= 12 || wasUserInterrupted()) return;\n            attempts += 1;\n            window.setTimeout(retryScroll, attempts < 4 ? 90 : attempts < 8 ? 180 : 350);\n          };\n          retryScroll();\n        });\n      };\n\n      // The tiny viewport loader uses this explicit lifecycle bridge when the\n      // customer's first review click is what loads the runtime. Replaying a\n      // synthetic click would correctly be rejected by the isTrusted guard\n      // above, which exists to stop Klaviyo hydration from moving the page.\n      const jumpToReviews = (options = {}) => jump(null, options);\n      this.jumpToReviews = jumpToReviews;\n      this.unsubs.push(() => {\n        if (this.jumpToReviews === jumpToReviews) delete this.jumpToReviews;\n      });\n\n      const triggerSelector = [\n        '[data-pdp-jump-reviews]',\n        '[data-pdp-reviews-fallback]',\n        '[data-pdp-reviews-summary] .kl_reviews__star_rating_widget',\n        '[data-pdp-reviews-summary] .klaviyo-star-rating-widget',\n        '[data-pdp-reviews-summary] .kl_reviews__rating-count',\n        '[data-pdp-reviews-summary] .kl_reviews__rating-meta',\n        '[data-pdp-reviews-summary] [class*=\"rating-count\"]',\n        '[data-pdp-reviews-summary] [class*=\"rating_count\"]',\n        'a[href*=\"#klaviyo-reviews-all\"]',\n        'a[href*=\"#reviews\"]',\n        'a[href*=\"#anmeldelser\"]',\n      ].join(', ');\n      const isReviewCountTrigger = (trigger) => Boolean(trigger?.closest?.('[data-pdp-reviews-summary]'))\n        && (\n          trigger.matches?.('.kl_reviews__rating-count, .kl_reviews__rating-meta, [class*=\"rating-count\"], [class*=\"rating_count\"]')\n          || trigger.closest?.('.kl_reviews__rating-count, .kl_reviews__rating-meta, [class*=\"rating-count\"], [class*=\"rating_count\"]')\n        );\n      const resolveTrigger = (event) => {\n        const directFallback = event?.target?.closest?.('[data-pdp-reviews-fallback]');\n        if (directFallback && this.section.contains(directFallback)) return directFallback;\n        const directJump = event?.target?.closest?.('[data-pdp-jump-reviews]');\n        if (directJump && this.section.contains(directJump)) return directJump;\n        const path = typeof event?.composedPath === 'function' ? event.composedPath() : [];\n        const trigger = path.find((node) => node?.matches?.(triggerSelector))\n          || event?.target?.closest?.(triggerSelector);\n        if (!trigger || !this.section.contains(trigger)) return null;\n        const summary = trigger.closest?.('[data-pdp-reviews-summary]');\n        if (summary && !trigger.matches?.('[data-pdp-reviews-fallback]')) {\n          const reviewIntentText = String(trigger.textContent || event?.target?.textContent || '');\n          if (/\\b(anmeldelse|anmeldelser|review|reviews)\\b/i.test(reviewIntentText)) return summary;\n        }\n        if (trigger.tagName === 'A' && !anchorHasReviewHash(trigger) && !isReviewCountTrigger(trigger)) return null;\n        return trigger;\n      };\n      const primeTriggers = () => {\n        this.section.querySelectorAll(triggerSelector).forEach((trigger) => {\n          if (trigger.dataset.pdpReviewsJumpBound !== 'true') {\n            trigger.dataset.pdpReviewsJumpBound = 'true';\n            const isNativeControl = trigger.matches('a[href], button, input, select, textarea, summary');\n            const isSummaryContainer = trigger.matches('[data-pdp-reviews-summary]');\n            const hasInteractiveAncestor = Boolean(trigger.parentElement?.closest('a[href], button, [role=\"button\"]'));\n            const hasInteractiveDescendant = Boolean(trigger.querySelector('a[href], button, [role=\"button\"]'));\n            const ownsInteraction = !isNativeControl\n              && !isSummaryContainer\n              && !hasInteractiveAncestor\n              && !hasInteractiveDescendant;\n\n            // Klaviyo hydrates a real button inside one or more wrapper spans.\n            // Giving those wrappers button semantics creates nested controls in\n            // the accessibility tree. Only standalone, non-native triggers own\n            // synthetic button semantics; the real child keeps keyboard focus.\n            if (ownsInteraction) {\n              if (!trigger.hasAttribute('tabindex')) trigger.tabIndex = 0;\n              if (!trigger.hasAttribute('role')) trigger.setAttribute('role', 'button');\n            }\n          }\n        });\n      };\n\n      primeTriggers();\n      this.on(this.section, 'click', (event) => {\n        const trigger = event.target?.closest?.('[data-pdp-reviews-fallback], [data-pdp-jump-reviews]');\n        if (!trigger || !this.section.contains(trigger)) return;\n        jump(event);\n      }, { capture: true });\n      this.on(this.section, 'keydown', (event) => {\n        const trigger = event.target?.closest?.('[data-pdp-reviews-fallback], [data-pdp-jump-reviews]');\n        if (!trigger || !this.section.contains(trigger)) return;\n        if (event.key !== 'Enter' && event.key !== ' ') return;\n        jump(event);\n      }, { capture: true });\n      this.on(document, 'click', (event) => {\n        if (!resolveTrigger(event)) return;\n        jump(event);\n      }, { capture: true });\n      this.on(document, 'keydown', (event) => {\n        const trigger = resolveTrigger(event);\n        if (!trigger) return;\n        if (event.key !== 'Enter' && event.key !== ' ') return;\n        jump(event);\n      }, { capture: true });\n\n      const initialReviewHash = window.__laleyInitialReviewHash;\n      if (isReviewHash(initialReviewHash) && !window.__laleyInitialReviewHashHandled) {\n        window.__laleyInitialReviewHashHandled = true;\n        window.__laleyInitialReviewHash = '';\n        window.setTimeout(() => {\n          jump(null, { initialHash: true, startedAt: Date.now() });\n        }, 120);\n      }\n    },\n\n    bindAllReviewsHeader() {\n      // \u00ABSkriv anmeldelse\u00BB bodde i Klaviyos tabs-rad, som skjules fordi den\n      // dublerte tittelen. Vi eier headeren: tittel + global sekund\u00E6rknapp som\n      // proxy-klikker Klaviyos skjulte knapp. Root kan byttes ut av widgeten\n      // \u2014 alt sl\u00E5s opp ferskt, og raden bor i forelderen og overlever bytter.\n      const getRoot = () => findReviewsRoot(this.section);\n      const initialRoot = getRoot();\n      if (!initialRoot || !initialRoot.parentElement) return;\n      const host = findReviewsSection(this.section) || initialRoot.parentElement;\n      const clickKlaviyoWrite = () => {\n        const root = getRoot();\n        const target = Array.from(root?.querySelectorAll?.('.kl_reviews__button_bar button, button.kl_reviews__button') || [])\n          .find((button) => /write a review|skriv anmeldelse/i.test(`${button.textContent || ''} ${button.getAttribute('aria-label') || ''}`));\n        if (target) {\n          target.click();\n          return true;\n        }\n        return false;\n      };\n      const ensure = () => {\n        const root = getRoot();\n        if (!root) return;\n        // Klaviyo can set an inline !important on the tabs row. Keep an empty\n        // Q&A tab out of the way, but release that inline lock as soon as a real\n        // customer question exists so the shared CSS can render both tabs.\n        root.querySelectorAll('.kl_reviews__list__tabs').forEach((el) => {\n          if (readReviewQuestionCount(root) > 0) el.style.removeProperty('display');\n          else el.style.setProperty('display', 'none', 'important');\n        });\n        root.querySelectorAll('.kl_reviews__summary__header').forEach((el) => {\n          el.style.setProperty('display', 'none', 'important');\n        });\n        const directReviewHeads = () => Array.from(host.children || [])\n          .filter((node) => node.classList?.contains('pdp-clean__reviews-head'));\n        let head = host.querySelector('[data-pdp-reviews-head]') || directReviewHeads()[0];\n        if (!head) {\n          head = document.createElement('div');\n          head.className = 'pdp-clean__reviews-head';\n          head.innerHTML = '<h2 class=\"pdp-clean__reviews-head-title lly-title\"></h2>'\n            + `<button type=\"button\" class=\"${reviewWriteButtonClass}\" data-pdp-reviews-write>Skriv anmeldelse</button>`;\n          host.insertBefore(head, root);\n        }\n        head.setAttribute('data-pdp-reviews-head', '');\n        directReviewHeads().forEach((node) => {\n          if (node !== head) node.remove();\n        });\n\n        let title = head.querySelector('.pdp-clean__reviews-head-title');\n        const legacyTitle = head.querySelector('.pdp-clean__reviews-title');\n        if (!title && legacyTitle) {\n          legacyTitle.className = 'pdp-clean__reviews-head-title lly-title';\n          title = legacyTitle;\n        }\n        if (!title) {\n          title = document.createElement('h2');\n          title.className = 'pdp-clean__reviews-head-title lly-title';\n          head.prepend(title);\n        }\n        let write = head.querySelector('[data-pdp-reviews-write]');\n        if (!write) {\n          write = document.createElement('button');\n          write.type = 'button';\n          write.className = reviewWriteButtonClass;\n          write.setAttribute('data-pdp-reviews-write', '');\n          write.textContent = 'Skriv anmeldelse';\n          head.appendChild(write);\n        }\n        if (!write.dataset.pdpReviewsBound) {\n          write.dataset.pdpReviewsBound = 'true';\n          this.on(write, 'click', () => {\n            this.unmuteDocScroll();\n            if (clickKlaviyoWrite()) return;\n            this.kickKlaviyoReviewsHydration();\n            const retryOnLifecycle = () => {\n              if (!clickKlaviyoWrite()) return;\n              cleanupRetry();\n            };\n            const cleanupRetry = () => {\n              document.removeEventListener('laley:pdp:reviews-polished', retryOnLifecycle);\n              window.clearTimeout(retryDeadline);\n            };\n            const retryDeadline = window.setTimeout(cleanupRetry, 4000);\n            document.addEventListener('laley:pdp:reviews-polished', retryOnLifecycle);\n            this.unsubs.push(cleanupRetry);\n          });\n        }\n        if (title) setTextIfChanged(title, 'Anmeldelser');\n        write.className = reviewWriteButtonClass;\n      };\n      ensure();\n      this.on(document, 'laley:pdp:reviews-polished', ensure);\n    },\n\n    bindKundeneSier() {\n      // Keep the buy column deterministic. Klaviyo can hydrate the rating\n      // summary and the full reviews section, but it must not inject a delayed\n      // proof card into the decision stack. If a product needs a featured quote,\n      // use the product metafields rendered in Liquid instead.\n      const slot = this.section.querySelector('[data-pdp-kundene-slot]');\n      if (slot) {\n        slot.hidden = true;\n        slot.innerHTML = '';\n        slot.removeAttribute('role');\n        slot.removeAttribute('tabindex');\n        slot.removeAttribute('aria-label');\n        slot.style.removeProperty('cursor');\n      }\n    },\n  });\n})();\n"],
  "mappings": "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",
  "names": ["state", "node"]
}
