// components.jsx — Shared UI: ListingCard variants, Nav, Filters, TrustBar, etc.

const { useState, useEffect, useRef, useMemo } = React;

// ─────────────────────────────────────────────────────────────
// NotifBell — bildirim ikonu + dropdown + polling
// ─────────────────────────────────────────────────────────────
function NotifBell({ L, lang }) {
  const [items, setItems] = useState([]);
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const ref = useRef(null);

  const unread = items.filter(n => !n.is_read).length;

  // Polling
  useEffect(() => {
    let alive = true;
    const fetch = async () => {
      if (!window.api || !window.api.isLoggedIn()) return;
      try {
        const res = await window.api.notifications.list();
        if (alive && res?.data) setItems(res.data);
      } catch {}
    };
    fetch();
    const id = setInterval(fetch, 30000); // 30sn
    return () => { alive = false; clearInterval(id); };
  }, []);

  // Dış tıklama kapatma
  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  const onOpen = async () => {
    setOpen(o => !o);
    if (!open && unread > 0 && window.api?.isLoggedIn()) {
      try {
        await window.api.notifications.readAll();
        setItems(prev => prev.map(n => ({ ...n, is_read: true })));
      } catch {}
    }
  };

  // Demo verisi (login değilse veya API boşsa)
  const demoItems = !window.api?.isLoggedIn() ? [
    { id: 'd1', type: 'message', title: lang === 'tr' ? 'Yeni mesaj' : 'New message', body: lang === 'tr' ? '@citytrails sana yazdı' : '@citytrails messaged you', created_at: new Date(Date.now() - 5*60000).toISOString(), is_read: false, link: 'panelim.html#mesajlar' },
    { id: 'd2', type: 'order', title: lang === 'tr' ? 'Sipariş onayı' : 'Order confirmed', body: lang === 'tr' ? '@velvet.looks · ödeme alındı' : '@velvet.looks · payment received', created_at: new Date(Date.now() - 2*3600000).toISOString(), is_read: false, link: 'panelim.html#siparisler' },
    { id: 'd3', type: 'system', title: lang === 'tr' ? 'Hoş geldin' : 'Welcome', body: lang === 'tr' ? 'InstaSatış\'a hoş geldin!' : 'Welcome to InstaSatış!', created_at: new Date(Date.now() - 24*3600000).toISOString(), is_read: true, link: null },
  ] : [];
  const display = items.length ? items : demoItems;
  const unreadDisplay = display.filter(n => !n.is_read).length;

  const fmtTime = (iso) => {
    const d = new Date(iso);
    const diff = (Date.now() - d.getTime()) / 1000;
    if (diff < 60) return lang === 'tr' ? 'şimdi' : 'now';
    if (diff < 3600) return Math.floor(diff/60) + (lang === 'tr' ? ' dk' : 'm');
    if (diff < 86400) return Math.floor(diff/3600) + (lang === 'tr' ? ' sa' : 'h');
    return Math.floor(diff/86400) + (lang === 'tr' ? ' g' : 'd');
  };

  const iconFor = (t) => ({ message: 'mail', order: 'tag', listing: 'sparkle', system: 'bell', payment: 'tag' }[t] || 'bell');

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button onClick={onOpen} className="is-btn is-btn-ghost"
              style={{ padding: '8px 10px', position: 'relative' }}
              aria-label="Bildirimler">
        <Icon name="bell" size={16}/>
        {unreadDisplay > 0 && (
          <span style={{
            position: 'absolute', top: 4, right: 4,
            minWidth: 16, height: 16, borderRadius: 8, padding: '0 4px',
            background: 'var(--danger)', color: '#fff',
            fontSize: 10, fontWeight: 700, fontFamily: 'var(--font-mono)',
            display: 'grid', placeItems: 'center',
            border: '2px solid var(--bg)',
          }}>{unreadDisplay > 9 ? '9+' : unreadDisplay}</span>
        )}
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 8px)', right: 0,
          width: 360, maxHeight: 480, overflow: 'auto',
          background: 'var(--card)', borderRadius: 14,
          border: '1px solid var(--line-2)',
          boxShadow: '0 12px 40px rgba(0,0,0,0.12)',
          zIndex: 200,
        }}>
          <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--line-2)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div style={{ fontWeight: 600, fontSize: 14 }}>{lang === 'tr' ? 'Bildirimler' : 'Notifications'}</div>
            {unreadDisplay > 0 && <div style={{ fontSize: 11, color: 'var(--accent)', fontFamily: 'var(--font-mono)', textTransform: 'uppercase' }}>{unreadDisplay} {lang === 'tr' ? 'YENİ' : 'NEW'}</div>}
          </div>
          {display.length === 0 ? (
            <div style={{ padding: 40, textAlign: 'center', color: 'var(--ink-3)' }}>
              <Icon name="bell" size={28}/>
              <div style={{ marginTop: 10, fontSize: 13 }}>{lang === 'tr' ? 'Henüz bildirim yok' : 'No notifications yet'}</div>
            </div>
          ) : (
            <div>
              {display.map(n => (
                <a key={n.id} href={n.link || '#'}
                   style={{
                     display: 'flex', gap: 12, padding: '14px 16px',
                     borderBottom: '1px solid var(--line-2)',
                     textDecoration: 'none', color: 'inherit',
                     background: n.is_read ? 'transparent' : 'color-mix(in oklab, var(--accent) 5%, transparent)',
                     cursor: 'pointer',
                   }}>
                  <span style={{
                    width: 36, height: 36, borderRadius: 10,
                    background: 'var(--chip)', color: 'var(--accent)',
                    display: 'grid', placeItems: 'center', flexShrink: 0,
                  }}>
                    <Icon name={iconFor(n.type)} size={16}/>
                  </span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, marginBottom: 3 }}>
                      <div style={{ fontWeight: 600, fontSize: 13 }}>{n.title}</div>
                      <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', flexShrink: 0 }}>{fmtTime(n.created_at)}</div>
                    </div>
                    <div style={{ fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.4 }}>{n.body}</div>
                  </div>
                  {!n.is_read && <span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--accent)', flexShrink: 0, alignSelf: 'center' }}/>}
                </a>
              ))}
            </div>
          )}
          <a href="panelim.html#bildirimler" style={{
            display: 'block', padding: '12px 16px', textAlign: 'center',
            fontSize: 12, color: 'var(--accent)', fontWeight: 600,
            textDecoration: 'none', borderTop: '1px solid var(--line-2)',
            fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '.06em',
          }}>{lang === 'tr' ? 'Tümünü Gör' : 'View All'}</a>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// TopNav — used in desktop ekranlarda
// ─────────────────────────────────────────────────────────────
function TopNav({ L, lang, setLang, active, onNav, onAuth, compact }) {
  const live = typeof window !== 'undefined' && window.__IS_LIVE_SITE;
  const items = [
    { id: 'home', label: L.nav_explore, href: 'index.html' },
    { id: 'compare', label: lang === 'en' ? 'Compare' : 'Karşılaştır', href: 'karsilastir.html' },
    { id: 'how', label: L.nav_how, href: 'aged-hesap-nedir.html' },
    { id: 'about', label: L.nav_about, href: 'hakkinda.html' },
  ];
  // Logged-in user state (read from api-client.js)
  const [me, setMe] = useState(() => (typeof window !== 'undefined' && window.api?.getUser?.()) || null);
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    if (!window.api) return;
    const sync = () => setMe(window.api.getUser?.() || null);
    // Refresh on focus / storage change
    window.addEventListener('focus', sync);
    window.addEventListener('storage', sync);
    return () => {
      window.removeEventListener('focus', sync);
      window.removeEventListener('storage', sync);
    };
  }, []);
  const logout = async () => {
    try { await window.api?.auth?.logout?.(); } catch {}
    setMe(null);
    if (live) window.location.href = 'index.html';
  };
  const handleAuth = (m) => {
    if (onAuth) return onAuth(m);
    if (live) window.location.href = 'giris.html';
  };
  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 30,
      background: 'color-mix(in oklab, var(--bg) 82%, transparent)',
      backdropFilter: 'blur(18px) saturate(180%)',
      WebkitBackdropFilter: 'blur(18px) saturate(180%)',
      borderBottom: '1px solid var(--line-2)',
    }}>
      <div style={{
        maxWidth: 1280, margin: '0 auto', padding: compact ? '12px 24px' : '16px 32px',
        display: 'flex', alignItems: 'center', gap: 28,
      }}>
        <a href={live ? 'index.html' : undefined}
           onClick={() => !live && onNav && onNav('home')}
           style={{ cursor: 'pointer', textDecoration: 'none' }}><Logo size={32}/></a>
        <nav style={{ display: 'flex', gap: 4, marginLeft: 12 }}>
          {items.map(it => (
            <a key={it.id}
               href={live ? it.href : undefined}
               onClick={() => !live && onNav && onNav(it.id)}
               style={{
                 padding: '8px 12px', borderRadius: 10, fontSize: 14, fontWeight: 500,
                 color: active === it.id ? 'var(--ink)' : 'var(--ink-2)',
                 background: active === it.id ? 'var(--chip)' : 'transparent',
                 cursor: 'pointer', textDecoration: 'none',
               }}>{it.label}</a>
          ))}
        </nav>
        <div style={{ flex: 1 }}/>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <button className="is-btn is-btn-ghost" onClick={() => setLang(lang === 'tr' ? 'en' : 'tr')}
                  style={{ padding: '8px 12px', fontSize: 13, fontFamily: 'var(--font-mono)', textTransform: 'uppercase' }}>
            <Icon name="globe" size={14}/> {lang}
          </button>
          {live && <NotifBell L={L} lang={lang}/>}
          <a href={live ? 'ilan-ver.html' : undefined}
             onClick={(e) => { if (!live) { e.preventDefault(); onNav && onNav('sell'); } }}
             className="is-btn"
             style={{
               padding: '9px 14px', textDecoration: 'none',
               background: 'var(--ink)', color: 'var(--bg)', border: 0,
               fontWeight: 600, gap: 6,
             }}>
            <Icon name="plus" size={14} strokeWidth={2.4}/> {L.nav_sell || 'İlan Ver'}
          </a>
          {me ? (
            <div style={{ position: 'relative' }}>
              <button onClick={() => setMenuOpen(o => !o)} className="is-btn" style={{
                padding: '6px 10px 6px 6px', gap: 8,
                background: 'var(--chip)', color: 'var(--ink)', fontWeight: 600,
              }}>
                <span style={{
                  width: 28, height: 28, borderRadius: '50%', background: 'var(--grad)',
                  color: '#fff', display: 'grid', placeItems: 'center',
                  fontSize: 12, fontWeight: 700, fontFamily: 'var(--font-display)',
                }}>{(me.name || me.email || '?').charAt(0).toUpperCase()}</span>
                <span style={{ fontSize: 13, maxWidth: 100, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {me.name || me.email?.split('@')[0]}
                </span>
                <Icon name="chevron-down" size={12}/>
              </button>
              {menuOpen && (
                <div style={{
                  position: 'absolute', top: 'calc(100% + 6px)', right: 0,
                  minWidth: 200, background: 'var(--card)',
                  border: '1px solid var(--line-2)', borderRadius: 12,
                  boxShadow: '0 12px 40px rgba(0,0,0,.12)', zIndex: 50, overflow: 'hidden',
                }}>
                  <div style={{ padding: '12px 14px', borderBottom: '1px solid var(--line-2)' }}>
                    <div style={{ fontWeight: 600, fontSize: 13 }}>{me.name || '—'}</div>
                    <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{me.email}</div>
                  </div>
                  {[
                    { label: 'Panelim', href: 'panelim.html', icon: 'grid' },
                    { label: 'İlanlarım', href: 'panelim.html?tab=listings', icon: 'tag' },
                    { label: 'Mesajlar', href: 'panelim.html?tab=messages', icon: 'mail' },
                    { label: 'Güvenlik', href: 'panelim.html?tab=security', icon: 'shield' },
                  ].map(it => (
                    <a key={it.label} href={it.href} style={{
                      display: 'flex', alignItems: 'center', gap: 10,
                      padding: '10px 14px', fontSize: 13, color: 'var(--ink)',
                      textDecoration: 'none',
                    }}>
                      <Icon name={it.icon} size={14}/> {it.label}
                    </a>
                  ))}
                  <button onClick={logout} style={{
                    width: '100%', display: 'flex', alignItems: 'center', gap: 10,
                    padding: '10px 14px', fontSize: 13, color: '#dc2626',
                    background: 'transparent', border: 0, borderTop: '1px solid var(--line-2)',
                    cursor: 'pointer', textAlign: 'left',
                  }}>
                    <Icon name="x" size={14}/> Çıkış yap
                  </button>
                </div>
              )}
            </div>
          ) : (
            <>
              <button className="is-btn is-btn-outline" onClick={() => handleAuth('login')} style={{ padding: '9px 16px' }}>
                {L.auth_tab_login}
              </button>
              <button className="is-btn is-btn-primary" onClick={() => handleAuth('signup')} style={{ padding: '9px 16px' }}>
                {L.auth_tab_signup}
              </button>
            </>
          )}
        </div>
      </div>
    </header>
  );
}

// ─────────────────────────────────────────────────────────────
// TrustBar — small inline row of trust signals
// ─────────────────────────────────────────────────────────────
function TrustBar({ L, compact = false }) {
  const items = [
    { icon: 'lock', label: L.trust_ssl },
    { icon: 'tag', label: L.trust_card },
    { icon: 'shield', label: L.trust_iban },
    { icon: 'check', label: L.trust_refund },
  ];
  return (
    <div style={{
      display: 'flex', gap: compact ? 14 : 22, alignItems: 'center',
      flexWrap: 'wrap', color: 'var(--ink-3)',
      fontSize: compact ? 12 : 13,
    }}>
      {items.map((it, i) => (
        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
          <span style={{
            width: 22, height: 22, borderRadius: 6,
            background: 'var(--chip)', display: 'grid', placeItems: 'center', color: 'var(--accent)',
          }}>
            <Icon name={it.icon} size={12} strokeWidth={2}/>
          </span>
          <span style={{ fontWeight: 500 }}>{it.label}</span>
        </div>
      ))}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Badge (NEW / HOT / RARE)
// ─────────────────────────────────────────────────────────────
function StatusBadge({ kind, L }) {
  if (!kind) return null;
  const map = {
    new: { bg: 'var(--success)', label: L.new_badge, icon: 'sparkle' },
    hot: { bg: 'var(--danger)', label: L.hot_badge, icon: 'flame' },
    rare: { bg: 'var(--grad)', label: L.rare_badge, icon: 'star' },
  };
  const m = map[kind]; if (!m) return null;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '4px 9px', borderRadius: 999,
      background: m.bg, color: '#fff', fontSize: 10, fontWeight: 700,
      letterSpacing: '0.08em', fontFamily: 'var(--font-mono)',
    }}>
      <Icon name={m.icon} size={10} strokeWidth={2.3}/> {m.label}
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// ListingCard — 3 layout variants
//   layout='grid'     → square post grid + stats underneath (default)
//   layout='passport' → left info / right post mosaic (novel, "passport")
//   layout='stat'     → stat radar hero, minimal posts (numbers-forward)
// ─────────────────────────────────────────────────────────────
function ListingCard({ listing, L, lang, layout = 'grid', onView, onToggleFav, isFav }) {
  const l = listing;
  const nicheLabel = L[`niche_${l.niche}`] || l.niche;

  if (layout === 'passport') {
    return (
      <div className="is-card" style={{ padding: 'var(--card-pad)', display: 'flex', gap: 14, cursor: 'pointer' }}
           onClick={() => onView && onView(l)}>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <Avatar handle={l.handle} postsStyle={l.postsStyle} size={40}/>
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 4, fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 15, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                {l.handle}
                {l.verified && <Icon name="verified" size={14} color="var(--accent)"/>}
              </div>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{nicheLabel.toUpperCase()} · {l.country}</div>
            </div>
            <FavBtn active={isFav} onClick={(e) => { e.stopPropagation(); onToggleFav && onToggleFav(l.id); }}/>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, marginTop: 2 }}>
            <Stat icon="users" value={fmtNum(l.followers)} label={L.card_followers}/>
            <Stat icon="calendar" value={fmtAge(l.age, lang, L)} label={L.card_age}/>
          </div>
          <div style={{ marginTop: 'auto', display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 10, paddingTop: 8 }}>
            <div>
              <div style={{ fontSize: 10, letterSpacing: '0.1em', color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{L.price_ttl.toUpperCase()}</div>
              <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 20, letterSpacing: '-0.02em' }}>{fmtPrice(l.price, lang)}</div>
            </div>
            <StatusBadge kind={l.badge} L={L}/>
          </div>
        </div>
        <div style={{ width: 108, flexShrink: 0 }}>
          <PostGrid handle={l.handle} postsStyle={l.postsStyle} cols={2} rows={3} gap={3} radius={6}/>
        </div>
      </div>
    );
  }

  if (layout === 'stat') {
    return (
      <div className="is-card" style={{ padding: 'var(--card-pad)', cursor: 'pointer' }}
           onClick={() => onView && onView(l)}>
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 10 }}>
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 17, letterSpacing: '-0.02em' }}>
              {l.handle}
              {l.verified && <Icon name="verified" size={14} color="var(--accent)"/>}
            </div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', marginTop: 2 }}>{nicheLabel.toUpperCase()}</div>
          </div>
          <FavBtn active={isFav} onClick={(e) => { e.stopPropagation(); onToggleFav && onToggleFav(l.id); }}/>
        </div>
        {/* Big gradient number */}
        <div style={{ margin: '14px 0 10px', display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <div className="is-grad-text" style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 44, letterSpacing: '-0.04em', lineHeight: 1 }}>
            {fmtNum(l.followers)}
          </div>
          <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{L.card_followers}</div>
        </div>
        <div style={{ display: 'flex', gap: 4 }}>
          {Array.from({ length: 9 }).map((_, i) => {
            const active = i < Math.round((l.er / 10) * 9);
            return <div key={i} style={{ flex: 1, height: 4, borderRadius: 2, background: active ? 'var(--grad)' : 'var(--chip)' }}/>;
          })}
        </div>
        <div style={{ marginTop: 6, fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', display: 'flex', justifyContent: 'space-between' }}>
          <span>ER {l.er.toFixed(1)}%</span>
          <span>{fmtAge(l.age, lang, L)}</span>
        </div>
        <div style={{ marginTop: 14, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 22, letterSpacing: '-0.02em' }}>
            {fmtPrice(l.price, lang)}
          </div>
          <StatusBadge kind={l.badge} L={L}/>
        </div>
      </div>
    );
  }

  // default: grid
  return (
    <div className="is-card" style={{ cursor: 'pointer', display: 'flex', flexDirection: 'column' }}
         onClick={() => onView && onView(l)}>
      <div style={{ position: 'relative', padding: 2 }}>
        <PostGrid handle={l.handle} postsStyle={l.postsStyle} cols={3} rows={3} gap={2} radius={0}/>
        <div style={{ position: 'absolute', top: 10, left: 10, display: 'flex', gap: 6 }}>
          <StatusBadge kind={l.badge} L={L}/>
        </div>
        <div style={{ position: 'absolute', top: 10, right: 10 }}>
          <FavBtn active={isFav} onClick={(e) => { e.stopPropagation(); onToggleFav && onToggleFav(l.id); }}/>
        </div>
      </div>
      <div style={{ padding: 'var(--card-pad)', display: 'flex', flexDirection: 'column', gap: 10 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Avatar handle={l.handle} postsStyle={l.postsStyle} size={38} ring={false}/>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 4, fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 15, color: 'var(--ink)' }}>
              {l.handle}
              {l.verified && <Icon name="verified" size={14} color="var(--accent)"/>}
            </div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{nicheLabel.toUpperCase()}</div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <MiniStat icon="users" value={fmtNum(l.followers)}/>
          <MiniStat icon="calendar" value={fmtAge(l.age, lang, L)}/>
          <MiniStat icon="bolt" value={`${l.er.toFixed(1)}%`}/>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginTop: 2 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 20, letterSpacing: '-0.02em' }}>
            {fmtPrice(l.price, lang)}
          </div>
          <button className="is-btn is-btn-primary" style={{ padding: '8px 14px', fontSize: 13 }} onClick={(e) => { e.stopPropagation(); onView && onView(l); }}>
            {L.card_view}
          </button>
        </div>
      </div>
    </div>
  );
}

function Stat({ icon, value, label }) {
  return (
    <div style={{
      background: 'var(--chip)', borderRadius: 10, padding: '8px 10px',
      display: 'flex', flexDirection: 'column', gap: 2,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 5, color: 'var(--ink-3)' }}>
        <Icon name={icon} size={12}/>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>{label}</span>
      </div>
      <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 15, letterSpacing: '-0.01em' }}>{value}</div>
    </div>
  );
}
function MiniStat({ icon, value }) {
  return (
    <div className="is-chip" style={{ gap: 5 }}>
      <Icon name={icon} size={12}/> {value}
    </div>
  );
}
function FavBtn({ active, onClick }) {
  return (
    <button onClick={onClick} style={{
      width: 34, height: 34, borderRadius: '50%', border: 0, cursor: 'pointer',
      background: active ? 'var(--grad)' : 'rgba(255,255,255,0.9)',
      color: active ? '#fff' : 'oklch(0.48 0.02 280)',
      display: 'grid', placeItems: 'center', padding: 0,
      boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
      transition: 'transform .15s',
    }}
    onMouseEnter={(e) => e.currentTarget.style.transform = 'scale(1.08)'}
    onMouseLeave={(e) => e.currentTarget.style.transform = 'scale(1)'}
    >
      <Icon name={active ? 'heart-fill' : 'heart'} size={16}/>
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// Filter sidebar
// ─────────────────────────────────────────────────────────────
function FilterPanel({ L, filters, setFilters, compact = false }) {
  const toggle = (key, v) => setFilters(f => ({ ...f, [key]: f[key] === v ? null : v }));
  const niches = ['fashion','food','travel','meme','sport','tech','art','lifestyle','music','beauty','fitness','auto'];
  const ages = [{k:'any', label: L.age_any},{k:'1', label: L.age_1},{k:'3', label: L.age_3},{k:'5', label: L.age_5}];

  return (
    <aside style={{ width: compact ? '100%' : 260, display: 'flex', flexDirection: 'column', gap: 22 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 18 }}>{L.filter_title}</div>
        <button onClick={() => setFilters({ age: 'any', niche: null, followers: null, priceMax: null })}
                style={{ background: 'none', border: 0, color: 'var(--ink-3)', fontSize: 12, cursor: 'pointer', fontFamily: 'var(--font-mono)' }}>
          {L.filter_reset}
        </button>
      </div>

      <FilterSection label={L.filter_age}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
          {ages.map(a => (
            <button key={a.k} onClick={() => setFilters(f => ({ ...f, age: a.k }))}
                    style={filterChipStyle(filters.age === a.k)}>{a.label}</button>
          ))}
        </div>
      </FilterSection>

      <FilterSection label={L.filter_niche}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {niches.map(n => (
            <button key={n} onClick={() => toggle('niche', n)} style={filterChipStyle(filters.niche === n)}>
              <span style={{ width: 8, height: 8, borderRadius: '50%', background: `linear-gradient(135deg, ${NICHE_COLORS[n][0]}, ${NICHE_COLORS[n][1]})`, marginRight: 6, display: 'inline-block' }}/>
              {L[`niche_${n}`]}
            </button>
          ))}
        </div>
      </FilterSection>

      <FilterSection label={L.filter_followers}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {[{k:'10k', label:'1K–10K'},{k:'100k', label:'10K–100K'},{k:'1m', label:'100K+'}].map(f => (
            <button key={f.k} onClick={() => toggle('followers', f.k)} style={filterChipStyle(filters.followers === f.k)}>{f.label}</button>
          ))}
        </div>
      </FilterSection>

      <FilterSection label={L.filter_price}>
        <PriceSlider value={filters.priceMax ?? 35000} onChange={(v) => setFilters(f => ({ ...f, priceMax: v }))}/>
      </FilterSection>
    </aside>
  );
}
function FilterSection({ label, children }) {
  return (
    <div>
      <div className="is-kicker" style={{ marginBottom: 10 }}>{label}</div>
      {children}
    </div>
  );
}
function filterChipStyle(active) {
  return {
    padding: '8px 12px', borderRadius: 999, border: 0,
    fontSize: 12, fontWeight: 500, cursor: 'pointer',
    background: active ? 'var(--grad)' : 'var(--chip)',
    color: active ? '#fff' : 'var(--ink-2)',
    fontFamily: 'var(--font-body)',
    display: 'inline-flex', alignItems: 'center',
  };
}
function PriceSlider({ value, onChange }) {
  return (
    <div>
      <input type="range" min="2000" max="35000" step="500" value={value}
             onChange={e => onChange(+e.target.value)}
             style={{ width: '100%', accentColor: 'oklch(0.66 0.22 350)' }}/>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--ink-3)', marginTop: 4 }}>
        <span>2.000 ₺</span>
        <span style={{ color: 'var(--ink)', fontWeight: 600 }}>≤ {fmtPrice(value, 'tr')}</span>
        <span>35.000 ₺</span>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// SortBar
// ─────────────────────────────────────────────────────────────
function SortBar({ L, sort, setSort, count, layout, setLayout }) {
  const opts = [
    { k: 'new', label: L.sort_new },
    { k: 'price_low', label: L.sort_price_low },
    { k: 'price_high', label: L.sort_price_high },
    { k: 'followers', label: L.sort_followers },
    { k: 'age', label: L.sort_age },
  ];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
      <div style={{ color: 'var(--ink-3)', fontSize: 13, fontFamily: 'var(--font-mono)' }}>
        <span style={{ color: 'var(--ink)', fontWeight: 600 }}>{count}</span> {L.stat_listings}
      </div>
      <div style={{ flex: 1 }}/>
      <div style={{ display: 'flex', gap: 4, background: 'var(--chip)', padding: 3, borderRadius: 10 }}>
        {opts.map(o => (
          <button key={o.k} onClick={() => setSort(o.k)}
                  style={{
                    border: 0, padding: '6px 12px', borderRadius: 8, cursor: 'pointer',
                    background: sort === o.k ? 'var(--card)' : 'transparent',
                    color: sort === o.k ? 'var(--ink)' : 'var(--ink-2)',
                    boxShadow: sort === o.k ? '0 1px 3px rgba(0,0,0,.08)' : 'none',
                    fontSize: 12, fontWeight: 500, fontFamily: 'var(--font-body)',
                  }}>{o.label}</button>
        ))}
      </div>
      {setLayout && (
        <div style={{ display: 'flex', gap: 2, background: 'var(--chip)', padding: 3, borderRadius: 10 }}>
          {['grid','passport','stat'].map(l => (
            <button key={l} onClick={() => setLayout(l)} title={l}
                    style={{
                      border: 0, padding: '6px 10px', borderRadius: 8, cursor: 'pointer',
                      background: layout === l ? 'var(--card)' : 'transparent',
                      color: layout === l ? 'var(--ink)' : 'var(--ink-2)',
                      fontSize: 11, fontWeight: 600, fontFamily: 'var(--font-mono)', textTransform: 'uppercase',
                    }}>{l}</button>
          ))}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// ScreenFrame — consistent wrapper for each artboard
// ─────────────────────────────────────────────────────────────
function ScreenFrame({ children, width, height, theme, label }) {
  return (
    <div className="is-surface" style={{
      ...theme, width, height, overflow: 'hidden', position: 'relative',
      fontFamily: 'var(--font-body)',
    }}>
      {children}
    </div>
  );
}

Object.assign(window, {
  TopNav, TrustBar, StatusBadge, ListingCard, Stat, MiniStat, FavBtn,
  FilterPanel, FilterSection, PriceSlider, SortBar, ScreenFrame,
  NotifBell,
});
