{"version":3,"file":"client.mjs","sources":["../app/data.ts","../app/asset-url.ts","../app/flame-asset.ts","../app/styles.ts","../app/skeleton.ts","../app/widget/harness.ts","../app/client.ts"],"sourcesContent":["export type DealzSort = 'popular' | 'hot' | 'new';\n\nexport const TABS: ReadonlyArray<{ id: DealzSort; label: string }> = [\n  { id: 'popular', label: 'Beliebteste' },\n  { id: 'hot', label: 'Heißeste' },\n  { id: 'new', label: 'Neueste' },\n];\n\nexport const CTA_LABEL = 'Deals finden';\n\nexport const LINK_LABEL = 'Zu den Dealz';\n\nconst DEALZ_URLS: Record<DealzSort, { prod: string; test: string }> = {\n  popular: {\n    prod: 'https://dealz.check24.de',\n    test: 'https://dealz.check24-test.de',\n  },\n  hot: {\n    prod: 'https://dealz.check24.de/?category=temperature',\n    test: 'https://dealz.check24-test.de/?category=temperature',\n  },\n  new: {\n    prod: 'https://dealz.check24.de/?category=newest',\n    test: 'https://dealz.check24-test.de/?category=newest',\n  },\n};\n\nexport function buildDealzUrl(sort: DealzSort = 'popular'): string {\n  const isProd = typeof location !== 'undefined' && location.hostname.endsWith('check24.de');\n  const url = new URL(isProd ? DEALZ_URLS[sort].prod : DEALZ_URLS[sort].test);\n  url.searchParams.set('tid3', 'home_teaser');\n  return url.toString();\n}\n","/** Resolve manifest asset paths relative to client.mjs (same rules as vanilla.home backgrounds). */\nexport function resolveAssetBaseUrl(clientBundleUrl: string): string {\n  if (clientBundleUrl === '') return '';\n  try {\n    const url = new URL(clientBundleUrl);\n    if (/\\/dist\\/[^/]+$/i.test(url.pathname)) {\n      return new URL('../', url).href;\n    }\n    return new URL('./', url).href;\n  } catch {\n    return clientBundleUrl.replace(/\\/dist\\/[^/?#]+$/, '/');\n  }\n}\n\nexport function resolveAssetUrl(manifestPath: string, clientBundleUrl: string): string {\n  const p = manifestPath.trim().replace(/^\\.\\//, '').replace(/^\\//, '');\n  if (p === '' || clientBundleUrl === '') return '';\n  try {\n    return new URL(p, resolveAssetBaseUrl(clientBundleUrl)).href;\n  } catch {\n    return '';\n  }\n}\n\nexport function cssUrlValue(assetUrl: string): string {\n  return `url(\"${assetUrl.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\")`;\n}\n","import manifest from '../manifest.json';\nimport { resolveAssetUrl } from './asset-url';\n\nexport const FLAME_URL_ATTR = 'data-flame-url';\n\n/** Flame PNG URL — host attr or manifest CDN path (not inlined; keeps client.mjs under 50 KB). */\nexport function resolveFlameUrl(host: HTMLElement): string {\n  const fromHost = host.getAttribute(FLAME_URL_ATTR)?.trim();\n  if (fromHost) return fromHost;\n\n  const manifestPath = manifest.assets?.flame;\n  if (!manifestPath || typeof import.meta === 'undefined' || !import.meta.url) return '';\n  return resolveAssetUrl(manifestPath, import.meta.url);\n}\n","const MOBILE_MAX_PX = 768;\nconst FORM_MIN_PX = 960;\n\nexport { MOBILE_MAX_PX, FORM_MIN_PX };\n\nexport const DEALZ_HOST_STYLE = `\n:host {\n  display: block;\n  width: 100%;\n  min-height: 360px;\n  box-sizing: border-box;\n  line-height: normal;\n}\n\n.dealz-teaser {\n  position: relative;\n  display: block;\n  width: 100%;\n  height: 360px;\n  box-sizing: border-box;\n  overflow: hidden;\n}\n\n.dealz-teaser__link {\n  display: block;\n  height: 100%;\n  color: inherit;\n  text-decoration: none;\n}\n\n.dealz-teaser__headline {\n  position: absolute;\n  left: 50%;\n  top: 50px;\n  transform: translateX(-50%);\n  z-index: 2;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 16px;\n  margin: 0;\n  padding: 0;\n  border: 0;\n  color: #ffffff;\n}\n\n.dealz-teaser__headline-line {\n  display: block;\n  box-sizing: border-box;\n  font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;\n  line-height: 100%;\n  letter-spacing: -0.32px;\n  text-align: center;\n  white-space: nowrap;\n}\n\n.dealz-teaser__headline-word {\n  display: block;\n  box-sizing: border-box;\n  font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;\n  font-weight: 800;\n  font-size: 90px;\n  line-height: 100%;\n  letter-spacing: -0.32px;\n  text-align: center;\n  white-space: nowrap;\n}\n\n.dealz-teaser__headline-line--die {\n  font-weight: 700;\n  font-size: 40px;\n}\n\n.dealz-teaser__headline-line--words {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  justify-content: center;\n  gap: 0.32em;\n  max-width: min(667px, calc(100vw - 2rem));\n}\n\n.dealz-teaser__headline-word--mobile-only {\n  display: none;\n}\n\n.dealz-teaser__flame {\n  display: none;\n  position: absolute;\n  left: 50%;\n  margin-left: 0;\n  top: 10px;\n  z-index: -1;\n  height: 218px;\n  width: auto;\n  pointer-events: none;\n}\n\n.dealz-filter {\n  position: absolute;\n  left: 50%;\n  bottom: 60px;\n  transform: translateX(-50%);\n  z-index: 2;\n  display: flex;\n  align-items: center;\n  gap: 0;\n  width: calc(100% - 2rem);\n  max-width: 672px;\n  height: 64px;\n  margin: 0;\n  padding: 4px;\n  box-sizing: border-box;\n  border: 3px solid #ffbb1c;\n  border-radius: 34px;\n  background: #ffffff;\n  gap: 8px;\n}\n\n.dealz-filter__tabs {\n  display: flex;\n  flex: 1 1 auto;\n  align-items: center;\n  min-width: 0;\n  height: 100%;\n}\n\n.dealz-filter__tab {\n  flex: 1 1 0;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  min-width: 0;\n  height: 50px;\n  margin: 0;\n  padding: 0 8px;\n  border: 1px solid transparent;\n  border-radius: 28px;\n  background: transparent;\n  color: #181818;\n  font: inherit;\n  font-size: 16px;\n  line-height: 1;\n  text-align: center;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  cursor: pointer;\n}\n\n.dealz-filter__tab:hover {\n  color: #0563c1;\n}\n\n.dealz-filter__tab[aria-selected='true'] {\n  background: #edf7fd;\n  border-color: #0563c1;\n}\n\n.dealz-filter__cta {\n  flex: 0 0 auto;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  min-width: 149px;\n  height: 50px;\n  margin: 0;\n  padding: 12px 24px;\n  border: 0;\n  border-radius: 28px;\n  background: #0563c1;\n  color: #ffffff;\n  font: inherit;\n  font-size: 16px;\n  line-height: normal;\n  text-align: center;\n  white-space: nowrap;\n  cursor: pointer;\n}\n\n.dealz-filter__cta:hover {\n  background: #064e9c;\n}\n\n.dealz-filter__cta:focus-visible,\n.dealz-filter__tab:focus-visible {\n  outline: 2px solid #0563c1;\n  outline-offset: 2px;\n}\n\n@media (max-width: ${MOBILE_MAX_PX}px) {\n  :host {\n    min-height: 230px;\n  }\n\n  .dealz-teaser {\n    height: 230px;\n  }\n\n  .dealz-teaser__headline {\n    top: 40px;\n    width: calc(100% - 2rem);\n    align-items: start;\n    gap: 8px;\n  }\n\n  .dealz-teaser__headline-line--die {\n    font-size: 32px;\n  }\n\n  .dealz-teaser__headline-line--words {\n    display: contents;\n    max-width: none;\n  }\n\n  .dealz-teaser__headline-word {\n    font-size: 36px;\n  }\n\n  .dealz-teaser__headline-word--desktop-only {\n    display: none;\n  }\n\n  .dealz-teaser__headline-word--mobile-only {\n    display: block;\n  }\n\n  .dealz-teaser__flame {\n    display: block;\n  }\n}\n\n/* Layout check: wide viewport with device-output=mobile (see mietwagen teaser). */\n:host(.device-mobile) {\n  min-height: 230px;\n}\n\n:host(.device-mobile) .dealz-teaser {\n  height: 230px;\n}\n\n:host(.device-mobile) .dealz-teaser__headline {\n  top: 40px;\n  width: calc(100% - 2rem);\n  align-items: start;\n  gap: 8px;\n}\n\n:host(.device-mobile) .dealz-teaser__headline-line--die {\n  font-size: 32px;\n}\n\n:host(.device-mobile) .dealz-teaser__headline-line--words {\n  display: contents;\n  max-width: none;\n}\n\n:host(.device-mobile) .dealz-teaser__headline-word {\n  font-size: 36px;\n}\n\n:host(.device-mobile) .dealz-teaser__headline-word--desktop-only {\n  display: none;\n}\n\n:host(.device-mobile) .dealz-teaser__headline-word--mobile-only {\n  display: block;\n}\n\n:host(.device-mobile) .dealz-teaser__flame {\n  display: block;\n}\n\n@media (max-width: ${FORM_MIN_PX - 1}px) {\n  .dealz-filter {\n    display: none;\n  }\n\n  .dealz-teaser__link {\n    position: absolute;\n    inset: 0;\n    z-index: 1;\n    cursor: pointer;\n    pointer-events: auto;\n  }\n\n  .dealz-teaser__headline {\n    pointer-events: none;\n  }\n}\n\n@media (min-width: ${FORM_MIN_PX}px) {\n  .dealz-teaser__link {\n    pointer-events: none;\n    cursor: default;\n  }\n\n  .dealz-filter {\n    pointer-events: auto;\n  }\n}\n`.trim();\n\n","import { DEALZ_HOST_STYLE, MOBILE_MAX_PX } from './styles';\n\nexport const SLOT_MARKER = 'data-dealz-teaser-slot';\nexport const SKELETON_SELECTOR = '.c24-dealz-teaser-skeleton';\n\nconst DESKTOP_MIN_PX = MOBILE_MAX_PX + 1;\n\nconst SKELETON_SHIMMER = `\n.c24-dealz-teaser-skeleton {\n  --skeleton-dark: rgba(235, 235, 235, 0.7);\n  --skeleton-light: rgba(245, 246, 245, 0.5);\n}\n\n.c24-dealz-teaser-skeleton .skeleton {\n  background: var(--skeleton-dark);\n  border-radius: 90px;\n  animation: c24-dealz-skeleton-pulse 1100ms ease-in-out 100ms infinite;\n}\n\n.c24-dealz-teaser-skeleton .c24-dealz-skel-headline {\n  flex-shrink: 0;\n  overflow: hidden;\n}\n\n@keyframes c24-dealz-skeleton-pulse {\n  0%, 9%, 100% { background-color: var(--skeleton-dark); }\n  50%, 59% { background-color: var(--skeleton-light); }\n}\n`.trim();\n\n/** Fixed pill sizes (Inter 700/800) — avoids font-swap width jump during load. */\nconst SKELETON_HEADLINE_PILLS = `\n@media (min-width: ${DESKTOP_MIN_PX}px) {\n  .c24-dealz-teaser-skeleton .c24-dealz-skel-headline--die {\n    width: 63px;\n    height: 40px;\n  }\n\n  .c24-dealz-teaser-skeleton .c24-dealz-skel-headline--title {\n    width: 667px;\n    height: 90px;\n  }\n}\n\n@media (max-width: ${MOBILE_MAX_PX}px) {\n  .c24-dealz-teaser-skeleton .c24-dealz-skel-headline--die {\n    width: 60px;\n    height: 32px;\n  }\n\n  .c24-dealz-teaser-skeleton .c24-dealz-skel-headline--besten {\n    width: 140px;\n    height: 36px;\n  }\n\n  .c24-dealz-teaser-skeleton .c24-dealz-skel-headline--dealz {\n    width: 117px;\n    height: 36px;\n  }\n}\n\n.c24-dealz-teaser-skeleton.device-mobile .c24-dealz-skel-headline--die {\n  width: 60px;\n  height: 32px;\n}\n\n.c24-dealz-teaser-skeleton.device-mobile .c24-dealz-skel-headline--besten {\n  width: 140px;\n  height: 36px;\n}\n\n.c24-dealz-teaser-skeleton.device-mobile .c24-dealz-skel-headline--dealz {\n  width: 117px;\n  height: 36px;\n}\n`.trim();\n\nconst DEALZ_SKELETON_LAYOUT_STYLE = `\n${DEALZ_HOST_STYLE.replace(/:host\\((\\.device-mobile)\\)/g, '.c24-dealz-teaser-skeleton$1').replace(/:host/g, '.c24-dealz-teaser-skeleton')}\n\n.c24-dealz-teaser-skeleton .c24-dealz-skel-filter {\n  border: 0;\n  border-radius: 30px;\n  height: 64px;\n}\n\n@media (max-width: 959px) {\n  .c24-dealz-teaser-skeleton .c24-dealz-skel-filter {\n    display: none;\n  }\n}\n\n${SKELETON_HEADLINE_PILLS}\n\n${SKELETON_SHIMMER}\n`.trim();\n\nexport const DEALZ_SKELETON_STYLE = DEALZ_SKELETON_LAYOUT_STYLE;\n\nexport const DEALZ_SKELETON_HTML = `\n<style>${DEALZ_SKELETON_LAYOUT_STYLE}</style>\n<section class=\"c24-dealz-teaser-skeleton dealz-teaser\" ${SLOT_MARKER}>\n  <div class=\"dealz-teaser__headline\" aria-hidden=\"true\">\n    <div class=\"dealz-teaser__headline-line dealz-teaser__headline-line--die skeleton c24-dealz-skel-headline c24-dealz-skel-headline--die\"></div>\n    <div class=\"dealz-teaser__headline-line dealz-teaser__headline-line--words\">\n      <div class=\"dealz-teaser__headline-word dealz-teaser__headline-word--besten dealz-teaser__headline-word--desktop-only skeleton c24-dealz-skel-headline c24-dealz-skel-headline--title\"></div>\n      <div class=\"dealz-teaser__headline-word dealz-teaser__headline-word--besten dealz-teaser__headline-word--mobile-only skeleton c24-dealz-skel-headline c24-dealz-skel-headline--besten\"></div>\n      <div class=\"dealz-teaser__headline-word dealz-teaser__headline-word--dealz dealz-teaser__headline-word--mobile-only skeleton c24-dealz-skel-headline c24-dealz-skel-headline--dealz\"></div>\n    </div>\n  </div>\n  <div class=\"dealz-filter skeleton c24-dealz-skel-filter\" aria-hidden=\"true\"></div>\n</section>`.trim();\n","export function isLayoutCheckHarness(): boolean {\n  if (typeof window === 'undefined') return false;\n  const { hostname, pathname } = window.location;\n  const hostOk =\n    hostname === 'localhost' ||\n    hostname === '[::1]' ||\n    hostname === '::1' ||\n    hostname === '127.0.0.1' ||\n    hostname.startsWith('127.');\n  if (!hostOk) return false;\n  const p = pathname.endsWith('/') && pathname.length > 1 ? pathname.slice(0, -1) : pathname;\n  return p === '/client' || p.endsWith('/client') || p === '/skeleton' || p.endsWith('/skeleton');\n}\n\nexport function isSkeletonHarnessRoute(): boolean {\n  if (typeof window === 'undefined') return false;\n  const { pathname } = window.location;\n  const p = pathname.endsWith('/') && pathname.length > 1 ? pathname.slice(0, -1) : pathname;\n  return p === '/skeleton' || p.endsWith('/skeleton');\n}\n","import type { HomeClientComponentElement, HomeClientComponentProps } from '../.check24-home/types/client';\nimport { buildDealzUrl, CTA_LABEL, LINK_LABEL, TABS, type DealzSort } from './data';\nimport { FLAME_URL_ATTR, resolveFlameUrl } from './flame-asset';\nimport { DEALZ_SKELETON_HTML, SKELETON_SELECTOR, SLOT_MARKER } from './skeleton';\nimport { DEALZ_HOST_STYLE, FORM_MIN_PX, MOBILE_MAX_PX } from './styles';\nimport { isLayoutCheckHarness, isSkeletonHarnessRoute } from './widget/harness';\n\nconst CUSTOM_ELEMENT_TAG = 'check24-lp-dealz';\n\nexport default class Check24LpDealzTeaser extends HTMLElement implements HomeClientComponentElement {\n  deviceOutput: HomeClientComponentProps['deviceOutput'] = 'desktop';\n  language: HomeClientComponentProps['language'] = 'de-DE';\n  platform: HomeClientComponentProps['platform'] = 'web';\n\n  onStyleLoaded?: (style: string) => void;\n  onRender?: () => void;\n\n  #shadow: ShadowRoot | null = null;\n  #selectedSort: DealzSort = 'popular';\n  #abort: AbortController | null = null;\n\n  static get observedAttributes(): string[] {\n    return ['device-output', 'language', 'platform', FLAME_URL_ATTR];\n  }\n\n  attributeChangedCallback(): void {\n    this.#readAttributes();\n    if (this.#shadow && !isLayoutCheckHarness() && !isSkeletonHarnessRoute()) {\n      this.#render();\n    }\n  }\n\n  connectedCallback(): void {\n    this.#abort?.abort();\n    this.#abort = new AbortController();\n    const { signal } = this.#abort;\n\n    this.#readAttributes();\n    this.innerHTML = '';\n\n    if (!this.#shadow) {\n      this.#shadow = this.attachShadow({ mode: 'closed' });\n    }\n\n    if (isLayoutCheckHarness() || isSkeletonHarnessRoute()) {\n      this.setAttribute('data-dealz-layout-check', '');\n      this.#shadow.innerHTML = DEALZ_SKELETON_HTML;\n      return;\n    }\n\n    this.removeAttribute('data-dealz-layout-check');\n    this.#syncDeviceClass();\n    this.#render();\n    this.#bindInteractions(signal);\n    this.#bindResponsiveLayout(signal);\n    this.onStyleLoaded?.(DEALZ_HOST_STYLE);\n    this.onRender?.();\n  }\n\n  disconnectedCallback(): void {\n    this.#abort?.abort();\n    this.#abort = null;\n  }\n\n  #readAttributes(): void {\n    if (typeof C24Home !== 'undefined' && C24Home.validateAttributes) {\n      const validated = C24Home.validateAttributes<HomeClientComponentProps>(this.attributes);\n      this.deviceOutput = validated.deviceOutput;\n      this.language = validated.language;\n      this.platform = validated.platform;\n      this.#syncDeviceClass();\n      return;\n    }\n    this.deviceOutput =\n      (this.getAttribute('device-output') as HomeClientComponentProps['deviceOutput']) || 'desktop';\n    this.language = this.getAttribute('language') === 'en-GB' ? 'en-GB' : 'de-DE';\n    this.platform = (this.getAttribute('platform') as HomeClientComponentProps['platform']) || 'web';\n    this.#syncDeviceClass();\n  }\n\n  #syncDeviceClass(): void {\n    const explicitMobileOutput = this.deviceOutput === 'mobile';\n    if (typeof window === 'undefined') {\n      this.classList.toggle('device-mobile', explicitMobileOutput);\n      return;\n    }\n    const viewportMobile = window.matchMedia(`(max-width: ${MOBILE_MAX_PX}px)`).matches;\n    // Only pin mobile layout on wide viewports when device-output is mobile (layout check).\n    this.classList.toggle('device-mobile', explicitMobileOutput && !viewportMobile);\n  }\n\n  #bindResponsiveLayout(signal: AbortSignal): void {\n    if (typeof window === 'undefined') return;\n\n    const viewportMq = window.matchMedia(`(max-width: ${MOBILE_MAX_PX}px)`);\n    viewportMq.addEventListener('change', () => this.#syncDeviceClass(), { signal });\n\n    const bodyObserver = new MutationObserver(() => this.#syncDeviceClass());\n    bodyObserver.observe(document.body, { attributes: true, attributeFilter: ['class'] });\n    signal.addEventListener('abort', () => bodyObserver.disconnect(), { once: true });\n  }\n\n  #isNarrowViewport(): boolean {\n    return typeof window !== 'undefined' && window.matchMedia(`(max-width: ${FORM_MIN_PX - 1}px)`).matches;\n  }\n\n  #render(): void {\n    if (!this.#shadow) return;\n\n    const tabs = TABS.map(\n      (tab) => `\n        <button\n          type=\"button\"\n          class=\"dealz-filter__tab\"\n          data-sort=\"${tab.id}\"\n          role=\"tab\"\n          aria-selected=\"${tab.id === this.#selectedSort ? 'true' : 'false'}\"\n        >${tab.label}</button>`,\n    ).join('');\n\n    this.#shadow.innerHTML = `\n      <style>${DEALZ_HOST_STYLE}</style>\n      <section class=\"dealz-teaser\" part=\"teaser\">\n        <img\n          class=\"dealz-teaser__flame\"\n          src=\"${resolveFlameUrl(this)}\"\n          alt=\"\"\n          width=\"300\"\n          height=\"375\"\n          decoding=\"async\"\n          aria-hidden=\"true\"\n        />\n        <a class=\"dealz-teaser__link\" part=\"link\" href=\"${buildDealzUrl(this.#selectedSort)}\" aria-label=\"${LINK_LABEL}\">\n          <div class=\"dealz-teaser__headline\" part=\"headline\" role=\"heading\" aria-level=\"2\">\n            <div class=\"dealz-teaser__headline-line dealz-teaser__headline-line--die\">DIE</div>\n            <div class=\"dealz-teaser__headline-line dealz-teaser__headline-line--words\">\n              <div class=\"dealz-teaser__headline-word dealz-teaser__headline-word--besten dealz-teaser__headline-word--desktop-only\">BESTEN DEALZ</div>\n              <div class=\"dealz-teaser__headline-word dealz-teaser__headline-word--besten dealz-teaser__headline-word--mobile-only\">BESTEN</div>\n              <div class=\"dealz-teaser__headline-word dealz-teaser__headline-word--dealz dealz-teaser__headline-word--mobile-only\">DEALZ</div>\n            </div>\n          </div>\n        </a>\n        <form class=\"dealz-filter\" part=\"filter\" action=\"${buildDealzUrl(this.#selectedSort)}\" method=\"get\">\n          <div class=\"dealz-filter__tabs\" role=\"tablist\" aria-label=\"Dealz sortieren\">\n            ${tabs}\n          </div>\n          <button class=\"dealz-filter__cta\" type=\"submit\">${CTA_LABEL}</button>\n        </form>\n      </section>\n    `;\n  }\n\n  #bindInteractions(signal: AbortSignal): void {\n    const shadow = this.#shadow;\n    if (!shadow) return;\n\n    const form = shadow.querySelector<HTMLFormElement>('.dealz-filter');\n    const link = shadow.querySelector<HTMLAnchorElement>('.dealz-teaser__link');\n    const tabs = shadow.querySelectorAll<HTMLButtonElement>('.dealz-filter__tab');\n\n    const syncUrls = (): void => {\n      const url = buildDealzUrl(this.#selectedSort);\n      if (form) form.action = url;\n      if (link) link.href = url;\n    };\n\n    tabs.forEach((tab) => {\n      tab.addEventListener(\n        'click',\n        (event) => {\n          event.preventDefault();\n          const sort = tab.dataset.sort as DealzSort | undefined;\n          if (!sort) return;\n          this.#selectedSort = sort;\n          tabs.forEach((item) => {\n            item.setAttribute('aria-selected', item === tab ? 'true' : 'false');\n          });\n          syncUrls();\n        },\n        { signal },\n      );\n    });\n\n    form?.addEventListener(\n      'submit',\n      (event) => {\n        event.preventDefault();\n        window.location.assign(buildDealzUrl(this.#selectedSort));\n      },\n      { signal },\n    );\n\n    if (typeof window !== 'undefined') {\n      const mq = window.matchMedia(`(max-width: ${FORM_MIN_PX - 1}px)`);\n      const onViewportChange = (): void => {\n        if (this.#isNarrowViewport() && link) {\n          link.href = buildDealzUrl(this.#selectedSort);\n        }\n      };\n      mq.addEventListener('change', onViewportChange, { signal });\n    }\n  }\n}\n\n// String literal in define — SlugTagMatchStep (pipeline) parses customElements.define('…', …).\nif (typeof window !== 'undefined' && 'customElements' in window) {\n  if (!customElements.get('check24-lp-dealz')) {\n    customElements.define('check24-lp-dealz', Check24LpDealzTeaser);\n  }\n}\n\nfunction replaceSkeletonWithComponent(): void {\n  document.querySelectorAll(SKELETON_SELECTOR).forEach((el) => {\n    if (el.closest(CUSTOM_ELEMENT_TAG)) return;\n    const parent = el.parentElement;\n    if (!parent) return;\n\n    const wrapper = el.closest(`[${SLOT_MARKER}]`) ?? el;\n    const replacement = document.createElement(CUSTOM_ELEMENT_TAG);\n\n    if (wrapper instanceof HTMLElement) {\n      for (const { name, value } of Array.from(wrapper.attributes)) {\n        if (name === SLOT_MARKER) continue;\n        if (name.startsWith('data-')) {\n          replacement.setAttribute(name.slice('data-'.length), value);\n        }\n      }\n    }\n\n    if (!(wrapper instanceof HTMLElement)) return;\n    wrapper.replaceWith(replacement);\n  });\n}\n\nif (typeof document !== 'undefined') {\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', replaceSkeletonWithComponent);\n  } else {\n    replaceSkeletonWithComponent();\n  }\n}\n"],"names":["_shadow","_selectedSort","_abort","_Check24LpDealzTeaser_instances","readAttributes_fn","syncDeviceClass_fn","bindResponsiveLayout_fn","isNarrowViewport_fn","render_fn","bindInteractions_fn","TABS","id","label","DEALZ_URLS","popular","prod","test","hot","new","buildDealzUrl","sort","isProd","location","hostname","endsWith","url","URL","searchParams","set","toString","resolveAssetUrl","manifestPath","clientBundleUrl","p","trim","replace","pathname","href","e","resolveAssetBaseUrl","FLAME_URL_ATTR","DEALZ_HOST_STYLE","SLOT_MARKER","SKELETON_SHIMMER","SKELETON_HEADLINE_PILLS","DEALZ_SKELETON_HTML","isLayoutCheckHarness","window","startsWith","length","slice","isSkeletonHarnessRoute","CUSTOM_ELEMENT_TAG","Check24LpDealzTeaser","HTMLElement","constructor","super","arguments","__privateAdd","this","deviceOutput","language","platform","__privateSet","observedAttributes","attributeChangedCallback","__privateMethod","call","__privateGet","connectedCallback","_a","_b","_c","abort","AbortController","signal","innerHTML","attachShadow","mode","setAttribute","removeAttribute","onStyleLoaded","onRender","disconnectedCallback","replaceSkeletonWithComponent","document","querySelectorAll","forEach","el","closest","parentElement","wrapper","replacement","createElement","name","value","Array","from","attributes","replaceWith","WeakMap","WeakSet","C24Home","validateAttributes","validated","getAttribute","explicitMobileOutput","classList","toggle","viewportMobile","matchMedia","matches","addEventListener","bodyObserver","MutationObserver","observe","body","attributeFilter","disconnect","once","tabs","map","tab","join","host","fromHost","manifest","flame","resolveFlameUrl","shadow","form","querySelector","link","syncUrls","action","event","preventDefault","dataset","item","assign","onViewportChange","customElements","get","define","readyState"],"mappings":"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"}