{"id":1590,"date":"2021-05-10T08:58:44","date_gmt":"2021-05-10T08:58:44","guid":{"rendered":"http:\/\/www.nicdarkthemes.com\/themes\/seafood\/wp\/demo\/restaurant\/?page_id=1590"},"modified":"2025-12-17T10:30:56","modified_gmt":"2025-12-17T10:30:56","slug":"woo-shop-01","status":"publish","type":"page","link":"https:\/\/psd-drugstore.com\/index.php\/woocommerce-pages\/woo-shop-01\/","title":{"rendered":"WOO &#8211; Shop 01"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1590\" class=\"elementor elementor-1590\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-3d904eb6 elementor-section-stretched elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"3d904eb6\" data-element_type=\"section\" data-settings=\"{&quot;stretch_section&quot;:&quot;section-stretched&quot;,&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t\t<div class=\"elementor-background-overlay\"><\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-6dc56f14\" data-id=\"6dc56f14\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-16c8e2d7 elementor-widget elementor-widget-heading\" data-id=\"16c8e2d7\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Our Shop<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-19ffa4e3 elementor-widget elementor-widget-heading\" data-id=\"19ffa4e3\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<p class=\"elementor-heading-title elementor-size-default\">Discover a wide selection of premium health, beauty, and wellness products at PSD Drugstore. We bring you trusted brands, great prices, and reliable service all in one place.<\/p>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4f8febee elementor-widget elementor-widget-spacer\" data-id=\"4f8febee\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-40e1b153 elementor-section-content-middle elementor-section-stretched elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"40e1b153\" data-element_type=\"section\" data-settings=\"{&quot;stretch_section&quot;:&quot;section-stretched&quot;,&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t\t<div class=\"elementor-background-overlay\"><\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7e8a359a\" data-id=\"7e8a359a\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-2608969 elementor-align-center elementor-widget elementor-widget-button\" data-id=\"2608969\" data-element_type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"#\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">MONTHLY SALE<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b99cb6d elementor-widget elementor-widget-heading\" data-id=\"6b99cb6d\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Shop Now!<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fd764a0 elementor-widget elementor-widget-html\" data-id=\"fd764a0\" data-element_type=\"widget\" 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\" \/>\r\n<title>Shop<\/title>\r\n\r\n<!-- If your shop is on another domain\/subdomain, UNCOMMENT & set: -->\r\n<!-- <script>window.WOO_BASE = \"https:\/\/YOUR-SHOP-DOMAIN.com\";<\/script> -->\r\n\r\n<style>\r\n  :root{\r\n    --bg:#f6f8fb; --card:#fff; --muted:#64748b; --border:#e5e7eb; --ink:#0f172a;\r\n    --brand:#0ea5e9; --brand2:#0284c7; --r:14px\r\n  }\r\n  *{box-sizing:border-box}\r\n  body{margin:0;background:var(--bg);color:var(--ink);font:14px\/1.6 system-ui,-apple-system,Segoe UI,Roboto}\r\n  #woo-app *{box-sizing:border-box}\r\n\r\n  .wrap{max-width:1240px;margin:0 auto;padding:16px}\r\n  .toolbar{display:flex;gap:10px;align-items:center;margin:6px 0 14px}\r\n  .input,.select,.btn{border:1px solid var(--border);border-radius:10px;padding:10px 12px;background:#fff;font-size:13px}\r\n  .btn{cursor:pointer}\r\n  .btn.primary{background:var(--brand);color:#fff;border-color:transparent}\r\n  .btn.primary:hover{background:var(--brand2)}\r\n  .btn.ghost{background:#fff;color:#0f172a}\r\n\r\n  .sr{position:relative;flex:1}\r\n  .sr input{padding-left:34px;width:100%}\r\n  .sr svg{position:absolute;left:10px;top:10px;width:16px;height:16px;opacity:.5}\r\n\r\n  .grid{display:grid;grid-template-columns:280px 1fr;gap:20px;align-items:start}\r\n  @media (max-width:992px){.grid{grid-template-columns:1fr}}\r\n\r\n  \/* Sidebar *\/\r\n  .sidebar{position:sticky;top:90px;background:var(--card);border:1px solid var(--border);border-radius:var(--r);padding:14px}\r\n  .h3{font-weight:800;margin:0 0 12px;font-size:18px;letter-spacing:.3px}\r\n  .error{margin:12px 0;padding:10px;border-radius:8px;background:#fff1f2;border:1px solid #fecdd3;color:#9f1239}\r\n\r\n  \/* Accordion groups *\/\r\n  details.group{border:1px solid var(--border);border-radius:12px;background:#fff;margin:10px 0;overflow:hidden}\r\n  details.group[open]{box-shadow:0 8px 24px rgba(2,6,23,.06)}\r\n  details.group summary{cursor:pointer;list-style:none;padding:10px 12px;font-weight:600}\r\n  details.group summary::-webkit-details-marker{display:none}\r\n  .catlist{padding:0 10px 10px;margin:0;list-style:none;max-height:260px;overflow:auto}\r\n  .catlist li{margin:6px 0}\r\n  .catlist label{display:flex;gap:8px;align-items:center;font-size:13px;color:#0f172a}\r\n  .catlist input[type=\"radio\"]{accent-color:var(--brand)}\r\n\r\n  \/* Products *\/\r\n  .products{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px}\r\n  @media (max-width:640px){\r\n    .products{grid-template-columns:repeat(2,minmax(0,1fr))}\r\n    .imgbox{height:160px}\r\n  }\r\n  .card{\r\n    background:var(--card);border:1px solid var(--border);border-radius:16px;\r\n    display:flex;flex-direction:column;overflow:hidden;transition:.15s ease;\r\n  }\r\n  .card:hover{transform:translateY(-2px);box-shadow:0 14px 26px rgba(2,6,23,.06)}\r\n  .imgbox{background:#f8fafc;height:200px;display:flex;align-items:center;justify-content:center}\r\n  .imgbox img{max-width:90%;max-height:90%;object-fit:contain}\r\n  .body{display:flex;flex-direction:column;gap:10px;padding:12px}\r\n  .title-sm{\r\n    font-size:12px;line-height:1.3;font-weight:600;margin:0;color:#0f172a;\r\n    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:32px\r\n  }\r\n  .price{font-weight:700;font-size:13px}\r\n  .cta-row{margin-top:auto}\r\n  .cta-row a{\r\n    display:block;width:100%;text-align:center;text-decoration:none;border-radius:10px;\r\n    padding:7px 10px;font-size:12px;border:1px solid var(--border);background:#fff;color:#0f172a\r\n  }\r\n  .cta-row a:hover{background:#f8fafc}\r\n\r\n  \/* Skeletons *\/\r\n  .skeleton{\r\n    background:linear-gradient(90deg,#f1f5f9, #e9eef5, #f1f5f9);\r\n    background-size:200% 100%; animation:shimmer 1s linear infinite;\r\n  }\r\n  @keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}\r\n  .skeleton.card .imgbox{height:200px}\r\n  .skeleton .title{height:18px;margin:10px;border-radius:6px}\r\n  .skeleton .price{height:14px;margin:0 10px 10px;border-radius:6px}\r\n\r\n  \/* ===== Pagination Bar (ALL DEVICES) ===== *\/\r\n  .mPagerWrap{display:none;justify-content:center;margin:20px 0}\r\n  .mPager{\r\n    display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:center;\r\n    background:#fff;border:1px solid var(--border);border-radius:12px;padding:8px 12px;\r\n    box-shadow:0 10px 24px rgba(2,6,23,.05);\r\n  }\r\n  .mPager button{\r\n    border:1px solid var(--border);background:#fff;border-radius:10px;\r\n    padding:6px 12px;font-size:13px;cursor:pointer;min-width:38px\r\n  }\r\n  .mPager button.active{background:var(--brand);border-color:transparent;color:#fff}\r\n  .mPager button:disabled{opacity:.45;cursor:not-allowed}\r\n  .mPager .dots{padding:0 6px;color:var(--muted)}\r\n\r\n  \/* ===== MOBILE: remove select bar under All categories by NOT using select ===== *\/\r\n  .mobile-bar{display:none}\r\n  @media (max-width:992px){\r\n    .sidebar{display:none}\r\n    .mobile-bar{display:flex;gap:8px;align-items:center;margin:6px 0 14px}\r\n    .mobile-bar .sr{flex:1}\r\n    .mobile-bar .btn{height:40px}\r\n  }\r\n\r\n  \/* ===== Drawer (Mobile Filters) ===== *\/\r\n  .drawer{position:fixed;inset:0;display:none;z-index:99999}\r\n  .drawer.open{display:block}\r\n  .drawer .overlay{position:absolute;inset:0;background:rgba(2,6,23,.45)}\r\n  .drawer .panel{\r\n    position:absolute;right:0;top:0;height:100%;width:min(92vw,380px);\r\n    background:#fff;border-left:1px solid var(--border);display:flex;flex-direction:column\r\n  }\r\n  .drawer .head{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border)}\r\n  .drawer .body{padding:14px;overflow:auto}\r\n<\/style>\r\n<\/head>\r\n\r\n<body>\r\n<div id=\"woo-app\"><\/div>\r\n\r\n<script>\r\n(async function(){\r\n  const ORIGIN = (window.WOO_BASE && typeof window.WOO_BASE==='string')\r\n    ? window.WOO_BASE.replace(\/\\\/$\/, '')\r\n    : window.location.origin;\r\n\r\n  async function resolveStoreApiBase(){\r\n    const candidates = [\r\n      ORIGIN + '\/wp-json\/wc\/store',\r\n      ORIGIN + '\/?rest_route=\/wc\/store'\r\n    ];\r\n    for (const base of candidates) {\r\n      try {\r\n        const ok = await fetch(base + '\/products\/categories?per_page=1', {mode:'cors'});\r\n        if (ok.status >= 200 && ok.status < 300) return base;\r\n      } catch (_) {}\r\n    }\r\n    throw new Error('WooCommerce Store API not reachable at ' + ORIGIN);\r\n  }\r\n\r\n  const app = document.getElementById('woo-app');\r\n  app.innerHTML = `\r\n    <div class=\"wrap\">\r\n      <div id=\"err\" class=\"error\" style=\"display:none\"><\/div>\r\n\r\n      <!-- MOBILE TOP BAR: search + Filters button (NO select => no white bar) -->\r\n      <div class=\"mobile-bar\">\r\n        <div class=\"sr\">\r\n          <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M21 21l-4.35-4.35M10 18a8 8 0 100-16 8 8 0 000 16z\"\/><\/svg>\r\n          <input id=\"search_m\" class=\"input\" placeholder=\"Search products\u2026\">\r\n        <\/div>\r\n        <button id=\"openFilters\" class=\"btn primary\">Filters<\/button>\r\n      <\/div>\r\n\r\n      <div class=\"grid\">\r\n        <!-- Desktop sidebar -->\r\n        <aside class=\"sidebar\">\r\n          <div class=\"sr\" style=\"margin-bottom:10px\">\r\n            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M21 21l-4.35-4.35M10 18a 8 8 0 100-16 8 8 0 000 16z\"\/><\/svg>\r\n            <input id=\"search_d\" class=\"input\" placeholder=\"Search products\u2026\">\r\n          <\/div>\r\n\r\n          <h3 class=\"h3\">Categories<\/h3>\r\n          <div id=\"catGroups\"><\/div>\r\n        <\/aside>\r\n\r\n        <main>\r\n          <div id=\"count\" class=\"h3\" style=\"font-weight:700;letter-spacing:.3px;margin:0 0 8px\"><\/div>\r\n          <section class=\"products\" id=\"grid\"><\/section>\r\n\r\n          <div class=\"mPagerWrap\" id=\"mPagerWrap\">\r\n            <div class=\"mPager\" id=\"mPager\"><\/div>\r\n          <\/div>\r\n        <\/main>\r\n      <\/div>\r\n\r\n      <!-- Mobile Drawer -->\r\n      <div id=\"filterDrawer\" class=\"drawer\" aria-hidden=\"true\">\r\n        <div class=\"overlay\"><\/div>\r\n        <div class=\"panel\">\r\n          <div class=\"head\">\r\n            <strong>Filters<\/strong>\r\n            <button id=\"closeFilters\" class=\"btn ghost\">Close<\/button>\r\n          <\/div>\r\n          <div class=\"body\">\r\n            <h3 class=\"h3\" style=\"margin-bottom:8px\">Categories<\/h3>\r\n            <div id=\"catGroups_m\"><\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  `;\r\n\r\n  const $ = id => document.getElementById(id);\r\n  const showErr = (m)=>{ const e=$('err'); e.textContent=m; e.style.display=''; };\r\n\r\n  let API_BASE;\r\n  try { API_BASE = await resolveStoreApiBase(); }\r\n  catch(e){ showErr(e.message + ' \u2014 Set window.WOO_BASE if needed.'); return; }\r\n\r\n  \/* ===================== State \/ cache \/ paging ===================== *\/\r\n  const S = { q:'', cat:null, page:1, perPage:24 };\r\n  let totalPages = 1;\r\n  let currentController = null;\r\n  const cache = new Map();\r\n  const CACHE_TTL = 1000 * 60 * 3;\r\n\r\n  const OTHER_TITLE = 'Supplements';\r\n  const GROUP_ORDER = ['Face','Body','Hair','Wellbeing','For him'];\r\n\r\n  const priceHtml = p => p.price_html?.trim()\r\n    || (p.prices?.price ? ('$'+(p.prices.price\/100).toFixed(2)) : '');\r\n\r\n  function keyForState(){ return JSON.stringify({q:S.q,cat:S.cat,page:S.page,pp:S.perPage}); }\r\n\r\n  function renderSkeletons(n=8){\r\n    const grid = $('grid'); grid.innerHTML='';\r\n    const frag = document.createDocumentFragment();\r\n    for(let i=0;i<n;i++){\r\n      const sk = document.createElement('article');\r\n      sk.className = 'card skeleton';\r\n      sk.innerHTML = `<div class=\"imgbox\"><\/div><div class=\"title\"><\/div><div class=\"price\"><\/div>`;\r\n      frag.appendChild(sk);\r\n    }\r\n    grid.appendChild(frag);\r\n  }\r\n\r\n  function renderProducts(items){\r\n    const grid = $('grid'); grid.innerHTML='';\r\n    const frag = document.createDocumentFragment();\r\n    items.forEach(p=>{\r\n      const img = (p.images && p.images[0]?.src) || '';\r\n      const el = document.createElement('article');\r\n      el.className = 'card';\r\n      el.innerHTML = `\r\n        <div class=\"imgbox\"><img decoding=\"async\" loading=\"lazy\" src=\"${img}\" alt=\"${p.name}\"><\/div>\r\n        <div class=\"body\">\r\n          <h3 class=\"title-sm\">${p.name}<\/h3>\r\n          <div class=\"price\">${priceHtml(p)}<\/div>\r\n          <div class=\"cta-row\"><a href=\"${p.permalink || '#'}\">View product<\/a><\/div>\r\n        <\/div>`;\r\n      frag.appendChild(el);\r\n    });\r\n    grid.appendChild(frag);\r\n    $('count').textContent = 'Showing ' + items.length + ' products';\r\n  }\r\n\r\n  function renderPager(){\r\n    const pager = $('mPager');\r\n    const wrap = $('mPagerWrap');\r\n    if(!pager || !wrap) return;\r\n\r\n    if(totalPages <= 1){\r\n      pager.innerHTML = '';\r\n      wrap.style.display = 'none';\r\n      return;\r\n    }\r\n    wrap.style.display = 'flex';\r\n    pager.innerHTML = '';\r\n\r\n    const makeBtn = (label, page, opts={})=>{\r\n      const b = document.createElement('button');\r\n      b.textContent = label;\r\n      if(opts.active) b.classList.add('active');\r\n      if(opts.disabled) b.disabled = true;\r\n      b.addEventListener('click', ()=>{\r\n        if(page === S.page) return;\r\n        S.page = page;\r\n        fetchProducts();\r\n        window.scrollTo({ top: 0, behavior: 'smooth' });\r\n      });\r\n      return b;\r\n    };\r\n\r\n    const frag = document.createDocumentFragment();\r\n    frag.appendChild(makeBtn('<', Math.max(1, S.page-1), {disabled: S.page===1}));\r\n\r\n    const maxShown = 4;\r\n\r\n    if(S.page <= maxShown){\r\n      for(let p=1; p<=Math.min(totalPages, maxShown); p++){\r\n        frag.appendChild(makeBtn(String(p), p, {active: p===S.page}));\r\n      }\r\n      if(totalPages > maxShown){\r\n        const dots = document.createElement('span');\r\n        dots.className='dots'; dots.textContent='\u2026';\r\n        frag.appendChild(dots);\r\n      }\r\n    } else {\r\n      frag.appendChild(makeBtn('1', 1, {active: S.page===1}));\r\n      const dots = document.createElement('span');\r\n      dots.className='dots'; dots.textContent='\u2026';\r\n      frag.appendChild(dots);\r\n\r\n      const start = Math.max(2, S.page-1);\r\n      const end = Math.min(totalPages-1, S.page+1);\r\n      for(let p=start; p<=end; p++){\r\n        frag.appendChild(makeBtn(String(p), p, {active: p===S.page}));\r\n      }\r\n\r\n      if(S.page < totalPages-2){\r\n        const dots2 = document.createElement('span');\r\n        dots2.className='dots'; dots2.textContent='\u2026';\r\n        frag.appendChild(dots2);\r\n      }\r\n      frag.appendChild(makeBtn(String(totalPages), totalPages, {active: S.page===totalPages}));\r\n    }\r\n\r\n    frag.appendChild(makeBtn('>', Math.min(totalPages, S.page+1), {disabled: S.page===totalPages}));\r\n    pager.appendChild(frag);\r\n  }\r\n\r\n  async function fetchProducts(){\r\n    const key = keyForState();\r\n    const now = Date.now();\r\n    const cached = cache.get(key);\r\n    if (cached && now - cached.time < CACHE_TTL) {\r\n      totalPages = cached.totalPages || 1;\r\n      renderProducts(cached.items);\r\n      renderPager();\r\n      return;\r\n    }\r\n\r\n    if (currentController) currentController.abort();\r\n    currentController = new AbortController();\r\n\r\n    renderSkeletons();\r\n\r\n    const q = new URLSearchParams({ per_page:S.perPage, page:S.page, orderby:'date', order:'desc' });\r\n    if (S.q) q.set('search', S.q);\r\n    if (S.cat) q.set('category', S.cat);\r\n\r\n    try{\r\n      const r = await fetch(`${API_BASE}\/products?${q}`, { signal: currentController.signal });\r\n      const tp = Number(r.headers.get('X-WP-TotalPages') || '1');\r\n      totalPages = isNaN(tp) ? 1 : Math.max(1, tp);\r\n\r\n      if(!r.ok) throw new Error('HTTP '+r.status);\r\n      const data = await r.json();\r\n      const items = Array.isArray(data) ? data : (data.products || []);\r\n\r\n      cache.set(key, { time: now, items, totalPages });\r\n      renderProducts(items);\r\n      renderPager();\r\n    }catch(e){\r\n      if (e.name === 'AbortError') return;\r\n      showErr('Could not load products: ' + e.message);\r\n      $('grid').innerHTML = ''; $('count').textContent = '';\r\n      totalPages = 1; renderPager();\r\n    }\r\n  }\r\n\r\n  \/* ===================== Categories: grouped correctly (desktop + mobile) ===================== *\/\r\n  async function fetchAllCats(){\r\n    const out=[]; for(let p=1;p<=10;p++){\r\n      const r=await fetch(`${API_BASE}\/products\/categories?per_page=100&page=${p}`);\r\n      if(!r.ok) break;\r\n      const b=await r.json();\r\n      if(!Array.isArray(b)||!b.length) break;\r\n      out.push(...b);\r\n      if(b.length<100) break;\r\n    }\r\n    return out;\r\n  }\r\n\r\n  const cats = await fetchAllCats();\r\n  const byId = new Map(cats.map(c=>[c.id,c]));\r\n\r\n  \/\/ children map\r\n  const children = new Map();\r\n  cats.forEach(c=>{\r\n    const p=c.parent||0;\r\n    if(!children.has(p)) children.set(p,[]);\r\n    children.get(p).push(c);\r\n  });\r\n  children.forEach(arr=>arr.sort((a,b)=> a.name.localeCompare(b.name)));\r\n\r\n  const roots = (children.get(0)||[]);\r\n  const orderedRoots = GROUP_ORDER.map(n=> roots.find(r=>r && r.name===n)).filter(Boolean);\r\n  const otherRoots = roots.filter(r=> !GROUP_ORDER.includes(r.name));\r\n\r\n  function makeRadio(cat){\r\n    const li = document.createElement('li');\r\n    li.innerHTML = `<label><input type=\"radio\" name=\"cat_radio\" value=\"${cat.id}\"> ${cat.name} (${cat.count})<\/label>`;\r\n    li.querySelector('input').addEventListener('change', e=>{\r\n      S.cat = Number(e.target.value)||null;\r\n      S.page=1;\r\n      fetchProducts();\r\n      \/\/ close drawer on mobile for better UX\r\n      const drawer = $('filterDrawer');\r\n      if (drawer) drawer.classList.remove('open');\r\n    });\r\n    return li;\r\n  }\r\n\r\n  function renderGroup(root, container){\r\n    const det = document.createElement('details');\r\n    det.className = 'group';\r\n    det.open = true;\r\n    det.innerHTML = `<summary>${root.name}<\/summary><ul class=\"catlist\"><\/ul>`;\r\n    const ul = det.querySelector('.catlist');\r\n\r\n    \/\/ only show subcategories under each main category (and sub-sub if exist)\r\n    (children.get(root.id)||[]).forEach(sub=>{\r\n      ul.appendChild(makeRadio(sub));\r\n      (children.get(sub.id)||[]).forEach(sub2=> ul.appendChild(makeRadio(sub2)));\r\n    });\r\n\r\n    container.appendChild(det);\r\n  }\r\n\r\n  function renderSupplements(container){\r\n    if(!otherRoots.length) return;\r\n    const det = document.createElement('details');\r\n    det.className = 'group';\r\n    det.open = true;\r\n    det.innerHTML = `<summary>${OTHER_TITLE}<\/summary><ul class=\"catlist\"><\/ul>`;\r\n    const ul = det.querySelector('.catlist');\r\n\r\n    otherRoots.forEach(r=>{\r\n      ul.appendChild(makeRadio(r));\r\n      (children.get(r.id)||[]).forEach(sub=> ul.appendChild(makeRadio(sub)));\r\n      (children.get(r.id)||[]).forEach(sub=>{\r\n        (children.get(sub.id)||[]).forEach(sub2=> ul.appendChild(makeRadio(sub2)));\r\n      });\r\n    });\r\n\r\n    container.appendChild(det);\r\n  }\r\n\r\n  \/\/ Desktop + Mobile groups rendered same structure\r\n  const desk = $('catGroups');\r\n  const mob  = $('catGroups_m');\r\n\r\n  orderedRoots.forEach(r=>{\r\n    renderGroup(r, desk);\r\n    renderGroup(r, mob);\r\n  });\r\n  renderSupplements(desk);\r\n  renderSupplements(mob);\r\n\r\n  \/* ===================== Search sync (desktop + mobile) ===================== *\/\r\n  const search_d = $('search_d');\r\n  const search_m = $('search_m');\r\n  function onSearch(v){\r\n    S.q = (v||'').trim();\r\n    S.page=1;\r\n    fetchProducts();\r\n  }\r\n  if(search_d) search_d.addEventListener('input', e=>{\r\n    if(search_m) search_m.value = e.target.value;\r\n    onSearch(e.target.value);\r\n  });\r\n  if(search_m) search_m.addEventListener('input', e=>{\r\n    if(search_d) search_d.value = e.target.value;\r\n    onSearch(e.target.value);\r\n  });\r\n\r\n  \/* ===================== Drawer open\/close ===================== *\/\r\n  const drawer = $('filterDrawer');\r\n  $('openFilters').addEventListener('click', ()=> drawer.classList.add('open'));\r\n  $('closeFilters').addEventListener('click', ()=> drawer.classList.remove('open'));\r\n  drawer.querySelector('.overlay').addEventListener('click', ()=> drawer.classList.remove('open'));\r\n\r\n  \/\/ Initial\r\n  fetchProducts();\r\n\r\n})();\r\n<\/script>\r\n\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Our Shop Discover a wide selection of premium health, beauty, and wellness products at PSD Drugstore. We bring you trusted brands, great prices, and reliable service all in one place. MONTHLY SALE Shop Now! Shop<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":8996,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1590","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/pages\/1590","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/comments?post=1590"}],"version-history":[{"count":96,"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/pages\/1590\/revisions"}],"predecessor-version":[{"id":14066,"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/pages\/1590\/revisions\/14066"}],"up":[{"embeddable":true,"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/pages\/8996"}],"wp:attachment":[{"href":"https:\/\/psd-drugstore.com\/index.php\/wp-json\/wp\/v2\/media?parent=1590"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}