{
  "version": 3,
  "sources": ["../../../theme-src/framewerk-runtime.js"],
  "sourcesContent": ["(() => {\n  const WEBSITE_SETTINGS_CONTROLLER_KEY =\n    \"__framewerkWebsiteSettingsController\";\n  const WEBSITE_SETTINGS_CACHE_KEY = \"framewerk:website-settings:v1\";\n  const WEBSITE_SETTINGS_TIMEOUT_MS = 5000;\n  const WEBSITE_SETTINGS_CACHE_TTL_MS = 60 * 1000;\n  const PRODUCT_VARIANT_IMAGE_FOCUS_CONTROLLER_KEY =\n    \"__framewerkProductVariantImageFocusController\";\n  const FORMS_EMBED_CONTROLLER_KEY = \"__framewerkFormsEmbedController\";\n  const PRODUCT_VARIANT_IMAGE_FOCUS_BREAKPOINT = \"(max-width: 749px)\";\n  const SELECTED_PRODUCT_MEDIA_SELECTOR =\n    '[data-testid=\"product-information-media\"] slideshow-slide[aria-hidden=\"false\"] .product-media[data-media-id]';\n  const PRODUCT_MEDIA_GESTURE_SELECTOR =\n    '[data-testid=\"product-information-media\"], media-gallery';\n\n  function installProductMediaExternalLinkGestureGuard() {\n    if (window.__framewerkProductMediaGestureGuard) return;\n    window.__framewerkProductMediaGestureGuard = true;\n    let gesture = null;\n    let lastDragAt = 0;\n\n    document.addEventListener(\n      \"touchstart\",\n      (event) => {\n        const touch = event.touches?.[0];\n        const target = event.target;\n        gesture =\n          touch &&\n          target instanceof Element &&\n          target.closest(PRODUCT_MEDIA_GESTURE_SELECTOR)\n            ? { x: touch.clientX, y: touch.clientY, dragged: false }\n            : null;\n      },\n      { capture: true, passive: true },\n    );\n    document.addEventListener(\n      \"touchmove\",\n      (event) => {\n        const touch = event.touches?.[0];\n        if (!gesture || !touch) return;\n        if (\n          Math.abs(touch.clientX - gesture.x) > 10 ||\n          Math.abs(touch.clientY - gesture.y) > 10\n        ) {\n          gesture.dragged = true;\n        }\n      },\n      { capture: true, passive: true },\n    );\n    document.addEventListener(\n      \"touchend\",\n      () => {\n        if (gesture?.dragged) lastDragAt = Date.now();\n        gesture = null;\n      },\n      { capture: true, passive: true },\n    );\n    document.addEventListener(\n      \"click\",\n      (event) => {\n        if (Date.now() - lastDragAt > 700) return;\n        const link =\n          event.target instanceof Element\n            ? event.target.closest(\"a[href]\")\n            : null;\n        if (!link) return;\n        const destination = new URL(link.href, window.location.href);\n        if (\n          destination.origin === window.location.origin &&\n          link.target !== \"_blank\"\n        )\n          return;\n        event.preventDefault();\n        event.stopImmediatePropagation();\n      },\n      true,\n    );\n  }\n\n  installProductMediaExternalLinkGestureGuard();\n\n  const HOMEPAGE_COLLECTION_LINKS = [\n    {\n      sectionSuffix: \"__product_list_PJ9LUk\",\n      href: \"/collections/new\",\n      label: \"New Releases\",\n    },\n    {\n      sectionSuffix: \"__product_list_fHpiA7\",\n      href: \"/collections/coming-soon\",\n      label: \"Coming Soon\",\n    },\n  ];\n\n  function installHomepageCollectionLinkCards() {\n    if (\n      typeof document.querySelector !== \"function\" ||\n      typeof document.createElement !== \"function\"\n    ) {\n      return;\n    }\n\n    if (\n      !document.getElementById?.(\"framewerk-homepage-collection-link-styles\")\n    ) {\n      const styles = document.createElement(\"style\");\n      styles.id = \"framewerk-homepage-collection-link-styles\";\n      styles.textContent = `\n        .framewerk-collection-link-slide {\n          height: auto !important;\n          align-self: stretch;\n        }\n        .framewerk-collection-link-slide > .resource-list__item {\n          height: 100%;\n        }\n        .framewerk-collection-link-card {\n          display: grid;\n          width: 100%;\n          height: var(--framewerk-collection-card-height, 100%);\n          min-height: 320px;\n          place-items: center;\n          padding: 28px;\n          border: 3px solid #ef1515;\n          border-radius: 24px;\n          background: #fff;\n          color: #151515;\n          text-align: center;\n          text-decoration: none;\n          transition: background 160ms ease, color 160ms ease, transform 160ms ease;\n        }\n        .framewerk-collection-link-card:hover {\n          background: #ef1515;\n          color: #fff;\n          transform: translateY(-2px);\n        }\n        .framewerk-collection-link-card:focus-visible {\n          outline: 4px solid #ffd500;\n          outline-offset: 3px;\n        }\n        .framewerk-collection-link-card__copy {\n          display: grid;\n          gap: 8px;\n          justify-items: center;\n          font-family: var(--font-heading--family, inherit);\n          font-weight: 900;\n          line-height: 0.92;\n          text-transform: uppercase;\n        }\n        .framewerk-collection-link-card__copy strong {\n          max-width: 6ch;\n          font-size: clamp(2.5rem, 4vw, 4.75rem);\n        }\n        .framewerk-collection-link-card__copy small {\n          font-size: 0.75rem;\n          letter-spacing: 0.08em;\n        }\n        @media (max-width: 749px) {\n          .framewerk-collection-link-card {\n            min-height: 280px;\n            padding: 20px;\n          }\n          .framewerk-collection-link-card__copy strong {\n            font-size: clamp(2rem, 12vw, 3.5rem);\n          }\n        }\n      `;\n      document.head?.append(styles);\n    }\n\n    for (const config of HOMEPAGE_COLLECTION_LINKS) {\n      const section = document.querySelector(`[id$=\"${config.sectionSuffix}\"]`);\n      if (!section) continue;\n      const slides = section.querySelector(\n        'slideshow-component[ref=\"resourceListCarousel\"] slideshow-slides[ref=\"scroller\"]',\n      );\n      if (!slides || slides.querySelector(\"[data-framewerk-collection-link]\"))\n        continue;\n\n      const slide = document.createElement(\"slideshow-slide\");\n      const slideIndex = slides.querySelectorAll(\n        \":scope > slideshow-slide\",\n      ).length;\n      slide.className = \"resource-list__slide framewerk-collection-link-slide\";\n      slide.setAttribute(\"ref\", \"slides[]\");\n      slide.setAttribute(\"data-framewerk-collection-link\", config.label);\n      slide.style.setProperty(\"--slideshow-timeline\", `--slide-${slideIndex}`);\n\n      const item = document.createElement(\"div\");\n      item.className = \"resource-list__item\";\n      const link = document.createElement(\"a\");\n      link.className = \"framewerk-collection-link-card\";\n      link.href = config.href;\n      link.setAttribute(\"aria-label\", `See more ${config.label}`);\n      const copy = document.createElement(\"span\");\n      copy.className = \"framewerk-collection-link-card__copy\";\n      const heading = document.createElement(\"strong\");\n      heading.textContent = \"See more\";\n      const detail = document.createElement(\"small\");\n      detail.textContent = config.label;\n      copy.append(heading, detail);\n      link.append(copy);\n      item.append(link);\n      slide.append(item);\n      slides.append(slide);\n\n      const matchProductHeight = () => {\n        const productCard = slides.querySelector(\n          \":scope > slideshow-slide:not([data-framewerk-collection-link]) product-card\",\n        );\n        const height = Math.ceil(\n          productCard?.getBoundingClientRect().height ?? 0,\n        );\n        if (height > 0)\n          link.style.setProperty(\n            \"--framewerk-collection-card-height\",\n            `${height}px`,\n          );\n      };\n      requestAnimationFrame(() => requestAnimationFrame(matchProductHeight));\n      window.addEventListener(\"load\", matchProductHeight, { once: true });\n      window.addEventListener(\"resize\", matchProductHeight, { passive: true });\n    }\n  }\n\n  installHomepageCollectionLinkCards();\n  document.addEventListener?.(\"shopify:section:load\", () =>\n    installHomepageCollectionLinkCards(),\n  );\n  window.addEventListener?.(\"pageshow\", () =>\n    installHomepageCollectionLinkCards(),\n  );\n\n  function readSessionValue(key) {\n    try {\n      return JSON.parse(window.sessionStorage?.getItem(key) ?? \"null\");\n    } catch {\n      return null;\n    }\n  }\n\n  function writeSessionValue(key, value) {\n    try {\n      window.sessionStorage?.setItem(key, JSON.stringify(value));\n    } catch {\n      // Session storage can be unavailable in privacy-restricted storefronts.\n    }\n  }\n\n  async function fetchJson(url, options = {}, timeoutMs = 8000) {\n    const controller =\n      typeof AbortController === \"function\" ? new AbortController() : null;\n    const timeout = controller\n      ? window.setTimeout(() => controller.abort(), timeoutMs)\n      : null;\n    try {\n      const response = await fetch(url, {\n        credentials: \"same-origin\",\n        ...options,\n        ...(controller ? { signal: controller.signal } : {}),\n      });\n      if (!response.ok) {\n        throw new Error(`Request failed (${response.status}).`);\n      }\n      return await response.json();\n    } finally {\n      if (timeout !== null) window.clearTimeout(timeout);\n    }\n  }\n\n  function createWebsiteSettingsController() {\n    let request = null;\n    const apply = async (root = document) => {\n      if (!request) {\n        request = (async () => {\n          const cacheEntry = readSessionValue(WEBSITE_SETTINGS_CACHE_KEY);\n          const cached =\n            cacheEntry?.data && typeof cacheEntry.storedAt === \"number\"\n              ? cacheEntry\n              : cacheEntry\n                ? { data: cacheEntry, storedAt: 0 }\n                : null;\n          if (\n            cached &&\n            Date.now() - cached.storedAt < WEBSITE_SETTINGS_CACHE_TTL_MS\n          ) {\n            return cached.data;\n          }\n          try {\n            const url = new URL(\"/apps/framewerk\", window.location.origin);\n            url.searchParams.set(\"resource\", \"website-access\");\n            const settings = await fetchJson(\n              url,\n              {\n                cache: \"no-store\",\n                headers: { Accept: \"application/json\" },\n              },\n              WEBSITE_SETTINGS_TIMEOUT_MS,\n            );\n            writeSessionValue(WEBSITE_SETTINGS_CACHE_KEY, {\n              data: settings,\n              storedAt: Date.now(),\n            });\n            return settings;\n          } catch (error) {\n            console.warn(\n              \"Framewerk Website settings could not be loaded.\",\n              error,\n            );\n            return cached?.data ?? { comparisonEnabled: false };\n          }\n        })();\n      }\n      const settings = await request;\n      const comparisonEnabled = settings.comparisonEnabled !== false;\n      document.documentElement.dataset.framewerkComparison = comparisonEnabled\n        ? \"enabled\"\n        : \"disabled\";\n      root\n        .querySelectorAll?.(\n          \"[data-framewerk-comparison]:not(html), [data-framewerk-comparison-toggle], compare-toggle\",\n        )\n        .forEach((surface) =>\n          surface.toggleAttribute(\"hidden\", !comparisonEnabled),\n        );\n      return settings;\n    };\n\n    document.addEventListener?.(\"shopify:section:load\", (event) => {\n      const root =\n        event.target instanceof HTMLElement ? event.target : document;\n      void apply(root);\n    });\n    return Object.freeze({ apply });\n  }\n\n  function createFormsEmbedController() {\n    const selector = 'iframe[src*=\"/forms/\"]';\n    const fallbackHeight = 960;\n    const mounted = new WeakSet();\n    const timers = new WeakMap();\n\n    const formDetails = (frame) => {\n      try {\n        const url = new URL(frame.src, document.baseURI);\n        const match = url.pathname.match(/\\/forms\\/([^/?#]+)/);\n        return {\n          origin: url.origin,\n          publicId: match ? decodeURIComponent(match[1]) : \"\",\n        };\n      } catch {\n        return null;\n      }\n    };\n\n    const requestHeight = (frame) => {\n      const details = formDetails(frame);\n      if (!details || !frame.contentWindow) return;\n      try {\n        frame.contentWindow.postMessage(\n          {\n            type: \"framewerk:request-form-height\",\n            publicId: details.publicId,\n          },\n          details.origin,\n        );\n      } catch {\n        // The generous fallback still keeps the complete form available.\n      }\n    };\n\n    const releaseClippingAncestors = (frame, height) => {\n      let ancestor = frame.parentElement;\n      let depth = 0;\n      while (ancestor && ancestor !== document.body && depth < 4) {\n        const styles = window.getComputedStyle(ancestor);\n        const overflow = styles.overflowY || styles.overflow;\n        if (\n          ancestor.clientHeight > 0 &&\n          ancestor.clientHeight + 4 < height &&\n          (overflow === \"hidden\" || overflow === \"clip\")\n        ) {\n          ancestor.style.setProperty(\"height\", \"auto\", \"important\");\n          ancestor.style.setProperty(\"max-height\", \"none\", \"important\");\n          ancestor.style.setProperty(\"overflow\", \"visible\", \"important\");\n        }\n        ancestor = ancestor.parentElement;\n        depth += 1;\n      }\n    };\n\n    const setHeight = (frame, height) => {\n      const nextHeight = Math.min(5000, Math.max(240, Math.ceil(height) + 2));\n      frame.style.setProperty(\"height\", `${nextHeight}px`, \"important\");\n      frame.style.setProperty(\"min-height\", \"240px\", \"important\");\n      frame.setAttribute(\"height\", String(nextHeight));\n      releaseClippingAncestors(frame, nextHeight);\n    };\n\n    const mount = (frame) => {\n      if (\n        typeof HTMLIFrameElement === \"undefined\" ||\n        !(frame instanceof HTMLIFrameElement) ||\n        mounted.has(frame)\n      )\n        return;\n      mounted.add(frame);\n      frame.style.setProperty(\"width\", \"100%\", \"important\");\n      frame.style.setProperty(\"height\", `${fallbackHeight}px`, \"important\");\n      frame.style.setProperty(\"min-height\", \"720px\", \"important\");\n      frame.style.setProperty(\"max-height\", \"none\", \"important\");\n      frame.style.setProperty(\"display\", \"block\", \"important\");\n      frame.style.setProperty(\"border\", \"0\", \"important\");\n      frame.style.setProperty(\"overflow\", \"hidden\", \"important\");\n      frame.style.setProperty(\"background\", \"transparent\", \"important\");\n      frame.setAttribute(\"scrolling\", \"no\");\n      frame.setAttribute(\"allowtransparency\", \"true\");\n      releaseClippingAncestors(frame, fallbackHeight);\n      const request = () => requestHeight(frame);\n      frame.addEventListener(\"load\", request);\n      timers.set(\n        frame,\n        [0, 100, 350, 900, 1800, 3500].map((delay) =>\n          window.setTimeout(request, delay),\n        ),\n      );\n    };\n\n    const apply = (root = document) => {\n      if (\n        typeof HTMLIFrameElement !== \"undefined\" &&\n        root instanceof HTMLIFrameElement &&\n        root.matches(selector)\n      ) {\n        mount(root);\n      }\n      root.querySelectorAll?.(selector).forEach(mount);\n    };\n\n    const onMessage = (event) => {\n      const payload = event.data;\n      if (!payload || payload.type !== \"framewerk:form-height\") return;\n      const frame = Array.from(document.querySelectorAll(selector)).find(\n        (candidate) => candidate.contentWindow === event.source,\n      );\n      if (!frame) return;\n      const details = formDetails(frame);\n      const height = Number(payload.height);\n      if (\n        !details ||\n        event.origin !== details.origin ||\n        (details.publicId && payload.publicId !== details.publicId) ||\n        !Number.isFinite(height) ||\n        height <= 0\n      )\n        return;\n      timers.get(frame)?.forEach((timer) => window.clearTimeout(timer));\n      timers.delete(frame);\n      setHeight(frame, height);\n    };\n\n    window.addEventListener?.(\"message\", onMessage);\n    window.addEventListener?.(\"resize\", () => apply(document), {\n      passive: true,\n    });\n    document.addEventListener?.(\"shopify:section:load\", (event) =>\n      apply(\n        typeof Element !== \"undefined\" && event.target instanceof Element\n          ? event.target\n          : document,\n      ),\n    );\n    if (typeof MutationObserver !== \"undefined\" && document.documentElement) {\n      new MutationObserver((records) => {\n        records.forEach((record) =>\n          record.addedNodes.forEach((node) => {\n            if (typeof Element !== \"undefined\" && node instanceof Element)\n              apply(node);\n          }),\n        );\n      }).observe(document.documentElement, { childList: true, subtree: true });\n    }\n    return Object.freeze({ apply });\n  }\n\n  if (typeof HTMLIFrameElement !== \"undefined\") {\n    const formsEmbedController =\n      window[FORMS_EMBED_CONTROLLER_KEY] ?? createFormsEmbedController();\n    window[FORMS_EMBED_CONTROLLER_KEY] = formsEmbedController;\n    formsEmbedController.apply(document);\n  }\n\n  const websiteSettingsController =\n    window[WEBSITE_SETTINGS_CONTROLLER_KEY] ??\n    createWebsiteSettingsController();\n  window[WEBSITE_SETTINGS_CONTROLLER_KEY] = websiteSettingsController;\n  void websiteSettingsController.apply(document);\n\n  function createProductVariantImageFocusController() {\n    let focusRequest = 0;\n\n    const isMobileProductPage = () =>\n      /^\\/products(?:\\/|$)/.test(window.location.pathname) &&\n      window.matchMedia?.(PRODUCT_VARIANT_IMAGE_FOCUS_BREAKPOINT)?.matches ===\n        true;\n\n    const selectedProductMedia = () =>\n      Array.from(\n        document.querySelectorAll?.(SELECTED_PRODUCT_MEDIA_SELECTOR) ?? [],\n      ).find((media) => {\n        const bounds = media.getBoundingClientRect();\n        return bounds.width > 0 && bounds.height > 0;\n      }) ?? null;\n\n    const requestedVariantId = (picker, control) => {\n      const selectedOption = control.selectedOptions?.[0];\n      const checkedOption = picker.querySelector?.(\n        \"input:checked[data-variant-id], option:checked[data-variant-id]\",\n      );\n      return String(\n        control.dataset?.variantId ??\n          selectedOption?.dataset?.variantId ??\n          checkedOption?.dataset?.variantId ??\n          \"\",\n      );\n    };\n\n    const currentUrlVariantId = () =>\n      new URL(window.location.href).searchParams.get(\"variant\") ?? \"\";\n\n    const centreSelectedMedia = (request) => {\n      const afterPaint =\n        window.requestAnimationFrame?.bind(window) ??\n        ((callback) => window.setTimeout(callback, 0));\n      afterPaint(() => {\n        afterPaint(() => {\n          if (request !== focusRequest || !isMobileProductPage()) return;\n          const media = selectedProductMedia();\n          if (!media) return;\n          media.scrollIntoView({\n            behavior: window.matchMedia?.(\"(prefers-reduced-motion: reduce)\")\n              ?.matches\n              ? \"auto\"\n              : \"smooth\",\n            block: \"center\",\n            inline: \"nearest\",\n          });\n        });\n      });\n    };\n\n    const queueFocus = (picker, control) => {\n      if (!isMobileProductPage()) return;\n      const request = ++focusRequest;\n      const initialMedia = selectedProductMedia();\n      const initialMediaId = initialMedia?.dataset?.mediaId ?? \"\";\n      const initialVariantId = currentUrlVariantId();\n      const targetVariantId = requestedVariantId(picker, control);\n      const startedAt = Date.now();\n      let readyAt = 0;\n\n      const check = () => {\n        if (request !== focusRequest || !isMobileProductPage()) return;\n        const media = selectedProductMedia();\n        const mediaChanged = Boolean(\n          media &&\n          (media !== initialMedia ||\n            !initialMedia?.isConnected ||\n            media.dataset?.mediaId !== initialMediaId),\n        );\n        const urlVariantId = currentUrlVariantId();\n        const variantChanged = targetVariantId\n          ? urlVariantId === targetVariantId\n          : urlVariantId !== initialVariantId;\n        const elapsed = Date.now() - startedAt;\n\n        if (media && (mediaChanged || variantChanged)) {\n          readyAt ||= Date.now();\n          if (mediaChanged || Date.now() - readyAt >= 180) {\n            centreSelectedMedia(request);\n            return;\n          }\n        }\n\n        if (media && elapsed >= 4000) {\n          centreSelectedMedia(request);\n          return;\n        }\n        window.setTimeout(check, 80);\n      };\n\n      window.setTimeout(check, 0);\n    };\n\n    document.addEventListener(\n      \"change\",\n      (event) => {\n        if (!(event.target instanceof Element)) return;\n        const control = event.target.closest(\"input, select\");\n        const picker = control?.closest(\"variant-picker\");\n        if (!control || !picker) return;\n        queueFocus(picker, control);\n      },\n      true,\n    );\n\n    return Object.freeze({ queueFocus });\n  }\n\n  const productVariantImageFocusController =\n    window[PRODUCT_VARIANT_IMAGE_FOCUS_CONTROLLER_KEY] ??\n    createProductVariantImageFocusController();\n  window[PRODUCT_VARIANT_IMAGE_FOCUS_CONTROLLER_KEY] =\n    productVariantImageFocusController;\n\n  if (window.Framewerk?.version) return;\n\n  const VERSION = \"2.0.8\";\n  const KEYS = Object.freeze({\n    vehicle: \"framewerk:vehicle:v1\",\n    garage: \"framewerk:garage:v1\",\n    comparison: \"framewerk:comparison:v1\",\n    quote: \"framewerk:quote:v1\",\n  });\n  const EVENTS = Object.freeze({\n    ready: \"framewerk:ready\",\n    vehicleChanged: \"framewerk:vehicle:changed\",\n    garageChanged: \"framewerk:garage:changed\",\n    comparisonChanged: \"framewerk:comparison:changed\",\n    quoteChanged: \"framewerk:quote:changed\",\n    sectionRendered: \"framewerk:lifecycle:section-rendered\",\n    catalogueState: \"framewerk:catalogue:state\",\n  });\n  const CATALOGUE_FILTER_SUFFIX =\n    \".framewerk_catalogue_spike.compatibility_tokens\";\n  const CATALOGUE_FILTER_PARAM =\n    \"filter.p.m.framewerk_catalogue_spike.compatibility_tokens\";\n  const CATALOGUE_VEHICLE_PREFIX = \"vehicle:\";\n  const CATALOGUE_UNIVERSAL_TOKEN = \"universal\";\n  const VEHICLE_CACHE_KEY = \"framewerk:vehicle-catalogue:v1\";\n  const VEHICLE_CACHE_TTL_MS = 5 * 60 * 1000;\n  const VEHICLE_REQUEST_KEY = \"__framewerkVehicleCatalogueRequest\";\n\n  const listeners = new Map();\n  const legacyVehicle = read(\"framewerk:mister-fitment:selected-vehicle\", null);\n  const state = {\n    vehicle: read(KEYS.vehicle, legacyVehicle),\n    garage: read(KEYS.garage, []),\n    comparison: read(KEYS.comparison, []),\n    quote: read(KEYS.quote, []),\n  };\n\n  function read(key, fallback) {\n    try {\n      const value = JSON.parse(localStorage.getItem(key));\n      return value ?? fallback;\n    } catch {\n      return fallback;\n    }\n  }\n\n  function write(key, value) {\n    try {\n      localStorage.setItem(key, JSON.stringify(value));\n      return true;\n    } catch (error) {\n      console.error(\"Framewerk storage write failed\", { key, error });\n      return false;\n    }\n  }\n\n  function notifyListener(event, listener, detail) {\n    try {\n      listener(detail);\n    } catch (error) {\n      console.error(\"Framewerk event listener failed\", { event, error });\n    }\n  }\n\n  function publish(event, detail) {\n    for (const listener of listeners.get(event) ?? []) {\n      notifyListener(event, listener, detail);\n    }\n    window.dispatchEvent(new CustomEvent(event, { detail }));\n  }\n\n  function subscribe(event, listener, options = {}) {\n    const group = listeners.get(event) ?? new Set();\n    group.add(listener);\n    listeners.set(event, group);\n    if (options.replayCurrent) {\n      if (event === EVENTS.vehicleChanged) {\n        notifyListener(event, listener, state.vehicle);\n      }\n      if (event === EVENTS.garageChanged) {\n        notifyListener(event, listener, [...state.garage]);\n      }\n      if (event === EVENTS.comparisonChanged) {\n        notifyListener(event, listener, [...state.comparison]);\n      }\n      if (event === EVENTS.quoteChanged) {\n        notifyListener(event, listener, [...state.quote]);\n      }\n    }\n    return () => group.delete(listener);\n  }\n\n  function stableVehicle(vehicle) {\n    if (!vehicle || typeof vehicle !== \"object\") return null;\n    const code = String(vehicle.vehicleCode ?? vehicle.code ?? \"\").trim();\n    if (!code) throw new Error(\"Framewerk vehicle requires a permanent code.\");\n    return {\n      id: vehicle.id ?? null,\n      key: vehicle.key ?? null,\n      code,\n      vehicleCode: code,\n      make: String(vehicle.make ?? \"\"),\n      model: String(vehicle.model ?? \"\"),\n      series: String(vehicle.series ?? \"\"),\n      variant: String(vehicle.variant ?? \"\"),\n      yearFrom: vehicle.yearFrom ?? null,\n      yearTo: vehicle.yearTo ?? null,\n      landingPageUrl: vehicle.landingPageUrl ?? null,\n      bannerImageUrl: vehicle.bannerImageUrl ?? null,\n      label: String(\n        vehicle.label ??\n          [vehicle.make, vehicle.model, vehicle.series, vehicle.variant]\n            .filter(Boolean)\n            .join(\" \"),\n      ),\n    };\n  }\n\n  function vehicleIdentity(vehicle) {\n    return [vehicle?.make, vehicle?.model, vehicle?.series, vehicle?.variant]\n      .map((value) =>\n        String(value ?? \"\")\n          .trim()\n          .toLowerCase(),\n      )\n      .join(\"|\");\n  }\n\n  function readVehicleCatalogueCache() {\n    try {\n      const cached = JSON.parse(\n        window.sessionStorage?.getItem(VEHICLE_CACHE_KEY),\n      );\n      if (\n        !cached ||\n        typeof cached.storedAt !== \"number\" ||\n        Date.now() - cached.storedAt > VEHICLE_CACHE_TTL_MS ||\n        !cached.data ||\n        !Array.isArray(cached.data.vehicles)\n      ) {\n        return null;\n      }\n      return cached.data;\n    } catch {\n      return null;\n    }\n  }\n\n  function writeVehicleCatalogueCache(data) {\n    if (!data || !Array.isArray(data.vehicles)) return;\n    try {\n      window.sessionStorage?.setItem(\n        VEHICLE_CACHE_KEY,\n        JSON.stringify({ storedAt: Date.now(), data }),\n      );\n    } catch {\n      // Session storage can be unavailable in privacy-restricted storefronts.\n      return undefined;\n    }\n  }\n\n  function vehicleCatalogueRequest() {\n    const pending = window[VEHICLE_REQUEST_KEY];\n    if (pending && typeof pending.then === \"function\") return pending;\n\n    let request;\n    request = fetchJson(\n      \"/apps/framewerk?resource=vehicles\",\n      {\n        cache: \"no-store\",\n        headers: { Accept: \"application/json\" },\n      },\n      6000,\n    )\n      .then((data) => {\n        writeVehicleCatalogueCache(data);\n        return data;\n      })\n      .finally(() => {\n        if (window[VEHICLE_REQUEST_KEY] === request) {\n          delete window[VEHICLE_REQUEST_KEY];\n        }\n      });\n    window[VEHICLE_REQUEST_KEY] = request;\n    return request;\n  }\n\n  async function reconcileStoredVehicle(catalogue = null) {\n    if (!state.vehicle) return false;\n    const previous = JSON.stringify(state.vehicle);\n    try {\n      let data = catalogue ?? readVehicleCatalogueCache();\n      if (!data) {\n        data = await vehicleCatalogueRequest();\n        if (!data) return false;\n      }\n      const vehicles = Array.isArray(data.vehicles) ? data.vehicles : [];\n      if (!vehicles.length) return false;\n\n      const identity = vehicleIdentity(state.vehicle);\n      const hasSemanticIdentity = identity.replaceAll(\"|\", \"\").length > 0;\n      const semanticMatch = hasSemanticIdentity\n        ? vehicles.find((vehicle) => vehicleIdentity(vehicle) === identity)\n        : null;\n      const codeMatch = vehicles.find(\n        (vehicle) =>\n          String(vehicle.code ?? vehicle.vehicleCode ?? \"\") ===\n          String(state.vehicle.code ?? \"\"),\n      );\n      const canonical = semanticMatch || codeMatch || null;\n\n      if (!canonical) {\n        state.vehicle = null;\n        write(KEYS.vehicle, null);\n        write(\"framewerk:mister-fitment:selected-vehicle\", null);\n        return previous !== JSON.stringify(state.vehicle);\n      }\n\n      const previousCode = String(state.vehicle.code ?? \"\");\n      state.vehicle = stableVehicle(canonical);\n      write(KEYS.vehicle, state.vehicle);\n      write(\"framewerk:mister-fitment:selected-vehicle\", {\n        ...canonical,\n        label: state.vehicle.label,\n      });\n      if (previousCode !== state.vehicle.code) {\n        console.info(\"Framewerk corrected a stale vehicle code\", {\n          previousCode,\n          vehicleCode: state.vehicle.code,\n          vehicle: state.vehicle.label,\n        });\n      }\n      return previous !== JSON.stringify(state.vehicle);\n    } catch (error) {\n      console.warn(\"Framewerk could not verify the stored vehicle\", error);\n      return false;\n    }\n  }\n\n  function stableProduct(product) {\n    if (typeof product === \"string\") return { handle: product };\n    if (!product || typeof product !== \"object\") {\n      throw new Error(\"Framewerk product is required.\");\n    }\n    const handle = String(product.handle ?? \"\").trim();\n    if (!handle) throw new Error(\"Framewerk product requires a handle.\");\n    return {\n      handle,\n      productId: product.productId ? String(product.productId) : null,\n      variantId: product.variantId ? String(product.variantId) : null,\n      title: String(product.title ?? \"\"),\n      url: String(product.url ?? `/products/${handle}`),\n      image: String(product.image ?? \"\"),\n      quantity: Math.max(1, Number(product.quantity) || 1),\n    };\n  }\n\n  function isManagedCatalogueToken(value) {\n    return (\n      value === CATALOGUE_UNIVERSAL_TOKEN ||\n      value.startsWith(CATALOGUE_VEHICLE_PREFIX)\n    );\n  }\n\n  function findCatalogueFilterParam(url = new URL(window.location.href)) {\n    for (const key of url.searchParams.keys()) {\n      if (key.endsWith(CATALOGUE_FILTER_SUFFIX)) return key;\n    }\n    const input = document.querySelector?.(\n      `input[name$=\"${CATALOGUE_FILTER_SUFFIX}\"]`,\n    );\n    const root = document.querySelector?.(\"[data-mf-catalogue-spike]\");\n    return root?.dataset?.filterParam || input?.name || CATALOGUE_FILTER_PARAM;\n  }\n\n  function buildCatalogueUrl(vehicle, currentHref = window.location.href) {\n    const url = new URL(currentHref, window.location.origin);\n    const filterParam = findCatalogueFilterParam(url);\n    const code = vehicle?.code ? String(vehicle.code).trim() : null;\n    const legacyParams = [...url.searchParams.keys()].filter((key) => {\n      const normalised = key.toLowerCase();\n      return (\n        normalised.startsWith(\"filter.p.m.\") &&\n        (normalised.includes(\"compatible_vehicles\") ||\n          normalised.includes(\"compatible-vehicles\"))\n      );\n    });\n    legacyParams.forEach((key) => url.searchParams.delete(key));\n\n    const current = url.searchParams.getAll(filterParam);\n    const preserved = current.filter(\n      (value) => !isManagedCatalogueToken(value),\n    );\n    const desired = code\n      ? [...preserved, `${CATALOGUE_VEHICLE_PREFIX}${code}`]\n      : preserved;\n    const uniqueDesired = [...new Set(desired)];\n    const changed =\n      legacyParams.length > 0 ||\n      JSON.stringify([...new Set(current)].sort()) !==\n        JSON.stringify([...uniqueDesired].sort());\n\n    url.searchParams.delete(filterParam);\n    uniqueDesired.forEach((value) =>\n      url.searchParams.append(filterParam, value),\n    );\n    if (changed) url.searchParams.delete(\"page\");\n    return { url, changed, filterParam, code };\n  }\n\n  function isCataloguePage() {\n    const pathname = String(window.location?.pathname ?? \"\");\n    // Full-text search owns its query and relevance. Applying a saved vehicle\n    // after Shopify has rendered results causes a late, contradictory rewrite.\n    return pathname.startsWith(\"/collections/\") || pathname === \"/collections\";\n  }\n\n  function normaliseStorefrontPath(value) {\n    if (!value) return \"\";\n    try {\n      const url = new URL(String(value), window.location.origin);\n      return decodeURIComponent(url.pathname).replace(/\\/+$/, \"\") || \"/\";\n    } catch {\n      return \"\";\n    }\n  }\n\n  async function collectionVehicleConflict(selectedVehicle) {\n    if (!selectedVehicle || !isCataloguePage()) return null;\n    try {\n      const catalogue =\n        readVehicleCatalogueCache() ?? (await vehicleCatalogueRequest());\n      const currentPath = normaliseStorefrontPath(window.location.pathname);\n      const collectionVehicle = (catalogue?.vehicles ?? []).find(\n        (vehicle) =>\n          normaliseStorefrontPath(vehicle?.landingPageUrl) === currentPath,\n      );\n      if (!collectionVehicle) return null;\n\n      const selectedCode = String(selectedVehicle.code ?? \"\").trim();\n      const collectionCode = String(\n        collectionVehicle.code ?? collectionVehicle.vehicleCode ?? \"\",\n      ).trim();\n      if (!selectedCode || !collectionCode || selectedCode === collectionCode) {\n        return null;\n      }\n      return {\n        selectedVehicle,\n        collectionVehicle: stableVehicle(collectionVehicle),\n      };\n    } catch (error) {\n      console.warn(\"Framewerk could not verify the collection vehicle\", error);\n      return null;\n    }\n  }\n\n  function removeVehicleConflictPrompt() {\n    document\n      .querySelectorAll?.(\"[data-framewerk-vehicle-conflict]\")\n      .forEach((prompt) => prompt.remove());\n  }\n\n  function renderVehicleConflictPrompt(conflict) {\n    removeVehicleConflictPrompt();\n    if (!conflict) return;\n\n    const facets = catalogueFacetController();\n    const anchor = facets ?? document.querySelector?.(\"main\");\n    if (!anchor?.parentNode) return;\n\n    if (!document.getElementById?.(\"framewerk-vehicle-conflict-styles\")) {\n      const styles = document.createElement(\"style\");\n      styles.id = \"framewerk-vehicle-conflict-styles\";\n      styles.textContent = `\n        [data-framewerk-vehicle-conflict]{display:flex;align-items:center;justify-content:space-between;gap:16px;box-sizing:border-box;width:100%;margin:0 0 16px;padding:14px 16px;border:1px solid rgb(215 25 32 / .38);border-left:5px solid #d71920;border-radius:14px;background:#fff7f7;color:#191b16;font:inherit}\n        [data-framewerk-vehicle-conflict] strong{display:block;margin:0 0 2px;font-weight:800}\n        [data-framewerk-vehicle-conflict] p{margin:0;line-height:1.4}\n        [data-framewerk-vehicle-conflict] button{flex:0 0 auto;min-height:44px;padding:10px 16px;border:0;border-radius:11px;background:#151913;color:#fff;font:inherit;font-weight:800;cursor:pointer}\n        [data-framewerk-vehicle-conflict] button:hover{background:#d71920}\n        @media(max-width:749px){[data-framewerk-vehicle-conflict]{align-items:stretch;flex-direction:column}[data-framewerk-vehicle-conflict] button{width:100%}}\n      `;\n      document.head?.append(styles);\n    }\n\n    const selectedLabel =\n      conflict.selectedVehicle.label || conflict.selectedVehicle.code;\n    const collectionLabel =\n      conflict.collectionVehicle.label || conflict.collectionVehicle.code;\n    const clearLabel =\n      conflict.selectedVehicle.series ||\n      conflict.selectedVehicle.model ||\n      conflict.selectedVehicle.code;\n    const prompt = document.createElement(\"section\");\n    prompt.dataset.framewerkVehicleConflict = \"true\";\n    prompt.setAttribute(\"role\", \"status\");\n\n    const copy = document.createElement(\"div\");\n    const title = document.createElement(\"strong\");\n    title.textContent = \"Vehicle filter conflict\";\n    const message = document.createElement(\"p\");\n    message.textContent = `This is the ${collectionLabel} collection, but ${selectedLabel} is selected. Clear the saved filter to see this collection correctly.`;\n    copy.append(title, message);\n\n    const clear = document.createElement(\"button\");\n    clear.type = \"button\";\n    clear.textContent = `Clear ${clearLabel} filter`;\n    clear.addEventListener(\"click\", () => window.Framewerk?.vehicle?.clear());\n    prompt.append(copy, clear);\n    anchor.parentNode.insertBefore(prompt, anchor);\n  }\n\n  function catalogueFacetController() {\n    const forms = [\n      ...(document.querySelectorAll?.(\"facets-form-component[section-id]\") ??\n        []),\n    ];\n    return (\n      forms.find((form) => !form.closest?.(\"dialog\") && form.isConnected) ||\n      forms.find((form) => form.isConnected) ||\n      null\n    );\n  }\n\n  function isCatalogueControlName(name) {\n    return (\n      name.startsWith(\"filter.\") ||\n      name === \"sort_by\" ||\n      name === \"q\" ||\n      name.startsWith(\"options[\")\n    );\n  }\n\n  function liveCatalogueUrl(currentHref = window.location.href) {\n    const url = new URL(currentHref, window.location.origin);\n    const facets = catalogueFacetController();\n    const controls = [\n      ...(facets?.querySelectorAll?.(\"input[name], select[name], textarea[name]\") ??\n        []),\n    ].filter((control) => {\n      const name = String(control?.name ?? \"\").trim();\n      return name && !control.disabled && isCatalogueControlName(name);\n    });\n    if (!controls.length) return url;\n\n    const names = new Set(\n      controls.map((control) => String(control.name).trim()),\n    );\n    names.forEach((name) => url.searchParams.delete(name));\n\n    controls.forEach((control) => {\n      const name = String(control.name).trim();\n      const type = String(control.type ?? \"\").toLowerCase();\n      if ([\"checkbox\", \"radio\"].includes(type) && !control.checked) return;\n\n      if (type === \"select-multiple\" && control.selectedOptions) {\n        [...control.selectedOptions].forEach((option) => {\n          const value = String(option?.value ?? \"\");\n          if (value) url.searchParams.append(name, value);\n        });\n        return;\n      }\n\n      const value = String(control.value ?? \"\");\n      if (value) url.searchParams.append(name, value);\n    });\n    return url;\n  }\n\n  function setCatalogueState(status, message = \"\", detail = {}) {\n    document.querySelectorAll?.(\"[data-mf-catalogue-spike]\").forEach((root) => {\n      root.dataset.state = status;\n      root.dataset.ready = \"true\";\n      const output = root.querySelector?.(\"[data-mf-catalogue-spike-status]\");\n      if (output) {\n        output.hidden = !message;\n        output.textContent = message;\n      }\n    });\n    if (document.documentElement?.dataset) {\n      document.documentElement.dataset.mfCatalogueProjectionState =\n        status.toUpperCase();\n    }\n    publish(EVENTS.catalogueState, { status, message, ...detail });\n  }\n\n  let catalogueBusy = false;\n  let catalogueQueued = false;\n  let catalogueQueuedVehicle = null;\n  let catalogueQueuedTarget = null;\n  let catalogueActiveTarget = null;\n\n  async function waitForCatalogueFacetController(timeoutMs = 800) {\n    let facets = catalogueFacetController();\n    if (typeof facets?.updateFiltersByURL === \"function\") return facets;\n\n    const startedAt = Date.now();\n    if (window.customElements?.whenDefined) {\n      await Promise.race([\n        window.customElements.whenDefined(\"facets-form-component\"),\n        new Promise((resolve) => window.setTimeout(resolve, 250)),\n      ]);\n    }\n\n    while (Date.now() - startedAt < timeoutMs) {\n      facets = catalogueFacetController();\n      if (typeof facets?.updateFiltersByURL === \"function\") return facets;\n      await new Promise((resolve) => window.setTimeout(resolve, 50));\n    }\n    return catalogueFacetController();\n  }\n\n  async function applyCatalogueVehicle(vehicle) {\n    if (!isCataloguePage()) return { changed: false, skipped: true };\n    if (vehicle && !String(vehicle.code ?? \"\").trim()) {\n      setCatalogueState(\n        \"failed\",\n        \"Compatibility filtering is unavailable because this vehicle has no permanent code.\",\n      );\n      return { changed: false, failed: true };\n    }\n\n    const conflict = await collectionVehicleConflict(vehicle);\n    renderVehicleConflictPrompt(conflict);\n    if (conflict) {\n      setCatalogueState(\"conflict\", \"\", {\n        selectedVehicleCode: conflict.selectedVehicle.code,\n        collectionVehicleCode: conflict.collectionVehicle.code,\n      });\n      return { changed: false, skipped: true, conflict: true };\n    }\n\n    // Shopify can replace the facet results before its History API update is\n    // visible to another event handler. Merge the live form controls so a\n    // category selected immediately before a vehicle is never lost.\n    const result = buildCatalogueUrl(vehicle, liveCatalogueUrl().toString());\n    if (!result.changed) {\n      setCatalogueState(\"current\", \"\", { url: result.url.toString() });\n      return result;\n    }\n\n    // The active controller is normally ready immediately. On first load, use\n    // a short bounded wait so a late custom-element upgrade does not force a\n    // premature full-page navigation or hold the storefront for two seconds.\n    const facets = await waitForCatalogueFacetController();\n\n    setCatalogueState(\"updating\", \"Updating compatible products\u2026\", {\n      url: result.url.toString(),\n    });\n    if (typeof facets?.updateFiltersByURL !== \"function\") {\n      window.location.assign(result.url.toString());\n      return result;\n    }\n\n    try {\n      await facets.updateFiltersByURL(result.url.toString());\n      setCatalogueState(\"current\", \"\", { url: result.url.toString() });\n      return result;\n    } catch (error) {\n      setCatalogueState(\n        \"failed\",\n        \"Shopify could not refresh compatible products. Retry or clear the selected vehicle.\",\n        { error },\n      );\n      console.error(\"Framewerk catalogue filtering failed\", error);\n      return { ...result, failed: true };\n    }\n  }\n\n  async function flushCatalogueVehicle() {\n    if (catalogueBusy) return;\n    catalogueBusy = true;\n    try {\n      while (catalogueQueued) {\n        const vehicle = catalogueQueuedVehicle;\n        catalogueActiveTarget = catalogueQueuedTarget;\n        catalogueQueued = false;\n        catalogueQueuedTarget = null;\n        await applyCatalogueVehicle(vehicle);\n      }\n    } finally {\n      catalogueBusy = false;\n      catalogueActiveTarget = null;\n    }\n  }\n\n  function queueCatalogueVehicle(vehicle) {\n    const target = isCataloguePage()\n      ? buildCatalogueUrl(vehicle, liveCatalogueUrl().toString()).url.toString()\n      : null;\n    if (\n      target &&\n      (target === catalogueActiveTarget ||\n        (catalogueQueued && target === catalogueQueuedTarget))\n    ) {\n      return;\n    }\n    catalogueQueuedVehicle = vehicle;\n    catalogueQueuedTarget = target;\n    catalogueQueued = true;\n    void flushCatalogueVehicle();\n  }\n\n  function collection(name, key, event, limit) {\n    return Object.freeze({\n      get: () => [...state[name]],\n      has: (handle) => state[name].some((item) => item.handle === handle),\n      add(product) {\n        const item = stableProduct(product);\n        if (this.has(item.handle)) return this.get();\n        if (state[name].length >= limit) {\n          throw new Error(`Framewerk ${name} limit of ${limit} reached.`);\n        }\n        state[name] = [...state[name], item];\n        write(key, state[name]);\n        publish(event, this.get());\n        return this.get();\n      },\n      remove(handle) {\n        state[name] = state[name].filter((item) => item.handle !== handle);\n        write(key, state[name]);\n        publish(event, this.get());\n        return this.get();\n      },\n      update(handle, changes) {\n        state[name] = state[name].map((item) =>\n          item.handle === handle\n            ? stableProduct({ ...item, ...changes })\n            : item,\n        );\n        write(key, state[name]);\n        publish(event, this.get());\n        return this.get();\n      },\n      clear() {\n        state[name] = [];\n        write(key, state[name]);\n        publish(event, []);\n      },\n      subscribe: (listener, options) => subscribe(event, listener, options),\n      limit,\n    });\n  }\n\n  function updateVehiclePresentation(root = document) {\n    const vehicle = state.vehicle;\n    if (document.body?.dataset) {\n      document.body.dataset.activeVehicle = vehicle ? \"true\" : \"false\";\n    }\n    root\n      .querySelectorAll?.(\"[data-active-vehicle-label]\")\n      .forEach((element) => {\n        if (!vehicle) {\n          element.textContent = element.dataset.activeVehicleLabelDefault ?? \"\";\n          return;\n        }\n\n        const labelMode =\n          element.dataset.mfSelectedLabelMode ||\n          element.closest?.(\"[data-mf-selected-label-mode]\")?.dataset\n            ?.mfSelectedLabelMode;\n        if (labelMode === \"series_model\") {\n          element.textContent =\n            [vehicle.series, vehicle.model]\n              .map((value) => String(value ?? \"\").trim())\n              .filter(Boolean)\n              .join(\" \") || vehicle.label;\n          return;\n        }\n\n        element.textContent = vehicle.label;\n      });\n    root\n      .querySelectorAll?.(\n        \"add-to-cart-component [data-force-vehicle-selection], [data-force-vehicle-selection]\",\n      )\n      .forEach((container) => {\n        if (container.dataset.canAddToCart !== \"true\") return;\n        const button =\n          container.matches?.(\"button\") && container.type === \"submit\"\n            ? container\n            : container.querySelector?.(\n                '[ref=\"addToCartButton\"], button[type=\"submit\"]',\n              );\n        if (button) button.disabled = !vehicle;\n      });\n  }\n\n  function hideCatalogueProjectionFacets(root = document) {\n    root\n      .querySelectorAll?.(`input[name$=\"${CATALOGUE_FILTER_SUFFIX}\"]`)\n      .forEach((input) => {\n        const facet =\n          input.closest?.(\"accordion-custom\") ?? input.closest?.(\"details\");\n        if (!facet) return;\n        facet.hidden = true;\n        facet.setAttribute?.(\"aria-hidden\", \"true\");\n        if (facet.dataset) facet.dataset.framewerkInternalFacet = \"true\";\n      });\n  }\n\n  function mountRuntime(root = document) {\n    hideCatalogueProjectionFacets(root);\n    updateVehiclePresentation(root);\n    root\n      .querySelectorAll?.(\"[data-framewerk-comparison]\")\n      .forEach(mountComparison);\n    root\n      .querySelectorAll?.(\"[data-framewerk-comparison-toggle]\")\n      .forEach(mountComparisonToggle);\n    root\n      .querySelectorAll?.(\"[data-framewerk-quote-add]\")\n      .forEach(mountQuoteButton);\n    root\n      .querySelectorAll?.(\"[data-framewerk-quote-form]\")\n      .forEach(mountQuoteForm);\n    updateQuoteCounters(root);\n  }\n\n  function updateQuoteCounters(root = document) {\n    const count = api.quoteRequest\n      .get()\n      .reduce((total, item) => total + item.quantity, 0);\n    root.querySelectorAll?.(\"[data-framewerk-quote-count]\").forEach((node) => {\n      node.textContent = String(count);\n      node.hidden = count === 0;\n    });\n  }\n\n  function mountComparisonToggle(button) {\n    if (button.dataset.framewerkMounted === \"true\") return;\n    button.dataset.framewerkMounted = \"true\";\n    const handle = button.dataset.productHandle;\n    if (!handle) {\n      button.disabled = true;\n      return;\n    }\n\n    button.addEventListener(\"click\", () => {\n      if (api.comparison.has(handle)) {\n        api.comparison.remove(handle);\n      } else {\n        api.comparison.add({\n          handle,\n          productId: button.dataset.productId,\n          variantId: button.dataset.variantId,\n          title: button.dataset.productTitle,\n          url: button.dataset.productUrl,\n          image: button.dataset.productImage,\n        });\n      }\n    });\n\n    const render = (items) => {\n      const selected = items.some((item) => item.handle === handle);\n      button.setAttribute(\"aria-pressed\", String(selected));\n      button.disabled = items.length >= api.comparison.limit && !selected;\n      button.textContent = selected\n        ? (button.dataset.removeLabel ?? \"Remove from comparison\")\n        : (button.dataset.addLabel ?? \"Compare\");\n    };\n    api.comparison.subscribe(render, { replayCurrent: true });\n  }\n\n  function mountQuoteButton(button) {\n    if (button.dataset.framewerkMounted === \"true\") return;\n    button.dataset.framewerkMounted = \"true\";\n    const handle = button.dataset.productHandle;\n    if (!handle) return;\n    button.addEventListener(\"click\", () => {\n      if (api.quoteRequest.has(handle)) {\n        api.quoteRequest.remove(handle);\n      } else {\n        api.quoteRequest.add({\n          handle,\n          productId: button.dataset.productId,\n          variantId: button.dataset.variantId,\n          title: button.dataset.productTitle,\n          quantity: 1,\n        });\n      }\n    });\n    const render = (items) => {\n      const selected = items.some((item) => item.handle === handle);\n      button.setAttribute(\"aria-pressed\", String(selected));\n      button.textContent = selected\n        ? (button.dataset.removeLabel ?? \"Remove from quote\")\n        : (button.dataset.addLabel ?? \"Request a quote\");\n    };\n    api.quoteRequest.subscribe(render, { replayCurrent: true });\n  }\n\n  function mountQuoteForm(form) {\n    if (form.dataset.framewerkMounted === \"true\") return;\n    form.dataset.framewerkMounted = \"true\";\n    const status = form.querySelector(\"[data-framewerk-quote-status]\");\n    const submit = form.querySelector('button[type=\"submit\"]');\n    form.addEventListener(\"submit\", async (event) => {\n      event.preventDefault();\n      const items = api.quoteRequest.get();\n      if (!items.length) {\n        if (status) status.textContent = \"Add at least one product first.\";\n        return;\n      }\n      if (submit) submit.disabled = true;\n      if (status) status.textContent = \"Submitting quote request\u2026\";\n      const fields = new FormData(form);\n      try {\n        const response = await fetch(\"/apps/framewerk?resource=quote\", {\n          method: \"POST\",\n          headers: {\n            \"Content-Type\": \"application/json\",\n            Accept: \"application/json\",\n          },\n          body: JSON.stringify({\n            customerName: fields.get(\"customerName\"),\n            email: fields.get(\"email\"),\n            phone: fields.get(\"phone\"),\n            message: fields.get(\"message\"),\n            vehicleCode: api.vehicle.get()?.code ?? null,\n            items,\n          }),\n        });\n        const body = await response.json();\n        if (!response.ok)\n          throw new Error(body.error ?? \"Quote submission failed.\");\n        api.quoteRequest.clear();\n        form.reset();\n        if (status) {\n          status.textContent = `Quote request #${body.quoteRequest.id} was submitted.`;\n        }\n      } catch (error) {\n        if (status) {\n          status.textContent =\n            error instanceof Error ? error.message : \"Quote submission failed.\";\n        }\n      } finally {\n        if (submit) submit.disabled = false;\n      }\n    });\n  }\n\n  async function loadProduct(handle) {\n    const response = await fetch(`/products/${encodeURIComponent(handle)}.js`);\n    if (!response.ok) throw new Error(`Product ${handle} could not be loaded.`);\n    return response.json();\n  }\n\n  function element(tag, text, className) {\n    const node = document.createElement(tag);\n    if (text) node.textContent = text;\n    if (className) node.className = className;\n    return node;\n  }\n\n  async function mountComparison(root) {\n    if (root.dataset.framewerkMounted === \"true\") return;\n    root.dataset.framewerkMounted = \"true\";\n    const status = root.querySelector(\"[data-framewerk-comparison-status]\");\n    const grid = root.querySelector(\"[data-framewerk-comparison-grid]\");\n\n    async function render(items = api.comparison.get()) {\n      if (!grid) return;\n      grid.replaceChildren();\n      if (!items.length) {\n        if (status) status.textContent = \"Choose products to compare.\";\n        return;\n      }\n      if (status) status.textContent = \"Loading comparison\u2026\";\n      const results = await Promise.allSettled(\n        items.map((item) => loadProduct(item.handle)),\n      );\n      results.forEach((result, index) => {\n        const saved = items[index];\n        if (result.status !== \"fulfilled\") return;\n        const product = result.value;\n        const card = element(\"article\", \"\", \"framewerk-comparison__product\");\n        const title = element(\n          \"a\",\n          product.title,\n          \"framewerk-comparison__title\",\n        );\n        title.href = product.url || `/products/${saved.handle}`;\n        card.append(title);\n        const variants = element(\n          \"select\",\n          \"\",\n          \"framewerk-comparison__variants\",\n        );\n        for (const variant of product.variants ?? []) {\n          const option = element(\"option\", variant.title);\n          option.value = String(variant.id);\n          option.selected =\n            String(saved.variantId ?? product.variants?.[0]?.id) ===\n            option.value;\n          variants.append(option);\n        }\n        variants.addEventListener(\"change\", () =>\n          api.comparison.update(saved.handle, { variantId: variants.value }),\n        );\n        card.append(variants);\n        const add = element(\"button\", \"Add to cart\");\n        add.type = \"button\";\n        add.addEventListener(\"click\", async () => {\n          add.disabled = true;\n          try {\n            const response = await fetch(\"/cart/add.js\", {\n              method: \"POST\",\n              headers: { \"Content-Type\": \"application/json\" },\n              body: JSON.stringify({\n                items: [{ id: variants.value, quantity: 1 }],\n              }),\n            });\n            if (!response.ok) throw new Error(\"Add to cart failed.\");\n            publish(\"framewerk:comparison:added-to-cart\", {\n              handle: saved.handle,\n              variantId: variants.value,\n            });\n          } finally {\n            add.disabled = false;\n          }\n        });\n        card.append(add);\n        const remove = element(\"button\", \"Remove\");\n        remove.type = \"button\";\n        remove.addEventListener(\"click\", () =>\n          api.comparison.remove(saved.handle),\n        );\n        card.append(remove);\n        grid.append(card);\n      });\n      if (status) {\n        const failed = results.filter(\n          (result) => result.status === \"rejected\",\n        ).length;\n        status.textContent = failed\n          ? `${failed} comparison product${failed === 1 ? \"\" : \"s\"} could not be loaded.`\n          : `${items.length} product${items.length === 1 ? \"\" : \"s\"} selected.`;\n      }\n    }\n\n    const unsubscribe = api.comparison.subscribe(render, {\n      replayCurrent: true,\n    });\n    root.framewerkUnmount = unsubscribe;\n  }\n\n  let readyResolve;\n  const ready = new Promise((resolve) => {\n    readyResolve = resolve;\n  });\n\n  const api = Object.freeze({\n    version: VERSION,\n    ready,\n    events: EVENTS,\n    storageKeys: KEYS,\n    vehicle: Object.freeze({\n      get: () => state.vehicle,\n      select(vehicle) {\n        const nextVehicle = stableVehicle(vehicle);\n        if (JSON.stringify(nextVehicle) === JSON.stringify(state.vehicle)) {\n          return state.vehicle;\n        }\n        state.vehicle = nextVehicle;\n        write(KEYS.vehicle, state.vehicle);\n        publish(EVENTS.vehicleChanged, state.vehicle);\n        return state.vehicle;\n      },\n      clear() {\n        if (!state.vehicle) return null;\n        state.vehicle = null;\n        write(KEYS.vehicle, null);\n        write(\"framewerk:mister-fitment:selected-vehicle\", null);\n        publish(EVENTS.vehicleChanged, null);\n        return null;\n      },\n      subscribe: (listener, options) =>\n        subscribe(EVENTS.vehicleChanged, listener, options),\n    }),\n    garage: Object.freeze({\n      get: () => [...state.garage],\n      replace(vehicles) {\n        const nextGarage = [];\n        const seenCodes = new Set();\n        for (const vehicle of Array.isArray(vehicles) ? vehicles : []) {\n          let item;\n          try {\n            item = stableVehicle(vehicle);\n          } catch {\n            continue;\n          }\n          if (!item || seenCodes.has(item.code)) continue;\n          seenCodes.add(item.code);\n          nextGarage.push(item);\n          if (nextGarage.length === 10) break;\n        }\n        if (JSON.stringify(nextGarage) === JSON.stringify(state.garage)) {\n          return [...state.garage];\n        }\n        state.garage = nextGarage;\n        write(KEYS.garage, state.garage);\n        publish(EVENTS.garageChanged, [...state.garage]);\n        return [...state.garage];\n      },\n      add(vehicle) {\n        const item = stableVehicle(vehicle);\n        state.garage = [\n          item,\n          ...state.garage.filter((saved) => saved.code !== item.code),\n        ].slice(0, 10);\n        write(KEYS.garage, state.garage);\n        publish(EVENTS.garageChanged, [...state.garage]);\n        return [...state.garage];\n      },\n      remove(code) {\n        const nextGarage = state.garage.filter(\n          (vehicle) => vehicle.code !== code,\n        );\n        if (nextGarage.length === state.garage.length) {\n          return [...state.garage];\n        }\n        state.garage = nextGarage;\n        write(KEYS.garage, state.garage);\n        publish(EVENTS.garageChanged, [...state.garage]);\n        return [...state.garage];\n      },\n      subscribe: (listener, options) =>\n        subscribe(EVENTS.garageChanged, listener, options),\n    }),\n    comparison: collection(\n      \"comparison\",\n      KEYS.comparison,\n      EVENTS.comparisonChanged,\n      4,\n    ),\n    quoteRequest: collection(\"quote\", KEYS.quote, EVENTS.quoteChanged, 50),\n    compatibility: Object.freeze({\n      async getProductCompatibility(productId, vehicle = state.vehicle) {\n        if (!vehicle)\n          return { productId, vehicleCode: null, status: \"unselected\" };\n        const url = new URL(\"/apps/framewerk\", window.location.origin);\n        url.searchParams.set(\"resource\", \"fitment\");\n        url.searchParams.set(\"product_id\", String(productId));\n        url.searchParams.set(\"vehicle_code\", String(vehicle.code));\n        const response = await fetch(url);\n        if (!response.ok)\n          throw new Error(`Compatibility request failed (${response.status}).`);\n        return response.json();\n      },\n    }),\n    catalogue: Object.freeze({\n      refresh() {\n        queueCatalogueVehicle(state.vehicle);\n      },\n      clearVehicleConstraint() {\n        api.vehicle.clear();\n      },\n      buildUrl(vehicle, currentHref) {\n        return buildCatalogueUrl(vehicle, currentHref).url.toString();\n      },\n    }),\n    lifecycle: Object.freeze({\n      mount(root = document) {\n        mountRuntime(root);\n        root.dispatchEvent(new CustomEvent(EVENTS.ready, { bubbles: true }));\n      },\n      unmount() {},\n      afterSectionRender(root = document) {\n        publish(EVENTS.sectionRendered, root);\n        api.lifecycle.mount(root);\n        void websiteSettingsController.apply(root);\n        queueCatalogueVehicle(state.vehicle);\n      },\n    }),\n    subscribe,\n  });\n\n  window.Framewerk = api;\n  subscribe(EVENTS.vehicleChanged, () => updateVehiclePresentation(document));\n  subscribe(EVENTS.vehicleChanged, queueCatalogueVehicle);\n  subscribe(EVENTS.quoteChanged, () => updateQuoteCounters(document));\n  document.addEventListener?.(\"shopify:section:load\", (event) => {\n    const root = event.target instanceof HTMLElement ? event.target : document;\n    api.lifecycle.afterSectionRender(root);\n  });\n  window.addEventListener?.(\"pageshow\", () => api.lifecycle.mount(document));\n  readyResolve();\n  publish(EVENTS.ready, api);\n  const publishInitialState = () => {\n    // Compatibility surfaces outside the shared runtime still use this event\n    // to initialise their selected-vehicle state. The selector now builds the\n    // final filtered landing URL up front, so this signal no longer needs to\n    // trigger a second navigation.\n    window.dispatchEvent(\n      new CustomEvent(\"framewerk:mister-fitment:vehicle-changed\", {\n        detail: state.vehicle,\n      }),\n    );\n    publish(EVENTS.vehicleChanged, state.vehicle);\n    publish(EVENTS.garageChanged, [...state.garage]);\n    publish(EVENTS.comparisonChanged, [...state.comparison]);\n    publish(EVENTS.quoteChanged, [...state.quote]);\n    api.lifecycle.mount(document);\n  };\n  const publishReconciledVehicle = () => {\n    window.dispatchEvent(\n      new CustomEvent(\"framewerk:mister-fitment:vehicle-changed\", {\n        detail: state.vehicle,\n      }),\n    );\n    publish(EVENTS.vehicleChanged, state.vehicle);\n  };\n  const reconcileInBackground = () => {\n    void reconcileStoredVehicle().then((changed) => {\n      if (changed) publishReconciledVehicle();\n    });\n  };\n\n  queueMicrotask(async () => {\n    const cachedCatalogue = readVehicleCatalogueCache();\n    if (cachedCatalogue) {\n      await reconcileStoredVehicle(cachedCatalogue);\n    }\n    publishInitialState();\n    void websiteSettingsController.apply(document);\n\n    if (!cachedCatalogue && state.vehicle) {\n      if (typeof window.requestIdleCallback === \"function\") {\n        window.requestIdleCallback(reconcileInBackground, { timeout: 1500 });\n      } else if (typeof window.setTimeout === \"function\") {\n        window.setTimeout(reconcileInBackground, 100);\n      } else {\n        queueMicrotask(reconcileInBackground);\n      }\n    }\n  });\n})();\n"],
  "mappings": "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",
  "names": ["WEBSITE_SETTINGS_CONTROLLER_KEY", "WEBSITE_SETTINGS_CACHE_KEY", "PRODUCT_VARIANT_IMAGE_FOCUS_CONTROLLER_KEY", "FORMS_EMBED_CONTROLLER_KEY", "PRODUCT_VARIANT_IMAGE_FOCUS_BREAKPOINT", "SELECTED_PRODUCT_MEDIA_SELECTOR", "PRODUCT_MEDIA_GESTURE_SELECTOR", "installProductMediaExternalLinkGestureGuard", "gesture", "lastDragAt", "event", "touch", "target", "link", "HOMEPAGE_COLLECTION_LINKS", "installHomepageCollectionLinkCards", "styles", "config", "section", "slides", "slide", "slideIndex", "item", "copy", "heading", "detail", "matchProductHeight", "productCard", "height", "readSessionValue", "key", "writeSessionValue", "value", "fetchJson", "url", "options", "timeoutMs", "controller", "timeout", "response", "createWebsiteSettingsController", "request", "apply", "root", "cacheEntry", "cached", "settings", "error", "comparisonEnabled", "surface", "createFormsEmbedController", "selector", "mounted", "timers", "formDetails", "frame", "match", "requestHeight", "details", "releaseClippingAncestors", "ancestor", "depth", "overflow", "setHeight", "nextHeight", "mount", "delay", "onMessage", "payload", "candidate", "timer", "records", "record", "node", "formsEmbedController", "websiteSettingsController", "createProductVariantImageFocusController", "focusRequest", "isMobileProductPage", "selectedProductMedia", "media", "bounds", "requestedVariantId", "picker", "control", "selectedOption", "checkedOption", "currentUrlVariantId", "centreSelectedMedia", "afterPaint", "callback", "queueFocus", "initialMedia", "initialMediaId", "initialVariantId", "targetVariantId", "startedAt", "readyAt", "check", "mediaChanged", "urlVariantId", "variantChanged", "elapsed", "productVariantImageFocusController", "VERSION", "KEYS", "EVENTS", "CATALOGUE_FILTER_SUFFIX", "CATALOGUE_FILTER_PARAM", "CATALOGUE_VEHICLE_PREFIX", "CATALOGUE_UNIVERSAL_TOKEN", "VEHICLE_CACHE_KEY", "VEHICLE_CACHE_TTL_MS", "VEHICLE_REQUEST_KEY", "listeners", "legacyVehicle", "read", "state", "fallback", "write", "notifyListener", "listener", "publish", "subscribe", "group", "stableVehicle", "vehicle", "code", "vehicleIdentity", "readVehicleCatalogueCache", "writeVehicleCatalogueCache", "data", "vehicleCatalogueRequest", "pending", "reconcileStoredVehicle", "catalogue", "previous", "vehicles", "identity", "semanticMatch", "codeMatch", "canonical", "previousCode", "stableProduct", "product", "handle", "isManagedCatalogueToken", "findCatalogueFilterParam", "input", "buildCatalogueUrl", "currentHref", "filterParam", "legacyParams", "normalised", "current", "preserved", "desired", "uniqueDesired", "changed", "isCataloguePage", "pathname", "normaliseStorefrontPath", "collectionVehicleConflict", "selectedVehicle", "currentPath", "collectionVehicle", "selectedCode", "collectionCode", "removeVehicleConflictPrompt", "prompt", "renderVehicleConflictPrompt", "conflict", "anchor", "catalogueFacetController", "selectedLabel", "collectionLabel", "clearLabel", "title", "message", "clear", "forms", "form", "isCatalogueControlName", "name", "liveCatalogueUrl", "controls", "type", "option", "setCatalogueState", "status", "output", "catalogueBusy", "catalogueQueued", "catalogueQueuedVehicle", "catalogueQueuedTarget", "catalogueActiveTarget", "waitForCatalogueFacetController", "facets", "resolve", "applyCatalogueVehicle", "result", "flushCatalogueVehicle", "queueCatalogueVehicle", "collection", "limit", "changes", "updateVehiclePresentation", "element", "container", "button", "hideCatalogueProjectionFacets", "facet", "mountRuntime", "mountComparison", "mountComparisonToggle", "mountQuoteButton", "mountQuoteForm", "updateQuoteCounters", "count", "api", "total", "render", "items", "selected", "submit", "fields", "body", "loadProduct", "tag", "text", "className", "grid", "results", "index", "saved", "card", "variants", "variant", "add", "remove", "failed", "unsubscribe", "readyResolve", "ready", "nextVehicle", "nextGarage", "seenCodes", "productId", "publishInitialState", "publishReconciledVehicle", "reconcileInBackground", "cachedCatalogue"]
}
