{
  "version": 3,
  "sources": ["/cdn/shop/t/113/assets/ada-accessibility.js?theme_ada=20261023-3"],
  "sourcesContent": ["document.documentElement.dataset.themeAdaVersion = \"20260924-11\";\n\ndocument.addEventListener(\n  \"click\",\n  (event) => {\n    const skipLink = event.target.closest?.(\".skip-to-content\");\n    if (!skipLink) return;\n\n    const target = document.querySelector(skipLink.getAttribute(\"href\"));\n    if (!target) return;\n\n    event.preventDefault();\n    event.stopImmediatePropagation();\n    target.focus({ preventScroll: true });\n    target.scrollIntoView({ block: \"start\" });\n  },\n  true\n);\n\nif (window.location.pathname.includes(\"/custom-tools/dynamic-box\")) {\n  // Two announcers: limit and error messages interrupt (assertive), everything else waits its turn (polite).\n  // Messages are cleared after a while so a screen reader user reading the page doesn't find stale ones.\n  const createBundleRegion = (id, role, live) => {\n    const region = document.createElement(\"div\");\n    region.id = id;\n    region.setAttribute(\"role\", role);\n    region.setAttribute(\"aria-live\", live);\n    region.setAttribute(\"aria-atomic\", \"true\");\n    document.body.appendChild(region);\n    return region;\n  };\n  const bundleStatus = createBundleRegion(\"theme-bundle-status\", \"alert\", \"assertive\");\n  const bundleUpdates = createBundleRegion(\"theme-bundle-updates\", \"status\", \"polite\");\n  const regionTimers = new WeakMap();\n\n  const setRegionText = (region, message) => {\n    window.clearTimeout(regionTimers.get(region));\n    region.textContent = \"\";\n    window.setTimeout(() => {\n      region.textContent = message;\n    }, 50);\n    regionTimers.set(\n      region,\n      window.setTimeout(() => {\n        region.textContent = \"\";\n      }, 8000)\n    );\n  };\n  const announceBundleLimit = (message) => setRegionText(bundleStatus, message);\n  const announceBundleUpdate = (message) => setRegionText(bundleUpdates, message);\n\n  const pluralBoxes = (count) => `${count} ${count === 1 ? \"box\" : \"boxes\"}`;\n\n  // The app reports the limit only in an animated toast that stays in the DOM (visibility: hidden) after it\n  // closes, so work the limit out from the quantities instead of reading the toast.\n  const getQuantityInputs = () => Array.from(document.querySelectorAll('input[aria-label^=\"Quantity of\"]'));\n  const getBundleTotal = () =>\n    getQuantityInputs().reduce((total, input) => total + (Number.parseInt(input.value, 10) || 0), 0);\n  const getBundleMax = () => {\n    const subheader = normalizeLabel(\n      document.querySelector(\"[data-dynamic-box-subheader]\")\n    );\n    const max = Number.parseInt(subheader.match(/up to (\\d+)/i)?.[1], 10);\n    return Number.isFinite(max) ? max : null;\n  };\n\n  // Text of the elements with no child elements, in document order.\n  const leafLabels = (element, visibleOnly = false) =>\n    Array.from(element.querySelectorAll(\"div\"))\n      .filter((leaf) => !leaf.children.length && (!visibleOnly || leaf.getClientRects().length > 0))\n      .map((leaf) => normalizeLabel(leaf))\n      .filter(Boolean);\n  const isPriceLabel = (label) => /\\d[\\d.,]*\\s*(?:USD|\\$)|\\$\\s*\\d/.test(label);\n\n  // The discount tier bar reads \"Min, 2, 3% off, 3, 5% off, Max, 6\": the minimum and each tier's box count and\n  // discount. Only sighted users could see how many boxes a discount needs.\n  const getBundleTiers = () => {\n    const bar = document.querySelector(\"[data-theme-tier-bar]\");\n    const result = { min: null, tiers: [] };\n    if (!bar) return result;\n    let afterMin = false;\n    let count = null;\n    leafLabels(bar).forEach((label) => {\n      if (/^min$/i.test(label)) {\n        afterMin = true;\n      } else if (/^\\d+$/.test(label)) {\n        count = Number(label);\n        if (afterMin && result.min === null) result.min = count;\n        afterMin = false;\n      } else {\n        const percent = label.match(/(\\d+)\\s*%/);\n        if (percent && count !== null) result.tiers.push({ count, percent: Number(percent[1]) });\n        count = null;\n      }\n    });\n    return result;\n  };\n\n  const describeDiscount = (total) => {\n    const { tiers } = getBundleTiers();\n    const reached = tiers.filter((tier) => total >= tier.count).pop();\n    const next = tiers.find((tier) => total < tier.count);\n    const parts = [];\n    if (reached) parts.push(`${reached.percent}% discount applied.`);\n    if (next) {\n      const needed = next.count - total;\n      parts.push(`Add ${needed} more ${needed === 1 ? \"box\" : \"boxes\"} for ${next.percent}% off.`);\n    }\n    return parts.join(\" \");\n  };\n\n  // \"Subtotal\" in the desktop summary, \"Total (n items)\" in the mobile bar: the first price after the label.\n  const getBundleSubtotal = () => {\n    const root = document.querySelector(\"#skio-root\") || document.querySelector(\"main\");\n    if (!root) return \"\";\n    const labels = leafLabels(root, true);\n    const labelIndex = labels.findIndex((label) => /^(subtotal|suma cz\u0119\u015Bciowa|total|razem)\\b/i.test(label));\n    if (labelIndex === -1) return \"\";\n    return labels.slice(labelIndex + 1).find(isPriceLabel) || \"\";\n  };\n\n  const describeBundleTotals = () => {\n    const max = getBundleMax();\n    const subtotal = getBundleSubtotal();\n    const parts = [];\n    if (getQuantityInputs().length && max) {\n      const total = getBundleTotal();\n      parts.push(`${total} of ${max} boxes selected.`);\n      const discount = describeDiscount(total);\n      if (discount) parts.push(discount);\n    }\n    if (subtotal) parts.push(`Subtotal ${subtotal}.`);\n    return parts.join(\" \");\n  };\n\n  document.addEventListener(\n    \"click\",\n    (event) => {\n      if (!event.target.closest?.('button[aria-label^=\"Add one\"]')) return;\n      if (!event.target.closest(\"[data-theme-bundle-grid]\") || !getQuantityInputs().length) return;\n\n      const max = getBundleMax();\n      if (!max || getBundleTotal() < max) return;\n      // Every attempt past the limit is announced.\n      window.setTimeout(() => {\n        announceBundleLimit(\n          `Bundle full. You can choose up to ${max} boxes. Remove a box to add a different one.`\n        );\n      }, 400);\n    },\n    true\n  );\n\n  // A quantity typed over the limit is quietly put back by the app. Say so, unless the change is announced anyway.\n  let lastContentsAnnouncement = 0;\n  const typedQuantityTimers = new WeakMap();\n  document.addEventListener(\n    \"input\",\n    (event) => {\n      const input = event.target.closest?.('input[aria-label^=\"Quantity of\"]');\n      if (!input) return;\n      const typed = Number.parseInt(input.value, 10);\n      if (!Number.isFinite(typed)) return;\n      const typedAt = performance.now();\n      window.clearTimeout(typedQuantityTimers.get(input));\n      typedQuantityTimers.set(\n        input,\n        window.setTimeout(() => {\n          const actual = Number.parseInt(input.value, 10) || 0;\n          const max = getBundleMax();\n          if (!input.isConnected || actual >= typed || !max || lastContentsAnnouncement > typedAt) return;\n          const title = input.getAttribute(\"aria-label\").replace(/^Quantity of /, \"\");\n          announceBundleLimit(\n            `You can choose up to ${max} boxes in total. Quantity of ${title} set to ${actual}. ${describeBundleTotals()}`\n          );\n        }, 900)\n      );\n    },\n    true\n  );\n\n  // Next: below the minimum the app only flashes a toast, so announce it; otherwise move focus to the next step's\n  // heading once the app has rendered it.\n  const isNextButton = (button) => /^(kolejny|next)$/i.test(normalizeLabel(button));\n  document.addEventListener(\n    \"click\",\n    (event) => {\n      const nextButton = event.target.closest?.(\"button\");\n      if (!nextButton || !isNextButton(nextButton) || !nextButton.closest(\"main\")) return;\n\n      const { min } = getBundleTiers();\n      const total = getBundleTotal();\n      if (getQuantityInputs().length && min && total < min) {\n        window.setTimeout(() => {\n          announceBundleLimit(\n            `Add at least ${pluralBoxes(min)} to continue. ${total} of ${min} selected.`\n          );\n        }, 300);\n        return;\n      }\n\n      const header = document.querySelector(\"[data-dynamic-box-header]\");\n      const startHeading = normalizeLabel(header);\n      let attempts = 0;\n      const focusNextStep = () => {\n        const stepHeading = document.querySelector(\"[data-dynamic-box-header]\");\n        if (stepHeading && normalizeLabel(stepHeading) !== startHeading) {\n          stepHeading.setAttribute(\"tabindex\", \"-1\");\n          stepHeading.setAttribute(\"data-theme-bundle-step-heading\", \"\");\n          stepHeading.focus({ preventScroll: true });\n          stepHeading.scrollIntoView({ block: \"start\" });\n          return;\n        }\n        attempts += 1;\n        if (attempts < 40) window.setTimeout(focusNextStep, 50);\n      };\n      window.setTimeout(focusNextStep, 0);\n    },\n    true\n  );\n\n  let bundleSyncTimer;\n  const bundleLimitObserver = new MutationObserver(() => {\n    window.clearTimeout(bundleSyncTimer);\n    bundleSyncTimer = window.setTimeout(() => {\n      enhanceBundleFrequencyOptions();\n      enhanceBundleSummary();\n      repairBundleHeadingLevels();\n      syncBundleDrawers();\n      repairBundleControls();\n      enhanceRemoveControls();\n      nameBundleProductCards();\n      restoreBoxFocus();\n      syncBundleLimitState();\n      muteAppAnnouncer();\n      scheduleContentsAnnouncement();\n    }, 50);\n  });\n\n  bundleLimitObserver.observe(document.body || document.documentElement, {\n    childList: true,\n    subtree: true,\n    attributes: true,\n    // The toast is shown and hidden through inline styles/classes, not by adding nodes. Quantities and the app's\n    // own control labels change as text and aria-label updates.\n    characterData: true,\n    attributeFilter: [\"tabindex\", \"style\", \"class\", \"aria-label\"]\n  });\n\n  // The app's \"product details\" drawer stays in the page when closed, just slid off screen, so its close button\n  // is still a (hidden) tab stop and screen readers still see a modal dialog. Learn the class the drawer has\n  // while closed (off screen), then hide it and take its controls out of the tab order whenever it has that class.\n  const drawerSelector = '[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby=\"drawer-title\"]';\n  const drawerFocusableSelector =\n    'a[href], button, input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n  const closedDrawerClass = new WeakMap();\n\n  // While the drawer is open, everything else on the page is inert (hidden from screen readers' browse mode, not\n  // just from Tab). The drawer sits deep inside the app, so make the siblings along its path inert.\n  const setPageBehindDrawerInert = (drawer, isOpen) => {\n    // Start from a clean state each time, so switching between drawers never leaves the new one inert.\n    document.querySelectorAll(\"[data-theme-drawer-inert]\").forEach((element) => {\n      element.inert = false;\n      delete element.dataset.themeDrawerInert;\n    });\n    if (!isOpen) return;\n    for (let node = drawer; node && node !== document.body; node = node.parentElement) {\n      Array.from(node.parentElement?.children || []).forEach((sibling) => {\n        if (sibling === node || sibling.inert || /^(SCRIPT|STYLE|LINK|NOSCRIPT|TEMPLATE)$/.test(sibling.tagName)) return;\n        sibling.inert = true;\n        sibling.dataset.themeDrawerInert = \"true\";\n      });\n    }\n  };\n\n  const applyDrawerState = (drawer) => {\n    const isClosed = drawer.className === closedDrawerClass.get(drawer);\n    // There is one drawer per product; only the open one decides what is inert.\n    const openDrawer = Array.from(document.querySelectorAll(drawerSelector)).find(\n      (candidate) => closedDrawerClass.has(candidate) && candidate.className !== closedDrawerClass.get(candidate)\n    );\n    setPageBehindDrawerInert(openDrawer, Boolean(openDrawer));\n\n    if (isClosed) {\n      if (drawer.getAttribute(\"aria-hidden\") !== \"true\") {\n        drawer.setAttribute(\"aria-hidden\", \"true\");\n      }\n      drawer.querySelectorAll(drawerFocusableSelector).forEach((control) => {\n        if (control.hasAttribute(\"data-theme-drawer-tabindex\")) return;\n        control.setAttribute(\n          \"data-theme-drawer-tabindex\",\n          control.getAttribute(\"tabindex\") ?? \"\"\n        );\n        control.setAttribute(\"tabindex\", \"-1\");\n      });\n    } else {\n      drawer.removeAttribute(\"aria-hidden\");\n      describeDrawer(drawer);\n      // The drawer is labelled by #drawer-title, but the app renders the product name as a plain heading without\n      // that id, so the dialog had no name. Point the label at the heading that is there.\n      const labelId = drawer.getAttribute(\"aria-labelledby\");\n      if (labelId && !document.getElementById(labelId)) {\n        const heading = drawer.querySelector(\"h1, h2, h3, [role='heading']\");\n        if (heading) {\n          heading.id ||= labelId;\n          if (heading.id !== labelId) drawer.setAttribute(\"aria-labelledby\", heading.id);\n        }\n      }\n      drawer.querySelectorAll(\"[data-theme-drawer-tabindex]\").forEach((control) => {\n        const originalTabindex = control.getAttribute(\"data-theme-drawer-tabindex\");\n        if (originalTabindex) {\n          control.setAttribute(\"tabindex\", originalTabindex);\n        } else {\n          control.removeAttribute(\"tabindex\");\n        }\n        control.removeAttribute(\"data-theme-drawer-tabindex\");\n      });\n    }\n  };\n\n  function syncBundleDrawers() {\n    document.querySelectorAll(drawerSelector).forEach((drawer) => {\n      if (!closedDrawerClass.has(drawer)) {\n        // Only learn from the closed state: the drawer is entirely past the right edge of the viewport.\n        // clientWidth excludes the scrollbar, which is where an off-screen drawer starts.\n        if (drawer.getBoundingClientRect().left < document.documentElement.clientWidth - 1) return;\n        closedDrawerClass.set(drawer, drawer.className);\n        // React to open/close immediately rather than through the debounced page observer.\n        new MutationObserver(() => applyDrawerState(drawer)).observe(drawer, {\n          attributes: true,\n          attributeFilter: [\"class\"]\n        });\n      }\n      applyDrawerState(drawer);\n    });\n  }\n\n  // The page subtitle is an <h3> directly under the <h1>; it sits at level 2 in the outline.\n  function repairBundleHeadingLevels() {\n    document\n      .querySelectorAll(\"h3[data-dynamic-box-subheader]\")\n      .forEach((subheader) => {\n        if (subheader.getAttribute(\"aria-level\") !== \"2\") {\n          subheader.setAttribute(\"aria-level\", \"2\");\n        }\n      });\n    markBundleProductGrid();\n    removeTierBarTabStop();\n  }\n\n  // The discount tier bar (\"Min 2\", \"3% off\", \"5% off\") scrolls sideways by a few pixels, and Chrome makes a\n  // scrolling area with nothing focusable inside it a tab stop of its own, whose focus ring the bar then clips at the\n  // bottom. It is a progress display with no controls, so keep it out of the tab order.\n  function removeTierBarTabStop() {\n    document.querySelectorAll(\"main div\").forEach((element) => {\n      if (element.hasAttribute(\"data-theme-tier-bar\")) return;\n      if (!/\\d+\\s*%/.test(element.textContent) || element.textContent.length > 300) return;\n      if (!/auto|scroll/.test(getComputedStyle(element).overflowX)) return;\n      if (element.querySelector(\"a[href], button, input, select, textarea\")) return;\n      // Its markers can be focusable text; they aren't controls.\n      element.querySelectorAll(\"[tabindex]:not([tabindex='-1'])\").forEach((marker) => marker.removeAttribute(\"tabindex\"));\n      element.setAttribute(\"data-theme-tier-bar\", \"\");\n      element.setAttribute(\"tabindex\", \"-1\");\n    });\n  }\n\n  // Reflow at 320px: the product grid uses two fixed 156px columns, wider than a 320px screen allows. The app's\n  // class names are generated, so tag the grid by its content and let ada-accessibility.css shrink its columns.\n  function markBundleProductGrid() {\n    const addButton = document.querySelector('button[aria-label^=\"Add one\"]');\n    let element = addButton?.parentElement;\n    while (element && element !== document.body) {\n      if (getComputedStyle(element).display === \"grid\" && element.children.length > 1) {\n        if (!element.hasAttribute(\"data-theme-bundle-grid\")) element.setAttribute(\"data-theme-bundle-grid\", \"\");\n        return;\n      }\n      element = element.parentElement;\n    }\n  }\n\n  // Product cards: each card is a group named after its product, which screen readers say once as focus (or the\n  // reading cursor) enters the card. Everything inside then leaves the name out, so it is heard only once: the\n  // controls get short names (\"Learn more\", \"Add one, current quantity 0\", \"Quantity\") and the product image and the\n  // visible title, which repeat the name, are hidden from screen readers.\n  // The app's aria-labels stay as they are (other code here finds the controls by them); the short names are\n  // given with aria-labelledby, which screen readers use instead, pointing at hidden text in the card.\n  const shortControlNames = [\n    [/^learn more about /i, () => \"Learn more\"],\n    [/^(add|remove) one\\b/i, (label, match) => {\n      const quantity = label.match(/current quantity:?\\s*(\\d+)/i)?.[1];\n      return `${match[1][0].toUpperCase()}${match[1].slice(1).toLowerCase()} one${quantity ? `, current quantity ${quantity}` : \"\"}`;\n    }],\n    [/^quantity of /i, () => \"Quantity\"]\n  ];\n\n  const setShortName = (control, id, name, card) => {\n    let text = document.getElementById(id);\n    if (!text) {\n      text = document.createElement(\"span\");\n      text.id = id;\n      text.hidden = true;\n      card.appendChild(text);\n    }\n    if (text.textContent !== name) text.textContent = name;\n    if (control.getAttribute(\"aria-labelledby\") !== id) control.setAttribute(\"aria-labelledby\", id);\n  };\n\n  // The price shown in a card or box item, as screen readers should hear it (\"$56.99, regular price $59.99\" when\n  // the old price is struck through), and the elements that show it, which are then hidden from screen readers\n  // because the group's name already says the price.\n  const describeBundlePrice = (container) => {\n    const prices = Array.from(container.querySelectorAll(\"*\")).filter(\n      (element) =>\n        !element.children.length &&\n        !element.hasAttribute(\"data-theme-price-note\") &&\n        !element.closest(\"[hidden], button, input, [role='button']\") &&\n        isPriceLabel(normalizeLabel(element))\n    );\n    const money = (element) => normalizeLabel(element).replace(/\\$\\s+/g, \"$\");\n    const current = prices.find((element) => !element.closest(\"s\"));\n    const regular = prices.find((element) => element.closest(\"s\"));\n    const text = current ? (regular ? `${money(current)}, regular price ${money(regular)}` : money(current)) : \"\";\n    const elements = [...prices, ...container.querySelectorAll(\"[data-theme-price-note]\")];\n    return { text, elements };\n  };\n  const hideFromScreenReaders = (elements) =>\n    elements.forEach((element) => {\n      if (element.getAttribute(\"aria-hidden\") !== \"true\") element.setAttribute(\"aria-hidden\", \"true\");\n    });\n\n  function nameBundleProductCards() {\n    document.querySelectorAll(\"[data-theme-bundle-grid] > div\").forEach((card, cardIndex) => {\n      const titleElement = card.querySelector(\"[title]\");\n      const title =\n        titleElement?.getAttribute(\"title\")?.trim() ||\n        leafLabels(card).find((label) => !/^\\d+$/.test(label) && !isPriceLabel(label) && !/^(min|max)$/i.test(label));\n      if (!title) return;\n      const price = describeBundlePrice(card);\n      const cardLabel = price.text ? `${title}, ${price.text}` : title;\n      if (card.getAttribute(\"role\") !== \"group\") card.setAttribute(\"role\", \"group\");\n      if (card.getAttribute(\"aria-label\") !== cardLabel) card.setAttribute(\"aria-label\", cardLabel);\n      if (price.text) hideFromScreenReaders(price.elements);\n\n      card.querySelectorAll(\"img\").forEach((image) => {\n        if (image.getAttribute(\"alt\") !== \"\") image.setAttribute(\"alt\", \"\");\n      });\n      if (titleElement && titleElement.getAttribute(\"aria-hidden\") !== \"true\") titleElement.setAttribute(\"aria-hidden\", \"true\");\n\n      card.querySelectorAll(\"button[aria-label], input[aria-label]\").forEach((control, controlIndex) => {\n        const label = control.getAttribute(\"aria-label\");\n        for (const [pattern, shorten] of shortControlNames) {\n          const match = label.match(pattern);\n          if (match) {\n            setShortName(control, `theme-bundle-card-${cardIndex}-${controlIndex}`, shorten(label, match), card);\n            break;\n          }\n        }\n      });\n    });\n  }\n\n  let selectedFrequencyLabel = \"\";\n  const normalizeLabel = (element) =>\n    (element?.textContent || \"\").replace(/\\s+/g, \" \").trim();\n  const isFrequencyOption = (label) =>\n    /^(jeden raz|one[\\s-]?time)/i.test(label) ||\n    /^every\\s+\\d+\\s+months?/i.test(label) ||\n    /^co\\s+\\d+\\s+miesi(?:\u0105c|\u0105ce|\u0119cy)/i.test(label);\n\n  const commonParent = (elements) => {\n    let parent = elements[0]?.parentElement;\n    while (parent && !elements.every((element) => parent.contains(element))) {\n      parent = parent.parentElement;\n    }\n    return parent;\n  };\n\n  function enhanceBundleFrequencyOptions() {\n    // The app makes plain text focusable: the tier markers (\"Min\", \"2\", \"3% off\", \"Max\", \"6\"), prices and product\n    // titles. Match them by shape rather than wording, since the app's text follows the browser's language.\n    document.querySelectorAll('div[tabindex=\"0\"]').forEach((element) => {\n      // Text only (a price may wrap its old price in <s>), never something with controls inside.\n      if (element.querySelector(\"a, button, input, select, textarea, [role='button']\")) return;\n      const label = normalizeLabel(element);\n      const isTierMarker = /^(min|max|maks|\\d+|\\d+\\s*%.*)$/i.test(label);\n      const isPrice = isPriceLabel(label) && !/[a-z]{4,}/i.test(label.replace(/usd/i, \"\"));\n      const isProductTitle =\n        element.parentElement?.hasAttribute(\"title\") ||\n        /box of \\d+/i.test(label);\n      if (isTierMarker || isPrice || isProductTitle) {\n        element.removeAttribute(\"tabindex\");\n      }\n    });\n\n    document\n      .querySelectorAll('button[aria-label^=\"Add one\"]')\n      .forEach((addButton) => {\n        const productCard = addButton.parentElement?.parentElement;\n        productCard?.querySelectorAll('div[tabindex=\"0\"]').forEach((element) => {\n          element.removeAttribute(\"tabindex\");\n        });\n      });\n\n    const options = Array.from(document.querySelectorAll(\"button\")).filter(\n      (button) => isFrequencyOption(normalizeLabel(button))\n    );\n    if (options.length < 2) return;\n\n    const group = commonParent(options);\n    if (!group) return;\n    // Only write attributes that differ: the page observer also watches aria-label, so rewriting the same value\n    // would keep triggering it.\n    if (group.getAttribute(\"role\") !== \"group\") group.setAttribute(\"role\", \"group\");\n    if (group.getAttribute(\"aria-label\") !== \"Purchase frequency\") group.setAttribute(\"aria-label\", \"Purchase frequency\");\n\n    let selected = options.find(\n      (option) => normalizeLabel(option) === selectedFrequencyLabel\n    );\n    selected ||= options.find(\n      (option) => option.getAttribute(\"aria-pressed\") === \"true\"\n    );\n    selected ||= options[0];\n    selectedFrequencyLabel = normalizeLabel(selected);\n\n    options.forEach((option) => {\n      const isSelected = option === selected;\n      option.setAttribute(\"aria-pressed\", String(isSelected));\n      if (option.getAttribute(\"tabindex\") !== \"0\") option.tabIndex = 0;\n      option.querySelectorAll(\"[tabindex]\").forEach((content) => {\n        content.removeAttribute(\"tabindex\");\n      });\n\n      if (option.dataset.themeFrequencyEnhanced === \"true\") return;\n      option.dataset.themeFrequencyEnhanced = \"true\";\n\n      option.addEventListener(\"click\", () => {\n        selectedFrequencyLabel = normalizeLabel(option);\n        window.setTimeout(enhanceBundleFrequencyOptions, 0);\n        // The frequency changes the prices, so say what it is now once the app has updated them.\n        const optionLabel = Array.from(option.children).map(normalizeLabel).filter(Boolean).join(\", \");\n        window.setTimeout(() => {\n          announceBundleUpdate(`${optionLabel} selected. ${describeBundleTotals()}`.trim());\n        }, 800);\n      });\n    });\n  }\n\n  function enhanceBundleSummary() {\n    const heading = Array.from(document.querySelectorAll(\"h2\")).find((element) =>\n      /^(twoje pude\u0142ko|your box)$/i.test(normalizeLabel(element))\n    );\n    const panel = heading?.parentElement?.parentElement;\n    if (!heading || !panel) return;\n\n    heading.id ||= \"theme-bundle-box-title\";\n    if (panel.getAttribute(\"role\") !== \"region\") panel.setAttribute(\"role\", \"region\");\n    if (panel.getAttribute(\"aria-labelledby\") !== heading.id) panel.setAttribute(\"aria-labelledby\", heading.id);\n\n    panel.querySelectorAll('[tabindex=\"0\"]').forEach((element) => {\n      if (\n        element.matches(\n          'button, a[href], input, select, textarea, [role=\"button\"]'\n        )\n      ) {\n        return;\n      }\n      element.removeAttribute(\"tabindex\");\n    });\n\n  }\n\n  // The \u00D7 buttons that remove an item, in the desktop \"Your box\" sidebar and in the mobile \"Show items\" list, are\n  // icons in divs: no role, no name, no keyboard access. Make them named buttons that work with Enter and Space.\n  const isVisible = (element) => element.getClientRects().length > 0;\n  function enhanceRemoveControls() {\n    document.querySelectorAll('main svg[data-testid=\"ClearIcon\"]').forEach((icon) => {\n      const removeControl = icon.parentElement?.parentElement;\n      const item = removeControl?.parentElement?.parentElement;\n      if (!removeControl || !item) return;\n\n      const productTitle = leafLabels(item).find((label) => !/^\\d+$/.test(label) && !isPriceLabel(label));\n      const image = item.querySelector(\"img\");\n\n      if (removeControl.getAttribute(\"role\") !== \"button\") removeControl.setAttribute(\"role\", \"button\");\n      if (removeControl.getAttribute(\"tabindex\") !== \"0\") removeControl.setAttribute(\"tabindex\", \"0\");\n      const removeLabel = productTitle ? `Remove ${productTitle} from bundle` : \"Remove item from bundle\";\n      if (removeControl.getAttribute(\"aria-label\") !== removeLabel) removeControl.setAttribute(\"aria-label\", removeLabel);\n      // The \u00D7 is the item's only stop for Tab, and nothing around it said which product it is or how many are in\n      // the box. Name the item as a group (\"P.B. Banana Protein Bar\u2026, quantity 2, $116.38\"), said once as focus\n      // enters it, and leave all that out of everything inside: the \u00D7 is \"Remove from bundle\" (through\n      // aria-labelledby; its aria-label, which the box contents are read from, stays), and the image, quantity badge,\n      // visible title and price are hidden from screen readers.\n      if (productTitle) {\n        const quantity = leafLabels(removeControl.parentElement).find((label) => /^\\d+$/.test(label)) || \"1\";\n        const price = describeBundlePrice(item);\n        const itemLabel = `${productTitle}, quantity ${quantity}${price.text ? `, ${price.text}` : \"\"}`;\n        if (price.text) hideFromScreenReaders(price.elements);\n        if (item.getAttribute(\"role\") !== \"group\") item.setAttribute(\"role\", \"group\");\n        if (item.getAttribute(\"aria-label\") !== itemLabel) item.setAttribute(\"aria-label\", itemLabel);\n\n        if (image && image.getAttribute(\"alt\") !== \"\") image.setAttribute(\"alt\", \"\");\n        Array.from(item.querySelectorAll(\"div\"))\n          .filter((leaf) => !leaf.children.length && !removeControl.contains(leaf))\n          .filter((leaf) => {\n            const text = normalizeLabel(leaf);\n            return text === productTitle || /^\\d+$/.test(text);\n          })\n          .forEach((leaf) => {\n            if (leaf.getAttribute(\"aria-hidden\") !== \"true\") leaf.setAttribute(\"aria-hidden\", \"true\");\n          });\n\n        let shortName = item.querySelector(\":scope > [data-theme-remove-name]\");\n        if (!shortName) {\n          shortName = document.createElement(\"span\");\n          shortName.hidden = true;\n          shortName.dataset.themeRemoveName = \"\";\n          shortName.id = `theme-bundle-remove-${Math.random().toString(36).slice(2, 9)}`;\n          shortName.textContent = \"Remove from bundle\";\n          item.appendChild(shortName);\n        }\n        if (removeControl.getAttribute(\"aria-labelledby\") !== shortName.id) {\n          removeControl.setAttribute(\"aria-labelledby\", shortName.id);\n        }\n      }\n\n      if (removeControl.dataset.themeRemoveEnhanced === \"true\") return;\n      removeControl.dataset.themeRemoveEnhanced = \"true\";\n      removeControl.addEventListener(\"keydown\", (event) => {\n        if (event.key !== \"Enter\" && event.key !== \" \") return;\n        event.preventDefault();\n        removeControl.click();\n      });\n      // Removing the item re-renders the list and drops focus to the top of the page; keep the user's place.\n      removeControl.addEventListener(\"click\", () => {\n        if (!removeControl.contains(document.activeElement)) return;\n        const controls = Array.from(document.querySelectorAll(\"[data-theme-remove-enhanced]\")).filter(isVisible);\n        pendingBoxFocus = { index: controls.indexOf(removeControl), until: performance.now() + 3000 };\n      });\n    });\n  }\n\n  // After an item is removed, put focus on the next item's remove button (or the previous one; when the list is empty,\n  // the mobile \"Hide items\" toggle or the \"Your box\" heading) instead of letting it fall to the top of the page.\n  let pendingBoxFocus = null;\n  function restoreBoxFocus() {\n    if (!pendingBoxFocus) return;\n    if (performance.now() > pendingBoxFocus.until) {\n      pendingBoxFocus = null;\n      return;\n    }\n    const active = document.activeElement;\n    if (active?.matches?.(\"[data-theme-remove-enhanced]\") && active.isConnected) return; // not re-rendered yet\n    if (active && active !== document.body) {\n      pendingBoxFocus = null; // the user has moved on\n      return;\n    }\n    const controls = Array.from(document.querySelectorAll(\"[data-theme-remove-enhanced]\")).filter(isVisible);\n    const boxHeading = document.getElementById(\"theme-bundle-box-title\");\n    // With the box empty the mobile bar disappears too; then go to the page heading.\n    const pageHeading = document.querySelector(\"[data-dynamic-box-header]\");\n    const target =\n      controls[pendingBoxFocus.index] ||\n      controls[pendingBoxFocus.index - 1] ||\n      Array.from(document.querySelectorAll(\"main [data-theme-div-button]\")).find(isVisible) ||\n      (boxHeading && isVisible(boxHeading) ? boxHeading : null) ||\n      pageHeading;\n    pendingBoxFocus = null;\n    if (!target) return;\n    if (target.matches(\"h1, h2, h3\")) target.setAttribute(\"tabindex\", \"-1\");\n    target.focus({ preventScroll: true });\n  }\n\n  // Controls the app builds from divs or leaves unnamed.\n  const makeDivButton = (element) => {\n    if (element.getAttribute(\"role\") !== \"button\") element.setAttribute(\"role\", \"button\");\n    if (element.dataset.themeDivButton === \"true\") return;\n    element.dataset.themeDivButton = \"true\";\n    element.addEventListener(\"keydown\", (event) => {\n      if (event.key !== \"Enter\" && event.key !== \" \") return;\n      event.preventDefault();\n      const index = Array.from(document.querySelectorAll(\"main [data-theme-div-button]\")).filter(isVisible).indexOf(element);\n      element.click();\n      if (!element.hasAttribute(\"aria-expanded\")) return; // only the Show/Hide items toggle is replaced in place\n      // The app replaces the control when it toggles (e.g. \"Show items\" becomes \"Hide items\"), which dropped focus to\n      // the top of the page. Put focus on the control that took its place.\n      [150, 400].forEach((delay) =>\n        window.setTimeout(() => {\n          if (document.activeElement && document.activeElement !== document.body) return;\n          const replacement = Array.from(document.querySelectorAll(\"main [data-theme-div-button]\")).filter(isVisible)[index];\n          replacement?.focus({ preventScroll: true });\n        }, delay)\n      );\n    });\n  };\n\n  function repairBundleControls() {\n    const root = document.querySelector(\"#skio-root\");\n    if (!root) return;\n\n    // Text the app makes focusable: the label inside the Next/Checkout buttons (a second, unlabelled tab stop) and\n    // the mobile bar's \"Total (n items)\". \"Modify box\" and the mobile \"Show items\" sit next to an icon and act as\n    // buttons, so expose them as buttons that also work with Enter and Space.\n    root.querySelectorAll('div[tabindex=\"0\"]').forEach((element) => {\n      if (element.closest(\"button\")) {\n        element.removeAttribute(\"tabindex\");\n      } else if (/^(total|razem)\\b/i.test(normalizeLabel(element))) {\n        element.removeAttribute(\"tabindex\");\n      } else if (element.parentElement?.querySelector(\":scope > svg, :scope > div > svg\")) {\n        makeDivButton(element);\n      }\n    });\n\n    // Mobile \"Show items\" / \"Hide items\" toggles the list of items in the bottom bar; say whether it is open.\n    root.querySelectorAll(\"[data-theme-div-button]\").forEach((toggle) => {\n      const label = normalizeLabel(toggle);\n      const expanded = /^(hide|ukryj)/i.test(label) ? \"true\" : /^(show|poka\u017C)/i.test(label) ? \"false\" : null;\n      if (expanded && toggle.getAttribute(\"aria-expanded\") !== expanded) toggle.setAttribute(\"aria-expanded\", expanded);\n    });\n\n    // Struck-through prices (e.g. \"$179.97 $170.97\" in the mobile bar) don't say which is which. Add hidden words\n    // before them: \"Regular price $179.97, now $170.97\".\n    // (The words are separate elements next to the prices, so the price elements themselves stay unchanged.)\n    const addPriceNote = (before, text) => {\n      if (before.previousElementSibling?.hasAttribute(\"data-theme-price-note\")) return;\n      const note = document.createElement(\"span\");\n      note.className = \"sr-only\";\n      note.dataset.themePriceNote = \"\";\n      note.textContent = text;\n      before.before(note);\n    };\n    root.querySelectorAll(\"s\").forEach((struck) => {\n      const holder = struck.parentElement;\n      if (!holder) return;\n      addPriceNote(holder, \"Regular price \");\n      let current = holder.nextElementSibling;\n      while (current?.hasAttribute(\"data-theme-price-note\")) current = current.nextElementSibling;\n      if (current && isPriceLabel(normalizeLabel(current))) addPriceNote(current, \", now \");\n    });\n\n    // Step 2 (six packs): the add/remove buttons say \"Add one item\" without the product.\n    root\n      .querySelectorAll('button[aria-label^=\"Add one item\"], button[aria-label^=\"Remove one item\"]')\n      .forEach((button) => {\n        const card = button.closest(\"[data-theme-bundle-grid] > div\");\n        if (!card) return;\n        const labels = leafLabels(card);\n        const title = labels.find((label) => !/^\\d+$/.test(label) && !isPriceLabel(label));\n        if (!title) return;\n        const quantity = labels.find((label) => /^\\d+$/.test(label)) ?? \"0\";\n        const verb = button.getAttribute(\"aria-label\").startsWith(\"Add\") ? \"Add one\" : \"Remove one\";\n        const label = `${verb} ${title}. Current quantity: ${quantity}`;\n        if (button.getAttribute(\"aria-label\") !== label) button.setAttribute(\"aria-label\", label);\n        card.querySelectorAll(\"img:not([alt])\").forEach((image) => image.setAttribute(\"alt\", \"\"));\n      });\n\n    // Step 2 renders an empty subtitle heading.\n    root.querySelectorAll(\"[data-dynamic-box-subheader]\").forEach((subheader) => {\n      const isEmpty = !normalizeLabel(subheader);\n      if (isEmpty && subheader.getAttribute(\"aria-hidden\") !== \"true\") subheader.setAttribute(\"aria-hidden\", \"true\");\n      if (!isEmpty && subheader.hasAttribute(\"aria-hidden\")) subheader.removeAttribute(\"aria-hidden\");\n    });\n\n    // The tier bar is read as one line that says what each discount needs.\n    const tierBar = document.querySelector(\"[data-theme-tier-bar]\");\n    const { min, tiers } = getBundleTiers();\n    if (tierBar && tiers.length) {\n      const max = getBundleMax();\n      const description = [\n        min ? `Choose at least ${pluralBoxes(min)}.` : \"\",\n        ...tiers.map((tier) => `${tier.percent}% off with ${tier.count} or more boxes.`),\n        max ? `Up to ${pluralBoxes(max)}.` : \"\"\n      ]\n        .filter(Boolean)\n        .join(\" \");\n      if (tierBar.getAttribute(\"role\") !== \"img\") tierBar.setAttribute(\"role\", \"img\");\n      if (tierBar.getAttribute(\"aria-label\") !== description) tierBar.setAttribute(\"aria-label\", description);\n    }\n  }\n\n  // Below the minimum, Next is marked unavailable (it still explains why when pressed). At the limit, the Add\n  // buttons are marked unavailable and a visible note says the bundle is full.\n  let bundleFullNotice = null;\n  function syncBundleLimitState() {\n    const inputs = getQuantityInputs();\n    if (!inputs.length) return;\n    const total = getBundleTotal();\n    const max = getBundleMax();\n    const { min } = getBundleTiers();\n\n    document.querySelectorAll(\"main button\").forEach((button) => {\n      if (!isNextButton(button)) return;\n      const unavailable = String(Boolean(min && total < min));\n      if (button.getAttribute(\"aria-disabled\") !== unavailable) button.setAttribute(\"aria-disabled\", unavailable);\n      // \"Next\" alone doesn't say where it goes; the next step offers six packs, then checkout.\n      const label = \"Next: add a six pack, then check out\";\n      if (button.getAttribute(\"aria-label\") !== label) button.setAttribute(\"aria-label\", label);\n    });\n\n    const isFull = Boolean(max && total >= max);\n    // Don't leave \"Bundle full\" in the announcer once the box has room again.\n    if (!isFull && /full/i.test(bundleStatus.textContent)) bundleStatus.textContent = \"\";\n    document.querySelectorAll('[data-theme-bundle-grid] button[aria-label^=\"Add one\"]').forEach((button) => {\n      if (isFull && button.getAttribute(\"aria-disabled\") !== \"true\") button.setAttribute(\"aria-disabled\", \"true\");\n      if (!isFull && button.hasAttribute(\"aria-disabled\")) button.removeAttribute(\"aria-disabled\");\n    });\n\n    const grid = document.querySelector(\"[data-theme-bundle-grid]\");\n    if (!grid) return;\n    if (!bundleFullNotice) {\n      bundleFullNotice = document.createElement(\"p\");\n      bundleFullNotice.className = \"theme-bundle-full-notice\";\n    }\n    if (bundleFullNotice.nextElementSibling !== grid) grid.before(bundleFullNotice);\n    const text = isFull ? `Your bundle is full: ${max} of ${max} boxes selected. Remove a box to add a different one.` : \"\";\n    if (bundleFullNotice.textContent !== text) bundleFullNotice.textContent = text;\n    bundleFullNotice.hidden = !isFull;\n  }\n\n  // The app announces each add as \"Added \u2026 to cart. Currently 1 in cart.\" (that product's count, not the box's) in\n  // an assertive region, which also collides with the limit messages. Silence it and announce every change to the\n  // box contents (+, -, typed quantities, the remove buttons, six packs) with the box's running total instead.\n  function muteAppAnnouncer() {\n    document.querySelectorAll('main [role=\"alert\"], main [aria-live=\"assertive\"]').forEach((region) => {\n      region.setAttribute(\"role\", \"none\");\n      region.setAttribute(\"aria-live\", \"off\");\n    });\n  }\n\n  // Read from the desktop \"Your box\" sidebar. Phones and narrow windows don't have it (only a \"Show items \u00B7 Total\"\n  // bar), so there read the product cards instead: the quantity fields in step 1, the six pack counts in step 2.\n  const getBoxContents = () => {\n    const contents = new Map();\n    const add = (title, quantity) => {\n      if (title && quantity > 0) contents.set(title, (contents.get(title) || 0) + quantity);\n    };\n    const panel = document.querySelector('[role=\"region\"][aria-labelledby=\"theme-bundle-box-title\"]');\n    if (panel && panel.getClientRects().length) {\n      panel.querySelectorAll(\"[data-theme-remove-enhanced]\").forEach((control) => {\n        const title = control.getAttribute(\"aria-label\").replace(/^Remove /, \"\").replace(/ from bundle$/, \"\");\n        add(title, Number(leafLabels(control.parentElement).find((label) => /^\\d+$/.test(label)) || 1));\n      });\n    } else {\n      document.querySelectorAll(\"[data-theme-bundle-grid] > div\").forEach((card) => {\n        const input = card.querySelector('input[aria-label^=\"Quantity of\"]');\n        if (input) {\n          add(input.getAttribute(\"aria-label\").replace(/^Quantity of /, \"\"), Number.parseInt(input.value, 10) || 0);\n          return;\n        }\n        const labels = leafLabels(card);\n        add(\n          labels.find((label) => !/^\\d+$/.test(label) && !isPriceLabel(label)),\n          Number(labels.find((label) => /^\\d+$/.test(label)) || 0)\n        );\n      });\n    }\n    // Moving between steps swaps the cards, which isn't a change to the box.\n    contents.step = normalizeLabel(document.querySelector(\"[data-dynamic-box-header]\"));\n    return contents;\n  };\n\n  let previousContents = null;\n  let contentsTimer;\n  function scheduleContentsAnnouncement() {\n    window.clearTimeout(contentsTimer);\n    // Wait for the app to finish updating counts and prices.\n    contentsTimer = window.setTimeout(announceContentsChange, 300);\n  }\n\n  function announceContentsChange() {\n    const contents = getBoxContents();\n    const previous = previousContents;\n    previousContents = contents;\n    if (!previous || previous.step !== contents.step) return;\n\n    const changes = [];\n    let added = false;\n    new Set([...previous.keys(), ...contents.keys()]).forEach((title) => {\n      const before = previous.get(title) || 0;\n      const after = contents.get(title) || 0;\n      if (before === after) return;\n      if (after === 0) changes.push(`Removed ${title} from your box.`);\n      else if (before === 0 && after === 1) changes.push(`Added ${title} to your box.`);\n      else changes.push(`${title}: quantity ${after}.`);\n      if (after > before) added = true;\n    });\n    if (!changes.length) return;\n\n    lastContentsAnnouncement = performance.now();\n    const max = getBundleMax();\n    const isFull = Boolean(getQuantityInputs().length && max && getBundleTotal() >= max);\n    const message = `${changes.join(\" \")} ${isFull ? \"Bundle full. \" : \"\"}${describeBundleTotals()}`.trim();\n    if (isFull && added) {\n      announceBundleLimit(message);\n    } else {\n      announceBundleUpdate(message);\n    }\n  }\n\n  // \"Learn more\" drawer: screen readers announced only the product name, not the details, and Tab left the\n  // (modal) drawer after its close button. Describe the drawer by its content and keep Tab inside it.\n  const openBundleDrawer = () =>\n    document.querySelector(`${drawerSelector}:not([aria-hidden=\"true\"])`);\n\n  document.addEventListener(\n    \"keydown\",\n    (event) => {\n      if (event.key !== \"Tab\") return;\n      const drawer = openBundleDrawer();\n      if (!drawer || !drawer.contains(document.activeElement)) return;\n      const controls = Array.from(drawer.querySelectorAll(drawerFocusableSelector)).filter(\n        (control) => control.tabIndex >= 0 && control.getClientRects().length > 0\n      );\n      if (!controls.length) return;\n      const first = controls[0];\n      const last = controls[controls.length - 1];\n      if (event.shiftKey && (document.activeElement === first || document.activeElement === drawer)) {\n        event.preventDefault();\n        last.focus();\n      } else if (!event.shiftKey && document.activeElement === last) {\n        event.preventDefault();\n        first.focus();\n      }\n    },\n    true\n  );\n\n  const describeDrawer = (drawer) => {\n    const heading = drawer.querySelector(\"h1, h2, h3, [role='heading']\");\n    const content = heading?.parentElement?.nextElementSibling;\n    if (!content || !normalizeLabel(content)) return;\n    content.id ||= \"theme-drawer-description\";\n    if (drawer.getAttribute(\"aria-describedby\") !== content.id) drawer.setAttribute(\"aria-describedby\", content.id);\n  };\n\n  enhanceBundleFrequencyOptions();\n  enhanceBundleSummary();\n  enhanceRemoveControls();\n  repairBundleHeadingLevels();\n  syncBundleDrawers();\n}\n\nlet upcartTrigger = null;\n\n// When the cart opens from a product form's \"Add to cart\" (the product page, or the \"Quick add\" popup whose button\n// isn't the element focus returns to), announce the added item rather than \"Cart opened\". UpCart intercepts the\n// button's click and submit before they reach the page, so note the key press / tap on it and the add request.\nlet lastAddToCartAt = 0;\nconst noteAddToCart = () => {\n  lastAddToCartAt = performance.now();\n  document.dispatchEvent(new CustomEvent(\"theme:add-to-cart\"));\n};\nconst rememberAddToCart = (event) => {\n  if (event.type === \"keydown\" && event.key !== \"Enter\" && event.key !== \" \") return;\n  if (event.target.closest?.(\"form[action*='/cart/add'] [type='submit'], [type='submit'][form]\")?.form?.matches(\"form[action*='/cart/add']\")) {\n    noteAddToCart();\n  }\n};\nwindow.addEventListener(\"keydown\", rememberAddToCart, true);\nwindow.addEventListener(\"pointerdown\", rememberAddToCart, true);\nif (\"PerformanceObserver\" in window) {\n  new PerformanceObserver((list) => {\n    if (list.getEntries().some((entry) => /\\/cart\\/add(\\.js)?$/.test(new URL(entry.name, location.href).pathname))) {\n      noteAddToCart();\n    }\n  }).observe({ type: \"resource\", buffered: false });\n}\n\n// Set by ada-upcart-keyboard.js when the cart opens from a theme dialog it then closes: the element that opened\n// the cart is hidden with that dialog, so focus returns to the dialog's toggle instead.\ndocument.addEventListener(\"theme:upcart-return-target\", (event) => {\n  if (event.detail?.target instanceof HTMLElement) upcartTrigger = event.detail.target;\n  // This only happens when the cart opens over a product dialog, i.e. after \"Add to cart\" in \"Quick add\".\n  noteAddToCart();\n});\n\ndocument.addEventListener(\n  \"keydown\",\n  (event) => {\n    if (event.key !== \"Escape\") return;\n\n    const host = document.querySelector(\"#upCart\");\n    const root = host?.shadowRoot;\n    const dialog = root?.querySelector('#CartPopup[aria-modal=\"true\"]');\n    const closeButton = dialog?.querySelector('[aria-label=\"Close cart\"]');\n    if (!dialog || !closeButton) return;\n\n    event.preventDefault();\n    closeButton.click();\n    window.setTimeout(() => {\n      dialog.setAttribute(\"aria-hidden\", \"true\");\n      if (upcartTrigger?.isConnected) upcartTrigger.focus();\n    }, 500);\n  },\n  true\n);\n\ndocument.addEventListener(\"focusin\", (event) => {\n  const host = event.target;\n  if (!(host instanceof HTMLElement)) return;\n\n  if (host.id !== \"upCart\") {\n    upcartTrigger = host;\n    return;\n  }\n\n  const root = host.shadowRoot;\n  if (!root || root.querySelector(\"#theme-cart-focus\")) return;\n\n  const style = document.createElement(\"style\");\n  style.id = \"theme-cart-focus\";\n  style.textContent = `#UpcartPopup :where(\n    a[href],\n    button,\n    input:not([type=\"hidden\"]),\n    select,\n    textarea,\n    [tabindex]:not([tabindex=\"-1\"]),\n    [role=\"button\"],\n    [role=\"switch\"],\n    [role=\"option\"]\n  ):focus-visible {\n    outline: 3px solid #002c6b !important;\n    outline-offset: 3px !important;\n    box-shadow: 0 0 0 3px #fff !important;\n  }\n  /* Cart buttons sit in clipping containers, so their ring is drawn inside. The white inner band keeps it visible\n     on the orange buttons, where a plain blue ring was about 2:1. */\n  #UpcartPopup :where(button, [role=\"button\"]):focus-visible {\n    outline-offset: -3px !important;\n    box-shadow: inset 0 0 0 5px #fff !important;\n  }\n  #UpcartPopup :where(\n    button[aria-label=\"Decrease quantity\"],\n    button[aria-label=\"Increase quantity\"]\n  ):focus-visible {\n    outline: 3px solid #002c6b !important;\n    outline-offset: -3px !important;\n    border-radius: 4px !important;\n    box-shadow: none !important;\n  }\n  #UpcartPopup input[inputmode=\"numeric\"]:focus-visible {\n    outline-offset: -3px !important;\n  }\n  /* Empty cart \"Shop Now\": the orange button is a div and only its text is the link, so the focus ring (and the\n     click area) covered just the word. Stretch the link over the whole button and draw the ring on the button. */\n  #UpcartPopup .upcart-public-upsell__shop-now-button {\n    position: relative;\n  }\n  #UpcartPopup .upcart-public-upsell__shop-now-button > a::after {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n  }\n  #UpcartPopup .upcart-public-upsell__shop-now-button > a:focus-visible {\n    outline: none !important;\n    box-shadow: none !important;\n  }\n  #UpcartPopup .upcart-public-upsell__shop-now-button:has(> a:focus-visible) {\n    outline: 3px solid #002c6b !important;\n    outline-offset: -3px !important;\n    box-shadow: inset 0 0 0 5px #fff !important;\n  }\n  #theme-cart-status {\n    position: absolute !important;\n    width: 1px !important;\n    height: 1px !important;\n    padding: 0 !important;\n    margin: -1px !important;\n    overflow: hidden !important;\n    clip: rect(0, 0, 0, 0) !important;\n    white-space: nowrap !important;\n    border: 0 !important;\n  }`;\n  root.appendChild(style);\n\n  const status = document.createElement(\"div\");\n  status.id = \"theme-cart-status\";\n  status.setAttribute(\"role\", \"status\");\n  status.setAttribute(\"aria-live\", \"polite\");\n  status.setAttribute(\"aria-atomic\", \"true\");\n  root.appendChild(status);\n\n  const configureDialog = () => {\n    const dialog = root.querySelector(\"#CartPopup\");\n    const heading = dialog?.querySelector(\"h1, h2, h3\");\n    if (!dialog || !heading) return;\n\n    heading.id ||= \"theme-cart-title\";\n    if (dialog.getAttribute(\"role\") !== \"dialog\") {\n      dialog.setAttribute(\"role\", \"dialog\");\n    }\n    if (dialog.getAttribute(\"aria-modal\") !== \"true\") {\n      dialog.setAttribute(\"aria-modal\", \"true\");\n    }\n    if (dialog.getAttribute(\"aria-labelledby\") !== heading.id) {\n      dialog.setAttribute(\"aria-labelledby\", heading.id);\n    }\n    dialog.removeAttribute(\"aria-hidden\");\n    configureAddonToggles();\n    configureCarousel();\n    labelCartControls();\n  };\n\n  // The recommended-products carousel is a polite live region, so every cart change re-rendered it and screen\n  // readers read out all its cards after the cart message. Its slides past the visible one also stayed in the Tab\n  // order, so focus disappeared off the side of the drawer. Silence it and make the hidden slides inert.\n  const syncCarouselSlides = () => {\n    const slides = root.querySelector(\"#carousel-slides\");\n    const viewport = slides?.parentElement;\n    if (!viewport) return;\n    const bounds = viewport.getBoundingClientRect();\n    slides.querySelectorAll(':scope > [aria-roledescription=\"slide\"]').forEach((slide) => {\n      const rect = slide.getBoundingClientRect();\n      const isVisible = rect.width > 0 && rect.left >= bounds.left - 1 && rect.right <= bounds.right + 1;\n      if (slide.inert === isVisible) slide.inert = !isVisible;\n    });\n  };\n\n  const configureCarousel = () => {\n    const slides = root.querySelector(\"#carousel-slides\");\n    if (!slides) return;\n    if (slides.getAttribute(\"aria-live\") !== \"off\") slides.setAttribute(\"aria-live\", \"off\");\n    syncCarouselSlides();\n  };\n\n  // \"Decrease quantity\", \"Increase quantity\", \"Product quantity\" and the carousel's \"Add\" don't say which product.\n  // Give them plain names that say what they do (\"Add one P.B. Crunchy\u2026\", \"Quantity of \u2026\") through\n  // aria-labelledby and hidden label text, keeping the aria-label the other cart code selects on.\n  let cartIdCount = 0;\n  const ensureId = (element) => {\n    if (!element.id) {\n      cartIdCount += 1;\n      element.id = `theme-cart-control-${cartIdCount}`;\n    }\n    return element.id;\n  };\n  const labelWithText = (control, text) => {\n    let labels = root.querySelector(\"#theme-cart-labels\");\n    if (!labels) {\n      labels = document.createElement(\"div\");\n      labels.id = \"theme-cart-labels\";\n      labels.hidden = true;\n      root.appendChild(labels);\n    }\n    const labelId = `${ensureId(control)}-name`;\n    let label = labels.querySelector(`[id=\"${labelId}\"]`);\n    if (!label) {\n      label = document.createElement(\"span\");\n      label.id = labelId;\n      labels.appendChild(label);\n    }\n    if (label.textContent !== text) label.textContent = text;\n    if (control.getAttribute(\"aria-labelledby\") !== labelId) control.setAttribute(\"aria-labelledby\", labelId);\n  };\n\n  const cartControlNames = {\n    \"Decrease quantity\": (title) => `Decrease quantity of ${title}`,\n    \"Increase quantity\": (title) => `Increase quantity of ${title}`,\n    \"Product quantity\": (title) => `Quantity of ${title}`\n  };\n\n  // A price as screen readers should hear it: \"$53.99, regular price $59.99\" when UpCart shows a struck-through\n  // price next to the current one. UpCart writes prices as \"$ 59.99\".\n  const describeCartPrice = (container) => {\n    if (!container) return \"\";\n    const prices = Array.from(container.querySelectorAll(\"*\"))\n      .filter((element) => !element.children.length && /\\$\\s?\\d/.test(element.textContent))\n      .map((element) => ({\n        text: normalizeText(element).replace(/\\$\\s+/g, \"$\"),\n        struck: /line-through/.test(getComputedStyle(element).textDecorationLine) || Boolean(element.closest(\"s, del\"))\n      }));\n    const current = prices.find((price) => !price.struck) || prices[0];\n    const regular = prices.find((price) => price.struck && price !== current);\n    if (!current) return \"\";\n    return regular ? `${current.text}, regular price ${regular.text}` : current.text;\n  };\n\n  const labelCartControls = () => {\n    getCartLines().forEach((line) => {\n      const title = normalizeText(line?.querySelector(\"h1, h2, h3, h4\"));\n      if (!title) return;\n      line\n        .querySelectorAll(\n          'button[aria-label=\"Decrease quantity\"], button[aria-label=\"Increase quantity\"], input[aria-label=\"Product quantity\"]'\n        )\n        .forEach((control) => labelWithText(control, cartControlNames[control.getAttribute(\"aria-label\")](title)));\n\n      // The product link says the whole line: product, option, quantity and price (the price was only text).\n      const titleLink = line.querySelector(\"h1 a, h2 a, h3 a, h4 a\");\n      const variant = normalizeText(line.querySelector('[class*=\"product-tile__variant\"]'));\n      const quantity = line.querySelector('input[aria-label=\"Product quantity\"]')?.value;\n      const pricing = line.querySelector('[class*=\"product-tile__product-pricing\"]');\n      const price = describeCartPrice(pricing);\n      if (titleLink) {\n        labelWithText(\n          titleLink,\n          [title, variant, quantity ? `quantity ${quantity}` : \"\", price].filter(Boolean).join(\", \")\n        );\n        // The link says the price, so the visible \"Price $59.99\" isn't read a second time.\n        if (price && pricing.getAttribute(\"aria-hidden\") !== \"true\") pricing.setAttribute(\"aria-hidden\", \"true\");\n      }\n    });\n    root.querySelectorAll(\"[data-upcart-upsell]\").forEach((tile) => {\n      const title = normalizeText(tile.querySelector(\"h1, h2, h3, h4\"));\n      const addButton = Array.from(tile.querySelectorAll(\"button\")).find((button) =>\n        /^add$/i.test(normalizeText(button))\n      );\n      // Say which option is added and what it costs: \"Add P.B. Crunchy\u2026 - 12 Bars to cart, $59.99\".\n      const option = tile.querySelector(\"select\")?.selectedOptions?.[0];\n      const optionText = option ? normalizeText(option) : \"\";\n      const priceRow = tile.querySelector('[class*=\"upsell-tile__price-row\"]');\n      const price = describeCartPrice(priceRow);\n      if (price && priceRow.getAttribute(\"aria-hidden\") !== \"true\") priceRow.setAttribute(\"aria-hidden\", \"true\");\n      if (title && addButton) {\n        labelWithText(addButton, `Add ${title}${optionText ? ` - ${optionText}` : \"\"} to cart${price ? `, ${price}` : \"\"}`);\n      }\n      const titleLink = tile.querySelector('[class*=\"upsell-tile__title-link\"]');\n      if (title && titleLink) labelWithText(titleLink, [title, price].filter(Boolean).join(\", \"));\n    });\n  };\n\n  // Choosing another option in a recommended product changes its price; name the Add button again once it has.\n  root.addEventListener(\"change\", (event) => {\n    if (event.target.closest?.(\"[data-upcart-upsell]\")) window.setTimeout(labelCartControls, 300);\n  });\n\n  // UpCart labels every add-on switch \"Addon toggle\" and puts the focus stop on the <label>, which has no\n  // role or state. Expose the label as the switch, named after the add-on, and hide the inner checkbox.\n  const configureAddonToggles = () => {\n    root\n      .querySelectorAll(\".upcart-public-addons__toggle-switch\")\n      .forEach((toggle) => {\n        const addon = toggle.closest(\".upcart-public-addons\");\n        const input = toggle.querySelector('input[type=\"checkbox\"]');\n        if (!addon || !input) return;\n\n        const title = normalizeText(\n          addon.querySelector(\".upcart-public-addons__content-title\")\n        );\n        const price = normalizeText(\n          addon.querySelector(\".upcart-public-addons__price\")\n        );\n        const label = [title || \"Add-on\", price].filter(Boolean).join(\", \");\n        const checked = String(input.checked);\n\n        if (toggle.getAttribute(\"role\") !== \"switch\") {\n          toggle.setAttribute(\"role\", \"switch\");\n        }\n        if (toggle.getAttribute(\"aria-label\") !== label) {\n          toggle.setAttribute(\"aria-label\", label);\n        }\n        if (toggle.getAttribute(\"aria-checked\") !== checked) {\n          toggle.setAttribute(\"aria-checked\", checked);\n        }\n        if (input.getAttribute(\"tabindex\") !== \"-1\") {\n          input.setAttribute(\"tabindex\", \"-1\");\n        }\n        if (input.getAttribute(\"aria-hidden\") !== \"true\") {\n          input.setAttribute(\"aria-hidden\", \"true\");\n        }\n        // The label is the switch; the hidden checkbox's own role=\"switch\" made it a switch inside a switch.\n        if (input.hasAttribute(\"role\")) input.removeAttribute(\"role\");\n      });\n  };\n\n  const getAddonTitle = (toggle) =>\n    normalizeText(\n      toggle\n        .closest(\".upcart-public-addons\")\n        ?.querySelector(\".upcart-public-addons__content-title\")\n    );\n\n  const findAddonToggle = (title) =>\n    Array.from(root.querySelectorAll(\".upcart-public-addons__toggle-switch\")).find(\n      (toggle) => getAddonTitle(toggle) === title\n    );\n\n  // UpCart controls the checkbox itself and re-renders the footer (dropping focus to <body>) only after the\n  // cart request finishes, so remember the state before activation and announce once it has actually changed.\n  let pendingAddonChange = null;\n\n  root.addEventListener(\n    \"click\",\n    (event) => {\n      const toggle = event.target.closest?.(\".upcart-public-addons__toggle-switch\");\n      // Skip the synthetic click the <label> forwards to its checkbox.\n      if (!toggle || event.target.matches?.(\"input\")) return;\n\n      pendingAddonChange = {\n        title: getAddonTitle(toggle),\n        wasChecked: toggle.querySelector('input[type=\"checkbox\"]')?.checked,\n        startedAt: performance.now()\n      };\n    },\n    true\n  );\n\n  const resolveAddonChange = (previousState, currentState) => {\n    const { title, wasChecked, startedAt } = pendingAddonChange;\n    const isChecked = findAddonToggle(title)\n      ?.querySelector('input[type=\"checkbox\"]')?.checked;\n    const settled =\n      isChecked !== wasChecked ||\n      previousState.subtotal !== currentState.subtotal ||\n      performance.now() - startedAt > 5000;\n    if (!settled) return null;\n\n    pendingAddonChange = null;\n    return {\n      message: `${title || \"Add-on\"} ${isChecked ? \"added\" : \"removed\"}. ${currentState.subtotal}`,\n      title\n    };\n  };\n\n  const focusAddonToggle = (title) => {\n    if (root.activeElement?.closest?.(\"#UpcartPopup\")) return;\n    findAddonToggle(title)?.focus({ preventScroll: true });\n  };\n\n  const normalizeText = (element) =>\n    (element?.textContent || \"\").replace(/\\s+/g, \" \").trim();\n\n  const getCartLines = () =>\n    Array.from(root.querySelectorAll('input[aria-label=\"Product quantity\"]')).map(\n      (quantityInput) => quantityInput.closest(\"li\")\n    );\n\n  const getCartState = () => {\n    const items = Array.from(\n      root.querySelectorAll('input[aria-label=\"Product quantity\"]')\n    ).map((quantityInput) => {\n      const item =\n        quantityInput.closest(\"li\") ||\n        quantityInput.closest('[class*=\"product-tile\"]');\n      const title =\n        normalizeText(item?.querySelector(\"h1, h2, h3, h4\")) ||\n        item?.querySelector(\"a[aria-label]\")?.getAttribute(\"aria-label\") ||\n        \"Item\";\n\n      return {\n        title,\n        quantity: Number.parseInt(quantityInput.value, 10) || 0\n      };\n    });\n    // UpCart has no subtotal element; the total only appears inside the button text, e.g. \"Checkout \u2022 $ 59.99\".\n    const checkout = Array.from(root.querySelectorAll(\"a, button\")).find((link) =>\n      /checkout/i.test(link.textContent)\n    );\n    const total = normalizeText(checkout).split(\"\u2022\").slice(1).join(\"\u2022\").trim();\n    const subtotal = total ? `Subtotal ${total}.` : \"\";\n\n    return { items, subtotal };\n  };\n\n  const announce = (message) => {\n    if (!message) return;\n    status.textContent = \"\";\n    window.setTimeout(() => {\n      status.textContent = message;\n    }, 50);\n  };\n\n  const describeCart = (state) => {\n    const count = state.items.reduce((sum, item) => sum + item.quantity, 0);\n    if (count === 0) return \"Your cart is empty.\";\n    const itemLabel = count === 1 ? \"item\" : \"items\";\n    return `${count} ${itemLabel} in cart. ${state.subtotal}`.trim();\n  };\n\n  // Several lines can share a title (e.g. one-time and subscription of the same product), so compare the\n  // quantities of each title's lines instead of keying lines by title.\n  const groupByTitle = (items) => {\n    const groups = new Map();\n    items.forEach((item) => {\n      if (!groups.has(item.title)) groups.set(item.title, []);\n      groups.get(item.title).push(item.quantity);\n    });\n    return groups;\n  };\n\n  const diffCartStates = (previousState, currentState) => {\n    const previousGroups = groupByTitle(previousState.items);\n    const currentGroups = groupByTitle(currentState.items);\n\n    for (const [title, quantities] of previousGroups) {\n      if ((currentGroups.get(title)?.length || 0) < quantities.length) {\n        return { type: \"removed\", title };\n      }\n    }\n    for (const [title, quantities] of currentGroups) {\n      if ((previousGroups.get(title)?.length || 0) < quantities.length) {\n        return { type: \"added\", title };\n      }\n    }\n    for (const [title, quantities] of currentGroups) {\n      const previousQuantities = previousGroups.get(title);\n      const index = quantities.findIndex(\n        (quantity, lineIndex) => quantity !== previousQuantities[lineIndex]\n      );\n      if (index !== -1) {\n        return { type: \"changed\", title, quantity: quantities[index] };\n      }\n    }\n    return null;\n  };\n\n  configureDialog();\n  let previousCartState = getCartState();\n  let cartUpdateTimer;\n  let pendingCartFocus = null;\n\n  const rememberCartFocus = (control) => {\n    if (!(control instanceof HTMLElement)) return;\n\n    const quantityInputs = Array.from(\n      root.querySelectorAll('input[aria-label=\"Product quantity\"]')\n    );\n    const item =\n      control.closest(\"li\") ||\n      control.closest('[class*=\"product-tile\"]');\n    const quantityInput = control.matches('input[aria-label=\"Product quantity\"]')\n      ? control\n      : item?.querySelector('input[aria-label=\"Product quantity\"]');\n    const itemIndex = quantityInputs.indexOf(quantityInput);\n    if (itemIndex < 0) return;\n\n    pendingCartFocus = {\n      itemIndex,\n      ariaLabel: control.getAttribute(\"aria-label\") || \"\",\n      isQuantityInput: control.matches('input[aria-label=\"Product quantity\"]'),\n      // UpCart re-renders the line more than once (as the quantity changes and again when the cart request\n      // returns), so keep putting focus back until the updates are over.\n      until: performance.now() + 5000\n    };\n  };\n\n  const restoreCartControlFocus = () => {\n    if (!pendingCartFocus) return;\n    if (performance.now() > pendingCartFocus.until) {\n      pendingCartFocus = null;\n      return;\n    }\n\n    const activeControl = root.activeElement;\n    if (activeControl?.closest?.(\"#UpcartPopup\")) return;\n\n    const quantityInputs = Array.from(\n      root.querySelectorAll('input[aria-label=\"Product quantity\"]')\n    );\n    const quantityInput = quantityInputs[pendingCartFocus.itemIndex];\n    const item =\n      quantityInput?.closest(\"li\") ||\n      quantityInput?.closest('[class*=\"product-tile\"]');\n    const replacementControl = pendingCartFocus.isQuantityInput\n      ? quantityInput\n      : Array.from(item?.querySelectorAll(\"button[aria-label]\") || []).find(\n          (button) =>\n            button.getAttribute(\"aria-label\") === pendingCartFocus.ariaLabel\n        );\n\n    if (replacementControl && !replacementControl.disabled) {\n      replacementControl.focus({ preventScroll: true });\n    }\n  };\n\n  const matchesPendingCartFocus = (control) => {\n    if (!pendingCartFocus || !(control instanceof HTMLElement)) return false;\n\n    const quantityInputs = Array.from(\n      root.querySelectorAll('input[aria-label=\"Product quantity\"]')\n    );\n    const item =\n      control.closest(\"li\") ||\n      control.closest('[class*=\"product-tile\"]');\n    const quantityInput = control.matches('input[aria-label=\"Product quantity\"]')\n      ? control\n      : item?.querySelector('input[aria-label=\"Product quantity\"]');\n\n    return (\n      quantityInputs.indexOf(quantityInput) === pendingCartFocus.itemIndex &&\n      (pendingCartFocus.isQuantityInput\n        ? control.matches('input[aria-label=\"Product quantity\"]')\n        : control.getAttribute(\"aria-label\") === pendingCartFocus.ariaLabel)\n    );\n  };\n  // UpCart updates a quantity straight away but the Checkout total only when the cart request returns, so the\n  // first announcement had the old subtotal. Hold a change until the total has caught up (or 3 seconds pass).\n  let pendingChange = null;\n  let settleTimer;\n  // Set when a recommended product's \"Add\" is pressed: the carousel re-renders and focus drops to the page.\n  let pendingUpsellFocus = false;\n\n  // After \"Add to cart\", UpCart updates the item lines and the Checkout total in separate steps, sometimes before the\n  // drawer opens and sometimes after, so describing each step said \"Your cart is empty\" or \"Cart subtotal updated\"\n  // before the item was even listed. Collect the whole update and announce it once, when the open cart has settled.\n  const isCartOpen = () => Boolean(root.querySelector(\"#UpcartPopup\")?.classList.contains(\"upcartPopupShow\"));\n  let addInProgress = null;\n  let addSettleTimer;\n  const scheduleAddSettle = () => {\n    window.clearTimeout(addSettleTimer);\n    addSettleTimer = window.setTimeout(finishAddAnnouncement, 900);\n  };\n  const startAddAnnouncement = () => {\n    addInProgress ||= { before: previousCartState, startedAt: performance.now() };\n    scheduleAddSettle();\n  };\n  const finishAddAnnouncement = () => {\n    if (!addInProgress) return;\n    const state = getCartState();\n    const waitedLongEnough = performance.now() - addInProgress.startedAt > 6000;\n    if (!waitedLongEnough && (!isCartOpen() || !state.items.length || !state.subtotal)) {\n      scheduleAddSettle();\n      return;\n    }\n    const change = diffCartStates(addInProgress.before, state);\n    const title = change && change.type !== \"removed\" ? change.title : state.items[0]?.title;\n    addInProgress = null;\n    pendingChange = null;\n    previousCartState = state;\n    if (!title) return;\n    announce(`${title} added to cart. ${describeCart(state)}`);\n    if (pendingUpsellFocus) {\n      pendingUpsellFocus = false;\n      focusCartLine(title);\n    }\n  };\n  document.addEventListener(\"theme:add-to-cart\", startAddAnnouncement);\n\n  // Opening the cart from the cart icon says so (each time), unless the opening comes from an add.\n  let cartWasOpen = false;\n  const checkCartOpened = () => {\n    const open = isCartOpen();\n    if (open && !cartWasOpen) {\n      window.setTimeout(() => {\n        if (addInProgress || performance.now() - lastAddToCartAt < 2000 || !isCartOpen()) return;\n        announce(`Cart opened. ${describeCart(getCartState())}`);\n      }, 400);\n    }\n    cartWasOpen = open;\n  };\n\n  const focusCartLine = (title) => {\n    if (root.activeElement?.closest?.(\"#UpcartPopup\")) return;\n    const line = getCartLines().find((cartLine) => normalizeText(cartLine?.querySelector(\"h1, h2, h3, h4\")) === title);\n    const target = line?.querySelector(\"h1 a, h2 a, h3 a, h4 a\") || line?.querySelector(\"a[href], button\");\n    target?.focus({ preventScroll: true });\n  };\n\n  const processCartUpdate = () => {\n    configureDialog();\n    checkCartOpened();\n    if (addInProgress) {\n      // An add is being collected into one announcement (see finishAddAnnouncement).\n      scheduleAddSettle();\n      restoreCartControlFocus();\n      return;\n    }\n    const currentCartState = getCartState();\n    let change = diffCartStates(previousCartState, currentCartState);\n\n    const addonChange = pendingAddonChange\n      ? resolveAddonChange(previousCartState, currentCartState)\n      : null;\n\n    if (\n      change &&\n      !pendingAddonChange &&\n      !addonChange &&\n      currentCartState.items.length &&\n      currentCartState.subtotal === previousCartState.subtotal\n    ) {\n      pendingChange = { change, subtotal: previousCartState.subtotal, startedAt: performance.now() };\n      previousCartState = currentCartState;\n      window.clearTimeout(settleTimer);\n      settleTimer = window.setTimeout(processCartUpdate, 3100);\n      restoreCartControlFocus();\n      if (change.type === \"removed\") focusAfterRemoval();\n      return;\n    }\n    if (change) {\n      pendingChange = null;\n    } else if (pendingChange) {\n      const settled =\n        currentCartState.subtotal !== pendingChange.subtotal ||\n        performance.now() - pendingChange.startedAt > 3000;\n      if (!settled) {\n        previousCartState = currentCartState;\n        restoreCartControlFocus();\n        return;\n      }\n      change = pendingChange.change;\n      pendingChange = null;\n    }\n\n    let message = \"\";\n    if (pendingAddonChange) {\n      // Still waiting for UpCart to apply the add-on; announce on a later update.\n    } else if (addonChange) {\n      message = addonChange.message;\n    } else if (change?.type === \"removed\") {\n      message = `${change.title} removed from cart. ${describeCart(currentCartState)}`;\n    } else if (change?.type === \"added\") {\n      message = `${change.title} added to cart. ${describeCart(currentCartState)}`;\n    } else if (change?.type === \"changed\") {\n      message = `Quantity for ${change.title} updated to ${change.quantity}. ${currentCartState.subtotal}`;\n    } else if (\n      previousCartState.subtotal &&\n      previousCartState.subtotal !== currentCartState.subtotal\n    ) {\n      message = `Cart subtotal updated. ${currentCartState.subtotal}`;\n    }\n\n    if (message) announce(message);\n    previousCartState = currentCartState;\n\n    restoreCartControlFocus();\n    if (addonChange) {\n      focusAddonToggle(addonChange.title);\n    } else if (change?.type === \"removed\") {\n      focusAfterRemoval();\n    } else if (pendingUpsellFocus && (change?.type === \"added\" || change?.type === \"changed\")) {\n      pendingUpsellFocus = false;\n      focusCartLine(change.title);\n    }\n  };\n\n  const cartObserver = new MutationObserver(() => {\n    restoreCartControlFocus();\n    window.clearTimeout(cartUpdateTimer);\n    cartUpdateTimer = window.setTimeout(processCartUpdate, 300);\n  });\n\n  // Index of the cart line the user last operated, so focus can land on its neighbour once it is removed.\n  let lastLineIndex = -1;\n\n  const rememberLine = (event) => {\n    const line = event.target.closest?.(\"li\");\n    const index = getCartLines().indexOf(line);\n    if (index !== -1) lastLineIndex = index;\n  };\n\n  root.addEventListener(\"click\", rememberLine, true);\n  root.addEventListener(\"keydown\", rememberLine, true);\n\n  const focusAfterRemoval = () => {\n    // Leave focus alone if it is still somewhere meaningful inside the cart.\n    if (root.activeElement?.closest?.(\"#UpcartPopup\")) return;\n\n    const lines = getCartLines();\n    const line = lines[Math.min(Math.max(lastLineIndex, 0), lines.length - 1)];\n    const target =\n      line?.querySelector(\"h1 a, h2 a, h3 a, h4 a\") ||\n      line?.querySelector(\"a[href], button\") ||\n      root.querySelector('#UpcartPopup [aria-label=\"Close cart\"]');\n\n    pendingCartFocus = null;\n    target?.focus({ preventScroll: true });\n  };\n  const cartObservationTarget = root.querySelector(\"#UpcartPopup\");\n  if (cartObservationTarget) {\n    cartObserver.observe(cartObservationTarget, {\n      childList: true,\n      subtree: true,\n      characterData: true,\n      attributes: true,\n      attributeFilter: [\"value\", \"aria-checked\", \"class\"]\n    });\n  }\n  // This code starts when focus first enters the cart, i.e. as it opens (possibly right after an add).\n  if (performance.now() - lastAddToCartAt < 5000) startAddAnnouncement();\n  checkCartOpened();\n\n  const restoreUpcartFocus = () => {\n    window.setTimeout(() => {\n      if (upcartTrigger?.isConnected) upcartTrigger.focus();\n    }, 500);\n  };\n\n  root.addEventListener(\"click\", (clickEvent) => {\n    const quantityButton = clickEvent.target.closest?.(\n      'button[aria-label=\"Increase quantity\"], button[aria-label=\"Decrease quantity\"]'\n    );\n    if (quantityButton) {\n      rememberCartFocus(quantityButton);\n    }\n\n    const upsellButton = clickEvent.target.closest?.(\"[data-upcart-upsell] button\");\n    if (upsellButton && /^add$/i.test(normalizeText(upsellButton))) pendingUpsellFocus = true;\n\n    if (clickEvent.target.closest?.('[aria-controls=\"carousel-slides\"]')) {\n      // The slides move with a transition; check which one is showing once it has settled.\n      [100, 600].forEach((delay) => window.setTimeout(syncCarouselSlides, delay));\n    }\n\n    if (clickEvent.target.closest?.('[aria-label=\"Close cart\"]')) {\n      const dialog = root.querySelector(\"#CartPopup\");\n      window.setTimeout(() => dialog?.setAttribute(\"aria-hidden\", \"true\"), 500);\n      restoreUpcartFocus();\n    }\n  }, true);\n\n  root.addEventListener(\"input\", (inputEvent) => {\n    const quantityInput = inputEvent.target.closest?.(\n      'input[aria-label=\"Product quantity\"]'\n    );\n    if (quantityInput) rememberCartFocus(quantityInput);\n  }, true);\n\n  root.addEventListener(\"focusin\", (focusEvent) => {\n    const quantityInput = focusEvent.target.closest?.(\n      'input[aria-label=\"Product quantity\"]'\n    );\n    if (quantityInput) {\n      quantityInput.dataset.themeInitialQuantity = quantityInput.value;\n    }\n  }, true);\n\n  root.addEventListener(\"focusout\", (focusEvent) => {\n    const quantityInput = focusEvent.target.closest?.(\n      'input[aria-label=\"Product quantity\"]'\n    );\n    if (\n      quantityInput &&\n      quantityInput.dataset.themeInitialQuantity === quantityInput.value\n    ) {\n      focusEvent.stopPropagation();\n    }\n  }, true);\n\n  root.addEventListener(\"focusin\", (focusEvent) => {\n    if (\n      pendingCartFocus &&\n      focusEvent.target instanceof HTMLElement &&\n      focusEvent.target.closest(\"#UpcartPopup\") &&\n      !matchesPendingCartFocus(focusEvent.target)\n    ) {\n      pendingCartFocus = null;\n    }\n  }, true);\n\n  root.addEventListener(\"keydown\", (keyboardEvent) => {\n    if (keyboardEvent.key === \"Escape\") {\n      restoreUpcartFocus();\n      return;\n    }\n\n    // \"Close cart\" is a div role=\"button\" that UpCart closes on Enter/Space without a click, so focus stayed in\n    // the hidden drawer. Turn the key into a click so it closes and focus returns like a mouse click.\n    const closeControl = keyboardEvent.target.closest?.('[aria-label=\"Close cart\"]');\n    if (closeControl && (keyboardEvent.key === \"Enter\" || keyboardEvent.key === \" \")) {\n      keyboardEvent.preventDefault();\n      keyboardEvent.stopImmediatePropagation();\n      closeControl.click();\n      return;\n    }\n\n    if (keyboardEvent.key === \"Tab\") {\n      const popup = root.querySelector(\"#UpcartPopup\");\n      const focusableElements = popup\n        ? Array.from(\n            popup.querySelectorAll(\n              'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n            )\n          ).filter((element) => {\n            const styles = getComputedStyle(element);\n            return (\n              styles.display !== \"none\" &&\n              styles.visibility !== \"hidden\" &&\n              element.getClientRects().length > 0 &&\n              !element.closest(\"[inert]\") &&\n              !element.matches(\".upcart-public-addons__toggle-switch input\")\n            );\n          })\n        : [];\n\n      const currentIndex = focusableElements.indexOf(keyboardEvent.target);\n      if (currentIndex === -1 || focusableElements.length === 0) return;\n\n      const direction = keyboardEvent.shiftKey ? -1 : 1;\n      const nextIndex =\n        (currentIndex + direction + focusableElements.length) %\n        focusableElements.length;\n\n      const nextControl = focusableElements[nextIndex];\n      if (\n        keyboardEvent.target.matches?.('input[aria-label=\"Product quantity\"]') ||\n        keyboardEvent.target.matches?.(\n          'button[aria-label=\"Increase quantity\"], button[aria-label=\"Decrease quantity\"]'\n        )\n      ) {\n        rememberCartFocus(nextControl);\n      }\n\n      keyboardEvent.preventDefault();\n      keyboardEvent.stopImmediatePropagation();\n      nextControl.focus();\n      return;\n    }\n\n    const toggle = keyboardEvent.target.closest?.(\n      \".upcart-public-addons__toggle-switch\"\n    );\n    if (!toggle || ![\" \", \"Enter\"].includes(keyboardEvent.key)) return;\n\n    keyboardEvent.preventDefault();\n    toggle.click();\n  }, true);\n});\n\n// App proxy pages (account, bundle builder, membership, order tracking) are rendered by third-party apps: they have\n// no page_title, so the tab only says the store name, and some start their outline at H2 or H3 with no H1. Once the\n// app has rendered, name the page after its main heading and, when there is no H1, shift the app's heading levels\n// up so the outline starts at 1 without skipping levels.\n(() => {\n  if (!/^\\/(a|apps|community)\\//.test(window.location.pathname)) return;\n\n  const shopName = document.documentElement.dataset.shopName || \"\";\n  const headingSelector = \"h1, h2, h3, h4, h5, h6, [role='heading']\";\n  const levelOf = (heading) => Number(heading.getAttribute(\"aria-level\") || heading.tagName.slice(1)) || 2;\n\n  const findPageHeadings = () =>\n    Array.from(document.querySelectorAll(`main ${headingSelector}`)).filter(\n      (heading) =>\n        heading.textContent.trim() &&\n        // Headings the theme has turned back into text (the portal's price).\n        !heading.matches(\"[role='none'], [role='presentation']\") &&\n        heading.getClientRects().length > 0 &&\n        // Apps hide inactive steps with visibility: hidden, which still has a layout box.\n        getComputedStyle(heading).visibility !== \"hidden\" &&\n        !heading.closest(\".shopify-section-group-footer-group, [aria-hidden='true']\")\n    );\n\n  const headingTextOf = (heading) => heading.textContent.replace(/\\s+/g, \" \").trim();\n\n  // The page title, from the main heading without emoji (the portal's \"Hello, Eric \uD83D\uDC4B\" was read as \"waving hand\").\n  // A subscription's heading is only its interval (\"Every 3 months\"), so its title says what the page is.\n  const titleTextOf = (heading) => {\n    const text = headingTextOf(heading).replace(/[\\p{Extended_Pictographic}\\u{FE0F}\\u{200D}\\u{1F3FB}-\\u{1F3FF}]/gu, \"\").trim();\n    return heading.dataset.skioName === \"subscription-header-interval\" ? `Subscription: ${text}` : text;\n  };\n\n  const findMainHeading = () => {\n    const headings = findPageHeadings();\n    if (headings.length === 0) return null;\n\n    let mainHeading = headings.find((heading) => levelOf(heading) === 1);\n    if (!mainHeading) {\n      const shift = levelOf(headings[0]) - 1;\n      headings.forEach((heading) => {\n        heading.setAttribute(\"role\", \"heading\");\n        heading.setAttribute(\"aria-level\", String(Math.max(1, levelOf(heading) - shift)));\n      });\n      mainHeading = headings[0];\n    }\n    return mainHeading;\n  };\n\n  // Field purposes the browser can autofill (WCAG 1.3.5), by the field names the apps use.\n  const autocompleteByName = [\n    [/^e-?mail$/i, \"email\"],\n    [/^phone(number)?$/i, \"tel\"],\n    [/^first[-_]?name$/i, \"given-name\"],\n    [/^last[-_]?name$/i, \"family-name\"]\n  ];\n\n  // The title this script last set. The Skio customer portal swaps screens (Subscriptions, Orders, Account\n  // details) without a page load, so the title is renamed whenever the main heading changes, as long as it is still\n  // one this script set (or the bare store name).\n  let themeTitle = \"\";\n\n  const repairAppPage = () => {\n    const mainHeading = findMainHeading();\n    if (!mainHeading) return;\n\n    const currentTitle = document.title.trim();\n    if (!currentTitle || currentTitle.toLowerCase() === shopName.toLowerCase() || currentTitle === themeTitle) {\n      const headingText = titleTextOf(mainHeading);\n      const title = shopName ? `${headingText} \u2013 ${shopName}` : headingText;\n      if (document.title !== title) document.title = title;\n      themeTitle = title;\n    }\n\n    const main = document.querySelector(\"main\");\n    main?.querySelectorAll(\"input:not([autocomplete])\").forEach((field) => {\n      const match = autocompleteByName.find(([pattern]) => pattern.test(field.name || \"\"));\n      if (match) field.setAttribute(\"autocomplete\", match[1]);\n    });\n\n    // Links the apps open in a new tab (e.g. the portal's \"Membership Benefits\") don't say so.\n    main?.querySelectorAll(\"a[target='_blank']\").forEach((link) => {\n      if (link.closest(\".shopify-section-group-footer-group\")) return;\n      const text = link.getAttribute(\"aria-label\") || link.textContent.replace(/\\s+/g, \" \").trim();\n      if (!text || /new tab/i.test(text)) return;\n      link.setAttribute(\"aria-label\", `${text} (opens in a new tab)`);\n    });\n  };\n\n  // Switching screens or editing the profile re-renders the part of the page that held focus, so focus fell to the\n  // top of the page and nothing said what changed. After a click in the app, if focus has been lost: on a new screen\n  // move it to the screen's heading; on the same screen (e.g. \"Edit information\", \"Discard changes\") move it to the\n  // first field that can now be edited, or the form's first button.\n  const fieldSelector = [\n    \"input:not([type='hidden']):not([disabled])\",\n    \"select:not([disabled])\",\n    \"textarea:not([disabled])\",\n    \"[contenteditable='true']\"\n  ].join(\",\");\n  const isShown = (element) => element.getClientRects().length > 0 && getComputedStyle(element).visibility !== \"hidden\";\n  const focusLost = () => !document.activeElement || document.activeElement === document.body || !document.activeElement.isConnected;\n  const focusHeading = (heading) => {\n    if (!heading.hasAttribute(\"tabindex\")) heading.setAttribute(\"tabindex\", \"-1\");\n    heading.focus();\n  };\n\n  const restoreFocus = (activation) => {\n    if (!focusLost()) return true;\n    const heading = findMainHeading();\n    if (heading && headingTextOf(heading) !== activation.headingText) {\n      focusHeading(heading);\n      return true;\n    }\n    const form = activation.form?.isConnected\n      ? activation.form\n      : activation.formName && document.querySelector(`form[data-skio-name=\"${activation.formName}\"]`);\n    if (form) {\n      const target =\n        Array.from(form.querySelectorAll(fieldSelector)).find(isShown) ||\n        Array.from(form.querySelectorAll(\"button:not([disabled])\")).find(isShown);\n      if (target) {\n        target.focus();\n        return true;\n      }\n    }\n    return false;\n  };\n\n  document.addEventListener(\n    \"click\",\n    (event) => {\n      const control = event.target.closest?.(\"main button, main [role='button'], main a[href]\");\n      if (!control || control.closest(\".shopify-section-group-footer-group\")) return;\n      const heading = findMainHeading();\n      const form = control.closest(\"form\");\n      const activation = {\n        headingText: heading ? headingTextOf(heading) : \"\",\n        form,\n        formName: form?.dataset.skioName\n      };\n      // The app renders the new screen after its own request, so check a few times while it does. Only step in\n      // once focus has actually been lost; stop after focus has been put back.\n      const delays = [300, 800, 1600, 3000];\n      let restored = false;\n      delays.forEach((delay, index) => {\n        window.setTimeout(() => {\n          if (restored || !focusLost()) return;\n          restored = restoreFocus(activation);\n          if (!restored && index === delays.length - 1) {\n            const fallback = findMainHeading();\n            if (fallback) focusHeading(fallback);\n          }\n        }, delay);\n      });\n    },\n    true\n  );\n\n  // Apps render (and re-render) their content after load, sometimes starting with a placeholder, so re-check\n  // whenever the page content changes during the first seconds.\n  let repairTimer;\n  const scheduleRepair = () => {\n    window.clearTimeout(repairTimer);\n    repairTimer = window.setTimeout(repairAppPage, 200);\n  };\n  const appObserver = new MutationObserver(scheduleRepair);\n  // Apps also switch steps by toggling classes/inline styles (e.g. hiding a login H1), not only by adding nodes.\n  // Keep watching: the Skio customer portal swaps whole screens (login, then \"Hello, \u2026\" / \"Account details\") long\n  // after load, without a page load.\n  appObserver.observe(document.body, {\n    childList: true,\n    subtree: true,\n    attributes: true,\n    attributeFilter: [\"class\", \"style\", \"hidden\"]\n  });\n  [0, 1000, 3000, 6000, 10000].forEach((delay) => window.setTimeout(repairAppPage, delay));\n})();\n\n// Skio customer portal (/a/account/\u2026): controls that don't say what they act on, a subscription card that is a button\n// wrapped around buttons, a menu whose actions are announced as radio buttons, and order numbers that aren't\n// headings. Skio marks its parts with data-skio-name, which is what this keys on (its class names are generated).\n(() => {\n  if (!/^\\/a\\/account(\\/|$)/.test(window.location.pathname)) return;\n\n  const text = (element) => (element?.textContent || \"\").replace(/\\s+/g, \" \").trim();\n  const skio = (root, name) => root.querySelector(`[data-skio-name=\"${name}\"]`);\n  const setLabel = (element, label) => {\n    if (element && label && element.getAttribute(\"aria-label\") !== label) element.setAttribute(\"aria-label\", label);\n  };\n\n  // Skio's option dropdowns are named only by their value (\"12 Bars\"); put what they choose in front of it. The words\n  // live in a hidden holder outside the portal, so nothing is added to the elements Skio (React) renders.\n  let labelCount = 0;\n  const labelHolder = () => {\n    let holder = document.getElementById(\"theme-skio-labels\");\n    if (!holder) {\n      holder = document.createElement(\"div\");\n      holder.id = \"theme-skio-labels\";\n      holder.hidden = true;\n      document.body.appendChild(holder);\n    }\n    return holder;\n  };\n  const prefixDropdown = (container, prefix) => {\n    const button = container?.querySelector(\"button[aria-labelledby]\");\n    if (!button) return;\n    let prefixText = document.getElementById(button.dataset.themePrefixId || \"\");\n    if (!prefixText) {\n      prefixText = document.createElement(\"span\");\n      prefixText.id = `theme-skio-select-${(labelCount += 1)}`;\n      labelHolder().appendChild(prefixText);\n      button.dataset.themePrefixId = prefixText.id;\n    }\n    if (prefixText.textContent !== prefix) prefixText.textContent = prefix;\n    // Skio's own label can name the value twice (\"12 Bars 12 Bars\"); keep each wording once.\n    const seen = new Set();\n    const ids = button\n      .getAttribute(\"aria-labelledby\")\n      .split(/\\s+/)\n      .filter((id) => {\n        if (!id || id === prefixText.id) return false;\n        const wording = text(document.getElementById(id));\n        if (seen.has(wording)) return false;\n        seen.add(wording);\n        return true;\n      });\n    const labelledBy = [prefixText.id, ...ids].join(\" \");\n    if (button.getAttribute(\"aria-labelledby\") !== labelledBy) button.setAttribute(\"aria-labelledby\", labelledBy);\n  };\n\n  // Quantity changes happen in place; say the new quantity (the number on screen isn't tied to the - and + buttons).\n  let announcer = null;\n  const announce = (message) => {\n    if (!announcer) {\n      announcer = document.createElement(\"div\");\n      announcer.className = \"sr-only\";\n      announcer.setAttribute(\"aria-live\", \"polite\");\n      document.body.appendChild(announcer);\n    }\n    announcer.textContent = \"\";\n    window.setTimeout(() => {\n      announcer.textContent = message;\n    }, 100);\n  };\n  const knownQuantities = new Map();\n\n  const repairSubscriptionCards = () => {\n    // \"Looking for past orders? See here\"\n    setLabel(skio(document, \"subscriptions-past-orders-button\"), \"See past orders\");\n\n    document.querySelectorAll('[data-skio-name=\"subscription-card\"]').forEach((card) => {\n      // The whole card was a button (an extra Tab stop read as all of its text) around the real buttons. It stays\n      // clickable for mouse and touch; keyboard and screen reader users use its \"View details\" button.\n      if (card.getAttribute(\"role\") === \"button\") card.removeAttribute(\"role\");\n      if (card.getAttribute(\"tabindex\") === \"0\") card.removeAttribute(\"tabindex\");\n\n      const products = [...new Set(Array.from(card.querySelectorAll(\"img[alt]\"), (image) => image.alt.trim()).filter(Boolean))];\n      const context = [\n        text(skio(card, \"subscription-card-interval\")),\n        products.join(\", \"),\n        text(skio(card, \"subscription-card-price\")).replace(/\\s*\u00B7\\s*$/, \"\"),\n        text(skio(card, \"subscription-card-status\"))\n      ].filter(Boolean).join(\", \");\n      [\"subscription-card-order-now-button\", \"subscription-card-skip-button\", \"subscription-card-view-details-button\"].forEach(\n        (name) => {\n          const button = skio(card, name);\n          if (button) setLabel(button, `${text(button)}: ${context}`);\n        }\n      );\n    });\n  };\n\n  const repairSubscriptionDetails = () => {\n    // Products in the subscription: name every control after its product.\n    document.querySelectorAll('[data-skio-name=\"variant-card\"]').forEach((card) => {\n      const title = text(skio(card, \"variant-card-product-title\"));\n      if (!title) return;\n      const quantity = text(skio(card, \"quantity-selector-quantity\"));\n      const current = quantity ? `, currently ${quantity}` : \"\";\n      setLabel(skio(card, \"quantity-selector-decrease-button\"), `Decrease quantity of ${title}${current}`);\n      setLabel(skio(card, \"quantity-selector-increase-button\"), `Increase quantity of ${title}${current}`);\n      const selector = skio(card, \"quantity-selector\");\n      if (selector) {\n        if (selector.getAttribute(\"role\") !== \"group\") selector.setAttribute(\"role\", \"group\");\n        setLabel(selector, `Quantity of ${title}`);\n      }\n      if (quantity) {\n        const previous = knownQuantities.get(title);\n        if (previous !== undefined && previous !== quantity) announce(`Quantity of ${title}: ${quantity}`);\n        knownQuantities.set(title, quantity);\n      }\n      setLabel(skio(card, \"variant-card-expand-image-button\"), `Expand image of ${title}`);\n      const swap = skio(card, \"variant-card-swap-button\");\n      if (swap) setLabel(swap, `${text(swap)} ${title}`);\n      const skip = skio(card, \"variant-card-skip-button\");\n      if (skip) setLabel(skip, `${text(skip)} ${title}`);\n      prefixDropdown(skio(card, \"variant-card-variant-select\"), `Option for ${title}:`);\n    });\n\n    // \"You might also like\": four identical \"Add\" buttons.\n    document.querySelectorAll('[data-skio-name=\"add-to-cart-button\"]').forEach((button) => {\n      let item = button.parentElement;\n      while (item && item !== document.body && !skio(item, \"product-name\")) item = item.parentElement;\n      if (!item || item === document.body) return;\n      const name = text(skio(item, \"product-name\"));\n      const price = text(skio(item, \"product-price\"));\n      const selectContainer = skio(item, \"variant-select\");\n      const option = text(selectContainer?.querySelector(\"button[aria-labelledby]\"));\n      setLabel(button, [`${text(button)} ${name}`, option, price].filter(Boolean).join(\", \"));\n      prefixDropdown(selectContainer, `Option for ${name}:`);\n    });\n\n    // Swap dialog: every product card has a \"Select\" button and unnamed option dropdowns.\n    document.querySelectorAll('[data-skio-name=\"product-grid-card-ui\"]').forEach((card) => {\n      const name = text(skio(card, \"product-grid-card-ui-title\"));\n      if (!name) return;\n      const variantSelect = skio(card, \"product-grid-card-ui-variant-select\");\n      const option = text(variantSelect?.querySelector(\"button[aria-labelledby]\"));\n      const price = text(skio(card, \"product-grid-card-ui-price\"));\n      const add = skio(card, \"product-grid-card-ui-add-button\");\n      if (add) setLabel(add, [`${text(add)} ${name}`, option, price].filter(Boolean).join(\", \"));\n      prefixDropdown(variantSelect, `Option for ${name}:`);\n      prefixDropdown(skio(card, \"product-grid-card-ui-subscription-or-one-time-upsell-select\"), `Purchase option for ${name}:`);\n    });\n\n    // The price under the subscription's heading is marked up as a heading itself.\n    const headerPrice = skio(document, \"subscription-header-price\");\n    if (headerPrice && headerPrice.getAttribute(\"role\") !== \"none\") {\n      headerPrice.setAttribute(\"role\", \"none\");\n      headerPrice.removeAttribute(\"aria-level\");\n    }\n\n    // \"Next on Jan 20\" opens the date picker; say that it changes the date.\n    const nextDate = skio(document, \"subscription-header-next-date-button\");\n    if (nextDate && text(nextDate)) setLabel(nextDate, `Change next order date, ${text(nextDate)}`);\n\n    // Two \"Edit\" buttons, for the shipping address and the payment method.\n    setLabel(skio(document, \"shipping-card-edit-button\"), \"Edit shipping address\");\n    setLabel(skio(document, \"billing-card-edit-button\"), \"Edit payment method\");\n\n    // The streak badge was a button named \"1\"; the dialog it opens had no name.\n    const streak = skio(document, \"streak-badge\");\n    if (streak) setLabel(streak, `Order streak: ${text(skio(streak, \"streak-badge-count\")) || text(streak)}`);\n    document.querySelectorAll('[data-skio-name=\"skio-modal-dialog\"]').forEach((dialog) => {\n      // Focus is kept inside the dialogs, but they weren't marked modal.\n      if (dialog.getAttribute(\"aria-modal\") !== \"true\") dialog.setAttribute(\"aria-modal\", \"true\");\n      // Date picker month arrows (plus the picker's hidden copy of \"Next\") were just \"Previous\" and \"Next\".\n      dialog.querySelectorAll(\"button[aria-label='Previous'], button[aria-label='Next']\").forEach((arrow) => {\n        if (dialog.querySelector(\"[role='grid']\")) setLabel(arrow, `${arrow.getAttribute(\"aria-label\")} month`);\n      });\n      if (dialog.getAttribute(\"aria-label\") || dialog.getAttribute(\"aria-labelledby\")) return;\n      // The header's first line (\"Order streak\"), not the whole header, whose lines would run together.\n      const title =\n        dialog.querySelector('[data-skio-name$=\"-header\"] p') ||\n        dialog.querySelector('[data-skio-name$=\"-header\"], h1, h2, h3');\n      if (!title || !text(title)) return;\n      title.id ||= `theme-skio-dialog-title-${(labelCount += 1)}`;\n      dialog.setAttribute(\"aria-labelledby\", title.id);\n    });\n\n    // \"More\" lists actions (Pause, Cancel\u2026) as radio items, which screen readers read as \"radio button, not checked\".\n    document.querySelectorAll('[data-skio-name=\"more-actions-dropdown-menu\"] [role=\"menuitemradio\"]').forEach((item) => {\n      item.setAttribute(\"role\", \"menuitem\");\n      item.removeAttribute(\"aria-checked\");\n    });\n  };\n\n  // Orders: the order number becomes the heading of its card (the outline jumped from H1 to the cards' H3s), and the\n  // buttons repeated in every card say which order they belong to.\n  const repairOrders = () => {\n    document.querySelectorAll('[data-skio-name=\"order-card\"]').forEach((card) => {\n      const number = skio(card, \"order-card-header-number\");\n      const order = text(number);\n      if (!order) return;\n      if (number.getAttribute(\"role\") !== \"heading\") number.setAttribute(\"role\", \"heading\");\n      if (number.getAttribute(\"aria-level\") !== \"2\") number.setAttribute(\"aria-level\", \"2\");\n      [\"order-card-details-shipping-trigger\", \"order-card-details-summary-trigger\"].forEach((name) => {\n        const trigger = skio(card, name);\n        if (trigger) setLabel(trigger, `${text(trigger)}, ${order}`);\n      });\n      const reorder = skio(card, \"order-card-reorder-button\");\n      if (reorder) setLabel(reorder, `${text(reorder)}: ${order}`);\n    });\n  };\n\n  let portalTimer;\n  const repairPortal = () => {\n    window.clearTimeout(portalTimer);\n    portalTimer = window.setTimeout(() => {\n      repairSubscriptionCards();\n      repairSubscriptionDetails();\n      repairOrders();\n    }, 150);\n  };\n  repairPortal();\n  // The portal renders after load and swaps screens without a page load.\n  new MutationObserver(repairPortal).observe(document.body, { childList: true, subtree: true, characterData: true });\n})();\n\n// Page-builder pages (Replo, e.g. Wholesale) style the page title as large text, not a heading, so the page has no\n// <h1>. When a page has none at all, expose its large title text near the top of the content as the level 1 heading.\n(() => {\n  if (/^\\/(a|apps|community)\\//.test(window.location.pathname)) return; // handled above\n\n  const promoteTitle = () => {\n    const main = document.querySelector(\"main\");\n    // The home page's H1 is the logo in the header, so look in the whole document.\n    if (!main || document.querySelector(\"h1, [role='heading'][aria-level='1']\")) return;\n    const candidates = Array.from(main.querySelectorAll(\"p, div, span\")).filter((element) => {\n      const text = element.textContent.replace(/\\s+/g, \" \").trim();\n      if (!text || text.length > 120 || element.querySelector(\"p, div, h2, h3, a, button\")) return false;\n      if (!element.getClientRects().length || getComputedStyle(element).visibility === \"hidden\") return false;\n      return Number.parseFloat(getComputedStyle(element).fontSize) >= 32;\n    });\n    const title = candidates.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top)[0];\n    if (!title) return;\n    title.setAttribute(\"role\", \"heading\");\n    title.setAttribute(\"aria-level\", \"1\");\n  };\n\n  [500, 2000, 5000].forEach((delay) => window.setTimeout(promoteTitle, delay));\n})();\n\n// Theme forms (contact, newsletter, blog comments, customer and password forms): replace the browser's validation\n// bubbles with errors that sit under the field, are linked to it (aria-describedby + aria-invalid) and are announced;\n// and after a submission reloads the page, move focus to the success/error banner rendered in the form.\n(() => {\n  const strings = Object.assign(\n    {\n      required: \"Enter your [field].\",\n      email: \"Enter a valid email address, like name@example.com.\",\n      minLength: \"[field] must be at least [count] characters.\",\n      summary: \"Please fix the [count] errors below.\",\n      summaryOne: \"Please fix the error below.\"\n    },\n    window.themeFormStrings || {}\n  );\n\n  const fieldSelector = \".form-control > :is(input.input, textarea.textarea, select.select)\";\n  const isThemeForm = (form) => form instanceof HTMLFormElement && Boolean(form.querySelector(fieldSelector));\n\n  let formStatus = null;\n  const announceForm = (message) => {\n    if (!formStatus) {\n      formStatus = document.createElement(\"div\");\n      formStatus.className = \"sr-only\";\n      formStatus.setAttribute(\"role\", \"alert\");\n      document.body.appendChild(formStatus);\n    }\n    formStatus.textContent = \"\";\n    window.setTimeout(() => {\n      formStatus.textContent = message;\n    }, 50);\n  };\n\n  const labelText = (field) =>\n    (field.labels?.[0]?.textContent || field.getAttribute(\"aria-label\") || field.name || \"\")\n      .replace(\"*\", \"\")\n      .replace(/\\s+/g, \" \")\n      .trim();\n\n  const describedByIds = (field) => (field.getAttribute(\"aria-describedby\") || \"\").split(/\\s+/).filter(Boolean);\n\n  const showFieldError = (field, message) => {\n    const errorId = `${field.id}-error`;\n    let error = document.getElementById(errorId);\n    if (!error) {\n      error = document.createElement(\"p\");\n      error.id = errorId;\n      error.className = \"form-control__error text-sm\";\n      field.closest(\".form-control\").appendChild(error);\n    }\n    error.textContent = message;\n    field.setAttribute(\"aria-invalid\", \"true\");\n    const ids = describedByIds(field);\n    if (!ids.includes(errorId)) field.setAttribute(\"aria-describedby\", [...ids, errorId].join(\" \"));\n  };\n\n  const clearFieldError = (field) => {\n    const errorId = `${field.id}-error`;\n    document.getElementById(errorId)?.remove();\n    field.removeAttribute(\"aria-invalid\");\n    const ids = describedByIds(field).filter((id) => id !== errorId);\n    if (ids.length) {\n      field.setAttribute(\"aria-describedby\", ids.join(\" \"));\n    } else {\n      field.removeAttribute(\"aria-describedby\");\n    }\n  };\n\n  const errorMessageFor = (field) => {\n    const { validity } = field;\n    const label = labelText(field);\n    if (validity.valueMissing) return strings.required.replace(\"[field]\", label.toLowerCase());\n    if (validity.typeMismatch && field.type === \"email\") return strings.email;\n    if (validity.tooShort) {\n      return strings.minLength.replace(\"[field]\", label).replace(\"[count]\", field.getAttribute(\"minlength\"));\n    }\n    return field.validationMessage;\n  };\n\n  // Turn off the browser's bubbles for theme forms before they can be submitted.\n  const disableNativeValidation = (form) => {\n    if (isThemeForm(form) && !form.noValidate) form.noValidate = true;\n  };\n  document.querySelectorAll(\"form\").forEach(disableNativeValidation);\n  document.addEventListener(\"focusin\", (event) => disableNativeValidation(event.target.form || event.target.closest?.(\"form\")), true);\n\n  document.addEventListener(\n    \"submit\",\n    (event) => {\n      const form = event.target;\n      if (!isThemeForm(form)) return;\n\n      const fields = Array.from(form.querySelectorAll(fieldSelector)).filter((field) => !field.disabled);\n      const invalid = fields.filter((field) => !field.checkValidity());\n      fields.forEach((field) => {\n        if (!invalid.includes(field) && field.getAttribute(\"aria-invalid\") === \"true\") clearFieldError(field);\n      });\n      if (invalid.length === 0) return;\n\n      event.preventDefault();\n      event.stopImmediatePropagation();\n      invalid.forEach((field) => showFieldError(field, errorMessageFor(field)));\n      invalid[0].focus();\n      announceForm(\n        invalid.length === 1\n          ? `${strings.summaryOne} ${errorMessageFor(invalid[0])}`\n          : `${strings.summary.replace(\"[count]\", invalid.length)} ${invalid.map(errorMessageFor).join(\" \")}`\n      );\n    },\n    true\n  );\n\n  // Once a field shows an error, keep its message in step with what is typed: clear it as soon as the value is\n  // valid, and otherwise say what is wrong now (e.g. \"Enter your e-mail.\" becomes the format message after \"abc\").\n  document.addEventListener(\"input\", (event) => {\n    const field = event.target;\n    if (!field.matches?.(fieldSelector) || field.getAttribute(\"aria-invalid\") !== \"true\") return;\n    if (field.checkValidity()) {\n      clearFieldError(field);\n    } else {\n      showFieldError(field, errorMessageFor(field));\n    }\n  });\n\n  // After a submission reloads the page, take the user to the result.\n  const feedback = document.querySelector(\"form .banner[data-form-feedback]\");\n  if (feedback) {\n    window.setTimeout(() => {\n      feedback.scrollIntoView({ block: \"center\" });\n      feedback.focus({ preventScroll: true });\n    }, 300);\n  }\n})();\n\n// Product quantity +/- (product page, the \"Quick add\" popup, featured product): the buttons change the number\n// silently. Say the new quantity after each press. The announcement region sits next to the field (created when\n// focus reaches it), because screen readers ignore live regions outside an open modal such as the \"Quick add\" popup.\n(() => {\n  const regionFor = (selector) => {\n    let region = selector.parentElement.querySelector(\":scope > [data-theme-quantity-status]\");\n    if (!region) {\n      region = document.createElement(\"span\");\n      region.className = \"sr-only\";\n      region.dataset.themeQuantityStatus = \"\";\n      region.setAttribute(\"role\", \"status\");\n      region.setAttribute(\"aria-live\", \"polite\");\n      region.setAttribute(\"aria-atomic\", \"true\");\n      selector.after(region);\n    }\n    return region;\n  };\n\n  document.addEventListener(\"focusin\", (event) => {\n    const selector = event.target.closest?.(\"quantity-selector\");\n    if (selector) regionFor(selector);\n  });\n\n  document.addEventListener(\"click\", (event) => {\n    const button = event.target.closest?.(\"quantity-selector .quantity-selector__button\");\n    if (!button) return;\n    const selector = button.closest(\"quantity-selector\");\n    const input = selector.querySelector(\"input\");\n    const region = regionFor(selector);\n    const before = input.value;\n    window.setTimeout(() => {\n      const value = input.value;\n      const atLimit = value === before && (value === input.min || value === input.max);\n      region.textContent = \"\";\n      window.setTimeout(() => {\n        region.textContent = `Quantity ${value}${atLimit ? (value === input.min ? \", minimum\" : \", maximum\") : \"\"}`;\n      }, 50);\n    }, 100);\n  });\n})();\n\n// Product page purchase controls: announce price changes, and name the third-party purchase options (Skio\n// subscription picker, \"Buy More Save More\" volume tiers) that screen readers otherwise read without context.\n(() => {\n  if (!document.querySelector(\".product-info\")) return;\n\n  let purchaseStatus = null;\n  const announcePurchase = (message) => {\n    if (!purchaseStatus) {\n      purchaseStatus = document.createElement(\"div\");\n      purchaseStatus.className = \"sr-only\";\n      purchaseStatus.setAttribute(\"role\", \"status\");\n      purchaseStatus.setAttribute(\"aria-live\", \"polite\");\n      purchaseStatus.setAttribute(\"aria-atomic\", \"true\");\n      document.body.appendChild(purchaseStatus);\n    }\n    purchaseStatus.textContent = \"\";\n    window.setTimeout(() => {\n      purchaseStatus.textContent = message;\n    }, 50);\n  };\n\n  const normalize = (text) => (text || \"\").replace(/\\s+/g, \" \").trim();\n  const lastPrice = (text) => normalize(text).match(/\\$\\s?[\\d,]+(?:\\.\\d{2})?/g)?.pop();\n\n  // 1. The price re-renders silently when the variant changes. The theme replaces the whole product info block,\n  // so watch the page and compare the current price text rather than observing one element.\n  const priceSelector = \".product-info__price price-list, .product-info price-list\";\n  const readPrice = () => normalize(document.querySelector(priceSelector)?.textContent);\n  let lastAnnouncedPrice = readPrice();\n  let priceTimer;\n  new MutationObserver(() => {\n    window.clearTimeout(priceTimer);\n    priceTimer = window.setTimeout(() => {\n      const current = readPrice();\n      if (current && current !== lastAnnouncedPrice) {\n        lastAnnouncedPrice = current;\n        announcePurchase(`Price: ${current}`);\n      }\n    }, 400);\n  }).observe(document.querySelector(\"main\") || document.body, {\n    childList: true,\n    subtree: true,\n    characterData: true\n  });\n\n  // 2. Skio subscription picker (open shadow DOM).\n  // The theme's focus ring can't reach into the shadow root, and Skio's own ring is a 2px #ccc outline (about 1.6:1\n  // on white). Give its options and frequency dropdown the theme's two-tone ring. The label is the visible card for\n  // a hidden radio, so the ring goes on the label.\n  let skioFocusSheet = null;\n  const getSkioFocusSheet = () => {\n    if (!skioFocusSheet) {\n      skioFocusSheet = new CSSStyleSheet();\n      skioFocusSheet.replaceSync(`\n        .group-input:focus-visible ~ .group-label,\n        .selling-plan-buttons input:focus-visible + label,\n        select:focus-visible {\n          outline: 3px solid #002c6b !important;\n          outline-offset: 2px !important;\n          box-shadow: 0 0 0 2px #fff !important;\n        }\n      `);\n    }\n    return skioFocusSheet;\n  };\n\n  // Each option's <label> wraps the whole card: title, \"Best Deal\" badge, both prices, the benefit list and the\n  // frequency dropdown, so the radio was read as one run-on sentence with the two prices side by side. Name it in\n  // a short phrase (\"Subscribe & save, $53.99, regular price $59.99, 10% OFF\") and attach the benefits as its\n  // description.\n  const nameSkioOptions = (root) => {\n    root.querySelectorAll(\".group-input\").forEach((radio) => {\n      const label = radio.labels?.[0];\n      if (!label) return;\n      const titleElement = label.querySelector(\".group-title\");\n      const title = normalize(\n        Array.from(titleElement?.childNodes || [])\n          .filter((node) => node.nodeType === Node.TEXT_NODE)\n          .map((node) => node.textContent)\n          .join(\" \")\n      ) || normalize(titleElement?.textContent);\n      if (!title) return;\n      const priceElement = label.querySelector(\".skio-price\");\n      const regular = money(priceElement?.querySelector(\"s\")?.textContent);\n      const price = money(\n        Array.from(priceElement?.childNodes || [])\n          .filter((node) => node.nodeType === Node.TEXT_NODE)\n          .map((node) => node.textContent)\n          .join(\" \")\n      );\n      const badge = normalize(priceElement?.querySelector(\".skio-plan-badge\")?.textContent);\n      setLabel(radio, [title, price, regular ? `regular price ${regular}` : \"\", badge].filter(Boolean).join(\", \"));\n\n      const benefits = label.querySelector(\".selling-plan-dropdown-label ul, .group-content ul\");\n      if (benefits) {\n        benefits.id ||= `${radio.id}-benefits`;\n        if (radio.getAttribute(\"aria-describedby\") !== benefits.id) radio.setAttribute(\"aria-describedby\", benefits.id);\n      }\n    });\n  };\n\n  const repairSkio = () => {\n    document.querySelectorAll(\"skio-plan-picker\").forEach((picker) => {\n      const root = picker.shadowRoot;\n      if (!root) return;\n\n      const focusSheet = getSkioFocusSheet();\n      if (!root.adoptedStyleSheets.includes(focusSheet)) {\n        root.adoptedStyleSheets = [...root.adoptedStyleSheets, focusSheet];\n      }\n      nameSkioOptions(root);\n\n      root.querySelectorAll(\"select\").forEach((select) => {\n        if (!select.labels?.length && !select.getAttribute(\"aria-label\")) {\n          select.setAttribute(\"aria-label\", \"Delivery frequency\");\n        }\n      });\n\n      // Skio already groups its radios in a <fieldset> with a legend (\"Select subscription plan\"); only name the\n      // group ourselves if a future version drops that.\n      const firstRadio = root.querySelector(\"input[type='radio']\");\n      if (firstRadio && !firstRadio.closest(\"fieldset\")?.querySelector(\"legend\")) {\n        const group = firstRadio.closest(\"form\") || firstRadio.parentElement?.parentElement;\n        if (group && !group.getAttribute(\"role\")) {\n          group.setAttribute(\"role\", \"radiogroup\");\n          group.setAttribute(\"aria-label\", \"Purchase options\");\n        }\n      }\n\n      if (root.dataset?.themeSkioEnhanced === \"true\" || picker.dataset.themeSkioEnhanced === \"true\") return;\n      picker.dataset.themeSkioEnhanced = \"true\";\n      // Skio re-renders its prices and options inside the shadow root (variant changes), out of reach of the page\n      // observer below, so name the options again from there.\n      new MutationObserver(() => nameSkioOptions(root)).observe(root, { childList: true, subtree: true, characterData: true });\n      let lastSkioSelection = Array.from(root.querySelectorAll(\"input[type='radio']\")).find((radio) => radio.checked)?.id;\n      root.addEventListener(\"change\", (event) => {\n        const radio = event.target;\n        if (!(radio instanceof HTMLInputElement) || radio.type !== \"radio\" || !radio.checked) return;\n        // Skio re-checks the same option when it re-renders (e.g. after a variant change); only announce real changes.\n        if (radio.id === lastSkioSelection) return;\n        lastSkioSelection = radio.id;\n        const labelText = normalize(radio.labels?.[0]?.textContent);\n        const optionName = labelText.split(/\\s(?=\\d+%|\\$|Best Deal)/)[0] || labelText;\n        const price = lastPrice(labelText);\n        announcePurchase(`${optionName} selected.${price ? ` Price ${price}.` : \"\"}`);\n      });\n    });\n  };\n\n  // 3. \"Buy More Save More\" volume tiers and the \"Purchase Options\" (one-time / subscribe) radios. Read as one\n  // plain phrase with the price and what it was, e.g. \"Buy 2, 3% off, $116.38, regular price $119.98\" and\n  // \"Subscribe & Save, Save Another 10%, $53.99, regular price $59.99\" (the app's labels ran the two prices\n  // together, or had none).\n  const money = (text) => normalize(text).replace(/\\$\\s+/g, \"$\");\n  const describeOption = (container, titleSelector, badgeSelector) => {\n    const title = normalize(container.querySelector(titleSelector)?.textContent);\n    if (!title) return \"\";\n    const badge = normalize(container.querySelector(badgeSelector)?.textContent);\n    const prices = Array.from(container.querySelectorAll(\"*\"))\n      .filter((element) => !element.children.length && !element.closest(\"select\") && /\\$\\s?\\d/.test(element.textContent))\n      .map((element) => money(element.textContent));\n    const [price, regular] = [...new Set(prices)];\n    return [title, badge, price, regular ? `regular price ${regular}` : \"\"].filter(Boolean).join(\", \");\n  };\n  const setLabel = (element, label) => {\n    if (label && element.getAttribute(\"aria-label\") !== label) element.setAttribute(\"aria-label\", label);\n  };\n\n  const repairVolumeTiers = () => {\n    const radios = Array.from(document.querySelectorAll(\".gfbVolumeDiscountWidgetOfferDiscountTierRadio\"));\n    radios.forEach((radio) => {\n      const container = radio.closest(\".gfbVolumeDiscountLabelContainer\") || radio.closest(\".gfbVolumeDiscountRadioLabelWrapper\");\n      if (container) setLabel(radio, describeOption(container, \".gfbVolumeDiscountTierTitle\", \".gfbVolumeDiscountTierBadge\"));\n    });\n    document.querySelectorAll(\".gfbVolumeDiscountTierImage:not([alt])\").forEach((image) => image.setAttribute(\"alt\", \"\"));\n\n    // Group all the tiers: the nearest element that contains every tier radio (each tier has its own wrapper).\n    if (radios.length > 1) {\n      let list = radios[0].parentElement;\n      while (list && !radios.every((radio) => list.contains(radio))) list = list.parentElement;\n      document.querySelectorAll(\"[data-theme-volume-group]\").forEach((stale) => {\n        if (stale === list) return;\n        stale.removeAttribute(\"role\");\n        stale.removeAttribute(\"aria-label\");\n        delete stale.dataset.themeVolumeGroup;\n      });\n      if (list && list !== document.body) {\n        list.dataset.themeVolumeGroup = \"true\";\n        if (list.getAttribute(\"role\") !== \"radiogroup\") list.setAttribute(\"role\", \"radiogroup\");\n        setLabel(list, \"Buy more and save\");\n      }\n    }\n\n    // One-time purchase vs Subscribe & Save: two radios with different names, so they weren't even one group.\n    document.querySelectorAll(\".gfbSubscriptionTiersWrapper\").forEach((tiers) => {\n      // The app gives the two radios different names, so browsers treat each as its own group (\"1 of 1\"). State\n      // their position in the group so screen readers say \"1 of 2\", \"2 of 2\".\n      const optionRadios = Array.from(tiers.querySelectorAll(\"label[for] input[type='radio']\"));\n      optionRadios.forEach((radio, index) => {\n        setLabel(radio, describeOption(radio.closest(\"label[for]\"), \".gfbTitle\", \".gfbDiscountBadge\"));\n        if (radio.getAttribute(\"aria-posinset\") !== String(index + 1)) radio.setAttribute(\"aria-posinset\", String(index + 1));\n        if (radio.getAttribute(\"aria-setsize\") !== String(optionRadios.length)) {\n          radio.setAttribute(\"aria-setsize\", String(optionRadios.length));\n        }\n      });\n      if (tiers.getAttribute(\"role\") !== \"radiogroup\") tiers.setAttribute(\"role\", \"radiogroup\");\n\n      // Choosing an option changed the price and showed or hid the frequency dropdown without a word. Say what is\n      // selected, and the delivery frequency once the dropdown has appeared.\n      if (tiers.dataset.themeOptionsAnnounced !== \"true\") {\n        tiers.dataset.themeOptionsAnnounced = \"true\";\n        tiers.addEventListener(\"change\", (event) => {\n          const radio = event.target;\n          if (!(radio instanceof HTMLInputElement) || radio.type !== \"radio\" || !radio.checked) return;\n          window.setTimeout(() => {\n            const frequency = Array.from(tiers.querySelectorAll(\"select.gfbSelect\")).find(\n              (select) => select.getBoundingClientRect().height > 0 && getComputedStyle(select).visibility !== \"hidden\"\n            );\n            const frequencyText = frequency ? ` Delivery frequency: ${normalize(frequency.selectedOptions[0]?.textContent)}.` : \"\";\n            announcePurchase(`${radio.getAttribute(\"aria-label\") || normalize(radio.labels?.[0]?.textContent)} selected.${frequencyText}`);\n          }, 300);\n        }, true); // capture: the app stops the event from bubbling past the radio\n      }\n      const title = tiers.previousElementSibling?.matches(\".gfbSubscriptionTitle\") ? tiers.previousElementSibling : null;\n      if (title) {\n        title.id ||= \"theme-purchase-options-title\";\n        if (tiers.getAttribute(\"aria-labelledby\") !== title.id) tiers.setAttribute(\"aria-labelledby\", title.id);\n      } else {\n        setLabel(tiers, \"Purchase options\");\n      }\n      tiers.querySelectorAll(\"select.gfbSelect\").forEach((select) => {\n        setLabel(select, \"Delivery frequency\");\n        // The list holds both Skio plan sets: \"Subscription\" and the bundle builder's \"Dynamic Box Subscription\",\n        // which the store hides with CSS. Screen readers still counted them (\"6 items\", only 3 to choose) and the\n        // arrow keys could land on them, so take the hidden ones out of the list.\n        Array.from(select.options).forEach((option) => {\n          if (!option.selected && getComputedStyle(option).display === \"none\") option.remove();\n        });\n      });\n    });\n  };\n\n  const repairPurchaseControls = () => {\n    repairSkio();\n    repairVolumeTiers();\n  };\n\n  repairPurchaseControls();\n  const purchaseObserver = new MutationObserver(repairPurchaseControls);\n  // Prices change as text when the variant or tier changes, so the option names are refreshed on text changes too.\n  purchaseObserver.observe(document.querySelector(\".product-info\") || document.body, {\n    childList: true,\n    subtree: true,\n    characterData: true\n  });\n})();\n\n// Cart page: the theme reloads the whole page after a quantity change or removal (theme.js LineItemQuantity), so\n// focus returns to the top of the page and nothing says what changed. Remember the change just before it happens,\n// then after the reload put focus back on that line's quantity field (or the cart heading if the line is gone) and\n// announce the new quantity and subtotal.\n(() => {\n  if (window.location.pathname !== \"/cart\") return;\n\n  const storageKey = \"themeCartChange\";\n\n  let cartStatus = null;\n  const announceCart = (message) => {\n    if (!cartStatus) {\n      cartStatus = document.createElement(\"div\");\n      cartStatus.className = \"sr-only\";\n      cartStatus.setAttribute(\"role\", \"status\");\n      cartStatus.setAttribute(\"aria-live\", \"polite\");\n      cartStatus.setAttribute(\"aria-atomic\", \"true\");\n      document.body.appendChild(cartStatus);\n    }\n    cartStatus.textContent = \"\";\n    window.setTimeout(() => {\n      cartStatus.textContent = message;\n    }, 50);\n  };\n\n  const formatMoney = (cents) =>\n    new Intl.NumberFormat(document.documentElement.lang || \"en\", {\n      style: \"currency\",\n      currency: window.Shopify?.currency?.active || \"USD\"\n    }).format(cents / 100);\n\n  const isVisible = (element) => element.getClientRects().length > 0;\n\n  // The cart table has no <line-item> wrapper, so the theme's \"line-item:will-change\" event never fires here; record\n  // the change from the quantity field / remove link itself (document capture runs before the theme's handler).\n  const rememberChange = (input, quantity) => {\n    if (!input) return;\n    const title = (input.getAttribute(\"aria-label\") || \"\").replace(/^Quantity for\\s*/i, \"\");\n    try {\n      sessionStorage.setItem(\n        storageKey,\n        JSON.stringify({ key: input.getAttribute(\"data-line-key\"), title, quantity })\n      );\n    } catch (error) {\n      // Storage can be unavailable (private mode); the change still works, it just isn't announced.\n    }\n  };\n\n  document.addEventListener(\n    \"change\",\n    (event) => {\n      const input = event.target.closest?.(\"line-item-quantity input[data-line-key]\");\n      if (input) rememberChange(input, Number.parseInt(input.value, 10));\n    },\n    true\n  );\n\n  document.addEventListener(\n    \"click\",\n    (event) => {\n      const link = event.target.closest?.(\"line-item-quantity a[href*='/cart/change']\");\n      if (!link) return;\n      const input = link.closest(\"line-item-quantity\").querySelector(\"input[data-line-key]\");\n      rememberChange(input, Number.parseInt(new URL(link.href).searchParams.get(\"quantity\"), 10));\n    },\n    true\n  );\n\n  let change = null;\n  try {\n    change = JSON.parse(sessionStorage.getItem(storageKey) || \"null\");\n    sessionStorage.removeItem(storageKey);\n  } catch (error) {\n    change = null;\n  }\n  if (!change) return;\n\n  window.addEventListener(\"load\", async () => {\n    // Let apps that grab focus on load (e.g. the cookie banner) run first.\n    await new Promise((resolve) => window.setTimeout(resolve, 800));\n    let cart = null;\n    try {\n      cart = await (await fetch(`${window.Shopify?.routes?.root || \"/\"}cart.js`)).json();\n    } catch (error) {\n      cart = null;\n    }\n\n    const input = Array.from(document.querySelectorAll(`input[data-line-key=\"${CSS.escape(change.key || \"\")}\"]`)).find(isVisible);\n    const removed = !input || change.quantity === 0;\n    const summary = cart\n      ? cart.item_count === 0\n        ? \"Your cart is empty.\"\n        : `${cart.item_count} item${cart.item_count === 1 ? \"\" : \"s\"} in cart. Subtotal ${formatMoney(cart.total_price)}.`\n      : \"\";\n\n    if (removed) {\n      const heading = document.querySelector(\"main h1\");\n      if (heading) {\n        heading.setAttribute(\"tabindex\", \"-1\");\n        heading.focus();\n      }\n      announceCart(`${change.title || \"Item\"} removed. ${summary}`.trim());\n    } else {\n      input.focus();\n      announceCart(`Quantity for ${change.title || \"item\"} updated to ${input.value}. ${summary}`.trim());\n    }\n  });\n})();\n"],
  "mappings": "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",
  "names": ["syncBundleDrawers", "repairBundleHeadingLevels", "markBundleProductGrid", "removeTierBarTabStop", "nameBundleProductCards", "enhanceBundleFrequencyOptions", "enhanceBundleSummary", "enhanceRemoveControls", "restoreBoxFocus", "repairBundleControls", "label", "syncBundleLimitState", "muteAppAnnouncer", "scheduleContentsAnnouncement", "announceContentsChange", "event"]
}
