<body class="min-h-screen">

<!-- ============ HERO ============ -->
<section class="border-b border-soft relative overflow-hidden">
  <svg class="hero-sparkle sparkle-1 w-4 h-4" style="top: 18%; left: 8%;" viewBox="0 0 24 24" fill="#f5a3c7"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
  <svg class="hero-sparkle sparkle-4 w-3 h-3" style="top: 65%; left: 4%;" viewBox="0 0 24 24" fill="#c084fc"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
  <svg class="hero-sparkle sparkle-5 w-3.5 h-3.5" style="top: 30%; left: 48%;" viewBox="0 0 24 24" fill="#fbbf24"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>

  <div class="max-w-[1320px] mx-auto px-6 pt-14 pb-12 relative">
    <div class="grid lg:grid-cols-12 gap-10 items-center">
      <div class="lg:col-span-7">
        <div class="inline-flex items-center gap-2 mb-5 text-xs font-mono uppercase tracking-widest muted">
          <span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
          <span id="hero-counter">Loading…</span> · updated daily
        </div>
        <h1 class="display text-[64px] md:text-[88px] lg:text-[100px] mb-5">
          Find smarter.<br/>
          Wear better.
        </h1>
        <p class="text-lg muted max-w-xl mb-9">
          Curated products, tagged outfits and vetted sellers from China's best shops &mdash; Taobao, Weidian and 1688, all in one clean index.
        </p>

        <div id="hero-search-anchor" class="search-shell rounded-full flex items-center pl-6 pr-2 py-2 max-w-2xl">
          <svg class="w-5 h-5 muted-2 mr-3 flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
          <input id="search-input" type="text" placeholder="Enter product name..." class="flex-1 bg-transparent py-3.5 outline-none text-base" />
          <button class="surface-2 hover:bg-black hover:text-white transition w-11 h-11 rounded-full flex items-center justify-center" aria-label="Image search">
            <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>
          </button>
        </div>
      </div>

      <div class="lg:col-span-5 relative">
        <div class="relative bg-white border border-default rounded-3xl p-7 lg:p-8 min-h-[280px] shadow-sm">
          <svg class="absolute top-6 right-6 w-5 h-5 sparkle-1" viewBox="0 0 24 24" fill="#f5a3c7"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
          <svg class="absolute bottom-12 left-8 w-3 h-3 sparkle-2" viewBox="0 0 24 24" fill="#fbbf24"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
          <svg class="absolute top-1/2 right-12 w-4 h-4 sparkle-3" viewBox="0 0 24 24" fill="#c084fc"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>

          <h3 class="text-xl font-bold mb-1">Follow Sellers & Creators</h3>
          <p class="text-sm muted mb-6">For custom feed and notifications</p>

          <div id="hero-sellers" class="space-y-2.5"></div>

          <button class="absolute top-1/2 -translate-y-1/2 -left-3 scroll-arrow w-9 h-9 rounded-full flex items-center justify-center">
            <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="m15 18-6-6 6-6"/></svg>
          </button>
          <button class="absolute top-1/2 -translate-y-1/2 -right-3 scroll-arrow w-9 h-9 rounded-full flex items-center justify-center">
            <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="m9 18 6-6-6-6"/></svg>
          </button>
        </div>
      </div>
    </div>
  </div>
</section>

<!-- ============ DISCOVER BENTO ============ -->
<section class="border-b border-soft reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="flex items-end justify-between mb-7 flex-wrap gap-3">
      <div>
        <h2 class="display text-3xl md:text-4xl">Discover</h2>
        <p class="text-sm muted mt-1.5">This week's featured drops, edits and tools.</p>
      </div>
      <a href="#section-popular" class="text-sm font-medium underline underline-offset-4 hover:opacity-60">See everything →</a>
    </div>

    <div class="grid grid-cols-12 grid-rows-2 gap-3 md:gap-4" style="grid-auto-rows: minmax(0, 1fr); min-height: 600px;">
      <a href="#section-new" class="bento col-span-12 md:col-span-7 row-span-2 group min-h-[300px] md:min-h-0">
        <div class="bento-img-wrap absolute inset-0">
          <img src="https://picsum.photos/seed/bento-drops/1200/900" alt="" class="w-full h-full object-cover"/>
          <div class="absolute inset-0 bg-gradient-to-t from-black/85 via-black/30 to-black/5"></div>
        </div>
        <svg class="absolute top-8 right-8 w-5 h-5 sparkle-1 z-10" viewBox="0 0 24 24" fill="#f5a3c7"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
        <svg class="absolute top-1/3 right-1/4 w-4 h-4 sparkle-3 z-10" viewBox="0 0 24 24" fill="#fbbf24"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
        <div id="bento-mini-card" class="hidden md:block absolute top-10 right-10 mini-float-1 z-10"></div>

        <div class="relative mt-auto p-8 md:p-10 text-white z-10">
          <div class="inline-flex items-center gap-2 text-[11px] font-mono uppercase tracking-widest opacity-80 mb-3">
            <span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span>
            <span id="bento-live-count">Live · — new finds</span>
          </div>
          <h3 class="display text-4xl md:text-5xl mb-3">Latest drops.</h3>
          <p class="opacity-90 max-w-md mb-5 text-sm md:text-base">The freshest items added across all your favorite shops. Updated every hour, curated by the community.</p>
          <div class="inline-flex items-center gap-1.5 text-sm font-medium group-hover:gap-2.5 transition-all">
            Browse drops
            <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
          </div>
        </div>
      </a>

      <a href="#section-outfits" class="bento col-span-12 md:col-span-5 row-span-1 group min-h-[220px] md:min-h-0">
        <div class="bento-img-wrap absolute inset-0">
          <img src="https://picsum.photos/seed/bento-outfit/700/400" alt="" class="w-full h-full object-cover"/>
          <div class="absolute inset-0 bg-gradient-to-r from-black/70 via-black/15 to-transparent"></div>
        </div>
        <svg class="absolute top-6 right-8 w-4 h-4 sparkle-2 z-10" viewBox="0 0 24 24" fill="#c084fc"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
        <div id="bento-outfit-meta" class="absolute top-5 right-5 surface text-[11px] font-medium px-2.5 py-1 rounded-full shadow-sm z-10">— tagged items</div>
        <div class="relative mt-auto p-6 md:p-7 text-white max-w-xs z-10">
          <div class="text-[11px] font-mono uppercase tracking-widest opacity-80 mb-1.5">Outfit of the week</div>
          <h3 id="bento-outfit-title" class="display text-2xl md:text-3xl mb-3">Tech-wear lite.</h3>
          <div class="flex items-center gap-2.5 mb-3">
            <div class="w-7 h-7 rounded-full overflow-hidden border-2 border-white/50">
              <img src="https://picsum.photos/seed/av-nori/40/40" class="w-full h-full object-cover"/>
            </div>
            <span id="bento-outfit-user" class="text-sm font-medium">@nori</span>
          </div>
          <div class="inline-flex items-center gap-1.5 text-sm font-medium group-hover:gap-2.5 transition-all">
            Shop the look
            <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
          </div>
        </div>
      </a>

      <a id="bento-seller-card" href="#section-sellers" class="bento col-span-7 md:col-span-3 row-span-1 group p-6 surface-2 min-h-[200px] md:min-h-0 relative"></a>

      <a href="#section-tools" class="bento col-span-5 md:col-span-2 row-span-1 group p-6 relative overflow-hidden min-h-[200px] md:min-h-0" style="background: #09090b; color: white;">
        <svg class="absolute -top-3 -right-3 w-20 h-20 opacity-10" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="1.5"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
        <svg class="absolute top-6 right-6 w-3 h-3 sparkle-4" viewBox="0 0 24 24" fill="#fbbf24"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
        <div class="text-[11px] font-mono uppercase tracking-widest opacity-70 mb-2.5">Tool</div>
        <h3 class="display text-2xl md:text-3xl leading-tight">Link<br/>Converter.</h3>
        <div class="absolute bottom-5 left-6 right-6 flex items-end justify-between">
          <div id="bento-agent-count" class="text-[11px] opacity-60 font-mono">— agents</div>
          <svg class="w-5 h-5 group-hover:translate-x-0.5 transition" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 17L17 7M7 7h10v10"/></svg>
        </div>
      </a>
    </div>
  </div>
</section>

<!-- ============ CATEGORIES ============ -->
<section class="border-b border-soft">
  <div class="max-w-[1320px] mx-auto px-6 py-8">
    <div class="relative">
      <div id="cat-scroll" class="flex items-start gap-2 md:gap-3 overflow-x-auto no-scrollbar pb-2 pr-12"></div>
      <button id="cat-scroll-right" class="absolute right-0 top-8 scroll-arrow w-10 h-10 rounded-full flex items-center justify-center z-10">
        <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="m9 18 6-6-6-6"/></svg>
      </button>
    </div>
  </div>
</section>

<section id="section-popular" class="border-b border-soft reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="flex items-end justify-between mb-7 flex-wrap gap-3">
      <h2 class="display text-3xl md:text-4xl">Popular</h2>
      <a href="#" class="text-sm font-medium underline underline-offset-4 hover:opacity-60">View all</a>
    </div>
    <div id="grid-popular" class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-2.5 md:gap-3"></div>
  </div>
</section>

<section id="section-new" class="border-b border-soft surface-3 reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="flex items-end justify-between mb-7 flex-wrap gap-3">
      <h2 class="display text-3xl md:text-4xl">New</h2>
      <a href="#" class="text-sm font-medium underline underline-offset-4 hover:opacity-60">View all</a>
    </div>
    <div id="grid-new" class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-2.5 md:gap-3"></div>
  </div>
</section>

<section id="section-outfits" class="border-b border-soft reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="flex items-end justify-between mb-7 flex-wrap gap-3">
      <h2 class="display text-3xl md:text-4xl">Outfits</h2>
      <a href="#" class="text-sm font-medium underline underline-offset-4 hover:opacity-60">View all</a>
    </div>
    <div id="grid-outfits" class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3 md:gap-4"></div>
  </div>
</section>

<section id="section-sellers" class="border-b border-soft surface-3 reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="flex items-end justify-between mb-7 flex-wrap gap-3">
      <h2 class="display text-3xl md:text-4xl">Sellers</h2>
      <a href="#" class="text-sm font-medium underline underline-offset-4 hover:opacity-60">View all</a>
    </div>
    <div id="grid-sellers" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 md:gap-4"></div>
  </div>
</section>

<section id="section-cat" class="border-b border-soft reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="flex items-end justify-between mb-7 flex-wrap gap-3">
      <h2 class="display text-3xl md:text-4xl" id="grid-title">All Products</h2>
      <div class="flex items-center gap-3">
        <span id="result-count" class="text-sm muted">— results</span>
        <button id="reset-cat" class="text-sm font-medium underline underline-offset-4 hover:opacity-60 hidden">Reset</button>
      </div>
    </div>
    <div id="grid-all" class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-2.5 md:gap-3"></div>
  </div>
</section>

<section id="section-agents" class="border-b border-soft surface-3 reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="mb-8 max-w-2xl">
      <h2 class="display text-3xl md:text-4xl mb-3">Buy through any agent</h2>
      <p class="muted">We don't sell &mdash; we surface what others received. Click through to your favourite shipping agent.</p>
    </div>
    <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3" id="grid-agents"></div>
  </div>
</section>

<section id="section-tools" class="border-b border-soft reveal">
  <div class="max-w-[1320px] mx-auto px-6 section">
    <div class="grid lg:grid-cols-2 gap-12 items-center">
      <div>
        <div class="text-xs font-mono uppercase tracking-widest muted mb-3">Tool</div>
        <h2 class="display text-3xl md:text-5xl mb-4">One link.<br/>Every agent.</h2>
        <p class="muted mb-6">Paste any Taobao, Weidian or 1688 URL &mdash; get purchase links for every agent. Free, no tracking.</p>
        <ul class="space-y-2 text-sm">
          <li class="flex items-start gap-2"><span class="muted">&mdash;</span><span>12+ agents (KakoBuy, CSSBuy, AllChinaBuy, Oopbuy, CNFans, Sugargoo…)</span></li>
          <li class="flex items-start gap-2"><span class="muted">&mdash;</span><span>Auto-detects source platform</span></li>
          <li class="flex items-start gap-2"><span class="muted">&mdash;</span><span>Browser extension coming soon</span></li>
        </ul>
      </div>

      <div class="surface-2 p-6 rounded-3xl">
        <div class="search-shell-mini rounded-full flex items-center px-5 py-1 bg-white">
          <svg class="w-4 h-4 muted-2 mr-3 flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
          <input id="convert-input" type="text" placeholder="https://weidian.com/item.html?itemID=..." class="flex-1 bg-transparent py-3 outline-none text-sm" />
        </div>
        <div id="convert-results" class="space-y-2 mt-5 max-h-72 overflow-auto no-scrollbar">
          <div class="text-xs muted font-mono text-center py-8">paste URL above to convert...</div>
        </div>
      </div>
    </div>
  </div>
</section>

<section class="border-b border-soft relative overflow-hidden" style="background: #09090b; color: white;">
  <div class="hidden md:block absolute left-[8%] top-1/2 -translate-y-1/2 cta-float-1">
    <div class="bg-white text-black rounded-2xl p-3 shadow-2xl w-44">
      <div class="card-img aspect-square mb-2 rounded-lg overflow-hidden">
        <img src="https://picsum.photos/seed/cta1/200/200" class="w-full h-full object-cover"/>
      </div>
      <div class="text-xs font-semibold">Knit hoodie</div>
      <div class="text-[11px] muted">¥145 · 7 QCs</div>
    </div>
  </div>
  <div class="hidden md:block absolute right-[8%] top-1/2 -translate-y-1/2 cta-float-2">
    <div class="bg-white text-black rounded-2xl p-3 shadow-2xl w-44">
      <div class="card-img aspect-square mb-2 rounded-lg overflow-hidden">
        <img src="https://picsum.photos/seed/cta2/200/200" class="w-full h-full object-cover"/>
      </div>
      <div class="text-xs font-semibold">Cargo pants</div>
      <div class="text-[11px] muted">¥89 · 4 QCs</div>
    </div>
  </div>

  <svg class="absolute top-[20%] left-[35%] w-5 h-5 sparkle-1" viewBox="0 0 24 24" fill="#f5a3c7"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
  <svg class="absolute top-[30%] right-[35%] w-4 h-4 sparkle-2" viewBox="0 0 24 24" fill="#fbbf24"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>
  <svg class="absolute bottom-[20%] left-[40%] w-3 h-3 sparkle-3" viewBox="0 0 24 24" fill="#c084fc"><path d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/></svg>

  <div class="max-w-[1320px] mx-auto px-6 py-28 text-center relative">
    <h2 class="display text-5xl md:text-7xl mb-5">Found something good?</h2>
    <p class="opacity-70 mb-9 max-w-md mx-auto text-lg">Share it. The community runs on great finds.</p>
    <div class="flex items-center justify-center gap-3 flex-wrap">
      <button onclick="openSubmitModal()" class="bg-white text-black px-7 py-3.5 text-sm font-semibold rounded-full hover:opacity-90 transition">Submit a find</button>
      <button class="border border-white/30 text-white px-7 py-3.5 text-sm font-semibold rounded-full hover:bg-white hover:text-black transition">How it works</button>
    </div>
  </div>
</section>


<div id="toast" class="toast"></div>


<script>
  // ====================================================================
  // HOMEPAGE-SPECIFIC LOGIC
  // ====================================================================
  let products = [], outfits = [], sellers = [], agents = [], categoriesData = [];

  const homeState = { searchQuery: '', activeCategory: null };

  // ---- RENDER HELPERS ------------------------------------------------
  function productCard(p) {
    const stackImgs = [];
    for (let i = 0; i < Math.min(p.qcs, 2); i++) {
      stackImgs.push(`<div class="qc-stack-img"><img src="https://picsum.photos/seed/qc-${p.id}-${i}/40/40" alt="" class="w-full h-full object-cover"/></div>`);
    }
    const liked = state.liked.has(p.id);
    return `
      <a href="${productUrl(p.id, p.title)}" class="card group block fade-in">
        <div class="card-img aspect-[4/5] mb-2">
          <img src="${p.img}" alt="${escapeHtml(p.title)}" class="w-full h-full object-cover" loading="lazy"/>
          ${p.new ? '<div class="new-badge">New</div>' : ''}
          <div class="qc-stack">
            <div class="qc-stack-imgs">${stackImgs.join('')}</div>
            <span>+${p.qcs}</span>
          </div>
          <button onclick="event.preventDefault(); event.stopPropagation(); toggleLike(${p.id}, this)" class="heart-btn ${liked ? 'liked' : ''} absolute bottom-2 right-2 surface w-7 h-7 rounded-full flex items-center justify-center transition opacity-0 group-hover:opacity-100 hover:scale-110 shadow-sm">
            <svg class="w-3 h-3" viewBox="0 0 24 24" fill="${liked ? 'currentColor' : 'none'}" stroke="currentColor" stroke-width="2"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.29 1.51 4.04 3 5.5l7 7Z"/></svg>
          </button>
        </div>
        <div class="px-0.5">
          <h3 class="text-xs md:text-sm font-medium truncate">${escapeHtml(p.title)}</h3>
          <div class="flex items-center justify-between mt-0.5 gap-1">
            <p class="text-[11px] muted truncate">${escapeHtml(p.shop || '')}</p>
            <div class="text-xs md:text-sm font-semibold whitespace-nowrap">¥${p.price}</div>
          </div>
        </div>
      </a>
    `;
  }

  function renderPopular() {
    document.getElementById('grid-popular').innerHTML = products.filter(p => p.popular).slice(0, 12).map(productCard).join('') || '<div class="col-span-full text-sm muted">No popular items yet.</div>';
  }
  function renderNew() {
    document.getElementById('grid-new').innerHTML = products.filter(p => p.new).slice(0, 12).map(productCard).join('') || '<div class="col-span-full text-sm muted">No new items yet.</div>';
  }
  function renderOutfits() {
    document.getElementById('grid-outfits').innerHTML = outfits.map(o => `
      <a href="${outfitUrl(o.id, o.title)}" class="card group block fade-in">
        <div class="card-img relative aspect-[3/4] mb-2.5">
          <img src="${o.img}" alt="${escapeHtml(o.title)}" class="w-full h-full object-cover" loading="lazy"/>
          <div class="absolute top-3 right-3 surface text-[11px] font-medium px-2.5 py-1 rounded-full shadow-sm">${o.items} items</div>
          <div class="absolute bottom-3 left-3 right-3">
            <div class="bg-white/95 backdrop-blur px-3 py-2 rounded-xl flex items-center justify-between">
              <div class="min-w-0">
                <div class="text-xs font-semibold truncate">${escapeHtml(o.title)}</div>
                <div class="text-[10px] muted">${escapeHtml(o.user)}</div>
              </div>
              <div class="text-xs font-medium">♥ ${o.likes}</div>
            </div>
          </div>
        </div>
      </a>
    `).join('');
  }
  function renderSellers() {
    document.getElementById('grid-sellers').innerHTML = sellers.map(s => {
      const followed = state.followed.has(s.id);
      return `
        <article class="card group fade-in surface border border-soft rounded-3xl overflow-hidden hover:border-default transition">
          <div class="aspect-[5/3] surface-2 overflow-hidden">
            <img src="${s.img || ''}" alt="" class="w-full h-full object-cover group-hover:scale-105 transition duration-500"/>
          </div>
          <div class="p-5 flex items-center gap-3">
            <div class="w-12 h-12 rounded-full overflow-hidden surface-2 -mt-12 border-4 border-white flex-shrink-0">
              <img src="${s.avatar || ''}" alt="" class="w-full h-full object-cover"/>
            </div>
            <div class="flex-1 min-w-0">
              <div class="font-semibold truncate">${escapeHtml(s.name)}</div>
              <div class="text-xs muted truncate">${escapeHtml(s.tagline || '')}</div>
            </div>
            <button onclick="toggleFollow(${s.id}, this)" class="follow-btn btn-primary ${followed ? 'following' : ''} text-xs font-semibold px-4 py-2 rounded-full flex-shrink-0">${followed ? 'Following' : 'Follow'}</button>
          </div>
          <div class="px-5 pb-5 flex items-center gap-3 text-xs muted">
            <span>★ ${s.rating}</span><span>•</span><span>${s.followers} followers</span><span>•</span><span>${s.items} items</span>
          </div>
        </article>
      `;
    }).join('');
  }
  function renderAll() {
    let filtered = products;
    if (homeState.searchQuery) {
      const q = homeState.searchQuery.toLowerCase();
      filtered = filtered.filter(p =>
        p.title.toLowerCase().includes(q) ||
        (p.shop || '').toLowerCase().includes(q) ||
        (p.cat || '').toLowerCase().includes(q)
      );
    }
    if (homeState.activeCategory && !['popular','new','outfits','sellers'].includes(homeState.activeCategory)) {
      filtered = filtered.filter(p => p.cat === homeState.activeCategory);
    } else if (homeState.activeCategory === 'popular') {
      filtered = filtered.filter(p => p.popular);
    } else if (homeState.activeCategory === 'new') {
      filtered = filtered.filter(p => p.new);
    }
    const grid = document.getElementById('grid-all');
    document.getElementById('result-count').textContent = `${filtered.length} result${filtered.length === 1 ? '' : 's'}`;
    if (filtered.length === 0) {
      grid.innerHTML = `<div class="col-span-full text-center py-16"><div class="text-2xl font-semibold mb-2">No matches</div><p class="muted text-sm">Try a different search or category.</p></div>`;
    } else {
      grid.innerHTML = filtered.map(productCard).join('');
    }
    const cat = categoriesData.find(c => c.id === homeState.activeCategory);
    document.getElementById('grid-title').textContent = homeState.searchQuery ? `Results for "${homeState.searchQuery}"` : (cat ? cat.name : 'All Products');
    document.getElementById('reset-cat').classList.toggle('hidden', !homeState.searchQuery && !homeState.activeCategory);
  }
  function renderAgents() {
    document.getElementById('grid-agents').innerHTML = agents.map(a => `
      <a href="https://${a.url}" target="_blank" rel="noopener" class="surface p-5 rounded-2xl border border-soft hover:border-default transition group">
        <div class="flex items-start justify-between mb-1.5">
          <div class="text-lg font-bold">${escapeHtml(a.name)}</div>
          <svg class="w-4 h-4 muted-2 group-hover:text-black transition mt-1.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 17L17 7M7 7h10v10"/></svg>
        </div>
        <div class="text-xs muted font-mono">${escapeHtml(a.url)}</div>
        ${a.tag ? `<div class="mt-3 inline-block text-[10px] font-mono uppercase tracking-wider surface-2 px-2 py-1 rounded-full">${escapeHtml(a.tag)}</div>` : ''}
      </a>
    `).join('');
  }
  function renderCategories() {
    document.getElementById('cat-scroll').innerHTML = categoriesData.map(c => `
      <button class="cat-item flex-shrink-0 flex flex-col items-center gap-2 group ${homeState.activeCategory === c.id ? 'active' : ''}" data-cat="${c.id}">
        <div class="cat-circle"><img src="${c.img}" alt="" class="w-full h-full object-cover"/></div>
        <span class="cat-label text-xs md:text-sm font-medium">${escapeHtml(c.name)}</span>
      </button>
    `).join('');
    document.querySelectorAll('.cat-item').forEach(el => {
      el.addEventListener('click', () => {
        const id = el.dataset.cat;
        if (['popular','new','outfits','sellers'].includes(id)) { scrollToSection('section-' + id); return; }
        homeState.activeCategory = homeState.activeCategory === id ? null : id;
        homeState.searchQuery = '';
        document.getElementById('search-input').value = '';
        document.getElementById('header-search-input').value = '';
        renderCategories();
        renderAll();
        scrollToSection('section-cat');
      });
    });
  }
  function renderHeroSellers() {
    const styles = ['float-1', 'float-2', 'float-3'];
    const margins = ['-8px', '12px', '-4px'];
    const opacities = ['', '', 'opacity-70'];
    document.getElementById('hero-sellers').innerHTML = sellers.slice(0, 3).map((s, i) => {
      const followed = state.followed.has(s.id);
      return `
        <div class="${styles[i]} surface border border-default rounded-2xl p-3 flex items-center gap-3 shadow-sm ${opacities[i]}" style="margin-left: ${margins[i]};">
          <div class="w-9 h-9 rounded-full overflow-hidden flex-shrink-0 surface-2"><img src="${s.avatar || ''}" alt="" class="w-full h-full object-cover"/></div>
          <div class="flex-1 min-w-0">
            <div class="text-sm font-semibold truncate">${escapeHtml(s.name)}</div>
            <div class="text-[11px] muted">★ ${s.rating} · ${s.followers} Followers</div>
          </div>
          <button onclick="toggleFollow(${s.id}, this)" class="follow-btn btn-primary ${followed ? 'following' : ''} text-xs font-semibold px-3.5 py-1.5 rounded-full">${followed ? 'Following' : 'Follow'}</button>
        </div>
      `;
    }).join('');
  }
  function renderBento() {
    const featured = products.find(p => p.popular) || products[0];
    if (featured) {
      document.getElementById('bento-mini-card').innerHTML = `
        <a href="${productUrl(featured.id, featured.title)}" class="block bg-white text-black rounded-2xl p-2.5 shadow-2xl w-32 hover:scale-105 transition">
          <div class="card-img aspect-square mb-1.5 rounded-md overflow-hidden"><img src="${featured.img}" class="w-full h-full object-cover"/></div>
          <div class="text-[11px] font-semibold truncate">${escapeHtml(featured.title)}</div>
          <div class="text-[10px] muted">¥${featured.price} · ${featured.qcs} QCs</div>
        </a>`;
    }
    const featuredOutfit = outfits[0];
    if (featuredOutfit) {
      document.getElementById('bento-outfit-title').textContent = featuredOutfit.title + '.';
      document.getElementById('bento-outfit-user').textContent = featuredOutfit.user;
      document.getElementById('bento-outfit-meta').textContent = `${featuredOutfit.items} tagged items`;
    }
    const featuredSeller = sellers[0];
    if (featuredSeller) {
      const followed = state.followed.has(featuredSeller.id);
      document.getElementById('bento-seller-card').innerHTML = `
        <div class="text-[11px] font-mono uppercase tracking-widest muted mb-2.5">Seller spotlight</div>
        <div class="flex items-center gap-3 mb-2">
          <div class="w-10 h-10 rounded-full surface overflow-hidden border border-default flex-shrink-0"><img src="${featuredSeller.avatar || ''}" class="w-full h-full object-cover"/></div>
          <div class="min-w-0">
            <div class="font-bold text-base truncate">${escapeHtml(featuredSeller.name)}</div>
            <div class="text-xs muted">★ ${featuredSeller.rating} · ${featuredSeller.followers} followers</div>
          </div>
        </div>
        <p class="text-xs muted leading-relaxed mb-auto">${escapeHtml(featuredSeller.tagline || '')}. ${featuredSeller.items} items.</p>
        <div class="flex items-center gap-1.5 mt-3 mb-3">
          ${products.filter(p => p.shop === featuredSeller.name).slice(0,3).map(p => `<div class="w-9 h-9 rounded-lg overflow-hidden surface border border-default"><img src="${p.img}" class="w-full h-full object-cover"/></div>`).join('')}
          ${featuredSeller.items > 3 ? `<div class="w-9 h-9 rounded-lg surface border border-default flex items-center justify-center text-[10px] font-mono muted">+${featuredSeller.items - 3}</div>` : ''}
        </div>
        <div class="flex items-end justify-between">
          <button onclick="event.preventDefault(); event.stopPropagation(); toggleFollow(${featuredSeller.id}, this)" class="follow-btn btn-primary ${followed ? 'following' : ''} text-xs font-semibold px-3.5 py-1.5 rounded-full">${followed ? 'Following' : 'Follow'}</button>
          <svg class="w-4 h-4 muted-2 group-hover:text-black group-hover:translate-x-0.5 transition" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 17L17 7M7 7h10v10"/></svg>
        </div>
      `;
    }
    document.getElementById('bento-live-count').textContent = `Live · ${products.filter(p => p.new).length} new finds`;
    document.getElementById('bento-agent-count').textContent = `${agents.length} agents`;
    document.getElementById('hero-counter').textContent = `${products.length.toLocaleString()} finds`;
  }

  // ---- LIKES / FOLLOWS (with auth + API) -----------------------------
  window.toggleLike = (id, btn) => {
    if (!state.user) { openAuthModal('signin'); toast('Sign in to save items'); return; }
    const wasLiked = state.liked.has(id);
    if (wasLiked) {
      state.liked.delete(id);
      btn.classList.remove('liked');
      btn.querySelector('svg').setAttribute('fill', 'none');
    } else {
      state.liked.add(id);
      btn.classList.add('liked', 'just-liked');
      btn.querySelector('svg').setAttribute('fill', 'currentColor');
      for (let i = 0; i < 6; i++) {
        const angle = (i / 6) * Math.PI * 2;
        const dist = 28 + Math.random() * 8;
        const particle = document.createElement('span');
        particle.className = 'burst-particle';
        particle.style.setProperty('--tx', Math.cos(angle) * dist + 'px');
        particle.style.setProperty('--ty', Math.sin(angle) * dist + 'px');
        btn.appendChild(particle);
        setTimeout(() => particle.remove(), 700);
      }
      setTimeout(() => btn.classList.remove('just-liked'), 500);
    }
    renderAccountUI();
    fetch(`${API_BASE}/likes.php`, {
      method: 'POST', headers: {'Content-Type':'application/json'}, credentials: 'same-origin',
      body: JSON.stringify({ product_id: id }),
    }).then(r => r.json()).then(j => { if (!j.ok) throw new Error(j.error); }).catch(() => {
      if (wasLiked) state.liked.add(id); else state.liked.delete(id);
      renderAccountUI();
      toast('Could not save — try again', true);
    });
  };

  window.toggleFollow = (id, btn) => {
    if (!state.user) { openAuthModal('signin'); toast('Sign in to follow sellers'); return; }
    const wasFollowed = state.followed.has(id);
    if (wasFollowed) {
      state.followed.delete(id);
      btn.classList.remove('following');
      btn.textContent = 'Follow';
    } else {
      state.followed.add(id);
      btn.classList.add('following');
      btn.textContent = 'Following';
    }
    renderAccountUI();
    fetch(`${API_BASE}/follows.php`, {
      method: 'POST', headers: {'Content-Type':'application/json'}, credentials: 'same-origin',
      body: JSON.stringify({ seller_id: id }),
    }).then(r => r.json()).then(j => { if (!j.ok) throw new Error(j.error); }).catch(() => {
      if (wasFollowed) { state.followed.add(id); btn.classList.add('following'); btn.textContent = 'Following'; }
      else             { state.followed.delete(id); btn.classList.remove('following'); btn.textContent = 'Follow'; }
      renderAccountUI();
      toast('Could not update — try again', true);
    });
  };

  function scrollToSection(id) {
    document.getElementById(id)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  }

  // ---- SEARCH --------------------------------------------------------
  function handleSearch(value) {
    homeState.searchQuery = value;
    homeState.activeCategory = null;
    document.getElementById('search-input').value = value;
    document.getElementById('header-search-input').value = value;
    renderCategories();
    renderAll();
  }
  document.getElementById('search-input').addEventListener('input', e => { handleSearch(e.target.value); if (e.target.value) scrollToSection('section-cat'); });
  document.getElementById('header-search-input').addEventListener('input', e => { handleSearch(e.target.value); if (e.target.value) scrollToSection('section-cat'); });
  document.getElementById('reset-cat').addEventListener('click', () => handleSearch(''));
  document.getElementById('cat-scroll-right').addEventListener('click', () => document.getElementById('cat-scroll').scrollBy({ left: 320, behavior: 'smooth' }));

  // ---- LINK CONVERTER ------------------------------------------------
  function convertLink(url, targetEl) {
    if (!url) { targetEl.innerHTML = '<div class="text-xs muted font-mono text-center py-8">paste URL above to convert...</div>'; return; }
    targetEl.innerHTML = agents.map(a => `
      <a href="${a.tpl}${encodeURIComponent(url)}" target="_blank" rel="noopener" class="flex items-center justify-between surface p-3 rounded-2xl hover:bg-black hover:text-white transition group">
        <div class="flex items-center gap-3">
          <div class="font-semibold text-sm">${escapeHtml(a.name)}</div>
          <div class="text-xs opacity-60 font-mono hidden sm:block">${escapeHtml(a.url)}</div>
        </div>
        <svg class="w-4 h-4 opacity-50 group-hover:opacity-100 transition" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 17L17 7M7 7h10v10"/></svg>
      </a>
    `).join('');
  }
  document.getElementById('convert-input').addEventListener('input', e => convertLink(e.target.value.trim(), document.getElementById('convert-results')));

  // ---- LOAD DATA -----------------------------------------------------
  async function loadHome() {
    try {
      const [p, o, s, a, c] = await Promise.all([
        fetchJson('products.php?limit=200'),
        fetchJson('outfits.php?limit=12'),
        fetchJson('sellers.php?limit=12'),
        fetchJson('agents.php'),
        fetchJson('categories.php'),
      ]);
      products = p; outfits = o; sellers = s; agents = a; categoriesData = c;
      renderCategories(); renderPopular(); renderNew(); renderOutfits();
      renderSellers(); renderAll(); renderAgents(); renderHeroSellers(); renderBento();
    } catch (err) {
      console.error(err);
      toast('Could not load data — check your API connection.', true);
    }
  }

  // Wait for auth to be ready (so we know likes/follows state), then load home
  document.addEventListener('auth:ready', loadHome, { once: true });
  document.addEventListener('auth:changed', () => {
    // Re-render grids when user signs in/out so hearts/follow buttons reflect state
    renderPopular(); renderNew(); renderAll(); renderSellers(); renderHeroSellers(); renderBento();
  });
</script>
</body>
</html>
