/* global React */
const { useState: useStateC, useEffect: useEffectC, useRef: useRefC, useMemo: useMemoC } = React;

const PLATFORM_ICONS_C = window.PLATFORM_ICONS;

// ===== Rating — compact star + number on catalog card =====
// Разбивка по критериям и обоснования остались в TrustMap внутри модалки
// профиля. На карточке — только звезда+цифра, без отдельной ссылки: клик
// по всей карточке открывает профиль блогера.

function RatingMicro({ rating, rb }) {
  let n = Number(rating) || 0;
  if (!n && rb) {
    const scores = ['independence', 'transparency', 'accuracy']
      .map(k => Number(rb[k]?.score) || 0)
      .filter(s => s > 0);
    if (scores.length) n = scores.reduce((a, b) => a + b, 0) / scores.length;
  }
  if (n <= 0) return null;

  return (
    <span className="rbar-link" title={`Рейтинг доверия ${n.toFixed(1)}`}>
      <span className="rbar-star" aria-hidden="true">
        <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
          <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
        </svg>
      </span>
      <span className="rbar-num">{n.toFixed(1)}</span>
    </span>
  );
}

window.RatingMicro = RatingMicro;

// ===== Sparkline =====
function Sparkline({ data, up=true }) {
  const w = 100, h = 36;
  if (!Array.isArray(data) || data.length < 2) {
    return (
      <div className="bcard-spark bcard-spark-empty" aria-hidden="true">
        <span>собираем историю подписчиков…</span>
      </div>
    );
  }
  // Зеро-бейзлайн как у большого графика в профиле — без визуального обмана
  // на тонких суточных колебаниях (61-подписчиковый дрейф не растягивается на всю высоту).
  const max = Math.max(...data) || 1;
  const pts = data.map((v,i)=>{
    const x = (i/(data.length-1))*w;
    const y = h - (v/max)*h*0.85 - 3;
    return `${x},${y}`;
  }).join(" ");
  const c = up ? "#26d97f" : "#ff5757";
  return (
    <div className="bcard-spark" title={`${data.length} точек · история подписчиков`}>
      <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
        <defs>
          <linearGradient id={`sg-${up}`} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={c} stopOpacity="0.35"/>
            <stop offset="100%" stopColor={c} stopOpacity="0"/>
          </linearGradient>
        </defs>
        <polygon points={`0,${h} ${pts} ${w},${h}`} fill={`url(#sg-${up})`}/>
        <polyline points={pts} fill="none" stroke={c} strokeWidth="1.5"/>
      </svg>
    </div>
  );
}

// ===== Top Authors — sticky horizontal scroll driven by vertical scroll =====
function TopAuthors({ bloggers, onOpenProfile }) {
  const sectionRef = useRefC(null);
  const railRef = useRefC(null);
  const [progress, setProgress] = useStateC(0); // 0..1

  const top = useMemoC(() => {
    const manualIds = (window.TOP_AUTHOR_IDS || []).filter(Boolean);
    if (manualIds.length > 0) {
      const byId = new Map(bloggers.map(b => [b.id, b]));
      const ordered = manualIds.map(id => byId.get(id)).filter(Boolean);
      if (ordered.length > 0) return ordered;
    }
    // По умолчанию — рейтинг (5.0 → 0). Tiebreak по охвату, чтобы при равных
    // оценках первым шёл автор с большей аудиторией.
    return [...bloggers]
      .sort((a, b) => (b.rating - a.rating) || (b.totalSubs - a.totalSubs))
      .slice(0, 8);
  }, [bloggers]);

  useEffectC(() => {
    let raf = 0;
    function onScroll() {
      if (raf) cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const sec = sectionRef.current;
        if (!sec) return;
        const rect = sec.getBoundingClientRect();
        const stickyEl = sec.querySelector(".top-authors-sticky");
        const stickyH = stickyEl ? stickyEl.offsetHeight : window.innerHeight;
        const total = sec.offsetHeight - stickyH;
        if (total <= 0) { setProgress(0); return; }
        const p = Math.min(1, Math.max(0, -rect.top / total));
        setProgress(p);
      });
    }
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, []);

  // translateX depends on how far the rail is wider than the viewport
  const translateX = useMemoC(() => {
    if (!railRef.current) return 0;
    const rail = railRef.current;
    const diff = Math.max(0, rail.scrollWidth - window.innerWidth + 48);
    return -diff * progress;
  }, [progress, top.length]);

  return (
    <section className="top-authors-section" id="rankings" ref={sectionRef}>
      <div className="top-authors-sticky">
        <div className="container">
          <div className="section-head">
            <div className="section-head-left">
              <div className="s-kicker bare">Лучшие из лучших</div>
              <h2>Рейтинг авторов</h2>
            </div>
          </div>
        </div>
        <div className="top-rail-viewport">
          <div className="top-rail" ref={railRef} style={{transform:`translate3d(${translateX}px,0,0)`}}>
            {top.map((b, i) => {
              const medalCls = i < 3 ? ` leader-card-medal leader-card-medal-${i+1}` : "";
              return (
              <div key={b.id} className={"leader-card" + medalCls} onClick={()=>onOpenProfile(b)}>
                <div className="leader-rank">#{String(i+1).padStart(2,"0")}</div>
                <div className="leader-head">
                  <window.Avatar b={b} size={52} radius={14} className="leader-avatar" />
                  <div className="leader-info">
                    <h3>{b.name}</h3>
                    <div className="leader-handle">{b.handle}</div>
                    <div className="leader-verified">
                      {b.rating > 0 && (
                        <span className="leader-rating" title={`${b.reviews||0} оценок`}>
                          <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
                          {Number(b.rating).toFixed(1)}
                        </span>
                      )}
                      <span>с {b.since}</span>
                    </div>
                  </div>
                </div>
                <div className="leader-bio">{b.bio}</div>
                <div className="leader-specs">
                  {b.specs.slice(0,3).map(s=><span key={s} className="spec-pill">{s}</span>)}
                </div>
                <div className="leader-stats">
                  <div className="leader-subs">
                    <div className="leader-subs-num num">{window.fmtK(b.totalSubs)}</div>
                    <div className="leader-subs-label">Суммарно</div>
                  </div>
                  <div className="leader-platforms">
                    {b.platforms.map((p,j)=>(
                      <span key={j} className="social-dot" data-p={p.k} title={`${p.name} · ${window.fmtK(p.subs)}`} aria-hidden="true">
                        <window.PlatIcon p={p.k} size={14} />
                      </span>
                    ))}
                  </div>
                </div>
              </div>
              );
            })}
          </div>
        </div>
      </div>
    </section>
  );
}

// ===== Blogger Card =====
function BloggerCard({ b, onOpen }) {
  const ref = useRefC(null);
  const badgesArr = Array.isArray(b.badges) ? b.badges : [];
  const isEditorsChoice = badgesArr.some(x => typeof x === "string" && /Выбор\s+редакции/i.test(x));
  const isGoldFrame    = badgesArr.some(x => typeof x === "string" && /Золотая\s+рамка/i.test(x));
  const onMove = (e) => {
    if (!ref.current) return;
    const r = ref.current.getBoundingClientRect();
    ref.current.style.setProperty("--mx", (e.clientX - r.left) + "px");
    ref.current.style.setProperty("--my", (e.clientY - r.top) + "px");
  };
  return (
    <div
      className={
        "bcard"
        + (isEditorsChoice ? " bcard-editors-choice" : "")
        + (isGoldFrame    ? " bcard-gold-frame"     : "")
      }
      ref={ref}
      onMouseMove={onMove}
      onClick={()=>onOpen(b)}
    >
      <div className="bcard-top">
        <window.Avatar b={b} size={44} radius={12} className="bcard-avatar" />
        <div style={{minWidth:0,flex:1}}>
          <div className="bcard-name">{b.name}</div>
          <div className="bcard-handle">{b.handle}</div>
        </div>
      </div>
      {b.rating > 0 && (
        <div className="bcard-rating-row">
          <RatingMicro rating={b.rating} rb={b.ratingBreakdown} />
        </div>
      )}
      <div className="bcard-bio">{b.bio}</div>
      <div className="bcard-specs">
        {b.specs.slice(0,3).map(s=><span key={s} className="spec-pill">{s}</span>)}
      </div>
      {(() => {
        const visible = badgesArr.filter(x => !(typeof x === "string" && /Золотая\s+рамка/i.test(x)));
        if (visible.length === 0) return null;
        return (
          <div className="bcard-badges">
            {visible.map((bg, i) => <span key={i} className="bcard-badge">{bg}</span>)}
          </div>
        );
      })()}
      <div className="bcard-socials">
        <div className="bcard-stat-block">
          <div className="bcard-stat-num num">{window.fmtK(b.totalSubs)}</div>
          <div className="bcard-stat-label">Подписчиков</div>
        </div>
        <div className="bcard-socials-right">
          {b.platforms.map((p,i)=>(
            <span key={i} className="social-dot" data-p={p.k} title={`${p.name} · ${window.fmtK(p.subs)}`} aria-hidden="true">
              <window.PlatIcon p={p.k} size={14} />
            </span>
          ))}
        </div>
      </div>
    </div>
  );
}

// ===== Catalog =====
function Catalog({ bloggers, onOpenProfile }) {
  const [query, setQuery] = useStateC("");
  const [specFilter, setSpecFilter] = useStateC([]);
  const [platFilter, setPlatFilter] = useStateC([]);
  const [levelFilter, setLevelFilter] = useStateC([]);
  const [minSubs, setMinSubs] = useStateC(0);
  const [sort, setSort] = useStateC("subs");
  const [view, setView] = useStateC("grid");

  const allSpecs = useMemoC(() => [...new Set(bloggers.flatMap(b=>b.specs))], [bloggers]);
  // Все платформы, на которых реально есть хоть один блогер — иначе фильтр был
  // зашит в 5 значений (tg/yt/vk/ig/sl) и расходился с модалкой.
  const allPlats = useMemoC(
    () => [...new Set(bloggers.flatMap(b => (b.platforms || []).map(p => p.k)))].filter(Boolean),
    [bloggers]
  );
  const allLevels = useMemoC(() => [...new Set(bloggers.map(b=>b.level).filter(Boolean))], [bloggers]);

  const filtered = useMemoC(() => {
    const q = query.trim().toLowerCase();
    let list = bloggers.filter(b => {
      if (q) {
        const hay = (b.name + " " + (b.handle||"") + " " + (b.bio||"") + " " + b.specs.join(" ")).toLowerCase();
        if (!hay.includes(q)) return false;
      }
      if (specFilter.length && !specFilter.some(s => b.specs.includes(s))) return false;
      if (platFilter.length && !platFilter.some(p => b.platforms.some(bp=>bp.k===p))) return false;
      if (levelFilter.length && !levelFilter.includes(b.level)) return false;
      if (b.totalSubs < minSubs) return false;
      return true;
    });
    list.sort((a,b)=>{
      if (sort==="rating") return b.rating-a.rating;
      if (sort==="subs") return b.totalSubs-a.totalSubs;
      if (sort==="new") return b.since-a.since;
      return 0;
    });
    return list;
  }, [bloggers, query, specFilter, platFilter, levelFilter, minSubs, sort]);

  const toggle = (setter, val) => setter(prev => prev.includes(val) ? prev.filter(x=>x!==val) : [...prev, val]);
  const resetAll = () => { setQuery(""); setSpecFilter([]); setPlatFilter([]); setLevelFilter([]); setMinSubs(0); };

  const activeCount = specFilter.length + platFilter.length + levelFilter.length + (minSubs>0?1:0) + (query.trim() ? 1 : 0);

  return (
    <section className="catalog-section" id="catalog">
      <div className="container">
        <div className="section-head" style={{marginBottom:24}}>
          <div className="section-head-left">
            <div className="s-kicker bare">все {bloggers.length} авторов</div>
            <h2>Найди своего автора</h2>
          </div>
        </div>

        <div className="catalog-search">
          <span className="catalog-search-icon" aria-hidden>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
          </span>
          <input
            className="catalog-search-input"
            type="text"
            placeholder="Поиск по имени, нику или тематике"
            value={query}
            onChange={(e)=>setQuery(e.target.value)}
          />
          {query && (
            <button className="catalog-search-clear" onClick={()=>setQuery("")} aria-label="Очистить">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            </button>
          )}
        </div>

        <button className="filter-sheet-toggle" onClick={()=>document.body.classList.toggle("mobile-filters-open")}>
          <span style={{display:"inline-flex",alignItems:"center",gap:8}}>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
            Фильтры
          </span>
          {activeCount > 0 && <span className="fs-count">{activeCount}</span>}
        </button>

        <div className="catalog-layout">
          <aside className="filters-panel desktop-only">
            <div className="filters-head">
              <h3>Фильтры {activeCount > 0 && <span style={{color:"var(--green)",fontFamily:"var(--mono)",fontSize:11}}>· {activeCount}</span>}</h3>
              <button className="reset-all" onClick={resetAll}>Сбросить</button>
            </div>

            <div className="filter-group">
              <div className="filter-group-label">Тематика</div>
              <div className="filter-chips">
                {allSpecs.map(s => (
                  <button key={s} className={"fchip " + (specFilter.includes(s)?"active":"")} onClick={()=>toggle(setSpecFilter,s)}>{s}</button>
                ))}
              </div>
            </div>

            <div className="filter-group">
              <div className="filter-group-label">Площадка</div>
              <div className="filter-chips">
                {allPlats.map(p => (
                  <button key={p} className={"fchip " + (platFilter.includes(p)?"active":"")} onClick={()=>toggle(setPlatFilter,p)}
                    style={{display:"inline-flex",alignItems:"center",gap:5}}>
                    <window.PlatIcon p={p} size={11}/> {p.toUpperCase()}
                  </button>
                ))}
              </div>
            </div>

            <div className="filter-group">
              <div className="filter-group-label">Мин. подписчиков</div>
              <div className="filter-range">
                <input type="range" min="0" max="500000" step="10000" value={minSubs} onChange={e=>setMinSubs(+e.target.value)}/>
                <span style={{minWidth:48,textAlign:"right"}}>{window.fmtK(minSubs)}+</span>
              </div>
            </div>
          </aside>

          <div className="catalog-main">
            <div className="catalog-toolbar">
              <div className="results-count">Найдено <b>{filtered.length}</b> автор{filtered.length===1?"":(filtered.length<5?"а":"ов")}</div>
              <div style={{display:"flex",gap:10}}>
                <div className="view-toggle">
                  <button className={view==="grid"?"active":""} onClick={()=>setView("grid")}>
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
                    Сетка
                  </button>
                  <button className={view==="list"?"active":""} onClick={()=>setView("list")}>
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
                    Список
                  </button>
                </div>
                <div className="sort-dropdown">
                  Сорт: <b onClick={()=>{
                    const order = ["rating","subs","new"];
                    setSort(order[(order.indexOf(sort)+1) % 3]);
                  }}>{sort==="rating"?"По рейтингу":sort==="subs"?"По охвату":"Новые"}</b>
                </div>
              </div>
            </div>

            <div className={"bloggers-grid " + (view==="list"?"list-view":"")}>
              {filtered.map(b => <BloggerCard key={b.id} b={b} onOpen={onOpenProfile}/>)}
              {filtered.length === 0 && (
                <div style={{gridColumn:"1/-1",padding:"60px 20px",textAlign:"center",color:"var(--text-3)"}}>
                  Ничего не найдено. Попробуйте сбросить фильтры.
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ===== Collections =====
function Collections({ bloggers, onOpenCollection }) {
  const colls = window.COLLECTIONS;
  const sizeFor = (i) => i===0?"featured":i===1?"wide":i===2?"wide":"normal";
  return (
    <section className="collections-section" id="collections">
      <div className="container">
        <div className="section-head">
          <div className="section-head-left">
            <div className="s-kicker bare">кураторские</div>
            <h2>Подборки под твою задачу</h2>
          </div>
        </div>
        <div className="collections-grid">
          {colls.map((c, i) => {
            const authors = c.ids.map(id => bloggers.find(b=>b.id===id)).filter(Boolean);
            return (
              <div key={c.id} className={"coll-card " + sizeFor(i)} style={{"--coll-c": c.accent}} onClick={()=>onOpenCollection(c, authors)}>
                <span className="coll-mono num">{c.hero}</span>
                <span className="coll-tag">Коллекция · {c.count}</span>
                <h3>{c.title}</h3>
                <p>{c.sub}</p>
                <div className="coll-footer">
                  <div className="coll-avs">
                    {authors.slice(0,3).map(a=>(
                      <window.Avatar key={a.id} b={a} size={26} radius={999} className="ca" />
                    ))}
                    {c.count > 3 && <span className="ca" style={{background:"rgba(255,255,255,0.1)"}}>+{c.count-3}</span>}
                  </div>
                  <span className="coll-arrow">Открыть →</span>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ===== Partners trust-bar (бегущая строка) =====
function PartnersStrip({ partners = [], onOpenAll }) {
  if (!partners.length) return null;

  // Повторяем список до длины >= 8, чтобы одна «группа» перекрывала ширину экрана;
  // рендерим две идентичные группы и крутим трек на -50% — бесшовный цикл.
  const loop = [];
  while (loop.length < 8) loop.push(...partners);

  const Logo = (p, i) => {
    const img = <img className="partner-logo" src={p.logo} alt={p.name} loading="lazy" />;
    const style = { "--accent": p.accent || "#fff" };
    // У партнёра со ссылкой — видимая подсказка «На сайт →» при наведении (affordance перехода).
    return p.url
      ? (
        <a key={i} className="partner-item has-link" style={style} href={p.url} target="_blank" rel="noopener" aria-label={p.name + " — перейти на сайт"}>
          {img}
          <span className="partner-tip">На сайт →</span>
        </a>
      )
      : <span key={i} className="partner-item" style={style} title={p.name}>{img}</span>;
  };

  return (
    <section className="partners-section" id="partners">
      <div className="container">
        <div className="section-head">
          <div className="section-head-left">
            <div className="s-kicker bare">партнёры</div>
            <h2>Наши партнёры</h2>
          </div>
          {onOpenAll ? (
            <button type="button" className="partners-more" onClick={onOpenAll}>
              Подробнее <span aria-hidden="true">→</span>
            </button>
          ) : null}
        </div>
      </div>
      <div className="partners-marquee" aria-label="Партнёры проекта">
        <div className="partners-track">
          <div className="partners-group">{loop.map(Logo)}</div>
          <div className="partners-group" aria-hidden="true">{loop.map(Logo)}</div>
        </div>
      </div>
    </section>
  );
}

// ===== About =====
function About() {
  const yearsOnMarket = new Date().getFullYear() - 2015;
  return (
    <section className="about-section" id="about">
      <div className="container">
        <div className="about-grid">
          <div className="about-mission">
            <div className="s-kicker" style={{marginBottom:10}}>{yearsOnMarket} {window.plur(yearsOnMarket,"год","года","лет")}</div>
            <h2>Мы — не агрегатор.<br/>Мы — <span className="accent">отборный</span> каталог.</h2>
            <p className="about-lede">Берём только авторов, прошедших ручную проверку. История постов, реальные метрики — всё на виду.</p>
            <p className="about-text">Мы отсеиваем шум, чтобы вы могли сосредоточиться на качественном контенте. Каждый автор в базе прошёл отбор — мы анализируем экспертизу, регулярность публикаций, качество подачи и реальную пользу для читателей.</p>
          </div>
          <div className="about-panel">
            <div className="year-display num"><span className="year-prefix">с</span>2015</div>
            <h3>Команда из тех, кто сам делал каналы</h3>
            <div className="roles-list">
              <div className="role-row">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
                <div className="role-row-text"><h4>Маркетологи</h4><p>Растим каналы и выстраиваем доверие аудитории</p></div>
              </div>
              <div className="role-row">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
                <div className="role-row-text"><h4>Разработчики</h4><p>Создаём инструменты, которые делают рынок прозрачнее</p></div>
              </div>
              <div className="role-row">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>
                <div className="role-row-text"><h4>Продюсеры</h4><p>Строили каналы, запускали проекты, растили авторов</p></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ===== Bloggers-only invite =====
function BloggersInvite({ bloggers = [] }) {
  const sample = bloggers.slice(0, 6);
  const rest = Math.max(0, bloggers.length - sample.length);
  return (
    <section className="bloggers-invite-section" id="bloggers-invite">
      <div className="container">
        <div className="bi-panel">
          <div className="bi-content">
            <span className="bi-kicker">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2">
                <rect x="4" y="11" width="16" height="10" rx="2"/>
                <path d="M8 11V7a4 4 0 0 1 8 0v4"/>
              </svg>
              Только для блогеров
            </span>
            <h2>Закрытый чат авторов каталога</h2>
            <p className="bi-lede">
              Сообщество проверенных инвест-блогеров: обмен опытом, взаимные интеграции и совместные проекты.
            </p>
            <div className="bi-actions">
              <a className="btn btn-primary btn-lg bi-cta" href={window.BLOGGERS_CHAT_INVITE_URL || "https://t.me/+hCxjBCBEaG8wODQy"} target="_blank" rel="noopener">
                <window.PlatIcon p="tg" size={16}/> Вступить в чат
              </a>
              <span className="bi-note">заявку проверяет админ · только активные авторы</span>
            </div>
          </div>
          {sample.length > 0 && (
            <div className="bi-members" aria-hidden="true">
              <div className="bi-status">
                <span className="bi-status-dot"></span>
                <span>приватный чат</span>
              </div>
              <div className="bi-avatars">
                {sample.map((b, i) => (
                  <div key={b.id || i} className="bi-av" style={{zIndex: sample.length - i}}>
                    <window.Avatar b={b} size={44} radius={999} />
                  </div>
                ))}
                {rest > 0 && <div className="bi-av-more num">+{rest}</div>}
              </div>
              <div className="bi-members-label">авторов уже внутри</div>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

// ===== CTAs =====
function CTASection({ onOpenAdd }) {
  return (
    <section className="cta-section">
      <div className="container">
        <div className="cta-grid">
          <div className="cta-tile" data-cta="add">
            <span className="cta-kicker">ДЛЯ АВТОРОВ</span>
            <h3>Знаете достойного автора?</h3>
            <p>Предложите блогера в базу — мы проверим и добавим его в каталог. Размещение бесплатное.</p>
            <button className="btn btn-primary cta-btn" onClick={onOpenAdd}>Предложить автора →</button>
          </div>
          <div className="cta-tile" data-cta="ad">
            <span className="cta-kicker">ДЛЯ РЕКЛАМОДАТЕЛЕЙ</span>
            <h3>Ищете каналы для интеграции?</h3>
            <p>Подберём авторов под задачу. Прямой контакт, без агентских накруток.</p>
            <button className="btn btn-outline cta-btn">Запрос подборки →</button>
          </div>
          <div className="cta-tile" data-cta="help">
            <span className="cta-kicker">ПОМОЩЬ</span>
            <h3>Есть вопрос?</h3>
            <p>Наш саппорт отвечает в Telegram в будни 10:00 – 20:00 МСК. Честно и без отписок.</p>
            <a className="btn btn-outline cta-btn" href="https://t.me/investbloggers_manager" target="_blank" rel="noopener">
              <window.PlatIcon p="tg" size={14}/> Написать в поддержку
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

window.TopAuthors = TopAuthors;
window.Catalog = Catalog;
window.Collections = Collections;
window.PartnersStrip = PartnersStrip;
window.About = About;
window.BloggersInvite = BloggersInvite;
window.CTASection = CTASection;
