{"id":5788,"date":"2026-10-22T15:02:30","date_gmt":"2026-10-22T15:02:30","guid":{"rendered":"https:\/\/tadro.at\/?page_id=5788"},"modified":"2026-10-22T15:16:13","modified_gmt":"2026-10-22T15:16:13","slug":"eshop","status":"publish","type":"page","link":"https:\/\/tadro.at\/en\/eshop\/","title":{"rendered":"eshop"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"5788\" class=\"elementor elementor-5788\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8e4f1c3 e-flex e-con-boxed parallax_section_no qode_elementor_container_no e-con e-parent\" data-id=\"8e4f1c3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ff9ce32 elementor-widget elementor-widget-html\" data-id=\"ff9ce32\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- =======================\r\nTADRO E-SHOP (WOOCOMMERCE PRICES + STOCK + FILTER + SEARCH)\r\nPaste into a Custom HTML block on the Products page\r\n======================== -->\r\n\r\n<section class=\"tadro-about\" aria-label=\"\u00dcber Tadro\">\r\n  <div class=\"tadro-about__inner\">\r\n\r\n    <!-- HERO IMAGE -->\r\n    <div class=\"tadro-about__hero\">\r\n      <img decoding=\"async\" src=\"https:\/\/tadro.at\/wp-content\/uploads\/2026\/03\/hero-about.png\" alt=\"Tadro Qualit\u00e4t\">\r\n    <\/div>\r\n\r\n    <h1 class=\"tadro-about__title\">E-Shop<\/h1>\r\n\r\n    <p class=\"tadro-about__lead\">\r\n      TADRO ist eine \u00f6sterreichische Premium-Marke f\u00fcr Nahrungserg\u00e4nzungsmittel und funktionelle Gesundheitsl\u00f6sungen.\r\n    <\/p>\r\n\r\n    <p class=\"tadro-about__p\">\r\n      Wir arbeiten mit \u00c4rzt:innen, Pharmazeut:innen und Ern\u00e4hrungswissenschaftler:innen zusammen,\r\n      um moderne, alltagstaugliche Formulierungen zu schaffen.\r\n    <\/p>\r\n\r\n    <p class=\"tadro-about__p\">\r\n      Unsere Mission ist es, Produkte zu entwickeln, die wirksam, vertr\u00e4glich,\r\n      verst\u00e4ndlich und vertrauensw\u00fcrdig sind.\r\n    <\/p>\r\n\r\n    <div class=\"tadro-about__divider\"><\/div>\r\n\r\n    <!-- CATALOG HEADER -->\r\n    <section class=\"tadro-favs\" aria-label=\"E-Shop \u2013 Produkte\">\r\n      <div class=\"tadro-favs__inner\">\r\n\r\n        <div class=\"tadro-favs__eyebrow\">E-Shop<\/div>\r\n        <h2 class=\"tadro-favs__title\">Alle Produkte<\/h2>\r\n\r\n        <!-- FILTER BAR -->\r\n        <div class=\"tadro-filter\" role=\"search\">\r\n          <div class=\"tadro-filter__row\">\r\n            <div class=\"tadro-filter__field\">\r\n              <label class=\"tadro-filter__label\" for=\"tadroSearch\">Suche<\/label>\r\n              <input id=\"tadroSearch\" class=\"tadro-filter__input\" type=\"search\" placeholder=\"Produktname suchen\u2026\">\r\n            <\/div>\r\n\r\n            <div class=\"tadro-filter__field\">\r\n              <label class=\"tadro-filter__label\" for=\"tadroCategory\">Kategorie<\/label>\r\n              <select id=\"tadroCategory\" class=\"tadro-filter__select\">\r\n                <option value=\"\">Alle Kategorien<\/option>\r\n              <\/select>\r\n            <\/div>\r\n\r\n            <button id=\"tadroReset\" class=\"tadro-filter__btn\" type=\"button\">Zur\u00fccksetzen<\/button>\r\n          <\/div>\r\n\r\n          <div class=\"tadro-filter__meta\">\r\n            <span id=\"tadroCount\" role=\"status\" aria-live=\"polite\">\u2014<\/span>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <!-- GRID -->\r\n        <div class=\"tadro-favs__grid\" id=\"tadroProductsGrid\" aria-busy=\"true\">\r\n          <div class=\"tadro-favs__status\" id=\"tadroStatus\">Lade Produkte\u2026<\/div>\r\n        <\/div>\r\n\r\n      <\/div>\r\n    <\/section>\r\n\r\n  <\/div>\r\n<\/section>\r\n\r\n<style>\r\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Cinzel+Decorative:wght@400&display=swap');\r\n\r\n.tadro-about{\r\n  --tadro-bg:#f6f0e8;\r\n  --tadro-bg-2:#f1e7da;\r\n  --tadro-ink:#402d1d;\r\n  --tadro-gold:#d8c08a;\r\n}\r\n\r\n\/* ============== ABOUT (TOP) ============== *\/\r\n.tadro-about{\r\n  width:100vw;\r\n  margin-left:calc(50% - 50vw);\r\n  background:var(--tadro-bg);\r\n  padding:clamp(40px,6vw,90px) 0;\r\n}\r\n.tadro-about__inner{\r\n  width:min(1100px,92vw);\r\n  margin:0 auto;\r\n}\r\n.tadro-about__hero{ margin-bottom:30px; }\r\n.tadro-about__hero img{\r\n  width:100%;\r\n  height:400px;\r\n  object-fit:cover;\r\n  border-radius:8px;\r\n}\r\n.tadro-about__title{\r\n  font-family:'Cinzel Decorative',serif;\r\n  font-size:clamp(34px,4vw,64px);\r\n  letter-spacing:.16em;\r\n  color:var(--tadro-ink);\r\n  margin:0 0 20px;\r\n}\r\n.tadro-about__lead,\r\n.tadro-about__p{\r\n  font-family:'Cinzel Decorative',serif;\r\n  color:rgba(64,45,29,.88);\r\n  line-height:1.95;\r\n  font-size:15px;\r\n  margin:0 0 14px;\r\n  max-width: 980px;\r\n}\r\n.tadro-about__divider{\r\n  height:1px;\r\n  background:linear-gradient(90deg,transparent,var(--tadro-gold),transparent);\r\n  margin:30px 0;\r\n}\r\n\r\n\/* ============== PRODUCTS SECTION ============== *\/\r\n.tadro-favs{\r\n  background: var(--tadro-bg-2);\r\n  border-radius: 14px;\r\n  padding: clamp(42px, 5vw, 80px) 0;\r\n  box-shadow: 0 18px 50px rgba(0,0,0,.06);\r\n}\r\n.tadro-favs__inner{\r\n  width: calc(100% - 40px);\r\n  margin: 0 auto;\r\n  text-align: center;\r\n}\r\n.tadro-favs__eyebrow{\r\n  font-family: 'Cinzel Decorative', serif;\r\n  font-weight: 400;\r\n  letter-spacing: .18em;\r\n  color: rgba(64,45,29,0.55);\r\n  margin: 0 0 10px;\r\n  font-size: 16px;\r\n  text-transform: none !important;\r\n}\r\n.tadro-favs__title{\r\n  font-family: 'Cinzel Decorative', serif;\r\n  font-weight: 400;\r\n  letter-spacing: .16em;\r\n  color: var(--tadro-ink);\r\n  margin: 0 0 clamp(18px, 2.5vw, 34px);\r\n  font-size: clamp(28px, 3.1vw, 58px);\r\n  text-transform: none !important;\r\n}\r\n\r\n\/* Filter bar *\/\r\n.tadro-filter{\r\n  width: min(860px, 100%);\r\n  margin: 0 auto clamp(26px, 3vw, 40px);\r\n  text-align: left;\r\n  background: rgba(255,255,255,.42);\r\n  border: 1px solid rgba(64,45,29,.12);\r\n  border-radius: 14px;\r\n  padding: 18px;\r\n  box-shadow: 0 10px 30px rgba(0,0,0,.04);\r\n}\r\n.tadro-filter__row{\r\n  display: grid;\r\n  grid-template-columns: 1.4fr 1fr auto;\r\n  gap: 14px;\r\n  align-items: end;\r\n}\r\n.tadro-filter__field{ display:flex; flex-direction:column; gap:6px; }\r\n.tadro-filter__label{\r\n  font-family: 'Cinzel Decorative', serif;\r\n  letter-spacing: .12em;\r\n  color: rgba(64,45,29,0.75);\r\n  font-size: 12px;\r\n}\r\n.tadro-filter__input,\r\n.tadro-filter__select{\r\n  font-family: 'Cinzel Decorative', serif;\r\n  letter-spacing: .06em;\r\n  color: var(--tadro-ink);\r\n  background: rgba(255,255,255,.62);\r\n  border: 1px solid rgba(64,45,29,.18);\r\n  border-radius: 12px;\r\n  padding: 13px 14px;\r\n  outline: none;\r\n}\r\n.tadro-filter__input:focus,\r\n.tadro-filter__select:focus{\r\n  border-color: rgba(216,192,138,.95);\r\n  box-shadow: 0 0 0 3px rgba(216,192,138,.25);\r\n}\r\n.tadro-filter__btn{\r\n  font-family: 'Cinzel Decorative', serif;\r\n  letter-spacing: .10em;\r\n  color: var(--tadro-ink);\r\n  background: rgba(255,255,255,.62);\r\n  border: 1px solid rgba(64,45,29,.18);\r\n  border-radius: 999px;\r\n  padding: 12px 18px;\r\n  cursor: pointer;\r\n  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;\r\n}\r\n.tadro-filter__btn:hover{\r\n  transform: translateY(-1px);\r\n  border-color: rgba(216,192,138,.95);\r\n  box-shadow: 0 10px 20px rgba(0,0,0,.06);\r\n}\r\n.tadro-filter__meta{\r\n  margin-top: 10px;\r\n  font-family: 'Cinzel Decorative', serif;\r\n  letter-spacing: .08em;\r\n  color: rgba(64,45,29,.62);\r\n  font-size: 12px;\r\n}\r\n\r\n\/* \u2705 GRID: 3 PRODUCTS PER ROW (desktop) *\/\r\n.tadro-favs__grid{\r\n  width: 100%;\r\n  margin: 0 auto;\r\n  display: grid;\r\n  grid-template-columns: repeat(3, minmax(0, 1fr));\r\n  gap: clamp(26px, 2.6vw, 46px);\r\n  align-items: stretch;\r\n  justify-items: center;\r\n}\r\n.tadro-favs__item{\r\n  width: 100%;\r\n  max-width: 320px;\r\n  text-align: center;\r\n  display: flex;\r\n  flex-direction: column;\r\n  align-items: center;\r\n}\r\n.tadro-favs__link{\r\n  display: inline-block;\r\n  text-decoration: none;\r\n}\r\n.tadro-favs__img{\r\n  width: clamp(190px, 15vw, 245px);\r\n  height: 285px;\r\n  max-width: 100%;\r\n  object-fit: contain;\r\n  display: block;\r\n  margin: 0 auto 18px;\r\n  background: transparent !important;\r\n  box-shadow: none !important;\r\n  border: 0 !important;\r\n  filter: drop-shadow(0 18px 28px rgba(0,0,0,0.14));\r\n  transition: transform .18s ease, filter .18s ease;\r\n}\r\n.tadro-favs__link:hover .tadro-favs__img{\r\n  transform: translateY(-4px);\r\n  filter: drop-shadow(0 22px 34px rgba(0,0,0,0.18));\r\n}\r\n.tadro-favs__name{\r\n  font-family: 'Cinzel Decorative', serif;\r\n  font-weight: 400;\r\n  letter-spacing: .12em;\r\n  text-transform: uppercase;\r\n  color: rgba(64,45,29,0.85);\r\n  font-size: 16px;\r\n  line-height: 1.35;\r\n  margin: 0;\r\n}\r\n.tadro-favs__status{\r\n  grid-column: 1 \/ -1;\r\n  color: rgba(64,45,29,0.7);\r\n  font-family: 'Cinzel Decorative', serif;\r\n  letter-spacing: .08em;\r\n  padding: 10px 0;\r\n  text-align: center;\r\n}\r\n\r\n\r\n\/* E-shop details: price and availability use live WooCommerce data. *\/\r\n.tadro-about *, .tadro-about *::before, .tadro-about *::after{box-sizing:border-box;}\r\n.tadro-filter__field{min-width:0;}\r\n.tadro-filter__input, .tadro-filter__select{width:100%;min-width:0;}\r\n.tadro-favs__details{width:100%;margin-top:auto;}\r\n.tadro-favs__heading{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;gap:10px;margin:0 0 12px;}\r\n.tadro-favs__name{overflow-wrap:anywhere;}\r\n.tadro-favs__name a{color:inherit;text-decoration:none;}\r\n.tadro-favs__name a:hover{text-decoration:underline;text-underline-offset:4px;}\r\n.tadro-favs__stock{display:inline-flex;align-items:center;gap:6px;border:1px solid transparent;border-radius:999px;padding:5px 9px;font:500 11px\/1.4 Arial,sans-serif;letter-spacing:.02em;white-space:nowrap;}\r\n.tadro-favs__stock::before{content:\"\";width:6px;height:6px;border-radius:50%;background:currentColor;flex-shrink:0;}\r\n.tadro-favs__stock--in{color:#386046;background:#e8eee4;border-color:#cbd8c5;}\r\n.tadro-favs__stock--out{color:#8a493b;background:#f3e5df;border-color:#e3c7bc;}\r\n.tadro-favs__stock--backorder{color:#7b5b24;background:#f4ead3;border-color:#dfcca3;}\r\n.tadro-favs__stock--unknown{color:#655d53;background:#eee8df;border-color:#d8d0c3;}\r\n.tadro-favs__price{display:flex;justify-content:center;align-items:baseline;flex-wrap:wrap;gap:9px;min-height:30px;margin:0 0 16px;color:var(--tadro-ink);font:600 22px\/1.4 Arial,sans-serif;}\r\n.tadro-favs__price del{color:#796f62;font-size:15px;font-weight:400;}\r\n.tadro-favs__price ins{color:var(--tadro-ink);background:none;text-decoration:none;}\r\n.tadro-favs__price-note{font-size:14px;font-weight:400;}\r\n.tadro-favs__button{display:inline-flex;justify-content:center;align-items:center;min-height:44px;padding:11px 20px;border:1px solid rgba(64,45,29,.26);border-radius:999px;background:rgba(255,255,255,.45);color:var(--tadro-ink);font:400 12px\/1.5 'Cinzel Decorative',serif;letter-spacing:.06em;text-decoration:none;transition:background .18s,border-color .18s;}\r\n.tadro-favs__button:hover{background:rgba(255,255,255,.8);border-color:var(--tadro-gold);color:var(--tadro-ink);}\r\n.tadro-about a:focus-visible,.tadro-about button:focus-visible{outline:2px solid var(--tadro-ink);outline-offset:4px;}\r\n.tadro-favs__placeholder{width:235px;max-width:100%;height:285px;display:grid;place-items:center;color:var(--tadro-ink);font:14px Arial,sans-serif;}\r\n@media(prefers-reduced-motion:reduce){.tadro-about *{transition:none!important;}}\r\n\r\n\/* ============== RESPONSIVE ============== *\/\r\n@media (max-width: 1024px){\r\n  .tadro-favs__grid{\r\n    grid-template-columns: repeat(2, minmax(0, 1fr));\r\n  }\r\n  .tadro-filter__row{\r\n    grid-template-columns: 1fr 1fr;\r\n  }\r\n  #tadroReset{\r\n    grid-column: 1 \/ -1;\r\n    justify-self: start;\r\n  }\r\n  .tadro-about__hero img{\r\n    height: 300px;\r\n  }\r\n}\r\n\r\n@media (max-width: 767px){\r\n  .tadro-favs__grid{\r\n    grid-template-columns: 1fr;\r\n  }\r\n  .tadro-filter__row{\r\n    grid-template-columns: 1fr;\r\n  }\r\n  .tadro-favs__img{\r\n    width: 235px;\r\n  }\r\n  .tadro-about__hero img{\r\n    height:260px;\r\n  }\r\n}\r\n<\/style>\r\n\r\n<script>\r\n(async function(){\r\n  const grid = document.getElementById(\"tadroProductsGrid\");\r\n  const statusEl = document.getElementById(\"tadroStatus\");\r\n  const searchEl = document.getElementById(\"tadroSearch\");\r\n  const categoryEl = document.getElementById(\"tadroCategory\");\r\n  const resetEl = document.getElementById(\"tadroReset\");\r\n  const countEl = document.getElementById(\"tadroCount\");\r\n  if(!grid || !statusEl || !searchEl || !categoryEl || !resetEl || !countEl) return;\r\n\r\n  const PER_PAGE = 100;\r\n\r\n\r\n  let allProducts = [];\r\n\r\n  function cleanText(html){\r\n    const doc = new DOMParser().parseFromString(String(html || \"\"), \"text\/html\");\r\n    return (doc.body.textContent || \"\").trim();\r\n  }\r\n  function escapeHtml(value){\r\n    return String(value ?? \"\").replace(\/[&<>\"']\/g, char => ({\r\n      \"&\":\"&amp;\", \"<\":\"&lt;\", \">\":\"&gt;\", '\"':\"&quot;\", \"'\":\"&#39;\"\r\n    })[char]);\r\n  }\r\n  function safeUrl(value){\r\n    if(!value) return \"\";\r\n    try{\r\n      const url = new URL(value, window.location.href);\r\n      return [\"http:\", \"https:\"].includes(url.protocol) ? url.href : \"\";\r\n    }catch(error){ return \"\"; }\r\n  }\r\n  function getImg(p){\r\n    return safeUrl(p.images?.[0]?.src);\r\n  }\r\n  function money(raw, prices){\r\n    if(raw === null || raw === undefined || raw === \"\") return \"\";\r\n    const minor = Number(prices.currency_minor_unit ?? 2);\r\n    const amount = Number(raw) \/ Math.pow(10, minor);\r\n    if(!Number.isFinite(amount)) return \"\";\r\n    try{\r\n      return new Intl.NumberFormat(\"de-AT\", {\r\n        style:\"currency\", currency:prices.currency_code || \"EUR\",\r\n        minimumFractionDigits:minor, maximumFractionDigits:minor\r\n      }).format(amount);\r\n    }catch(error){ return amount.toFixed(minor); }\r\n  }\r\n  function priceHtml(p){\r\n    const prices = p.prices || {};\r\n    const range = prices.price_range;\r\n    if(range && range.min_amount != null && range.max_amount != null &&\r\n       String(range.min_amount) !== String(range.max_amount)){\r\n      return escapeHtml(money(range.min_amount, prices)) + \" \u2013 \" +\r\n             escapeHtml(money(range.max_amount, prices));\r\n    }\r\n    const current = money(prices.price, prices);\r\n    if(!current) return '<span class=\"tadro-favs__price-note\">Preis auf Anfrage<\/span>';\r\n    const regular = money(prices.regular_price, prices);\r\n    if(p.on_sale && regular && Number(prices.regular_price) > Number(prices.price)){\r\n      return '<del aria-label=\"Bisheriger Preis\">' + escapeHtml(regular) +\r\n        '<\/del><ins aria-label=\"Aktueller Preis\">' + escapeHtml(current) + '<\/ins>';\r\n    }\r\n    return escapeHtml(current);\r\n  }\r\n  function stockInfo(p){\r\n    if(p.is_on_backorder === true) return {type:\"backorder\", label:\"Nachbestellbar\"};\r\n    if(p.is_in_stock === true) return {type:\"in\", label:\"Auf Lager\"};\r\n    if(p.is_in_stock === false) return {type:\"out\", label:\"Nicht auf Lager\"};\r\n    return {type:\"unknown\", label:\"Verf\u00fcgbarkeit pr\u00fcfen\"};\r\n  }\r\n\r\n  \/\/ Build candidate base paths from current URL\r\n  function buildCandidateBases(){\r\n    const path = window.location.pathname.replace(\/\\\/+$\/, \"\");\r\n    const parts = path.split(\"\/\").filter(Boolean);\r\n\r\n    \/\/ Try: \"\" (root), then progressively shorter prefixes from the current path\r\n    const candidates = new Set();\r\n    candidates.add(\"\"); \/\/ root install\r\n\r\n    \/\/ Example: \/demo\/tadro\/produkte -> tries \/demo\/tadro, \/demo\r\n    if(parts.length >= 2) candidates.add(\"\/\" + parts.slice(0,2).join(\"\/\"));\r\n    if(parts.length >= 1) candidates.add(\"\/\" + parts.slice(0,1).join(\"\/\"));\r\n\r\n    \/\/ also try full first 3 segments if you have deeper installs\r\n    if(parts.length >= 3) candidates.add(\"\/\" + parts.slice(0,3).join(\"\/\"));\r\n\r\n    return Array.from(candidates);\r\n  }\r\n\r\n  async function probeBase(base){\r\n    const url = `${base}\/wp-json\/wc\/store\/v1\/products?per_page=1`;\r\n    const res = await fetch(url, { credentials: \"same-origin\", cache: \"no-store\", signal: AbortSignal.timeout(15000) });\r\n    if(!res.ok) return null;\r\n    const data = await res.json();\r\n    return Array.isArray(data) ? base : null;\r\n  }\r\n\r\n  async function detectBase(){\r\n    const bases = buildCandidateBases();\r\n    for(const base of bases){\r\n      try{\r\n        const ok = await probeBase(base);\r\n        if(ok !== null) return ok;\r\n      } catch(e){}\r\n    }\r\n    return null;\r\n  }\r\n\r\n  async function fetchProductsPage(base, page){\r\n    const url = `${base}\/wp-json\/wc\/store\/v1\/products?per_page=${PER_PAGE}&page=${page}&orderby=menu_order&order=asc`;\r\n    const res = await fetch(url, { credentials: \"same-origin\", cache: \"no-store\", signal: AbortSignal.timeout(15000) });\r\n    if(!res.ok) throw new Error(`HTTP ${res.status} fetching products`);\r\n    const items = await res.json();\r\n    if(!Array.isArray(items)) throw new Error(\"Invalid product response\");\r\n    const total = Number(res.headers.get(\"X-WP-TotalPages\"));\r\n    return {items, totalPages:Number.isInteger(total) && total > 0 ? total : null};\r\n  }\r\n\r\n  function populateCategoryDropdown(products){\r\n    const map = new Map();\r\n    for(const p of products){\r\n      for(const c of (p.categories || [])){\r\n        const slug = String(c.slug || \"\").trim();\r\n        const name = cleanText(c.name);\r\n        if(slug && !map.has(slug)) map.set(slug, name);\r\n      }\r\n    }\r\n    const cats = Array.from(map.entries()).sort((a,b)=>a[1].localeCompare(b[1], \"de\"));\r\n    categoryEl.innerHTML =\r\n      `<option value=\"\">Alle Kategorien<\/option>` +\r\n      cats.map(([slug,name]) => `<option value=\"${escapeHtml(slug)}\">${escapeHtml(name)}<\/option>`).join(\"\");\r\n  }\r\n\r\n  function matchesFilters(p){\r\n    const q = searchEl.value.trim().toLowerCase();\r\n    const selectedCat = categoryEl.value.trim().toLowerCase();\r\n\r\n    const name = cleanText(p.name).toLowerCase();\r\n    const shortDesc = cleanText(p.short_description).toLowerCase();\r\n    const desc = cleanText(p.description).toLowerCase();\r\n\r\n    const textMatch = !q || name.includes(q) || shortDesc.includes(q) || desc.includes(q);\r\n\r\n    let catMatch = true;\r\n    if(selectedCat){\r\n      catMatch = (p.categories || []).some(c => String(c.slug || \"\").toLowerCase() === selectedCat);\r\n    }\r\n    return textMatch && catMatch;\r\n  }\r\n\r\n  function render(){\r\n    const filtered = allProducts.filter(matchesFilters);\r\n    countEl.textContent = `${filtered.length} Produkt(e) gefunden`;\r\n\r\n    if(filtered.length === 0){\r\n      grid.innerHTML = `<div class=\"tadro-favs__status\">Keine Produkte gefunden.<\/div>`;\r\n      return;\r\n    }\r\n\r\n    \/\/ Build links with DOM properties. No dynamic href strings in HTML markup.\r\n    const fragment = document.createDocumentFragment();\r\n    filtered.forEach(p => {\r\n      const name = cleanText(p.name);\r\n      const link = safeUrl(p.permalink);\r\n      const img = getImg(p);\r\n      const stock = stockInfo(p);\r\n      const buttonText = p.has_options ? \"Optionen w\u00e4hlen\" : \"Zum Produkt\";\r\n      const card = document.createElement(\"article\");\r\n      card.className = \"tadro-favs__item\";\r\n\r\n      function productLink(className, label){\r\n        const element = document.createElement(link ? \"a\" : \"span\");\r\n        element.className = className;\r\n        if(link) element.href = link;\r\n        if(label) element.setAttribute(\"aria-label\", label);\r\n        return element;\r\n      }\r\n\r\n      const imageLink = productLink(\"tadro-favs__link\", name);\r\n      if(img){\r\n        const image = document.createElement(\"img\");\r\n        image.className = \"tadro-favs__img\";\r\n        image.src = img;\r\n        image.alt = name;\r\n        image.loading = \"lazy\";\r\n        image.decoding = \"async\";\r\n        imageLink.appendChild(image);\r\n      }else{\r\n        const placeholder = document.createElement(\"div\");\r\n        placeholder.className = \"tadro-favs__placeholder\";\r\n        placeholder.textContent = \"Kein Produktbild\";\r\n        imageLink.appendChild(placeholder);\r\n      }\r\n      card.appendChild(imageLink);\r\n\r\n      const details = document.createElement(\"div\");\r\n      details.className = \"tadro-favs__details\";\r\n      const heading = document.createElement(\"div\");\r\n      heading.className = \"tadro-favs__heading\";\r\n      const title = document.createElement(\"h3\");\r\n      title.className = \"tadro-favs__name\";\r\n      const titleLink = productLink(\"\", \"\");\r\n      titleLink.textContent = name;\r\n      title.appendChild(titleLink);\r\n      heading.appendChild(title);\r\n      const badge = document.createElement(\"span\");\r\n      badge.className = \"tadro-favs__stock tadro-favs__stock--\" + stock.type;\r\n      badge.textContent = stock.label;\r\n      heading.appendChild(badge);\r\n      details.appendChild(heading);\r\n\r\n      const price = document.createElement(\"div\");\r\n      price.className = \"tadro-favs__price\";\r\n      price.innerHTML = priceHtml(p);\r\n      details.appendChild(price);\r\n      if(link){\r\n        const button = productLink(\"tadro-favs__button\", buttonText + \": \" + name);\r\n        button.textContent = buttonText;\r\n        details.appendChild(button);\r\n      }\r\n      card.appendChild(details);\r\n      fragment.appendChild(card);\r\n    });\r\n    grid.replaceChildren(fragment);\r\n  }\r\n\r\n  function debounce(fn, wait){\r\n    let t; return (...args) => { clearTimeout(t); t = setTimeout(()=>fn(...args), wait); };\r\n  }\r\n  const rerender = debounce(render, 150);\r\n\r\n  searchEl.addEventListener(\"input\", rerender);\r\n  categoryEl.addEventListener(\"change\", render);\r\n  resetEl.addEventListener(\"click\", () => {\r\n    searchEl.value = \"\";\r\n    categoryEl.value = \"\";\r\n    render();\r\n  });\r\n\r\n  try{\r\n    statusEl.textContent = \"Lade Produkte\u2026\";\r\n\r\n    const BASE = await detectBase();\r\n    if(BASE === null){\r\n      throw new Error(\"Store API not reachable. wp-json might be blocked or base path unknown.\");\r\n    }\r\n\r\n    let loaded = [];\r\n    for(let page=1; ; page++){\r\n      const {items, totalPages} = await fetchProductsPage(BASE, page);\r\n      if(!Array.isArray(items) || items.length === 0) break;\r\n      loaded = loaded.concat(items);\r\n      if((totalPages && page >= totalPages) || (!totalPages && items.length < PER_PAGE)) break;\r\n    }\r\n\r\n    allProducts = loaded;\r\n\r\n    if(allProducts.length === 0){\r\n      grid.innerHTML = `<div class=\"tadro-favs__status\">Keine Produkte gefunden.<\/div>`;\r\n      countEl.textContent = `0 Produkt(e) gefunden`;\r\n      return;\r\n    }\r\n\r\n    populateCategoryDropdown(allProducts);\r\n    render();\r\n\r\n  }catch(e){\r\n    console.error(\"Tadro Products error:\", e);\r\n    grid.innerHTML = `<div class=\"tadro-favs__status\">Fehler beim Laden der Produkte.<\/div>`;\r\n    countEl.textContent = `\u2014`;\r\n  }finally{\r\n    grid.setAttribute(\"aria-busy\", \"false\");\r\n  }\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>E-Shop TADRO ist eine \u00f6sterreichische Premium-Marke f\u00fcr Nahrungserg\u00e4nzungsmittel und funktionelle Gesundheitsl\u00f6sungen. Wir arbeiten mit \u00c4rzt:innen, Pharmazeut:innen und Ern\u00e4hrungswissenschaftler:innen zusammen, um moderne, alltagstaugliche Formulierungen zu schaffen. Unsere Mission ist es, Produkte zu entwickeln, die wirksam, vertr\u00e4glich, verst\u00e4ndlich und vertrauensw\u00fcrdig sind. E-Shop Alle Produkte Suche Kategorie Alle Kategorien Zur\u00fccksetzen \u2014 Lade Produkte\u2026<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"class_list":["post-5788","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/pages\/5788","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/comments?post=5788"}],"version-history":[{"count":7,"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/pages\/5788\/revisions"}],"predecessor-version":[{"id":5795,"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/pages\/5788\/revisions\/5795"}],"wp:attachment":[{"href":"https:\/\/tadro.at\/en\/wp-json\/wp\/v2\/media?parent=5788"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}