/* ==========================================================
   NewsNator — Page: Maker profile + Makers list
   ========================================================== */

// ============= MAKERS LIST PAGE ===========================
function MakersListPage() {
  const [sort, setSort] = useState('mrr');
  const sorted = useMemo(() => {
    return [...MAKERS].sort((a,b) => {
      if (sort === 'mrr') return (b.totalMrr || 0) - (a.totalMrr || 0);
      if (sort === 'products') return b.products.length - a.products.length;
      if (sort === 'alpha') return a.name.localeCompare(b.name);
      return 0;
    });
  }, [sort]);

  return (
    <div className="page-enter" style={{padding:'56px 0 80px'}}>
      <div className="container">
        <div className="eyebrow mb-4">/ {t('nav_makers')}</div>
        <h1 className="title-xl" style={{marginBottom:14}}>
          {window.__lang === 'zh' ? '100 位独立创业者' : '100 indie builders'}
        </h1>
        <p className="lede" style={{maxWidth:'56ch', marginBottom: 32}}>
          {window.__lang === 'zh'
            ? '我们追踪的每一位创业者 —— 他们的产品、工具栈、MRR 走势和最近的公开动态。仅基于公开来源整理。'
            : 'Every builder we track — their products, tool stack, MRR trajectory and most recent public moves. All from public sources.'}
        </p>

        <NewsletterStrip variant="makers"/>

        <div className="flex items-center gap-3 mb-6" style={{paddingBottom:14, borderBottom:'1px solid var(--border)'}}>
          <span className="mono faint" style={{fontSize:11, letterSpacing:'0.06em'}}>SORT</span>
          {[
            {id:'mrr', label:'Portfolio MRR'},
            {id:'products', label:'# of products'},
            {id:'alpha', label:'A–Z'},
          ].map(s => (
            <button key={s.id} onClick={()=>setSort(s.id)}
                    className="mono"
                    style={{padding:'4px 10px', borderRadius:'var(--r-sm)', fontSize:11, whiteSpace:'nowrap',
                            border:'1px solid ' + (sort === s.id ? 'var(--fg)' : 'transparent'),
                            background: sort === s.id ? 'var(--bg-sunken)' : 'transparent',
                            color: sort === s.id ? 'var(--fg)' : 'var(--fg-muted)'}}>
              {s.label}
            </button>
          ))}
          <div className="grow"/>
          <span className="mono faint" style={{fontSize:11}}>{sorted.length} / 100</span>
        </div>

        <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:16}}>
          {sorted.map(m => <MakerCardCompact key={m.slug} maker={m}/>)}
        </div>
      </div>

      <OPCIntro/>
    </div>
  );
}

// ----------------- OPC Intro (footer of builders page) -----------------
function OPCIntro() {
  const isZh = window.__lang === 'zh';
  return (
    <section style={{borderTop:'1px solid var(--border)', marginTop:80, padding:'96px 0 80px', background:'var(--bg-elev)'}}>
      <div className="container">
        <div className="eyebrow mb-6">{isZh ? '关于 opc.how' : 'About opc.how'}</div>

        {/* Full wordmark — the brand mark in full lockup */}
        <div style={{padding:'40px 0 56px', display:'flex', justifyContent:'flex-start'}}>
          <span style={{color:'var(--fg)'}}>
            <BrandWordmark height={140}/>
          </span>
        </div>

        {/* Two cards: OPC + How */}
        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:24, marginBottom:48}}>
          <div className="card" style={{padding:'32px'}}>
            <div className="num mono" style={{fontSize:44, fontWeight:600, lineHeight:1, color:'var(--accent)', marginBottom:18, letterSpacing:'-0.02em'}}>OPC</div>
            <p style={{margin:0, fontSize:15, lineHeight:1.65, color:'var(--fg-soft)'}}>
              {isZh
                ? <><strong style={{color:'var(--fg)'}}>One Person Company</strong> —— 一个人，独立造业的一家公司。不只是软件。一个 YouTube 频道、一份 newsletter、一个 Etsy 店，都算。</>
                : <><strong style={{color:'var(--fg)'}}>One Person Company</strong> — one person, one company, fully accountable. Not only software. A YouTube channel, a newsletter, an Etsy store all count.</>}
            </p>
          </div>
          <div className="card" style={{padding:'32px'}}>
            <div className="num mono" style={{fontSize:44, fontWeight:600, lineHeight:1, color:'var(--accent)', marginBottom:18, letterSpacing:'-0.02em'}}>How</div>
            <p style={{margin:0, fontSize:15, lineHeight:1.65, color:'var(--fg-soft)'}}>
              {isZh
                ? <>不只看 ta <strong style={{color:'var(--fg)'}}>做什么</strong>，更看 ta <strong style={{color:'var(--fg)'}}>怎么做</strong>。怎么定价、怎么找用户、怎么砍掉一个产品、怎么把失败变成下个月的输入。</>
                : <>Not just <strong style={{color:'var(--fg)'}}>what</strong> they ship — <strong style={{color:'var(--fg)'}}>how</strong>. How they price, how they find users, how they decide to kill, how they turn failure into next month's input.</>}
            </p>
          </div>
        </div>

        {/* Mysterious CTA — pulls the reader into /about */}
        <a href="/about" className="opc-cta"
           style={{
             display:'block',
             padding:'40px 44px',
             border:'1px solid var(--fg)',
             borderRadius:'var(--r-lg)',
             background:'var(--fg)',
             textDecoration:'none',
             color:'var(--bg)',
             transition:'all 200ms var(--ease-out)',
             position:'relative',
             overflow:'hidden',
           }}>
          {/* The OPC pulse itself — high contrast, on black */}
          <div style={{padding:'4px 0 28px', display:'flex', justifyContent:'center'}}>
            <svg width="100%" style={{maxWidth: 560}} height="44" viewBox="0 0 56 16" fill="none" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
              <path d="M24.4443 10.2217L27.792 4.00586L29.7207 8.08691H46.4746L49.5742 4.20703L52.207 6.57031L54.708 2.70703L55.2539 3.05957L55.7998 3.41309L52.4727 8.55469L49.7295 6.09375L47.2949 9.14258L47.1006 9.38672H28.8975L27.7158 6.8877L24.0635 13.6719L21.3154 3.89453L18.5273 10.3945L16.3408 7.32617L13.6602 10.6982L9.69434 7.15918L4.80469 12.5127L2.45312 9.52832L0.507812 10.3535L0 9.15625L2.86035 7.94434L4.87793 10.5039L9.16797 5.80859L9.60059 5.33398L13.499 8.81152L16.3975 5.16699L18.2441 7.75684L21.5723 0L24.4443 10.2217Z" fill="#FF6A00"/>
            </svg>
          </div>

          <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', gap:24, flexWrap:'wrap'}}>
            <div style={{flex:'1 1 460px', minWidth:0}}>
              <div className="eyebrow mb-2" style={{color:'inherit', opacity:0.65}}>
                {isZh ? '我们叫它 OPC 心电图' : 'We call it the OPC pulse'}
              </div>
              <p style={{margin:0, fontFamily:'var(--font-mono)', fontSize:22, fontWeight:500, letterSpacing:'-0.015em', lineHeight:1.35, textWrap:'balance'}}>
                {isZh
                  ? '一份增长曲线。一段心跳。两个读法都对。'
                  : 'A growth chart. A heartbeat. Both readings are right.'}
              </p>
              <p style={{margin:'14px 0 0', fontSize:14, lineHeight:1.6, opacity:0.75, maxWidth:'52ch'}}>
                {isZh
                  ? '有高峰，有低谷，甚至有那些看似停下来的平稳。但真正的 OPC 从不会就此放弃 ——'
                  : 'There are peaks. Valleys. The flat stretches no one talks about. And then there\'s what real OPCs do next —'}
              </p>
            </div>
            <div style={{display:'flex', alignItems:'center', gap:10, fontFamily:'var(--font-mono)', fontSize:13, fontWeight:600, letterSpacing:'0.02em', flexShrink:0}}>
              <span>{isZh ? '读完整故事' : 'Read the rest'}</span>
              <span style={{fontSize:18}}>→</span>
            </div>
          </div>
        </a>
      </div>
    </section>
  );
}

function MakerCardCompact({ maker }) {
  const eventsCount = EVENTS.filter(e => e.makerSlug === maker.slug).length;
  return (
    <a href={`/makers/${maker.slug}`} className="card card-hover" style={{padding:'20px', textDecoration:'none', color:'var(--fg)'}}>
      <div className="flex items-center gap-3 mb-4">
        <Avatar maker={maker} size={42}/>
        <div style={{minWidth:0, flex:1}}>
          <div style={{fontWeight:600, fontSize:15}}>{maker.name}</div>
          <div className="mono" style={{fontSize:11, color:'var(--fg-muted)'}}>@{maker.handle} · {maker.flag}</div>
        </div>
        {eventsCount > 0 && (
          <span className="chip chip-accent">{eventsCount} this wk</span>
        )}
      </div>
      <p className="soft" style={{fontSize:13, lineHeight:1.5, marginBottom:14, overflow:'hidden', display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical'}}>
        {maker.bio}
      </p>
      <div className="hr mb-3"/>
      <div className="flex items-center gap-4">
        <div>
          <div className="mono faint" style={{fontSize:10, letterSpacing:'0.05em'}}>MRR</div>
          <div className="num mono" style={{fontSize:14, fontWeight:600, color:'var(--accent)'}}>{fmtMRR(maker.totalMrr)}</div>
        </div>
        <div>
          <div className="mono faint" style={{fontSize:10, letterSpacing:'0.05em'}}>PRODUCTS</div>
          <div className="num mono" style={{fontSize:14, fontWeight:600}}>{maker.products.filter(p=>p.status==='active'||p.status==='stagnant').length}</div>
        </div>
        <div className="grow"/>
        <div className="flex items-center" style={{marginLeft:'auto'}}>
          {maker.tools.slice(0, 4).map((d, i) => (
            <span key={d} style={{marginLeft: i === 0 ? 0 : -4}}>
              <ToolIcon domain={d} size={20}/>
            </span>
          ))}
          {maker.tools.length > 4 && <span className="mono faint" style={{fontSize:10, marginLeft:6}}>+{maker.tools.length-4}</span>}
        </div>
      </div>
    </a>
  );
}

// ============= MAKER PROFILE PAGE ==========================
function MakerProfilePage({ slug }) {
  const maker = makerBySlug(slug);
  const events = useMemo(() => EVENTS.filter(e => e.makerSlug === slug).sort((a,b) => new Date(b.published) - new Date(a.published)), [slug]);

  // Quick-nav active state — scroll-based: pick the last section whose top has passed the sticky-nav offset.
  const [activeSection, setActiveSection] = useState('bio');
  useEffect(() => {
    const update = () => {
      const sections = document.querySelectorAll('[data-mksec]');
      if (!sections.length) return;
      let active = sections[0].getAttribute('data-mksec');
      const threshold = 140; // sticky-nav top (88) + small padding
      sections.forEach(s => {
        if (s.getBoundingClientRect().top <= threshold) {
          active = s.getAttribute('data-mksec');
        }
      });
      setActiveSection(prev => prev === active ? prev : active);
    };
    update();
    window.addEventListener('scroll', update, { passive: true });
    window.addEventListener('resize', update);
    return () => {
      window.removeEventListener('scroll', update);
      window.removeEventListener('resize', update);
    };
  }, [slug]);

  if (!maker) {
    return (
      <div style={{padding:'120px 0', textAlign:'center'}}>
        <div className="container">
          <div className="eyebrow mb-3">404</div>
          <h1 className="title-xl">Builder not found</h1>
          <p className="lede mt-4">No builder with slug "{slug}".</p>
          <a className="btn mt-6" href="/makers">← Back to builders</a>
        </div>
      </div>
    );
  }

  const sections = [
    { id: 'bio',       label: t('sec_bio') },
    { id: 'keystats',  label: t('sec_keystats') },
    { id: 'audience',  label: t('sec_audience') },
    { id: 'products',  label: t('sec_products'),  count: maker.products.length },
    { id: 'partners',  label: t('sec_partners') },
    { id: 'tools',     label: t('sec_tools'),     count: maker.tools.length },
    { id: 'mrr',       label: t('sec_mrr') },
    { id: 'methods',   label: t('sec_methods') },
    { id: 'insights',  label: t('sec_insights') },
    { id: 'lessons',   label: t('sec_lessons'),   count: maker.lessonsFromFailure ? maker.lessonsFromFailure.length : 0 },
    { id: 'killed',    label: t('sec_killed'),    count: maker.killedProducts ? maker.killedProducts.length : 0 },
    { id: 'timeline',  label: t('sec_timeline') },
    { id: 'reading',   label: t('sec_reading') },
    { id: 'recent',    label: t('sec_recent'),    count: events.length },
    { id: 'sources',   label: t('sec_sources') },
  ].filter(s => {
    // hide sections without data
    if (s.id === 'audience' && !maker.audience) return false;
    if (s.id === 'partners' && (!maker.partners || !maker.partners.length)) return false;
    if (s.id === 'methods' && (!maker.methods || !maker.methods.length)) return false;
    if (s.id === 'insights' && (!maker.insights || !maker.insights.length)) return false;
    if (s.id === 'lessons' && (!maker.lessonsFromFailure || !maker.lessonsFromFailure.length)) return false;
    if (s.id === 'killed' && (!maker.killedProducts || !maker.killedProducts.length)) return false;
    if (s.id === 'mrr' && (!maker.mrrHistory || maker.mrrHistory.length < 3)) return false;
    if (s.id === 'reading' && (!maker.readingList || !maker.readingList.length)) return false;
    return true;
  });

  return (
    <div className="page-enter">
      <MakerHeader maker={maker} events={events}/>

      <div className="container" style={{padding:'0 32px 80px'}}>
        <div style={{display:'grid', gridTemplateColumns:'220px 1fr', gap:48}}>
          {/* QUICK NAV */}
          <aside className="quicknav">
            <div className="eyebrow mb-3" style={{paddingLeft:16}}>On this page</div>
            <ul className="quicknav-list">
              {sections.map(s => (
                <li key={s.id}>
                  <a href={'#' + s.id} className={activeSection === s.id ? 'active' : ''}
                     onClick={(e) => {
                       e.preventDefault();
                       const el = document.getElementById(s.id);
                       if (el) {
                         window.scrollTo({ top: el.offsetTop - 80, behavior: 'smooth' });
                         history.replaceState(null, '', '#/makers/' + slug + '#' + s.id);
                       }
                     }}>
                    <span>{s.label}</span>
                    {s.badge && <span className="badge-ai">{s.badge}</span>}
                    {s.count != null && <span className="count">{s.count}</span>}
                  </a>
                </li>
              ))}
            </ul>
            <div className="ai-strip mt-6" style={{paddingLeft:16, fontSize:10}}>
              <span className="ai-strip-dot"/>
              <span>Updated weekly</span>
            </div>
          </aside>

          {/* SECTIONS */}
          <main>
            {/* BIO */}
            <section id="bio" data-mksec="bio" className="section-anchor" style={{marginBottom:64}}>
              <div className="section-head">
                <div className="section-head-left">
                  <h2 className="title-lg">{t('sec_bio')}</h2>
                </div>
                <span className="mono faint" style={{fontSize:11}}>maker's own words + public sources</span>
              </div>
              {maker.quote && (
                <div style={{margin:'0 0 28px', padding:'24px 28px', borderLeft:'3px solid var(--accent)', background:'var(--bg-elev)', borderRadius:'0 var(--r-md) var(--r-md) 0'}}>
                  <div className="flex items-center gap-3 mb-2" style={{flexWrap:'wrap'}}>
                    <span className="eyebrow">Signature line</span>
                    <span className="grow"/>
                    {(() => {
                      const q = (maker.quotes || []).find(x => x.text === maker.quote);
                      return q && q.source ? <SourceCite maker={maker} source={q.source}/> : null;
                    })()}
                  </div>
                  <p style={{margin:0, fontFamily:'var(--font-mono)', fontSize:20, lineHeight:1.4, letterSpacing:'-0.01em', color:'var(--fg)'}}>
                    "{window.__lang === 'zh' && maker.quoteZh ? maker.quoteZh : maker.quote}"
                  </p>
                </div>
              )}
              <p className="lede">{window.__lang === 'zh' && maker.bioZh ? maker.bioZh : maker.bio}</p>
              {(maker.location || maker.family) && (
                <div className="flex items-center gap-8 mt-6 mono" style={{fontSize:12, color:'var(--fg-muted)', flexWrap:'wrap', paddingTop:18, borderTop:'1px dashed var(--border)'}}>
                  {maker.location && (
                    <span className="flex items-center gap-2">
                      <span className="faint" style={{letterSpacing:'0.04em'}}>LOCATION</span>
                      <span style={{color:'var(--fg)'}}>{maker.location}</span>
                    </span>
                  )}
                  {maker.family && (
                    <span className="flex items-center gap-2">
                      <span className="faint" style={{letterSpacing:'0.04em'}}>LIFE</span>
                      <span style={{color:'var(--fg)'}}>{maker.family}</span>
                    </span>
                  )}
                </div>
              )}
            </section>

            {/* KEY STATS */}
            <section id="keystats" data-mksec="keystats" className="section-anchor" style={{marginBottom:64}}>
              <div className="section-head">
                <h2 className="title-lg">{t('sec_keystats')}</h2>
              </div>
              <MakerKeyStats maker={maker} events={events}/>
            </section>

            {/* AUDIENCE */}
            {maker.audience && (
              <section id="audience" data-mksec="audience" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_audience')}</h2>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>"the only channels I really own"</span>
                </div>
                <AudienceSection maker={maker}/>
              </section>
            )}

            {/* PRODUCTS */}
            <section id="products" data-mksec="products" className="section-anchor" style={{marginBottom:64}}>
              <div className="section-head">
                <div className="section-head-left">
                  <h2 className="title-lg">{t('sec_products')}</h2>
                  <span className="count">{maker.products.length}</span>
                </div>
                <span className="mono faint" style={{fontSize:11}}>{maker.products.filter(p=>p.status==='active').length} active · {maker.products.filter(p=>p.status==='sold').length} sold · {maker.products.filter(p=>p.status==='stagnant').length} stagnant</span>
              </div>
              <ProductsTable products={maker.products}/>
            </section>

            {/* PARTNERS */}
            {maker.partners && maker.partners.length > 0 && (
              <section id="partners" data-mksec="partners" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_partners')}</h2>
                    <span className="count">{maker.partners.length}</span>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>portfolio is co-built, not solo</span>
                </div>
                <PartnersSection partners={maker.partners} products={maker.products}/>
              </section>
            )}

            {/* TOOLS */}
            <section id="tools" data-mksec="tools" className="section-anchor" style={{marginBottom:64}}>
              <div className="section-head">
                <div className="section-head-left">
                  <h2 className="title-lg">{t('sec_tools')}</h2>
                  <span className="count">{maker.toolStack
                    ? maker.toolStack.reduce((s, g) => s + (g.tools?.length || 0), 0)
                    : (maker.tools ? maker.tools.length : 0)}</span>
                </div>
                <span className="mono faint" style={{fontSize:11}}>maker reviews + extracted mentions</span>
              </div>
              <ToolStack maker={maker} tools={maker.tools}/>
            </section>

            {/* MRR */}
            {sections.find(s => s.id === 'mrr') && (
              <section id="mrr" data-mksec="mrr" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_mrr')}</h2>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>{maker.mrrHistory.length} snapshots since launch</span>
                </div>
                <div className="card" style={{padding:'28px 28px 16px'}}>
                  <LineChart data={maker.mrrHistory}/>
                  <div className="hr-dashed mt-4 mb-3"/>
                  <div className="ai-strip" style={{fontSize:11}}>
                    <span className="ai-strip-dot"/>
                    <span>Numbers from public posts. Each point links to its source.</span>
                  </div>
                </div>
              </section>
            )}

            {/* METHODS */}
            {sections.find(s => s.id === 'methods') && (
              <section id="methods" data-mksec="methods" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_methods')}</h2>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>distilled from 79 blog posts</span>
                </div>
                <div style={{display:'grid', gap:16}}>
                  {maker.methods.map((m, i) => (
                    <div key={i} className="card" style={{padding:'24px 26px'}}>
                      <div className="flex items-baseline gap-3 mb-3" style={{flexWrap:'wrap'}}>
                        <span className="num mono faint" style={{fontSize:14, fontWeight:600, flexShrink:0}}>{String(i+1).padStart(2,'0')}</span>
                        <h3 className="title-md" style={{whiteSpace:'nowrap'}}>{m.title}</h3>
                        <span className="grow"/>
                        {m.source && <SourceCite maker={maker} source={m.source}/>}
                      </div>
                      <p className="soft" style={{margin:0, paddingLeft:36, fontSize:14, lineHeight:1.6}}>{m.body}</p>
                      {m.quote && (
                        <div style={{marginTop:14, paddingLeft:36}}>
                          <p style={{margin:0, padding:'10px 14px', borderLeft:'2px solid var(--accent)', background:'var(--bg-sunken)', fontFamily:'var(--font-mono)', fontSize:13, color:'var(--fg)', borderRadius:'0 var(--r-sm) var(--r-sm) 0'}}>
                            "{m.quote}"
                          </p>
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              </section>
            )}

            {/* INSIGHTS */}
            {sections.find(s => s.id === 'insights') && (
              <section id="insights" data-mksec="insights" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_insights')}</h2>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>from {events.length + 18} public posts</span>
                </div>
                <ul style={{listStyle:'none', padding:0, margin:0, display:'grid', gap:14}}>
                  {maker.insights.map((ins, i) => {
                    const text = typeof ins === 'string' ? ins : ins.text;
                    const source = typeof ins === 'object' ? ins.source : null;
                    return (
                      <li key={i} className="flex items-start gap-3" style={{padding:'16px 20px', background:'var(--bg-elev)', border:'1px solid var(--border)', borderRadius:'var(--r-md)'}}>
                        <span style={{marginTop:8, width:6, height:6, borderRadius:3, background:'var(--accent)', flexShrink:0}}/>
                        <div style={{flex:1, minWidth:0}}>
                          <span style={{fontSize:14, lineHeight:1.6}}>{text}</span>
                          {source && <SourceCite maker={maker} source={source} inline/>}
                        </div>
                      </li>
                    );
                  })}
                </ul>
              </section>
            )}

            {/* LESSONS FROM FAILURE */}
            {sections.find(s => s.id === 'lessons') && (
              <section id="lessons" data-mksec="lessons" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_lessons')}</h2>
                    <span className="count">{maker.lessonsFromFailure.length}</span>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>{window.__lang === 'zh' ? '从 7 次失败里提炼' : 'extracted from 7 documented failures'}</span>
                </div>
                <LessonsFromFailure items={maker.lessonsFromFailure} maker={maker}/>
              </section>
            )}

            {/* KILLED PRODUCTS */}
            {sections.find(s => s.id === 'killed') && (
              <section id="killed" data-mksec="killed" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_killed')}</h2>
                    <span className="count">{maker.killedProducts.length}</span>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>each under $5K + a few weeks · all public</span>
                </div>
                <KilledProducts items={maker.killedProducts} criteria={maker.killCriteria} maker={maker}/>
              </section>
            )}

            {/* TIMELINE */}
            <section id="timeline" data-mksec="timeline" className="section-anchor" style={{marginBottom:64}}>
              <div className="section-head">
                <div className="section-head-left">
                  <h2 className="title-lg">{t('sec_timeline')}</h2>
                  {maker.timeline && <span className="count">{maker.timeline.length}</span>}
                </div>
                <span className="mono faint" style={{fontSize:11}}>most-recent first</span>
              </div>
              <Timeline maker={maker}/>
            </section>

            {/* READING LIST */}
            {sections.find(s => s.id === 'reading') && (
              <section id="reading" data-mksec="reading" className="section-anchor" style={{marginBottom:64}}>
                <div className="section-head">
                  <div className="section-head-left">
                    <h2 className="title-lg">{t('sec_reading')}</h2>
                    <span className="count">{maker.readingList.length}</span>
                  </div>
                  <span className="mono faint" style={{fontSize:11}}>{t('sec_reading_sub')}</span>
                </div>
                <ReadingList items={maker.readingList} maker={maker}/>
              </section>
            )}

            {/* RECENT ACTIVITY */}
            <section id="recent" data-mksec="recent" className="section-anchor" style={{marginBottom:64}}>
              <div className="section-head">
                <div className="section-head-left">
                  <h2 className="title-lg">{t('sec_recent')}</h2>
                  <span className="count">{events.length}</span>
                </div>
              </div>
              {events.length === 0 ? (
                <div className="card" style={{padding:'40px', textAlign:'center', color:'var(--fg-muted)'}}>
                  <span className="mono">No recent activity tracked.</span>
                </div>
              ) : (
                <div style={{display:'grid', gap:20}}>
                  {events.map(ev => <EventCard key={ev.id} event={ev}/>)}
                </div>
              )}
            </section>

            {/* SOURCES */}
            <section id="sources" data-mksec="sources" className="section-anchor" style={{marginBottom:32}}>
              <div className="section-head">
                <h2 className="title-lg">{t('sec_sources')}</h2>
              </div>
              <div className="card" style={{padding:'4px 24px'}}>
                {[
                  { type:'rss', label:`Blog RSS · tmaker.io/blog/rss.xml`, lastSeen:'2h ago' },
                  { type:'twitter', label:`X · @${maker.handle}`, lastSeen:'7h ago' },
                  { type:'github', label:`GitHub · github.com/${maker.handle}`, lastSeen:'2d ago' },
                  { type:'producthunt', label:`Product Hunt · @${maker.handle}`, lastSeen:'12d ago' },
                ].map((s, i) => (
                  <div key={i} className="row-line" style={{gridTemplateColumns:'auto 1fr auto auto', gap:16}}>
                    <SourceChip source={s.type}/>
                    <span className="mono" style={{fontSize:12, color:'var(--fg)'}}>{s.label}</span>
                    <span className="mono faint" style={{fontSize:11}}>last fetched {s.lastSeen}</span>
                    <span className="chip chip-positive chip-dot">live</span>
                  </div>
                ))}
              </div>
              <div className="ai-strip mt-4">
                <span className="ai-strip-dot"/>
                <span>{maker.name} can request removal at any time · <a href="/opt-out" style={{color:'var(--fg)', textDecoration:'underline'}}>{t('footer_remove')}</a></span>
              </div>
            </section>
          </main>
        </div>
      </div>
    </div>
  );
}

// ----------------- Maker header -----------------
function MakerHeader({ maker, events }) {
  const activeProducts = maker.products.filter(p => p.status === 'active' || p.status === 'stagnant').length;
  const exitedProducts = maker.products.filter(p => p.status === 'sold' || p.status === 'killed').length;
  const totalExit = maker.products.reduce((s, p) => s + (p.exitValue || 0), 0);
  const mrrEnd = maker.mrrHistory && maker.mrrHistory.length ? maker.mrrHistory[maker.mrrHistory.length - 1].v : 0;
  const mrrYearAgo = maker.mrrHistory && maker.mrrHistory.length > 4 ? maker.mrrHistory[Math.max(0, maker.mrrHistory.length - 8)].v : 0;
  const growthPct = mrrYearAgo > 0 ? Math.round(((mrrEnd - mrrYearAgo) / mrrYearAgo) * 100) : 0;
  const growthLabel = growthPct >= 0 ? `+${growthPct}%` : `${growthPct}%`;
  const audience = maker.audience;
  return (
    <section style={{borderBottom:'1px solid var(--border)', background:'var(--bg-elev)', padding:'56px 0'}}>
      <div className="container">
        <div className="eyebrow mb-4">
          <a href="/makers" style={{color:'var(--fg-muted)'}}>{t('nav_makers')}</a> / {maker.slug}
        </div>
        <div className="flex items-center gap-6" style={{marginBottom:36}}>
          <Avatar maker={maker} size={88}/>
          <div style={{flex:1}}>
            <div className="flex items-center gap-3 mb-2">
              <h1 className="title-xl" style={{fontSize:'40px'}}>{maker.name}</h1>
              <span style={{fontSize:24, lineHeight:1}}>{maker.flag}</span>
              <span className="chip chip-positive chip-dot">{maker.status}</span>
            </div>
            <div className="flex items-center gap-3 mono" style={{fontSize:13, color:'var(--fg-muted)', flexWrap:'wrap'}}>
              <a href={'https://x.com/' + maker.handle} target="_blank" rel="noopener" style={{color:'var(--fg-soft)', whiteSpace:'nowrap'}}>@{maker.handle}</a>
              <span style={{color:'var(--fg-faint)'}}>·</span>
              <span style={{whiteSpace:'nowrap'}}>{audience && audience.newsletter ? audience.newsletter.name : 'tracked since 2024'}</span>
              <span style={{color:'var(--fg-faint)'}}>·</span>
              <span style={{whiteSpace:'nowrap'}}>{events.length} events this week</span>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <a className="btn" href={'https://x.com/' + maker.handle} target="_blank" rel="noopener">Follow on X →</a>
            <button className="icon-btn" title="Export"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg></button>
          </div>
        </div>

        {/* Header stat strip */}
        <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:24, paddingTop:28, borderTop:'1px solid var(--border)'}}>
          <HeaderStat label="Portfolio MRR" value={fmtMRR(maker.totalMrr)} sub={fmtMRRFull(maker.totalMrr) + '/mo · ' + activeProducts + ' active'} accent/>
          <HeaderStat label="Lifetime exits" value={totalExit ? fmtMRR(totalExit) : '—'} sub={totalExit ? `${exitedProducts} products acquired` : 'no exits yet'}/>
          <HeaderStat label="MRR growth (1Y)" value={mrrYearAgo > 0 ? growthLabel : '—'}
                      sub={<Sparkline data={maker.mrrHistory ? maker.mrrHistory.slice(-12).map(p=>p.v) : []} width={120} height={20}/>}/>
          <HeaderStat label="Reach" value={audience ? ((audience.newsletter.subs + audience.x.followers)/1000).toFixed(0) + 'k' : '—'}
                      sub={audience ? (audience.newsletter.subs/1000).toFixed(0) + 'k newsletter · ' + (audience.x.followers/1000).toFixed(0) + 'k X' : ''}/>
        </div>
      </div>
    </section>
  );
}
function HeaderStat({ label, value, sub, accent }) {
  return (
    <div>
      <div className="eyebrow mb-2">{label}</div>
      <div className="num mono" style={{fontSize:24, fontWeight:600, color: accent ? 'var(--accent)' : 'var(--fg)'}}>{value}</div>
      <div className="mono faint" style={{fontSize:11, marginTop:4}}>{sub}</div>
    </div>
  );
}

// ----------------- Key stats grid -----------------
function MakerKeyStats({ maker, events }) {
  const activeProducts = maker.products.filter(p => p.status === 'active').length;
  const stagnant = maker.products.filter(p => p.status === 'stagnant').length;
  const sold = maker.products.filter(p => p.status === 'sold').length;
  const totalExit = maker.products.reduce((s, p) => s + (p.exitValue || 0), 0);
  const killedCount = maker.killedProducts ? maker.killedProducts.length : 0;
  // multiplier: latest / one-year-ago MRR
  const mrrEnd = maker.mrrHistory && maker.mrrHistory.length ? maker.mrrHistory[maker.mrrHistory.length - 1].v : 0;
  const mrrPrev = maker.mrrHistory && maker.mrrHistory.length > 4 ? maker.mrrHistory[Math.max(0, maker.mrrHistory.length - 8)].v : 0;
  const multiplier = mrrPrev > 0 ? (mrrEnd / mrrPrev).toFixed(1) + '×' : '—';
  const totalLaunched = (maker.products?.length || 0) + killedCount;
  return (
    <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:14}}>
      <KeyStatCard label="Active portfolio" value={activeProducts} caption={`${stagnant} stagnant · ${sold} sold`}/>
      <KeyStatCard label="Lifetime exits" value={fmtMRR(totalExit)} caption={`${sold} products · 2023`} accent/>
      <KeyStatCard label="Public kills" value={killedCount} caption="under $5K each"/>
      <KeyStatCard label="Total launched" value={totalLaunched} caption="active + dead + exited"/>
      <KeyStatCard label="MRR growth (1Y)" value={multiplier} caption={`${fmtMRR(mrrPrev)} → ${fmtMRR(mrrEnd)}`} accent/>
      <KeyStatCard label="Newsletter subs" value={maker.audience ? (maker.audience.newsletter.subs/1000).toFixed(0) + 'k' : '—'} caption={maker.audience ? maker.audience.newsletter.cadence : ''}/>
      <KeyStatCard label="X followers" value={maker.audience ? (maker.audience.x.followers/1000).toFixed(0) + 'k' : '—'} caption={maker.audience ? '@' + maker.audience.x.handle : ''}/>
      <KeyStatCard label="Years building" value={5} caption="since 2020"/>
    </div>
  );
}
function KeyStatCard({ label, value, caption, accent }) {
  return (
    <div style={{padding:'18px 20px', border:'1px solid var(--border)', borderRadius:'var(--r-md)', background:'var(--bg-elev)'}}>
      <div className="eyebrow mb-2" style={{fontSize:10}}>{label}</div>
      <div className="num mono" style={{fontSize:24, fontWeight:600, color: accent ? 'var(--accent)' : 'var(--fg)'}}>{value}</div>
      <div className="mono faint" style={{fontSize:11, marginTop:3}}>{caption}</div>
    </div>
  );
}

// ----------------- Products table -----------------
function ProductsTable({ products }) {
  const [openSlug, setOpenSlug] = useState(null);
  const statusChip = (s) => {
    const tone = {
      active: 'chip-positive',
      sold: 'chip-accent',
      killed: 'chip-negative',
      stagnant: 'chip',
      transferred: 'chip',
    }[s] || 'chip';
    return <span className={`chip ${tone} chip-dot`}>{s}</span>;
  };
  return (
    <div className="card" style={{padding:'4px 24px'}}>
      <div className="row-line mono faint" style={{gridTemplateColumns:'1.8fr 1.2fr 90px 110px 110px 30px', fontSize:11, letterSpacing:'0.04em', padding:'14px 0', borderBottom:'1px solid var(--border)'}}>
        <span>PRODUCT</span>
        <span>CATEGORY</span>
        <span>STATUS</span>
        <span style={{textAlign:'right'}}>MRR</span>
        <span style={{textAlign:'right'}}>LAUNCH</span>
        <span/>
      </div>
      {products.map(p => {
        const isOpen = openSlug === p.slug;
        const hasStory = !!p.story;
        return (
          <div key={p.slug} style={{borderTop:'1px solid var(--border-soft)'}}>
            <div
              onClick={() => hasStory && setOpenSlug(isOpen ? null : p.slug)}
              style={{
                display:'grid', gridTemplateColumns:'1.8fr 1.2fr 90px 110px 110px 30px',
                alignItems:'center', padding:'14px 0',
                cursor: hasStory ? 'pointer' : 'default',
              }}>
              <div className="flex items-center gap-3" style={{minWidth:0}}>
                <span className="tool-icon tool-icon-32" style={{background: 'var(--bg-sunken)', color:'var(--fg)', border:'1px solid var(--border)'}}>{p.name[0]}</span>
                <div style={{minWidth:0, display:'flex', flexDirection:'column', gap:4}}>
                  <div style={{display:'flex', alignItems:'center', gap:8, flexWrap:'wrap'}}>
                    <span style={{fontWeight:500, fontSize:14, whiteSpace:'nowrap'}}>{p.name}</span>
                    {p.forkedFrom && (
                      <span className="mono" style={{fontSize:10, padding:'1px 6px', borderRadius:3, background:'var(--accent-soft)', color:'var(--accent)', letterSpacing:'0.04em', whiteSpace:'nowrap'}}>
                        fork ← {p.forkedFrom}
                      </span>
                    )}
                    {p.partner && (
                      <span className="mono faint" style={{fontSize:10, whiteSpace:'nowrap'}}>w/ {p.partner}</span>
                    )}
                  </div>
                  <div className="mono faint" style={{fontSize:11, lineHeight:1.4}}>{p.tagline || p.domain}</div>
                </div>
              </div>
              <span className="soft" style={{fontSize:13}}>{p.cat}</span>
              {statusChip(p.status)}
              <span className="num mono" style={{textAlign:'right', fontWeight: p.status==='active'?600:400, color: p.mrr ? 'var(--fg)' : 'var(--fg-faint)'}}>
                {p.status === 'sold' && p.exitValue ? fmtMRR(p.exitValue) + ' exit' : fmtMRR(p.mrr)}
              </span>
              <span className="mono faint" style={{fontSize:11, textAlign:'right'}}>{p.launchDate}</span>
              <span className="mono faint" style={{fontSize:14, textAlign:'right', opacity: hasStory ? 1 : 0}}>
                {isOpen ? '−' : '+'}
              </span>
            </div>
            {isOpen && hasStory && (
              <div style={{padding:'0 0 18px 56px', display:'flex', gap:24, flexWrap:'wrap'}}>
                <p style={{margin:0, fontSize:13, lineHeight:1.6, color:'var(--fg-soft)', flex:'1 1 460px', maxWidth:'70ch'}}>{p.story}</p>
                <div style={{flex:'0 0 auto', display:'flex', flexDirection:'column', gap:8, minWidth:160}}>
                  {p.mrrPrev != null && (
                    <div className="mono" style={{fontSize:11, color:'var(--fg-muted)'}}>
                      <div className="faint" style={{letterSpacing:'0.04em'}}>1Y AGO</div>
                      <div className="num" style={{fontSize:13, color:'var(--fg)', fontWeight:600}}>{fmtMRR(p.mrrPrev)} MRR</div>
                    </div>
                  )}
                  {p.tools && p.tools.length > 0 && (
                    <div>
                      <div className="mono faint" style={{fontSize:10, letterSpacing:'0.04em', marginBottom:4}}>BUILT WITH</div>
                      <div className="flex items-center gap-1">
                        {p.tools.map(d => <ToolIcon key={d} domain={d} size={20}/>)}
                      </div>
                    </div>
                  )}
                </div>
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ----------------- Tool stack -----------------
function ToolStack({ maker, tools }) {
  // Rich, categorized form: maker.toolStack with categories + per-tool reviews
  if (maker && maker.toolStack && maker.toolStack.length) {
    return (
      <div style={{display:'flex', flexDirection:'column', gap:14}}>
        {maker.toolStack.map((group, gi) => (
          <div key={gi} className="card" style={{padding:'22px 26px'}}>
            <div className="flex items-baseline gap-3 mb-3">
              <div className="eyebrow" style={{whiteSpace:'nowrap'}}>{group.category}</div>
              {group.tools && group.tools.length > 0 && (
                <span className="mono faint" style={{fontSize:10, whiteSpace:'nowrap'}}>{group.tools.length} tool{group.tools.length === 1 ? '' : 's'}</span>
              )}
            </div>
            {group.note && (
              <p className="soft" style={{margin:'0 0 14px', fontSize:12, color:'var(--fg-muted)', lineHeight:1.55, maxWidth:'70ch'}}>{group.note}</p>
            )}
            {group.tools && group.tools.length > 0 ? (
              <div>
                {group.tools.map(item => (
                  <ToolRow key={item.domain} item={item} maker={maker}/>
                ))}
              </div>
            ) : (
              <div className="mono faint" style={{fontSize:12, fontStyle:'italic', paddingTop:4}}>—</div>
            )}
          </div>
        ))}
      </div>
    );
  }
  // Fallback: flat array of domains, grouped by tool.cat (legacy)
  const groups = {};
  (tools || []).forEach(d => {
    const tool = toolByDomain(d);
    const cat = tool.cat || 'Other';
    if (!groups[cat]) groups[cat] = [];
    groups[cat].push(tool);
  });
  return (
    <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:16}}>
      {Object.entries(groups).map(([cat, list]) => (
        <div key={cat} className="card" style={{padding:'18px 20px'}}>
          <div className="eyebrow mb-3" style={{fontSize:10}}>{cat}</div>
          <div style={{display:'flex', flexWrap:'wrap', gap:8}}>
            {list.map(tool => (
              <a key={tool.domain} href={`/tools/${tool.domain}`} className="flex items-center gap-2"
                 style={{padding:'4px 10px 4px 4px', borderRadius:999, border:'1px solid var(--border)', color:'var(--fg)'}}>
                <ToolIcon domain={tool.domain} size={20}/>
                <span className="mono" style={{fontSize:12}}>{tool.name}</span>
              </a>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

// ----------------- Timeline -----------------
function Timeline({ maker }) {
  // Prefer a hand-curated maker.timeline; otherwise build from product launches/exits
  let items;
  if (maker.timeline && maker.timeline.length) {
    items = [...maker.timeline];
  } else {
    items = [];
    maker.products.forEach(p => {
      items.push({ date: p.launchDate || '—', type: 'launch', label: 'Launched ' + p.name, sub: p.cat });
      if (p.exitDate) items.push({ date: p.exitDate, type: 'exit', label: p.name + ' acquired', sub: fmtMRR(p.exitValue) + ' exit' });
    });
  }
  items.sort((a,b) => (a.date < b.date ? 1 : -1));

  const dotColor = (type) => ({
    exit: 'var(--accent)',
    acquisition: 'var(--accent)',
    milestone: 'var(--accent)',
    kill: 'var(--negative)',
    launch: 'var(--fg)',
  }[type] || 'var(--fg)');

  const ringColor = (type) => ({
    exit: 'var(--accent-soft)',
    acquisition: 'var(--accent-soft)',
    milestone: 'var(--accent-soft)',
    kill: 'var(--negative-soft)',
  }[type] || 'transparent');

  return (
    <div style={{position:'relative', paddingLeft: 28}}>
      <div style={{position:'absolute', left: 8, top: 6, bottom: 6, width: 2, background:'var(--border)'}}/>
      {items.map((it, i) => (
        <div key={i} style={{position:'relative', marginBottom: 18}}>
          <span style={{
            position:'absolute', left: -28 + 8 - 6, top: 4,
            width: 12, height: 12, borderRadius: 6, background: dotColor(it.type),
            boxShadow: ringColor(it.type) !== 'transparent' ? `0 0 0 4px ${ringColor(it.type)}` : 'none',
            border:'3px solid var(--bg)'
          }}/>
          <div style={{display:'grid', gridTemplateColumns:'70px 1fr auto', gap:16, alignItems:'baseline'}}>
            <span className="mono num" style={{fontSize:11, color:'var(--fg-muted)'}}>{it.date}</span>
            <div>
              <div style={{fontWeight:500, fontSize:14, color:'var(--fg)'}}>{it.label}</div>
              {it.sub && <div className="mono faint" style={{fontSize:11, marginTop:2}}>{it.sub}</div>}
            </div>
            {(it.type === 'exit' || it.type === 'acquisition' || it.type === 'kill') && (
              <span className={`chip ${it.type === 'kill' ? 'chip-negative' : 'chip-accent'}`} style={{fontSize:9, padding:'2px 6px'}}>
                {it.type.toUpperCase()}
              </span>
            )}
          </div>
        </div>
      ))}
    </div>
  );
}

// ----------------- Audience -----------------
function AudienceSection({ maker }) {
  const a = maker.audience;
  return (
    <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
      {/* Newsletter card */}
      <div className="card" style={{padding:'24px 26px'}}>
        <div className="flex items-baseline gap-3 mb-3">
          <div className="eyebrow">Newsletter</div>
          <div className="grow"/>
          <div className="mono faint" style={{fontSize:11}}>{a.newsletter.platform}</div>
        </div>
        <div className="num mono" style={{fontSize:40, fontWeight:600, letterSpacing:'-0.02em', lineHeight:1}}>{a.newsletter.subs.toLocaleString()}</div>
        <div className="mono faint" style={{fontSize:11, marginTop:4}}>subscribers · {a.newsletter.name}</div>
        <div className="hr-dashed mt-6 mb-3"/>
        <div className="flex items-center gap-2 mono" style={{fontSize:11, color:'var(--fg-muted)'}}>
          <span style={{width:6, height:6, borderRadius:3, background:'var(--positive)'}}/>
          <span>{a.newsletter.cadence}</span>
        </div>
      </div>
      {/* X card */}
      <div className="card" style={{padding:'24px 26px'}}>
        <div className="flex items-baseline gap-3 mb-3">
          <div className="eyebrow">X / Twitter</div>
          <div className="grow"/>
          <div className="mono faint" style={{fontSize:11}}>@{a.x.handle}</div>
        </div>
        <div className="num mono" style={{fontSize:40, fontWeight:600, letterSpacing:'-0.02em', lineHeight:1}}>{a.x.followers.toLocaleString()}</div>
        <div className="mono faint" style={{fontSize:11, marginTop:4}}>followers · primary distribution channel</div>
        <div className="hr-dashed mt-6 mb-3"/>
        <a href={'https://x.com/' + a.x.handle} target="_blank" rel="noopener" className="mono" style={{fontSize:11, color:'var(--fg)', textDecoration:'underline', textUnderlineOffset:'3px'}}>
          Open profile →
        </a>
      </div>
      {/* Style note (full width) */}
      <div style={{gridColumn:'1 / -1', padding:'18px 22px', border:'1px dashed var(--border)', borderRadius:'var(--r-md)', background:'var(--bg-sunken)'}}>
        <div className="flex items-baseline gap-3">
          <span className="mono" style={{fontSize:10, letterSpacing:'0.06em', color:'var(--accent)', textTransform:'uppercase'}}>Style</span>
          <span className="soft" style={{fontSize:13, lineHeight:1.55}}>{a.style}</span>
        </div>
      </div>
    </div>
  );
}

// ----------------- Partners -----------------
function PartnersSection({ partners, products }) {
  const productByslug = (slug) => products.find(p => p.slug === slug);
  return (
    <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:14}}>
      {partners.map((p, i) => {
        const prod = productByslug(p.product);
        return (
          <div key={i} className="card" style={{padding:'20px 22px'}}>
            <div className="flex items-center gap-3 mb-3">
              <div style={{width:36, height:36, borderRadius:'50%', background:'var(--bg-sunken)', color:'var(--fg)', display:'grid', placeItems:'center', fontFamily:'var(--font-mono)', fontWeight:600, fontSize:14, border:'1px solid var(--border)'}}>
                {p.name[0]}
              </div>
              <div style={{minWidth:0, flex:1}}>
                <div style={{fontWeight:600, fontSize:14}}>{p.name}</div>
                <div className="mono faint" style={{fontSize:11}}>{p.role}</div>
              </div>
              {prod && (
                <span className="chip">{prod.name}</span>
              )}
            </div>
            {p.note && <p className="soft" style={{margin:0, fontSize:12, lineHeight:1.5, color:'var(--fg-muted)'}}>{p.note}</p>}
          </div>
        );
      })}
      <div style={{gridColumn:'1 / -1', marginTop:8, padding:'14px 18px', borderRadius:'var(--r-md)', background:'var(--bg-sunken)'}}>
        <span className="mono" style={{fontSize:11, color:'var(--fg-muted)', lineHeight:1.6}}>
          <span style={{color:'var(--accent)', fontWeight:600}}>Pattern:</span>{' '}
          Tibo operates as portfolio CEO + top-level positioner. He almost never plays single-product IC alone — every active product has at least one co-founder running it day to day.
        </span>
      </div>
    </div>
  );
}

// ----------------- Lessons from failure -----------------
function LessonsFromFailure({ items, maker }) {
  const isZh = window.__lang === 'zh';
  return (
    <div style={{display:'grid', gap:14}}>
      {items.map((l, i) => (
        <article key={i} className="card" style={{padding:'24px 28px', borderLeft:'3px solid var(--accent)', borderRadius:'0 var(--r-md) var(--r-md) 0'}}>
          <div className="flex items-baseline gap-3 mb-3" style={{flexWrap:'wrap'}}>
            <span className="num mono faint" style={{fontSize:14, fontWeight:600, flexShrink:0, minWidth: 28}}>{String(i+1).padStart(2,'0')}</span>
            <h3 className="title-md" style={{flex:1, lineHeight:1.3, fontSize: 18, textWrap:'balance'}}>{l.lesson}</h3>
            <span className="grow"/>
            {l.source && <SourceCite maker={maker} source={l.source}/>}
          </div>
          <p className="soft" style={{margin:0, paddingLeft:40, fontSize:14, lineHeight:1.6, color:'var(--fg-soft)'}}>{l.body}</p>
          {l.from && (
            <div className="mt-3" style={{paddingLeft:40, paddingTop:10, borderTop:'1px dashed var(--border-soft)', marginTop:14}}>
              <div className="flex items-center gap-2 mono" style={{fontSize:10, color:'var(--fg-faint)', letterSpacing:'0.04em'}}>
                <span style={{textTransform:'uppercase'}}>{isZh ? '出处' : 'From'}</span>
                <span style={{textTransform:'none', color:'var(--fg-muted)', letterSpacing:'0.01em'}}>{l.from}</span>
              </div>
            </div>
          )}
        </article>
      ))}
    </div>
  );
}

// ----------------- Killed products -----------------
function KilledProducts({ items, criteria, maker }) {
  return (
    <>
      <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:14}}>
        {items.map((k, i) => (
          <div key={i} style={{padding:'20px 22px', borderLeft:'3px solid var(--negative)', background:'var(--bg-elev)', border:'1px solid var(--border)', borderRadius:'0 var(--r-md) var(--r-md) 0'}}>
            <div className="flex items-baseline gap-3 mb-2" style={{flexWrap:'wrap'}}>
              <h3 className="title-sm mono" style={{color:'var(--fg)', whiteSpace:'nowrap', textDecoration:'line-through', textDecorationColor:'var(--negative)', textDecorationThickness:'1.5px'}}>{k.name}</h3>
              <span className="mono faint" style={{fontSize:11, whiteSpace:'nowrap'}}>{k.year}</span>
              <span className="grow"/>
              {k.source && <SourceCite maker={maker} source={k.source}/>}
            </div>
            <div className="soft" style={{fontSize:13, marginBottom:10}}><span className="mono faint" style={{fontSize:10, letterSpacing:'0.04em'}}>IDEA</span> · {k.idea}</div>
            <div className="soft" style={{fontSize:13}}><span className="mono" style={{fontSize:10, letterSpacing:'0.04em', color:'var(--negative)'}}>LESSON</span> · {k.lesson}</div>
          </div>
        ))}
      </div>
      {criteria && criteria.length > 0 && (
        <div className="mt-6" style={{padding:'22px 26px', border:'1px solid var(--border)', borderRadius:'var(--r-md)', background:'var(--bg-elev)'}}>
          <div className="eyebrow mb-3">Kill criteria — applied to every new bet</div>
          <ul style={{listStyle:'none', padding:0, margin:0, display:'grid', gap:14}}>
            {criteria.map((c, i) => (
              <li key={i} className="flex items-start gap-3" style={{fontSize:13, lineHeight:1.55, color:'var(--fg-soft)'}}>
                <span className="mono" style={{fontSize:10, color:'var(--accent)', minWidth:22, letterSpacing:'0.04em', flexShrink:0, paddingTop:2}}>{String(i+1).padStart(2,'0')}</span>
                <span>{c}</span>
              </li>
            ))}
          </ul>
        </div>
      )}
    </>
  );
}

// ----------------- Peer compare table -----------------
function PeerCompareTable({ rows, subject }) {
  return (
    <div className="card" style={{padding:'4px 24px'}}>
      <div className="row-line mono faint" style={{gridTemplateColumns:'1fr 1.3fr 1.3fr 1.3fr', fontSize:11, letterSpacing:'0.04em', padding:'14px 0', borderBottom:'1px solid var(--border)'}}>
        <span>DIMENSION</span>
        <span style={{color:'var(--accent)'}}>{subject.toUpperCase()}</span>
        <span>PIETER LEVELS</span>
        <span>MARC LOU</span>
      </div>
      {rows.map((r, i) => (
        <div key={i} className="row-line" style={{gridTemplateColumns:'1fr 1.3fr 1.3fr 1.3fr', padding:'14px 0'}}>
          <span className="mono" style={{fontSize:12, color:'var(--fg-muted)'}}>{r.dim}</span>
          <span style={{fontSize:13, fontWeight:500, color:'var(--accent)'}}>{r.tibo}</span>
          <span className="soft" style={{fontSize:13}}>{r.pieter}</span>
          <span className="soft" style={{fontSize:13}}>{r.marc}</span>
        </div>
      ))}
    </div>
  );
}

// ----------------- Reading list -----------------
function ReadingList({ items, maker }) {
  const root = maker.blogRoot || 'https://www.tmaker.io/blog/';
  return (
    <div className="card" style={{padding:'4px 24px'}}>
      {items.map((it, i) => (
        <a key={i}
           href={`${root}${it.slug}`}
           target="_blank" rel="noopener"
           className="row-line"
           style={{gridTemplateColumns:'40px 1fr auto', textDecoration:'none', color:'var(--fg)', gap:16, padding:'16px 0'}}>
          <span style={{fontSize:18, lineHeight:1}}>{it.priority || ''}</span>
          <div>
            <div style={{fontWeight:500, fontSize:14, marginBottom: it.note ? 4 : 0}}>{it.title}</div>
            {it.note && <div className="soft" style={{fontSize:12, color:'var(--fg-muted)'}}>{it.note}</div>}
            <div className="mono faint" style={{fontSize:10, marginTop:6, letterSpacing:'0.02em'}}>{root.replace(/^https?:\/\//, '').replace(/\/$/, '')}/{it.slug}</div>
          </div>
          <span className="mono faint" style={{fontSize:14}}>→</span>
        </a>
      ))}
    </div>
  );
}

// ----------------- Source link helpers -----------------
function makerBlogUrl(maker, source) {
  if (!source) return null;
  if (source.url) return source.url;
  if (source.slug) {
    const root = maker.blogRoot || (maker.slug === 'tibo' ? 'https://www.tmaker.io/blog/' : null);
    if (root) return root + source.slug;
  }
  return null;
}

// Infer source kind (blog / x / github / ...) from the URL host
function sourceKind(url) {
  try {
    const host = new URL(url).hostname.replace(/^www\./, '');
    if (host === 'x.com' || host === 'twitter.com' || host === 'mobile.twitter.com') return 'x';
    if (host === 'github.com') return 'github';
    if (host === 'producthunt.com' || host === 'www.producthunt.com') return 'producthunt';
    if (host === 'youtube.com' || host === 'youtu.be') return 'youtube';
    if (host === 'reddit.com' || host.endsWith('.reddit.com')) return 'reddit';
    if (host.includes('indiehackers')) return 'indiehackers';
    return 'blog';
  } catch (e) {
    return 'blog';
  }
}

const SOURCE_LABEL = {
  x: 'X (Twitter)',
  github: 'GitHub',
  producthunt: 'Product Hunt',
  youtube: 'YouTube',
  reddit: 'Reddit',
  indiehackers: 'Indie Hackers',
  blog: 'Blog',
};

// ----------------- SourceCite (icon + tooltip) -----------------
function SourceCite({ maker, source, label, inline = false }) {
  const [hover, setHover] = useState(false);
  const url = makerBlogUrl(maker, source);
  if (!url) return null;
  const kind = sourceKind(url);
  const kindLabel = SOURCE_LABEL[kind] || 'Source';
  const title = label || source.title || (source.slug ? source.slug.replace(/-/g, ' ') : null);
  const host = (() => { try { return new URL(url).hostname.replace(/^www\./,''); } catch (e) { return url; } })();

  // Icon glyph by source kind
  const Icon = () => {
    const s = { width: 12, height: 12, flexShrink: 0 };
    switch (kind) {
      case 'x':
        return <svg {...s} viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>;
      case 'github':
        return <svg {...s} viewBox="0 0 24 24" fill="currentColor"><path d="M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.11.79-.25.79-.56v-2c-3.2.7-3.87-1.36-3.87-1.36-.52-1.33-1.27-1.69-1.27-1.69-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.18 1.76 1.18 1.02 1.75 2.69 1.24 3.35.95.1-.74.4-1.24.72-1.53-2.55-.29-5.23-1.28-5.23-5.7 0-1.26.45-2.29 1.18-3.1-.12-.29-.51-1.46.11-3.04 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.8 0c2.21-1.49 3.18-1.18 3.18-1.18.62 1.58.23 2.75.11 3.04.74.81 1.18 1.84 1.18 3.1 0 4.43-2.69 5.41-5.25 5.7.41.36.78 1.06.78 2.14v3.17c0 .31.21.68.8.56A11.5 11.5 0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5z"/></svg>;
      case 'youtube':
        return <svg {...s} viewBox="0 0 24 24" fill="currentColor"><path d="M23 7.2s-.2-1.6-.9-2.3c-.8-.9-1.7-.9-2.1-1C16.9 3.5 12 3.5 12 3.5h0s-4.9 0-8 .4c-.4.1-1.3.1-2.1 1C1.2 5.6 1 7.2 1 7.2S.8 9.1.8 11v1.7c0 1.9.2 3.8.2 3.8s.2 1.6.9 2.3c.8.9 2 .9 2.5 1C6.2 20 12 20 12 20s4.9 0 8-.4c.4-.1 1.3-.1 2.1-1 .7-.7.9-2.3.9-2.3s.2-1.9.2-3.8V11c0-1.9-.2-3.8-.2-3.8zM9.8 14.8V8.2l6.4 3.3z"/></svg>;
      case 'reddit':
        return <svg {...s} viewBox="0 0 24 24" fill="currentColor"><path d="M22 12c0-1.2-1-2.3-2.3-2.3-.6 0-1.2.2-1.6.6-1.6-1-3.7-1.7-6.1-1.8l1-4.7 3.3.7c0 .9.7 1.6 1.6 1.6.9 0 1.6-.7 1.6-1.6S18.8 3 17.9 3c-.6 0-1.2.4-1.5.9l-3.7-.8c-.2 0-.4 0-.5.3l-1.2 5.4c-2.4.1-4.5.8-6.2 1.8-.4-.4-1-.6-1.6-.6C2 9.7 1 10.8 1 12c0 .9.5 1.7 1.3 2-.1.3-.1.6-.1.9 0 3.3 3.8 6 8.6 6s8.6-2.7 8.6-6c0-.3 0-.6-.1-.9.7-.3 1.2-1.1 1.2-2-.2 0-.2 0 .5 0zM7 13.6c0-.9.7-1.6 1.6-1.6.9 0 1.6.7 1.6 1.6 0 .9-.7 1.6-1.6 1.6-.9 0-1.6-.7-1.6-1.6zm8.4 4c-1.1.7-2.4 1.1-3.7 1.1-1.4 0-2.7-.4-3.7-1.1-.2-.2-.3-.5-.1-.7s.5-.3.7-.1c.9.6 2 .9 3.1.9 1.1 0 2.2-.3 3.1-1 .2-.2.5-.1.7.1.2.2.1.6-.1.8zm-.1-2.4c-.9 0-1.6-.7-1.6-1.6 0-.9.7-1.6 1.6-1.6.9 0 1.6.7 1.6 1.6 0 .9-.7 1.6-1.6 1.6z"/></svg>;
      case 'producthunt':
        return <svg {...s} viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1.6 11.4H10v3.2H8V7h5.6c1.77 0 3.2 1.43 3.2 3.2s-1.43 3.2-3.2 3.2zm0-4.8H10v3.2h3.6c.88 0 1.6-.72 1.6-1.6s-.72-1.6-1.6-1.6z"/></svg>;
      case 'indiehackers':
        return <svg {...s} viewBox="0 0 24 24" fill="currentColor"><rect x="3" y="3" width="18" height="18" rx="3"/><rect x="7" y="8" width="2.2" height="8" fill="var(--bg-elev)"/><rect x="11" y="8" width="2.2" height="8" fill="var(--bg-elev)"/><rect x="15" y="8" width="2.2" height="3" fill="var(--bg-elev)"/></svg>;
      default:
        return <svg {...s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><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>;
    }
  };

  const handleClick = (e) => {
    // Don't bubble up — many parent rows have their own onClick
    e.stopPropagation();
  };

  return (
    <span
      className="cite"
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      onFocus={() => setHover(true)}
      onBlur={() => setHover(false)}
      style={{display:'inline-flex', position:'relative', verticalAlign: inline ? 'middle' : 'baseline', marginLeft: inline ? 6 : 0}}>
      <a
        href={url}
        target="_blank"
        rel="noopener"
        onClick={handleClick}
        aria-label={`Source: ${kindLabel}${title ? ' — ' + title : ''}`}
        className="cite-link"
        style={{
          display:'inline-flex', alignItems:'center', justifyContent:'center',
          width: 22, height: 22, borderRadius: 4,
          color: hover ? 'var(--accent)' : 'var(--fg-muted)',
          border:'1px solid ' + (hover ? 'var(--accent)' : 'var(--border)'),
          background: hover ? 'var(--accent-soft)' : 'var(--bg-elev)',
          transition:'all 140ms var(--ease-out)',
        }}>
        <Icon/>
      </a>
      <span role="tooltip" style={{
        position:'absolute',
        bottom:'calc(100% + 8px)',
        left:'50%',
        transform: hover ? 'translateX(-50%) translateY(0)' : 'translateX(-50%) translateY(4px)',
        padding:'10px 12px',
        background:'var(--fg)',
        color:'var(--bg)',
        borderRadius: 6,
        boxShadow:'var(--shadow-md)',
        minWidth: 220, maxWidth: 320,
        width: 'max-content',
        fontFamily:'var(--font-sans)',
        fontSize: 12, lineHeight: 1.4,
        whiteSpace:'normal',
        textAlign:'left',
        pointerEvents:'none',
        opacity: hover ? 1 : 0,
        visibility: hover ? 'visible' : 'hidden',
        transition:'opacity 140ms var(--ease-out), transform 140ms var(--ease-out), visibility 0s linear ' + (hover ? '0s' : '140ms'),
        zIndex: 80,
      }}>
        <div style={{display:'flex', alignItems:'center', gap:6, fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.06em', textTransform:'uppercase', opacity: 0.7, marginBottom: title ? 6 : 0}}>
          <span style={{display:'inline-flex'}}><Icon/></span>
          <span>{kindLabel}</span>
        </div>
        {title && <div style={{fontWeight:500, marginBottom:4, color: 'var(--bg)'}}>{title}</div>}
        <div style={{fontFamily:'var(--font-mono)', fontSize:10, opacity: 0.55, wordBreak:'break-word'}}>{host}</div>
        <span style={{position:'absolute', top:'100%', left:'50%', marginLeft:-5, width:0, height:0, borderLeft:'5px solid transparent', borderRight:'5px solid transparent', borderTop:'5px solid var(--fg)'}}/>
      </span>
    </span>
  );
}

// ----------------- Tool row (used inside ToolStack) -----------------
function ToolRow({ item, maker }) {
  const tool = toolByDomain(item.domain);
  return (
    <div className="flex items-start gap-3" style={{padding:'12px 0', borderTop:'1px solid var(--border-soft)'}}>
      <span style={{marginTop:2}}>
        <ToolIcon domain={item.domain} size={24}/>
      </span>
      <div style={{flex:1, minWidth:0}}>
        <div className="flex items-center gap-2 mb-1" style={{flexWrap:'wrap'}}>
          {item.isOwn ? (
            <span className="mono" style={{fontWeight:600, fontSize:13}}>{tool.name}</span>
          ) : (
            <a href={`/tools/${item.domain}`} className="mono" style={{fontWeight:600, fontSize:13, color:'var(--fg)'}}>{tool.name}</a>
          )}
          <span className="mono faint" style={{fontSize:10}}>{tool.domain}</span>
          {item.isOwn && <span className="chip chip-accent" style={{fontSize:9, padding:'1px 6px'}}>self-built</span>}
        </div>
        {item.review && (
          <p className="soft" style={{margin:'0 0 6px', fontSize:13, lineHeight:1.5, color:'var(--fg-soft)'}}>
            <span style={{color:'var(--fg-faint)'}}>"</span>{item.review}<span style={{color:'var(--fg-faint)'}}>"</span>
          </p>
        )}
        {item.source && (
          <SourceCite maker={maker} source={item.source}/>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { MakersListPage, MakerCardCompact, MakerProfilePage, SourceCite, makerBlogUrl });
