{"id":810,"date":"2026-05-07T15:04:12","date_gmt":"2026-05-07T15:04:12","guid":{"rendered":"https:\/\/browseshop.shop\/?page_id=810"},"modified":"2026-05-08T09:10:02","modified_gmt":"2026-05-08T09:10:02","slug":"shops","status":"publish","type":"page","link":"https:\/\/browseshop.shop\/pl\/shops\/","title":{"rendered":"Shop"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"810\" class=\"elementor elementor-810\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3286b0b e-flex e-con-boxed e-con e-parent\" data-id=\"3286b0b\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ekit_has_onepagescroll_dot&quot;:&quot;yes&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f0e72cb elementor-widget elementor-widget-html\" data-id=\"f0e72cb\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!doctype html>\r\n<html lang=\"en\">\r\n<head>\r\n  <meta charset=\"UTF-8\">\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n  <title>Shop \u00b7 SparkNest<\/title>\r\n  <link rel=\"stylesheet\" href=\"page.css\">\r\n<\/head>\r\n<!--\r\n  WooCommerce Store API: set data-store-api-root on <body> when this page is not served from the same URL as WordPress.\r\n  - Example: data-store-api-root=\"https:\/\/your-shop.com\" or \"https:\/\/your-shop.com\/wp\"\r\n  - Same host as WP: omit the attribute (uses window.location.origin), or data-store-api-root=\"\" if your theme injects it empty.\r\n  Filters + product grid call \/wp-json\/wc\/store\/v1\/products; cart-bridge.js uses the same base for add-to-cart (needs cookies + nonce when embedded in WP).\r\n-->\r\n<body class=\"wf-body\">\r\n  <header class=\"wf-header\">\r\n    <div class=\"wf-header-inner\">\r\n      <a class=\"wf-logo\">SparkNest<\/a>\r\n      <nav class=\"wf-nav\" aria-label=\"Quick links\">\r\n     \r\n      <\/nav>\r\n    <\/div>\r\n  <\/header>\r\n\r\n  <main class=\"wf-main wf-main--wide\">\r\n    <div class=\"wf-page-heading\">\r\n      <h1>Shop<\/h1>\r\n    <\/div>\r\n\r\n    <div class=\"layout-archive\">\r\n      <aside class=\"layout-archive__sidebar\" aria-label=\"Shop filters\">\r\n        <h2 class=\"layout-archive__sidebar-title\">Filters<\/h2>\r\n        <form id=\"shop-filter-form\" class=\"shop-filter-form\">\r\n          <label class=\"shop-filter-field\">\r\n            <span>Keyword<\/span>\r\n            <input type=\"search\" name=\"q\" placeholder=\"Search products\">\r\n          <\/label>\r\n\r\n          <label class=\"shop-filter-field\">\r\n            <span>Category<\/span>\r\n            <select name=\"category\">\r\n              <option value=\"\">All categories<\/option>\r\n            <\/select>\r\n          <\/label>\r\n\r\n          <div class=\"shop-filter-row\">\r\n            <label class=\"shop-filter-field\">\r\n              <span>Min $<\/span>\r\n              <input type=\"number\" name=\"min\" min=\"0\" step=\"0.01\" inputmode=\"decimal\" placeholder=\"0\">\r\n            <\/label>\r\n            <label class=\"shop-filter-field\">\r\n              <span>Max $<\/span>\r\n              <input type=\"number\" name=\"max\" min=\"0\" step=\"0.01\" inputmode=\"decimal\" placeholder=\"100\">\r\n            <\/label>\r\n          <\/div>\r\n\r\n          <label class=\"shop-filter-field\">\r\n            <span>Sort<\/span>\r\n            <select name=\"sort\">\r\n              <option value=\"newest\">Newest<\/option>\r\n              <option value=\"price_asc\">Price: Low to High<\/option>\r\n              <option value=\"price_desc\">Price: High to Low<\/option>\r\n              <option value=\"popularity\">Best selling<\/option>\r\n              <option value=\"rating\">Top rated<\/option>\r\n            <\/select>\r\n          <\/label>\r\n\r\n          <div class=\"page-actions shop-filter-actions\">\r\n            <button type=\"submit\">Apply<\/button>\r\n            <button type=\"button\" class=\"secondary\" id=\"shop-filter-reset\">Reset<\/button>\r\n          <\/div>\r\n        <\/form>\r\n      <\/aside>\r\n\r\n      <section class=\"layout-archive__main\" aria-label=\"Product listing\">\r\n        <h2 class=\"layout-archive__heading\">All products<\/h2>\r\n        <p class=\"layout-archive__lead\" id=\"shop-meta\">Loading products...<\/p>\r\n        <div class=\"loop-grid\" id=\"shop-grid\" role=\"list\"><\/div>\r\n        <div class=\"page-actions\" id=\"shop-pagination\">\r\n          <button type=\"button\" class=\"secondary\" id=\"shop-prev\">Previous<\/button>\r\n          <button type=\"button\" id=\"shop-next\">Next<\/button>\r\n        <\/div>\r\n      <\/section>\r\n    <\/div>\r\n  <\/main>\r\n  <script src=\"..\/main-layout-parts\/cart-bridge.js\"><\/script>\r\n  <script>\r\n(() => {\r\n  const body = document.body;\r\n  const fromAttr = body?.dataset?.storeApiRoot?.trim();\r\n  const storeBase = fromAttr\r\n    ? fromAttr.replace(\/\\\/$\/, \"\")\r\n    : (window.location.protocol === \"file:\" ? \"\" : window.location.origin.replace(\/\\\/$\/, \"\"));\r\n  const API_ROOT = storeBase ? `${storeBase}\/wp-json\/wc\/store\/v1` : \"\";\r\n  const LIMIT = 12;\r\n\r\n  const form = document.getElementById(\"shop-filter-form\");\r\n  const resetBtn = document.getElementById(\"shop-filter-reset\");\r\n  const grid = document.getElementById(\"shop-grid\");\r\n  const meta = document.getElementById(\"shop-meta\");\r\n  const prevBtn = document.getElementById(\"shop-prev\");\r\n  const nextBtn = document.getElementById(\"shop-next\");\r\n  const catSelect = form.elements.category;\r\n\r\n  let page = 1;\r\n  let totalPages = 1;\r\n  let totalItems = 0;\r\n\r\n  const sortPreset = {\r\n    newest: { orderby: \"date\", order: \"desc\" },\r\n    price_asc: { orderby: \"price\", order: \"asc\" },\r\n    price_desc: { orderby: \"price\", order: \"desc\" },\r\n    popularity: { orderby: \"popularity\", order: \"desc\" },\r\n    rating: { orderby: \"rating\", order: \"desc\" },\r\n  };\r\n\r\n  const esc = (s) =>\r\n    String(s || \"\").replace(\/[&<>\"']\/g, (ch) => ({\r\n      \"&\": \"&amp;\",\r\n      \"<\": \"&lt;\",\r\n      \">\": \"&gt;\",\r\n      \"\\\"\": \"&quot;\",\r\n      \"'\": \"&#39;\",\r\n    }[ch]));\r\n\r\n  const money = (cents, currency) => {\r\n    const value = Number(cents || 0) \/ 100;\r\n    if (!Number.isFinite(value)) return \"\";\r\n    try {\r\n      return new Intl.NumberFormat(undefined, { style: \"currency\", currency: currency || \"USD\" }).format(value);\r\n    } catch {\r\n      return `$${value.toFixed(2)}`;\r\n    }\r\n  };\r\n\r\n  const priceToMinor = (v) => {\r\n    if (!v) return \"\";\r\n    const n = Number(v);\r\n    if (!Number.isFinite(n) || n < 0) return \"\";\r\n    return String(Math.round(n * 100));\r\n  };\r\n\r\n  const setPagination = () => {\r\n    prevBtn.disabled = page <= 1;\r\n    nextBtn.disabled = page >= totalPages;\r\n  };\r\n\r\n  const renderStatus = (message) => {\r\n    grid.innerHTML = `<article class=\"loop-card\" role=\"listitem\"><div class=\"loop-card__body\"><h3 class=\"loop-card__title\">${esc(message)}<\/h3><\/div><\/article>`;\r\n    setPagination();\r\n  };\r\n\r\n  const renderProducts = (products) => {\r\n    if (!Array.isArray(products) || products.length === 0) {\r\n      renderStatus(\"No products found for this filter.\");\r\n      return;\r\n    }\r\n    grid.innerHTML = products.map((p) => {\r\n      const title = p?.name || \"Product\";\r\n      const img = p?.images?.[0]?.src || \"\";\r\n      const url = p?.permalink || \"#\";\r\n      const priceNow = money(p?.prices?.price, p?.prices?.currency_code || \"USD\");\r\n      const priceOld = money(p?.prices?.regular_price, p?.prices?.currency_code || \"USD\");\r\n      const oldHtml = priceOld && priceOld !== priceNow ? `<del>${esc(priceOld)}<\/del> ` : \"\";\r\n      return `\r\n        <article class=\"loop-card\" role=\"listitem\" data-product-id=\"${esc(p?.id)}\">\r\n          <a class=\"loop-card__media\" href=\"${esc(url)}\"><img decoding=\"async\" src=\"${esc(img)}\" alt=\"${esc(title)}\" loading=\"lazy\"><\/a>\r\n          <div class=\"loop-card__body\">\r\n            <h3 class=\"loop-card__title\"><a href=\"${esc(url)}\">${esc(title)}<\/a><\/h3>\r\n            <p class=\"loop-card__price\">${oldHtml}<ins>${esc(priceNow)}<\/ins><\/p>\r\n            <a href=\"cart.html\" class=\"loop-card__btn add_to_cart_button\" data-product-id=\"${esc(p?.id)}\">Add to cart<\/a>\r\n          <\/div>\r\n        <\/article>\r\n      `;\r\n    }).join(\"\");\r\n    setPagination();\r\n  };\r\n\r\n  const buildParams = () => {\r\n    const q = form.elements.q.value.trim();\r\n    const category = form.elements.category.value;\r\n    const min = priceToMinor(form.elements.min.value.trim());\r\n    const max = priceToMinor(form.elements.max.value.trim());\r\n    const sort = sortPreset[form.elements.sort.value] || sortPreset.newest;\r\n\r\n    const params = new URLSearchParams({\r\n      per_page: String(LIMIT),\r\n      page: String(page),\r\n      orderby: sort.orderby,\r\n      order: sort.order,\r\n    });\r\n    if (q) params.set(\"search\", q);\r\n    if (category) params.set(\"category\", category);\r\n    if (min) params.set(\"min_price\", min);\r\n    if (max) params.set(\"max_price\", max);\r\n    return params;\r\n  };\r\n\r\n  const syncQueryString = () => {\r\n    const q = form.elements.q.value.trim();\r\n    const category = form.elements.category.value;\r\n    const min = form.elements.min.value.trim();\r\n    const max = form.elements.max.value.trim();\r\n    const sort = form.elements.sort.value;\r\n    const qs = new URLSearchParams();\r\n    if (q) qs.set(\"q\", q);\r\n    if (category) qs.set(\"category\", category);\r\n    if (min) qs.set(\"min\", min);\r\n    if (max) qs.set(\"max\", max);\r\n    if (sort && sort !== \"newest\") qs.set(\"sort\", sort);\r\n    if (page > 1) qs.set(\"page\", String(page));\r\n    const next = qs.toString();\r\n    const url = `${window.location.pathname}${next ? `?${next}` : \"\"}`;\r\n    history.replaceState(null, \"\", url);\r\n  };\r\n\r\n  const hydrateFromQuery = () => {\r\n    const qs = new URLSearchParams(window.location.search);\r\n    form.elements.q.value = qs.get(\"q\") || \"\";\r\n    form.elements.min.value = qs.get(\"min\") || \"\";\r\n    form.elements.max.value = qs.get(\"max\") || \"\";\r\n    form.elements.sort.value = qs.get(\"sort\") || \"newest\";\r\n    page = Math.max(1, Number(qs.get(\"page\") || 1));\r\n    return qs.get(\"category\") || \"\";\r\n  };\r\n\r\n  const loadCategories = async (selectedCategory) => {\r\n    if (!API_ROOT) return;\r\n    try {\r\n      const res = await fetch(`${API_ROOT}\/products\/categories?per_page=100`, { credentials: \"same-origin\" });\r\n      if (!res.ok) throw new Error();\r\n      const rows = await res.json();\r\n      if (!Array.isArray(rows)) return;\r\n      catSelect.innerHTML = `<option value=\"\">All categories<\/option>${rows.map((c) => `<option value=\"${esc(c.id)}\">${esc(c.name)}<\/option>`).join(\"\")}`;\r\n      if (selectedCategory) catSelect.value = selectedCategory;\r\n    } catch {\r\n      catSelect.innerHTML = '<option value=\"\">All categories<\/option>';\r\n    }\r\n  };\r\n\r\n  const loadProducts = async () => {\r\n    if (!API_ROOT) {\r\n      totalPages = 1;\r\n      totalItems = 0;\r\n      meta.textContent = \"No backend URL. Open this page from WordPress, or set data-store-api-root on <body>.\";\r\n      renderStatus(\"Backend is not connected.\");\r\n      return;\r\n    }\r\n\r\n    meta.textContent = \"Loading products...\";\r\n    const params = buildParams();\r\n    syncQueryString();\r\n    try {\r\n      let res = await fetch(`${API_ROOT}\/products?${params.toString()}`, { credentials: \"same-origin\" });\r\n      \/* Some WC builds reject orderby=rating on the Store API; retry with popularity *\/\r\n      if (!res.ok && form.elements.sort.value === \"rating\" && res.status >= 400) {\r\n        const fallback = new URLSearchParams(params);\r\n        fallback.set(\"orderby\", \"popularity\");\r\n        fallback.set(\"order\", \"desc\");\r\n        res = await fetch(`${API_ROOT}\/products?${fallback.toString()}`, { credentials: \"same-origin\" });\r\n      }\r\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n      totalItems = Number(res.headers.get(\"X-WP-Total\") || 0) || 0;\r\n      totalPages = Number(res.headers.get(\"X-WP-TotalPages\") || 1) || 1;\r\n      const rows = await res.json();\r\n      meta.textContent = `${totalItems} product(s) \u00b7 page ${page}\/${totalPages}`;\r\n      renderProducts(rows);\r\n    } catch (err) {\r\n      totalPages = 1;\r\n      totalItems = 0;\r\n      meta.textContent = `Backend request failed. ${err?.message || \"\"}`;\r\n      renderStatus(\"Could not load products. Check WooCommerce API URL\/CORS.\");\r\n    }\r\n  };\r\n\r\n  form.addEventListener(\"submit\", (e) => {\r\n    e.preventDefault();\r\n    page = 1;\r\n    loadProducts();\r\n  });\r\n\r\n  resetBtn.addEventListener(\"click\", () => {\r\n    form.reset();\r\n    form.elements.sort.value = \"newest\";\r\n    page = 1;\r\n    loadProducts();\r\n  });\r\n\r\n  prevBtn.addEventListener(\"click\", () => {\r\n    if (page <= 1) return;\r\n    page -= 1;\r\n    loadProducts();\r\n  });\r\n\r\n  nextBtn.addEventListener(\"click\", () => {\r\n    if (page >= totalPages) return;\r\n    page += 1;\r\n    loadProducts();\r\n  });\r\n\r\n  (async () => {\r\n    const selectedCategory = hydrateFromQuery();\r\n    await loadCategories(selectedCategory);\r\n    loadProducts();\r\n  })();\r\n})();\r\n  <\/script>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-924ccc6 elementor-widget elementor-widget-html\" data-id=\"924ccc6\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t\t<html>\n    <script>\n        (() => {\n  const body = document.body;\n  if (!body) return;\n\n  const storeBase = (() => {\n    const fromAttr = body.dataset?.storeApiRoot?.trim();\n    if (fromAttr) return fromAttr.replace(\/\\\/$\/, \"\");\n    if (window.location.protocol === \"file:\") return \"\";\n    return window.location.origin.replace(\/\\\/$\/, \"\");\n  })();\n  const API_ROOT = storeBase ? `${storeBase}\/wp-json\/wc\/store\/v1` : \"\";\n\n  const safeText = (v) => String(v || \"\").replace(\/\\s+\/g, \" \").trim();\n  const cartCountSpans = () => Array.from(document.querySelectorAll(\"#cart-count\"));\n  const cartLinks = () =>\n    Array.from(document.querySelectorAll(\"a\"))\n      .filter((a) => \/\\bcart\\b\/i.test(safeText(a.textContent)));\n\n  const getNonce = () => {\n    if (window.wc?.wcSettings?.storeApiNonce) return window.wc.wcSettings.storeApiNonce;\n    if (window.wcSettings?.storeApiNonce) return window.wcSettings.storeApiNonce;\n    if (window.wc_store_api_nonce) return window.wc_store_api_nonce;\n    return \"\";\n  };\n\n  const parseCountFromCart = (cart) => {\n    const itemsCount = Number(cart?.items_count);\n    if (Number.isFinite(itemsCount)) return itemsCount;\n    const items = Array.isArray(cart?.items) ? cart.items : [];\n    const sum = items.reduce((n, it) => n + Number(it?.quantity || 0), 0);\n    return Number.isFinite(sum) ? sum : 0;\n  };\n\n  const writeCount = (count) => {\n    const value = Number.isFinite(Number(count)) ? String(Number(count)) : \"0\";\n    try {\n      localStorage.setItem(\"sn_cart_count\", value);\n    } catch {}\n\n    cartCountSpans().forEach((el) => {\n      el.textContent = value;\n    });\n\n    cartLinks().forEach((a) => {\n      if (a.querySelector(\"#cart-count\")) return;\n      const t = safeText(a.textContent);\n      if (\/cart\\s*\\(\\d+\\)\/i.test(t)) {\n        a.textContent = t.replace(\/cart\\s*\\(\\d+\\)\/i, `Cart (${value})`);\n      }\n    });\n  };\n\n  const warmFromStorage = () => {\n    try {\n      const raw = localStorage.getItem(\"sn_cart_count\");\n      if (raw != null) writeCount(Number(raw));\n    } catch {}\n  };\n\n  const fetchCart = async () => {\n    if (!API_ROOT) return null;\n    const nonce = getNonce();\n    const headers = {};\n    if (nonce) {\n      headers.Nonce = nonce;\n      headers[\"X-WC-Store-API-Nonce\"] = nonce;\n    }\n    const res = await fetch(`${API_ROOT}\/cart`, { credentials: \"same-origin\", headers });\n    if (!res.ok) throw new Error(`cart fetch failed: ${res.status}`);\n    return res.json();\n  };\n\n  const addItemViaStoreApi = async (productId, quantity) => {\n    const nonce = getNonce();\n    const headers = { \"Content-Type\": \"application\/x-www-form-urlencoded; charset=UTF-8\" };\n    if (nonce) {\n      headers.Nonce = nonce;\n      headers[\"X-WC-Store-API-Nonce\"] = nonce;\n    }\n    const body = new URLSearchParams({\n      id: String(productId),\n      quantity: String(quantity || 1),\n    }).toString();\n    const res = await fetch(`${API_ROOT}\/cart\/add-item`, {\n      method: \"POST\",\n      credentials: \"same-origin\",\n      headers,\n      body,\n    });\n    if (!res.ok) throw new Error(`store-api add-item failed: ${res.status}`);\n    return res.json();\n  };\n\n  const addItemViaWcAjax = async (productId, quantity) => {\n    const body = new URLSearchParams({\n      product_id: String(productId),\n      quantity: String(quantity || 1),\n    });\n    const wcParams = window.wc_add_to_cart_params;\n    if (wcParams?.nonce) {\n      body.append(\"security\", wcParams.nonce);\n    }\n    let ajaxUrl = wcParams?.wc_ajax_url || \"\/?wc-ajax=add_to_cart\";\n    if (ajaxUrl.includes(\"%%endpoint%%\")) {\n      ajaxUrl = ajaxUrl.replace(\"%%endpoint%%\", \"add_to_cart\");\n    } else if (!ajaxUrl.includes(\"wc-ajax=\")) {\n      ajaxUrl += ajaxUrl.includes(\"?\") ? \"&wc-ajax=add_to_cart\" : \"?wc-ajax=add_to_cart\";\n    }\n    const res = await fetch(ajaxUrl, {\n      method: \"POST\",\n      credentials: \"same-origin\",\n      headers: {\n        \"Content-Type\": \"application\/x-www-form-urlencoded; charset=UTF-8\",\n      },\n      body: body.toString(),\n    });\n    if (!res.ok) throw new Error(`wc-ajax add_to_cart failed: ${res.status}`);\n    const data = await res.json().catch(() => ({}));\n    if (data && data.error) throw new Error(\"wc-ajax returned error\");\n    return data;\n  };\n\n  const cartHasProduct = (cart, productId) => {\n    const want = Number(productId);\n    if (!Number.isFinite(want)) return false;\n    const items = cart?.items;\n    if (!Array.isArray(items)) return false;\n    return items.some((item) => {\n      const candidates = [item?.id, item?.product_id, item?.parent_id, item?.variation_id];\n      return candidates.some((v) => Number(v) === want);\n    });\n  };\n\n  const addItemToWooCart = async (productId, quantity) => {\n    try {\n      const cart = await addItemViaStoreApi(productId, quantity);\n      if (cartHasProduct(cart, productId)) return cart;\n    } catch {\n      \/* fall through to classic AJAX *\/\n    }\n    await addItemViaWcAjax(productId, quantity);\n    const cart = await fetchCart();\n    if (!cartHasProduct(cart, productId)) {\n      throw new Error(\"product not in cart after add\");\n    }\n    return cart;\n  };\n\n  \/** WooCommerce classic loops use data-product_id; our demos use data-product-id *\/\n  const readDirectProductId = (button) => {\n    const raw =\n      button?.getAttribute?.(\"data-product_id\") ||\n      button?.dataset?.productId ||\n      button?.dataset?.product_id ||\n      button?.closest?.(\"[data-product_id]\")?.getAttribute(\"data-product_id\") ||\n      button?.closest?.(\"[data-product-id]\")?.getAttribute(\"data-product-id\");\n    const n = Number(raw);\n    return Number.isFinite(n) && n > 0 ? n : null;\n  };\n\n  const resolveProductId = async (button) => {\n    const direct = readDirectProductId(button);\n    if (direct) return direct;\n    const product = button.closest(\".product, article, li, .loop-card, .newin-card\");\n    const titleNode = product?.querySelector(\".woocommerce-loop-product__title, .woocommerce-loop-product__title a, h3, h2\");\n    const title = safeText(titleNode?.textContent);\n    if (!title || !API_ROOT) return null;\n    const res = await fetch(`${API_ROOT}\/products?search=${encodeURIComponent(title)}&per_page=10`, {\n      credentials: \"same-origin\",\n    });\n    if (!res.ok) return null;\n    const rows = await res.json().catch(() => []);\n    if (!Array.isArray(rows) || rows.length === 0) return null;\n    const exact = rows.find((p) => safeText(p?.name).toLowerCase() === title.toLowerCase());\n    const hit = exact || rows[0];\n    return Number(hit?.id) || null;\n  };\n\n  const bindButtons = () => {\n    document.querySelectorAll(\".add_to_cart_button\").forEach((btn) => {\n      if (btn.dataset.cartBridgeBound === \"1\") return;\n      \/* Avoid double handlers with embed-segments\/01 bindAddToCartHandlers *\/\n      if (btn.getAttribute(\"data-cart-bound\") === \"1\") return;\n\n      btn.dataset.cartBridgeBound = \"1\";\n      btn.addEventListener(\"click\", async (e) => {\n        if (!API_ROOT) return;\n        if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n        e.preventDefault();\n        const old = btn.textContent;\n        btn.textContent = \"Adding...\";\n        btn.setAttribute(\"aria-busy\", \"true\");\n        btn.classList.add(\"is-adding\");\n        try {\n          const productId = await resolveProductId(btn);\n          if (!productId) throw new Error(\"missing product id\");\n          const cart = await addItemToWooCart(productId, 1);\n          writeCount(parseCountFromCart(cart));\n          btn.textContent = \"Added\";\n          window.dispatchEvent(new CustomEvent(\"sn:cart-updated\", { detail: { count: parseCountFromCart(cart) } }));\n        } catch (err) {\n          btn.textContent = \"Failed\";\n          console.warn(\"[SparkNest cart-bridge]\", err?.message || err);\n        }\n        setTimeout(() => {\n          btn.textContent = old;\n          btn.removeAttribute(\"aria-busy\");\n          btn.classList.remove(\"is-adding\");\n        }, 1200);\n      });\n    });\n  };\n\n  const observeDynamicButtons = () => {\n    const mo = new MutationObserver(() => bindButtons());\n    mo.observe(document.body, { childList: true, subtree: true });\n  };\n\n  const init = async () => {\n    warmFromStorage();\n    bindButtons();\n    observeDynamicButtons();\n    if (!API_ROOT) return;\n    try {\n      const cart = await fetchCart();\n      writeCount(parseCountFromCart(cart));\n    } catch {\n      \/\/ Keep local count fallback if backend temporarily unavailable.\n    }\n  };\n\n  init();\n})();\n\n    <\/script>\n<\/html>\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>Shop \u00b7 SparkNest SparkNest Shop Filters Keyword Category All categories Min $ Max $ Sort NewestPrice: Low to HighPrice: High to LowBest sellingTop rated Apply Reset All products Loading products&#8230; Previous Next<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-810","page","type-page","status-publish","hentry"],"acf":[],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/pages\/810","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/comments?post=810"}],"version-history":[{"count":25,"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/pages\/810\/revisions"}],"predecessor-version":[{"id":932,"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/pages\/810\/revisions\/932"}],"wp:attachment":[{"href":"https:\/\/browseshop.shop\/pl\/wp-json\/wp\/v2\/media?parent=810"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}