const { useState, useEffect, useRef, useCallback, createContext, useContext } = React;

const AuthContext = createContext(null);
function useAuth() { return useContext(AuthContext); }

function apiFetch(url, opts = {}) {
  return fetch(url, { ...opts, credentials: "same-origin" }).then(res => {
    if (res.status === 401 && !url.includes("/api/auth/")) {
      window.location.hash = "";
      window.location.reload();
    }
    return res;
  });
}

// ── Landing Page ──────────────────────────────────────────────────────────────
function ScrollReveal({ children, delay }) {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const obs = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setVisible(true); obs.disconnect(); } }, { threshold: 0.12 });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return (
    <div ref={ref} style={{ opacity: visible ? 1 : 0, transform: visible ? "translateY(0)" : "translateY(32px)", transition: `opacity 0.7s ease ${delay||0}s, transform 0.7s ease ${delay||0}s` }}>
      {children}
    </div>
  );
}

function LandingPage({ onShowAuth }) {
  const features = [
    { icon: "🔍", title: "AI Research", desc: "Live news + AI analysis for 5 genres", free: true },
    { icon: "✍️", title: "Newsletter Writing", desc: "Full newsletter issues written by AI", free: true },
    { icon: "📣", title: "Social Content", desc: "Platform-specific social posts", free: true },
    { icon: "🌐", title: "Custom Topics", desc: "Unlimited niche topics & search", free: false },
    { icon: "🔗", title: "Affiliate Discovery", desc: "Find & manage affiliate programs", free: false },
    { icon: "📡", title: "Multi-Platform Publish", desc: "Beehiiv, Medium, Facebook & more", free: false },
    { icon: "⚡", title: "Automated Scheduling", desc: "Set it and forget it", free: false },
    { icon: "💰", title: "Sponsor Pitch", desc: "AI-generated sponsor outreach", free: true },
  ];

  const [hoveredFeature, setHoveredFeature] = useState(null);

  return (
    <div style={{ minHeight:"100vh", background:"#07060f", color:"#b5b0ce", fontFamily:"Georgia, serif" }}>
      <style>{`
        @keyframes heroGradientShift {
          0% { background-position: 0% 50%; }
          50% { background-position: 100% 50%; }
          100% { background-position: 0% 50%; }
        }
        @keyframes heroPulse {
          0%, 100% { opacity: 0.15; transform: scale(1); }
          50% { opacity: 0.28; transform: scale(1.05); }
        }
        @keyframes borderGlow {
          0%, 100% { border-color: #7c3aed; box-shadow: 0 0 20px rgba(124,58,237,0.15); }
          50% { border-color: #a78bfa; box-shadow: 0 0 30px rgba(124,58,237,0.3); }
        }
        @keyframes eliteBorderGlow {
          0%, 100% { border-color: #f59e0b; box-shadow: 0 0 20px rgba(245,158,11,0.15); }
          50% { border-color: #fbbf24; box-shadow: 0 0 30px rgba(245,158,11,0.3); }
        }
        .landing-cta-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(124,58,237,0.4) !important; }
        .landing-cta-secondary:hover { background: rgba(79,70,229,0.1) !important; transform: translateY(-2px); }
        .landing-cta-primary, .landing-cta-secondary { transition: all 0.25s ease; }
        .feature-card-hover { transition: all 0.3s ease; }
        .feature-card-hover:hover { transform: translateY(-4px); border-color: #2a2448 !important; box-shadow: 0 8px 30px rgba(0,0,0,0.3); }
        .pricing-card { transition: all 0.3s ease; }
        .pricing-card:hover { transform: translateY(-4px); }
        .pricing-btn { transition: all 0.25s ease; }
        .pricing-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.3); }
        details[open] summary .faq-icon { transform: rotate(45deg); }
        .faq-icon { transition: transform 0.25s ease; display: inline-block; }
        .stat-card { transition: all 0.3s ease; }
        .stat-card:hover { transform: translateY(-3px); border-color: #2a2448 !important; }
      `}</style>

      <div className="landing-hero" style={{ background:"linear-gradient(180deg,#100d1f 0%,#07060f 100%)", padding:"80px 20px 70px", textAlign:"center", position:"relative", overflow:"hidden" }}>
        <div style={{ position:"absolute", inset:0, background:"linear-gradient(135deg, rgba(124,58,237,0.12), rgba(79,70,229,0.08), rgba(139,92,246,0.12), rgba(79,70,229,0.06))", backgroundSize:"400% 400%", animation:"heroGradientShift 12s ease infinite", pointerEvents:"none" }} />
        <div style={{ position:"absolute", top:"-30%", left:"50%", transform:"translateX(-50%)", width:"800px", height:"800px", background:"radial-gradient(ellipse, rgba(124,58,237,0.18) 0%, transparent 70%)", animation:"heroPulse 6s ease-in-out infinite", pointerEvents:"none" }} />
        <div style={{ position:"relative", zIndex:1 }}>
          <div style={{ display:"inline-block", background:"linear-gradient(90deg,#7c3aed,#4f46e5)", borderRadius:20, padding:"5px 16px", fontSize:10, fontFamily:"monospace", letterSpacing:3, color:"#fff", fontWeight:"bold", marginBottom:24 }}>AI-POWERED NEWSLETTER ENGINE</div>
          <h1 style={{ fontSize:"clamp(32px,6.5vw,60px)", fontWeight:"bold", background:"linear-gradient(135deg,#fff 20%,#c4b5fd 50%,#a78bfa 100%)", WebkitBackgroundClip:"text", WebkitTextFillColor:"transparent", letterSpacing:-1.5, margin:"0 0 20px", lineHeight:1.08 }}>Build a Newsletter Business<br/>in Minutes, Not Months</h1>
          <p style={{ color:"#8b82b0", margin:"0 auto 20px", fontSize:18, maxWidth:560, lineHeight:1.7 }}>AI researches, writes, and distributes your newsletter across 5 genres. You review and publish. That's it.</p>
          <p style={{ color:"#635e80", margin:"0 auto 36px", fontSize:13, fontFamily:"monospace" }}>No credit card required &middot; Free forever plan</p>
          <div className="landing-cta-row" style={{ display:"flex", gap:14, justifyContent:"center", flexWrap:"wrap" }}>
            <button className="landing-cta-primary" onClick={() => onShowAuth("register")} style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:12, color:"#fff", padding:"16px 40px", cursor:"pointer", fontSize:16, fontWeight:"bold", fontFamily:"monospace", boxShadow:"0 4px 20px rgba(124,58,237,0.3)" }}>Get Started Free</button>
            <button className="landing-cta-secondary" onClick={() => onShowAuth("login")} style={{ background:"transparent", border:"2px solid #4f46e5", borderRadius:12, color:"#a78bfa", padding:"16px 40px", cursor:"pointer", fontSize:16, fontWeight:"bold", fontFamily:"monospace" }}>Sign In</button>
          </div>
        </div>
      </div>

      <ScrollReveal>
        <div style={{ maxWidth:900, margin:"0 auto", padding:"60px 20px 30px" }}>
          <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit, minmax(160px, 1fr))", gap:16 }}>
            {[
              { value:"< 2 min", label:"Setup time", icon:"⚡" },
              { value:"5+", label:"Built-in genres", icon:"📰" },
              { value:"6", label:"Publish platforms", icon:"📡" },
              { value:"100%", label:"AI-powered", icon:"🤖" },
            ].map((s, i) => (
              <div key={i} className="stat-card" style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"20px 16px", textAlign:"center" }}>
                <div style={{ fontSize:20, marginBottom:6 }}>{s.icon}</div>
                <div style={{ fontSize:28, fontWeight:"bold", color:"#e8e3f8", fontFamily:"monospace", marginBottom:4 }}>{s.value}</div>
                <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", textTransform:"uppercase", letterSpacing:1 }}>{s.label}</div>
              </div>
            ))}
          </div>
        </div>
      </ScrollReveal>

      <div style={{ maxWidth:900, margin:"0 auto", padding:"50px 20px 60px" }}>
        <ScrollReveal>
          <div style={{ textAlign:"center", marginBottom:44 }}>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:3, marginBottom:10 }}>FEATURES</div>
            <h2 style={{ fontSize:30, color:"#e8e3f8", fontWeight:"bold", margin:"0 0 8px" }}>Everything You Need to Launch</h2>
            <p style={{ color:"#635e80", fontSize:14, margin:0 }}>From research to publishing, all powered by AI</p>
          </div>
        </ScrollReveal>
        <div className="features-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(200px,1fr))", gap:16 }}>
          {features.map((f, i) => (
            <ScrollReveal key={f.title} delay={i * 0.06}>
              <div className="feature-card-hover" style={{ background: hoveredFeature === i ? "#11102a" : "#0e0c1a", border:"1px solid #1c1830", borderRadius:14, padding:"22px 18px", position:"relative", cursor:"default" }}
                onMouseEnter={() => setHoveredFeature(i)} onMouseLeave={() => setHoveredFeature(null)}>
                <div style={{ fontSize:28, marginBottom:10, transition:"transform 0.3s", transform: hoveredFeature === i ? "scale(1.15)" : "scale(1)" }}>{f.icon}</div>
                <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:6 }}>{f.title}</div>
                <div style={{ fontSize:12, color:"#635e80", lineHeight:1.6 }}>{f.desc}</div>
                {!f.free && <div style={{ position:"absolute", top:14, right:14, background:"linear-gradient(135deg,#7c3aed,#4f46e5)", borderRadius:6, padding:"3px 10px", fontSize:9, fontFamily:"monospace", color:"#fff", fontWeight:"bold" }}>PRO</div>}
              </div>
            </ScrollReveal>
          ))}
        </div>
      </div>

      <div style={{ maxWidth:900, margin:"0 auto", padding:"50px 20px 60px" }}>
        <ScrollReveal>
          <div style={{ textAlign:"center", marginBottom:44 }}>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:3, marginBottom:10 }}>HOW IT WORKS</div>
            <h2 style={{ fontSize:30, color:"#e8e3f8", fontWeight:"bold", margin:"0 0 8px" }}>Three Steps to Your First Newsletter</h2>
            <p style={{ color:"#635e80", fontSize:14, margin:0 }}>From idea to inbox in minutes</p>
          </div>
        </ScrollReveal>
        <div className="steps-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(240px,1fr))", gap:22 }}>
          {[
            { num:"01", icon:"🔍", title:"Generate", desc:"Pick a genre and let AI research trending topics, then write a complete newsletter issue with subject line and social posts.", color:"#7c3aed" },
            { num:"02", icon:"✅", title:"Review & Edit", desc:"Use the rich editor to refine your draft. Approve what you love, reject what doesn't fit. A/B test subject lines.", color:"#4f46e5" },
            { num:"03", icon:"📡", title:"Publish & Grow", desc:"One-click publish to Beehiiv, Medium, Facebook, Instagram, and TikTok. Copy social content to Twitter/X and LinkedIn. Set up auto-scheduling.", color:"#8b5cf6" },
          ].map((s, i) => (
            <ScrollReveal key={s.num} delay={i * 0.12}>
              <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:16, padding:"28px 24px", position:"relative", overflow:"hidden" }}>
                <div style={{ position:"absolute", top:-8, right:10, fontSize:64, fontFamily:"monospace", fontWeight:"bold", color:"rgba(139,92,246,0.06)", lineHeight:1 }}>{s.num}</div>
                <div style={{ width:48, height:48, borderRadius:12, background:`linear-gradient(135deg,${s.color}22,${s.color}11)`, display:"flex", alignItems:"center", justifyContent:"center", fontSize:24, marginBottom:16 }}>{s.icon}</div>
                <h3 style={{ color:"#e8e3f8", fontSize:18, margin:"0 0 10px", fontWeight:"bold" }}>{s.title}</h3>
                <p style={{ color:"#8b82b0", fontSize:13, lineHeight:1.7, margin:0 }}>{s.desc}</p>
              </div>
            </ScrollReveal>
          ))}
        </div>
      </div>

      <ScrollReveal>
        <div style={{ maxWidth:900, margin:"0 auto", padding:"40px 20px 50px" }}>
          <div style={{ textAlign:"center", marginBottom:40 }}>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:3, marginBottom:10 }}>TESTIMONIALS</div>
            <h2 style={{ fontSize:30, color:"#e8e3f8", fontWeight:"bold", margin:"0 0 8px" }}>Loved by Newsletter Creators</h2>
            <p style={{ color:"#635e80", fontSize:14, margin:0 }}>See what our users have to say</p>
          </div>
          <div className="testimonials-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))", gap:18 }}>
            {[
              { name:"Sarah M.", role:"Health Newsletter", text:"I went from zero to 500 subscribers in 3 weeks. The AI writes better hooks than I ever could.", stars:5 },
              { name:"James R.", role:"Real Estate Investor", text:"The social content alone saves me 4 hours a week. Twitter threads that actually get engagement.", stars:5 },
              { name:"Pastor Dave", role:"Church Leader", text:"My congregation gets a weekly devotional now. Setup took 10 minutes. It's been transformative.", stars:5 },
            ].map((t, i) => (
              <ScrollReveal key={t.name} delay={i * 0.1}>
                <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:16, padding:"24px 22px" }}>
                  <div style={{ color:"#f59e0b", fontSize:14, marginBottom:12, letterSpacing:2 }}>{"★".repeat(t.stars)}</div>
                  <p style={{ color:"#c8c3de", fontSize:14, lineHeight:1.7, margin:"0 0 16px", fontStyle:"italic" }}>"{t.text}"</p>
                  <div style={{ display:"flex", alignItems:"center", gap:12 }}>
                    <div style={{ width:40, height:40, borderRadius:"50%", background:"linear-gradient(135deg,#7c3aed,#4f46e5)", display:"flex", alignItems:"center", justifyContent:"center", color:"#fff", fontSize:15, fontWeight:"bold" }}>{t.name[0]}</div>
                    <div>
                      <div style={{ color:"#e8e3f8", fontSize:13, fontWeight:"bold" }}>{t.name}</div>
                      <div style={{ color:"#635e80", fontSize:11, fontFamily:"monospace" }}>{t.role}</div>
                    </div>
                  </div>
                </div>
              </ScrollReveal>
            ))}
          </div>
        </div>
      </ScrollReveal>

      <div style={{ maxWidth:1000, margin:"0 auto", padding:"50px 20px 70px" }} id="pricing">
        <ScrollReveal>
          <div style={{ textAlign:"center", marginBottom:44 }}>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:3, marginBottom:10 }}>PRICING</div>
            <h2 style={{ fontSize:30, color:"#e8e3f8", fontWeight:"bold", margin:"0 0 8px" }}>Simple, Transparent Pricing</h2>
            <p style={{ color:"#635e80", fontSize:14, margin:0 }}>Start free, upgrade when you're ready</p>
          </div>
        </ScrollReveal>
        <div className="pricing-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))", gap:20, maxWidth:960, margin:"0 auto" }}>
          <ScrollReveal delay={0}>
            <div className="pricing-card" style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:18, padding:"32px 26px", height:"100%" }}>
              <div style={{ fontSize:10, fontFamily:"monospace", color:"#635e80", letterSpacing:2, marginBottom:10 }}>FREE</div>
              <div style={{ fontSize:40, fontWeight:"bold", color:"#e8e3f8", marginBottom:4 }}>$0<span style={{ fontSize:16, color:"#635e80", fontWeight:"normal" }}>/mo</span></div>
              <div style={{ fontSize:13, color:"#635e80", marginBottom:28 }}>Get started with the basics</div>
              <div style={{ borderTop:"1px solid #1c1830", paddingTop:20, marginBottom:20 }}>
                {["5 starter genres", "2 generations per week", "Newsletter + social content", "Sponsor pitch generator", "Draft management"].map(f => (
                  <div key={f} style={{ fontSize:13, color:"#b5b0ce", padding:"6px 0", display:"flex", alignItems:"center", gap:10 }}>
                    <span style={{ color:"#86efac", fontSize:14 }}>✓</span> {f}
                  </div>
                ))}
              </div>
              <button className="pricing-btn" onClick={() => onShowAuth("register")} style={{ width:"100%", marginTop:"auto", background:"#13102a", border:"1px solid #4f46e5", borderRadius:10, color:"#a78bfa", padding:"13px", cursor:"pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold" }}>Start Free</button>
            </div>
          </ScrollReveal>
          <ScrollReveal delay={0.1}>
            <div className="pricing-card" style={{ background:"linear-gradient(180deg,#110f24,#0e0c1a)", border:"2px solid #7c3aed", borderRadius:18, padding:"32px 26px", position:"relative", animation:"borderGlow 3s ease-in-out infinite", height:"100%" }}>
              <div style={{ position:"absolute", top:-13, left:"50%", transform:"translateX(-50%)", background:"linear-gradient(135deg,#7c3aed,#4f46e5)", borderRadius:20, padding:"5px 20px", fontSize:10, fontFamily:"monospace", color:"#fff", fontWeight:"bold", letterSpacing:1.5 }}>MOST POPULAR</div>
              <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:2, marginBottom:10 }}>PRO</div>
              <div style={{ fontSize:40, fontWeight:"bold", color:"#e8e3f8", marginBottom:4 }}>$19<span style={{ fontSize:16, color:"#635e80", fontWeight:"normal" }}>/mo</span></div>
              <div style={{ fontSize:13, color:"#86efac", marginBottom:6, fontFamily:"monospace" }}>Start with a 7-day free trial</div>
              <div style={{ fontSize:13, color:"#635e80", marginBottom:22 }}>Everything, unlimited</div>
              <div style={{ borderTop:"1px solid #2a2448", paddingTop:20, marginBottom:20 }}>
                {["Everything in Free", "Unlimited generations", "Unlimited custom topics", "Affiliate discovery engine", "Multi-platform publishing", "Automated scheduling", "Full social content suite"].map(f => (
                  <div key={f} style={{ fontSize:13, color:"#b5b0ce", padding:"6px 0", display:"flex", alignItems:"center", gap:10 }}>
                    <span style={{ color:"#86efac", fontSize:14 }}>✓</span> {f}
                  </div>
                ))}
              </div>
              <button className="pricing-btn" onClick={() => onShowAuth("register")} style={{ width:"100%", marginTop:"auto", background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:10, color:"#fff", padding:"13px", cursor:"pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold", boxShadow:"0 4px 20px rgba(124,58,237,0.3)" }}>Start Free Trial</button>
            </div>
          </ScrollReveal>
          <ScrollReveal delay={0.2}>
            <div className="pricing-card" style={{ background:"linear-gradient(180deg,#141008,#0e0c1a)", border:"2px solid #f59e0b", borderRadius:18, padding:"32px 26px", position:"relative", animation:"eliteBorderGlow 3s ease-in-out infinite", height:"100%" }}>
              <div style={{ position:"absolute", top:-13, left:"50%", transform:"translateX(-50%)", background:"linear-gradient(135deg,#f59e0b,#d97706)", borderRadius:20, padding:"5px 20px", fontSize:10, fontFamily:"monospace", color:"#fff", fontWeight:"bold", letterSpacing:1.5 }}>BEST VALUE</div>
              <div style={{ fontSize:10, fontFamily:"monospace", color:"#f59e0b", letterSpacing:2, marginBottom:10 }}>ELITE</div>
              <div style={{ fontSize:40, fontWeight:"bold", color:"#e8e3f8", marginBottom:4 }}>$49<span style={{ fontSize:16, color:"#635e80", fontWeight:"normal" }}>/mo</span></div>
              <div style={{ fontSize:13, color:"#635e80", marginBottom:28 }}>Premium AI + exclusive tools</div>
              <div style={{ borderTop:"1px solid #2a2020", paddingTop:20, marginBottom:20 }}>
                {["Everything in Pro", "Priority AI (deeper analysis)", "A/B subject line testing", "PDF export", "White-label newsletters", "Bulk multi-genre scheduling", "Premium support badge"].map(f => (
                  <div key={f} style={{ fontSize:13, color:"#b5b0ce", padding:"6px 0", display:"flex", alignItems:"center", gap:10 }}>
                    <span style={{ color:"#fbbf24", fontSize:14 }}>✓</span> {f}
                  </div>
                ))}
              </div>
              <button className="pricing-btn" onClick={() => onShowAuth("register")} style={{ width:"100%", marginTop:"auto", background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:10, color:"#fff", padding:"13px", cursor:"pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold", boxShadow:"0 4px 20px rgba(245,158,11,0.2)" }}>Get Elite — $49/mo</button>
            </div>
          </ScrollReveal>
        </div>
      </div>

      <div style={{ maxWidth:700, margin:"0 auto", padding:"40px 20px 60px" }}>
        <ScrollReveal>
          <div style={{ textAlign:"center", marginBottom:40 }}>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:3, marginBottom:10 }}>FAQ</div>
            <h2 style={{ fontSize:30, color:"#e8e3f8", fontWeight:"bold", margin:"0 0 8px" }}>Frequently Asked Questions</h2>
            <p style={{ color:"#635e80", fontSize:14, margin:0 }}>Everything you need to know</p>
          </div>
        </ScrollReveal>
        {[
          { q:"What do I need to get started?", a:"Just an email address. Sign up free, pick a genre, and generate your first newsletter in under 2 minutes. No credit card required." },
          { q:"How does the AI generate content?", a:"We use Claude (Anthropic) to research live news and trends, then write complete newsletter issues with subject lines, social posts, and sponsor pitches tailored to your audience." },
          { q:"Can I edit the content before publishing?", a:"Absolutely. Every draft goes through your approval. Use the rich text editor to refine headlines, rewrite sections, or add your personal touch before sending." },
          { q:"What platforms can I publish to?", a:"Beehiiv (email newsletters), Medium (articles), Facebook Pages, Twitter/X (threads), LinkedIn, Instagram (captions), and TikTok (captions). More integrations coming soon." },
          { q:"Can I try Pro before committing?", a:"Yes! Pro comes with a 7-day free trial. You won't be charged until day 8. If you cancel during the trial, you'll never be billed." },
          { q:"Is there a limit on the free plan?", a:"Free accounts get 2 AI generations per week across 5 built-in genres. Upgrade to Pro for unlimited generations and custom topics." },
          { q:"Can I cancel anytime?", a:"Yes, all plans are month-to-month with no contracts. Cancel directly from your Account tab with one click — your access continues until the end of your billing period, then reverts to Free." },
        ].map((faq, i) => (
          <ScrollReveal key={i} delay={i * 0.05}>
            <details style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, marginBottom:10, overflow:"hidden" }}>
              <summary style={{ padding:"16px 20px", color:"#e8e3f8", fontSize:14, cursor:"pointer", fontFamily:"monospace", fontWeight:"bold", listStyle:"none", display:"flex", alignItems:"center", justifyContent:"space-between" }}>
                {faq.q}
                <span className="faq-icon" style={{ color:"#8b5cf6", fontSize:18, flexShrink:0, marginLeft:12, fontWeight:"bold" }}>+</span>
              </summary>
              <div style={{ padding:"0 20px 16px", color:"#a78bfa", fontSize:13, lineHeight:1.8 }}>{faq.a}</div>
            </details>
          </ScrollReveal>
        ))}
      </div>

      <ScrollReveal>
        <div style={{ background:"#0a0818", borderTop:"1px solid #1c1830", padding:"60px 20px" }}>
          <div style={{ maxWidth:900, margin:"0 auto" }}>
            <div style={{ textAlign:"center", marginBottom:28 }}>
              <div style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", borderRadius:18, padding:"40px 32px", maxWidth:640, margin:"0 auto", position:"relative", overflow:"hidden" }}>
                <div style={{ position:"absolute", inset:0, background:"radial-gradient(circle at 30% 50%, rgba(255,255,255,0.05) 0%, transparent 50%)", pointerEvents:"none" }} />
                <h3 style={{ color:"#fff", fontSize:24, margin:"0 0 12px", fontWeight:"bold", position:"relative" }}>Ready to launch your newsletter?</h3>
                <p style={{ color:"#c4b5fd", fontSize:15, margin:"0 0 24px", position:"relative" }}>Join thousands of creators using AI to grow their audience.</p>
                <button className="landing-cta-primary" onClick={() => onShowAuth("register")} style={{
                  background:"#fff", border:"none", borderRadius:10, color:"#4f46e5", padding:"14px 36px",
                  cursor:"pointer", fontSize:16, fontWeight:"bold", fontFamily:"monospace", position:"relative",
                  boxShadow:"0 4px 20px rgba(0,0,0,0.2)",
                }}>Get Started Free →</button>
              </div>
            </div>
            <div style={{ display:"flex", justifyContent:"center", gap:28, flexWrap:"wrap", marginTop:32, marginBottom:18 }}>
              <a href="#" onClick={e => { e.preventDefault(); document.getElementById("pricing")?.scrollIntoView({ behavior:"smooth" }); }} style={{ color:"#635e80", fontSize:12, fontFamily:"monospace", textDecoration:"none", transition:"color 0.2s" }}>Pricing</a>
              <span style={{ color:"#1c1830" }}>|</span>
              <a href="#" onClick={e => { e.preventDefault(); onShowAuth("register"); }} style={{ color:"#635e80", fontSize:12, fontFamily:"monospace", textDecoration:"none", transition:"color 0.2s" }}>Sign Up</a>
              <span style={{ color:"#1c1830" }}>|</span>
              <a href="#" onClick={e => { e.preventDefault(); onShowAuth("login"); }} style={{ color:"#635e80", fontSize:12, fontFamily:"monospace", textDecoration:"none", transition:"color 0.2s" }}>Sign In</a>
            </div>
            <div style={{ textAlign:"center", fontSize:11, color:"#3a3555", fontFamily:"monospace" }}>
              © {new Date().getFullYear()} Weekly Newsletter Engine — Powered by AI
            </div>
          </div>
        </div>
      </ScrollReveal>
    </div>
  );
}

// ── Auth Forms ────────────────────────────────────────────────────────────────
function AuthPage({ mode, onSwitch, onSuccess }) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    setLoading(true);
    setError(null);
    try {
      const endpoint = mode === "register" ? "/api/auth/register" : "/api/auth/login";
      const res = await apiFetch(endpoint, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, password }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed");
      onSuccess(data.user, data.isNew);
    } catch (err) {
      setError(err.message);
    }
    setLoading(false);
  }

  const inputStyle = { background:"#06050e", border:"1px solid #2a2448", borderRadius:8, color:"#e8e3f8", padding:"12px 16px", fontSize:14, fontFamily:"monospace", width:"100%", boxSizing:"border-box" };

  return (
    <div style={{ minHeight:"100vh", background:"#07060f", display:"flex", alignItems:"center", justifyContent:"center", padding:20 }}>
      <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:16, padding:"40px 36px", width:"100%", maxWidth:400 }}>
        <div style={{ textAlign:"center", marginBottom:28 }}>
          <div style={{ display:"inline-block", background:"linear-gradient(90deg,#7c3aed,#4f46e5)", borderRadius:4, padding:"3px 10px", fontSize:9, fontFamily:"monospace", letterSpacing:3, color:"#fff", fontWeight:"bold", marginBottom:12 }}>WEEKLY NEWSLETTER</div>
          <h2 style={{ fontSize:22, color:"#e8e3f8", fontWeight:"bold", margin:0 }}>{mode === "register" ? "Create Account" : "Welcome Back"}</h2>
          <p style={{ color:"#635e80", fontSize:13, marginTop:6 }}>{mode === "register" ? "Start building your newsletter business" : "Sign in to your account"}</p>
        </div>
        <form onSubmit={handleSubmit}>
          <div style={{ marginBottom:16 }}>
            <label style={{ display:"block", fontSize:11, color:"#635e80", fontFamily:"monospace", marginBottom:6, textTransform:"uppercase", letterSpacing:".05em" }}>Email</label>
            <input type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="you@email.com" required style={inputStyle} />
          </div>
          <div style={{ marginBottom:20 }}>
            <label style={{ display:"block", fontSize:11, color:"#635e80", fontFamily:"monospace", marginBottom:6, textTransform:"uppercase", letterSpacing:".05em" }}>Password</label>
            <input type="password" value={password} onChange={e => setPassword(e.target.value)} placeholder={mode === "register" ? "Min 6 characters" : "Your password"} required minLength={mode === "register" ? 6 : 1} style={inputStyle} />
          </div>
          {error && <div style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, padding:"10px 14px", marginBottom:16, fontSize:12, color:"#fca5a5", fontFamily:"monospace" }}>{error}</div>}
          <button type="submit" disabled={loading} style={{ width:"100%", background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"13px", cursor: loading?"not-allowed":"pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold", opacity: loading?0.7:1 }}>
            {loading ? "Please wait..." : mode === "register" ? "Create Account" : "Sign In"}
          </button>
        </form>
        <div style={{ textAlign:"center", marginTop:20 }}>
          <span style={{ color:"#635e80", fontSize:13 }}>{mode === "register" ? "Already have an account?" : "Don't have an account?"} </span>
          <button onClick={onSwitch} style={{ background:"none", border:"none", color:"#a78bfa", cursor:"pointer", fontSize:13, fontFamily:"monospace", textDecoration:"underline" }}>
            {mode === "register" ? "Sign in" : "Create one"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Account Tab ───────────────────────────────────────────────────────────────
function AccountTab() {
  const { user, refreshUser, logout } = useAuth();
  const [upgrading, setUpgrading] = useState(false);
  const [portalLoading, setPortalLoading] = useState(false);
  const [cancelLoading, setCancelLoading] = useState(false);
  const [showCancelConfirm, setShowCancelConfirm] = useState(false);
  const [confirmPlan, setConfirmPlan] = useState(null);
  const [msg, setMsg] = useState(null);

  useEffect(() => {
    const params = new URLSearchParams(window.location.hash.split("?")[1] || "");
    const sessionId = params.get("session_id");
    if (sessionId) {
      apiFetch("/api/stripe/check-session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ session_id: sessionId }),
      }).then(r => r.json()).then(data => {
        if (data.success) {
          refreshUser();
          const tier = data.plan === "elite" ? "Elite" : "Pro";
          setMsg(`Your ${tier} subscription is now active!`);
          window.location.hash = "#account";
        }
      }).catch(() => {});
    }
  }, []);

  async function handleUpgrade(plan) {
    setUpgrading(true);
    try {
      const isPaidUser = user?.tier === "pro" || user?.tier === "elite";
      if (isPaidUser && user?.has_stripe) {
        const res = await apiFetch("/api/stripe/upgrade-subscription", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ plan: plan || "elite" }),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || "Failed");
        setMsg(`Subscription upgraded to ${(plan || "elite").toUpperCase()}! Refreshing...`);
        setTimeout(() => window.location.reload(), 1500);
      } else {
        const res = await apiFetch("/api/stripe/create-checkout", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ plan: plan || "pro" }),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || "Failed");
        window.location.href = data.url;
      }
    } catch (err) {
      setMsg("Error: " + err.message);
    }
    setUpgrading(false);
  }

  async function handleManageBilling() {
    setPortalLoading(true);
    try {
      const res = await apiFetch("/api/stripe/create-portal", { method: "POST", headers: { "Content-Type": "application/json" } });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed");
      window.location.href = data.url;
    } catch (err) {
      setMsg("Error: " + err.message);
    }
    setPortalLoading(false);
  }

  async function handleCancelSubscription() {
    setCancelLoading(true);
    try {
      const res = await apiFetch("/api/stripe/cancel-subscription", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed");
      const cancelDate = new Date(data.cancel_at).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
      setMsg(`Subscription cancelled. You'll keep access until ${cancelDate}, then revert to Free.`);
      setShowCancelConfirm(false);
      refreshUser();
    } catch (err) {
      setMsg("Error: " + err.message);
    }
    setCancelLoading(false);
  }

  const sectionCard = { background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"20px 22px", marginBottom:14 };
  const isPro = user?.tier === "pro";
  const isElite = user?.tier === "elite";
  const isPaid = isPro || isElite;

  const tierBadge = isElite
    ? { bg: "linear-gradient(135deg,#f59e0b,#d97706)", color: "#fff", label: "ELITE" }
    : isPro
    ? { bg: "linear-gradient(135deg,#7c3aed,#4f46e5)", color: "#fff", label: "PRO" }
    : { bg: "#13102a", color: "#635e80", label: "FREE" };

  return (
    <div>
      {msg && (
        <div style={{ background: msg.startsWith("Error") ? "#1c0808" : "#0a1a0a", border: `1px solid ${msg.startsWith("Error") ? "#7f1d1d" : "#16a34a"}`, borderRadius:10, padding:"12px 18px", marginBottom:14, fontSize:13, color: msg.startsWith("Error") ? "#fca5a5" : "#86efac", fontFamily:"monospace" }}>
          {msg}
        </div>
      )}

      <div style={sectionCard}>
        <div style={{ fontWeight:"bold", fontSize:16, color:"#e8e3f8", marginBottom:16 }}>Account Details</div>
        <div className="account-grid" style={{ display:"grid", gridTemplateColumns:"120px 1fr", gap:"12px 16px", fontSize:13 }}>
          <div style={{ color:"#635e80", fontFamily:"monospace" }}>EMAIL</div>
          <div style={{ color:"#e8e3f8" }}>{user?.email}</div>
          <div style={{ color:"#635e80", fontFamily:"monospace" }}>PLAN</div>
          <div style={{ display:"flex", alignItems:"center", gap:8, flexWrap:"wrap" }}>
            <span style={{ background: tierBadge.bg, border: isPaid ? "none" : "1px solid #2a2448", borderRadius:6, color: tierBadge.color, padding:"4px 14px", fontSize:12, fontFamily:"monospace", fontWeight:"bold" }}>
              {tierBadge.label}
            </span>
            {user?.subscription_status === "trialing" && user?.trial_end && (() => {
              const daysLeft = Math.max(0, Math.ceil((new Date(user.trial_end) - new Date()) / (1000 * 60 * 60 * 24)));
              const billingDate = new Date(user.trial_end).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
              return (
                <span style={{ fontSize:11, fontFamily:"monospace", color:"#fbbf24" }}>
                  Trial — {daysLeft} day{daysLeft !== 1 ? "s" : ""} remaining (billing starts {billingDate})
                </span>
              );
            })()}
            {user?.subscription_status && user?.subscription_status !== "trialing" && !user?.cancel_at_period_end && (
              <span style={{ fontSize:11, fontFamily:"monospace", color: user.subscription_status === "active" ? "#86efac" : "#fca5a5" }}>
                ({user.subscription_status})
              </span>
            )}
            {user?.cancel_at_period_end && user?.current_period_end && (
              <span style={{ fontSize:11, fontFamily:"monospace", color:"#fca5a5" }}>
                Cancels on {new Date(user.current_period_end).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" })}
              </span>
            )}
            {isElite && <span style={{ fontSize:10, fontFamily:"monospace", color:"#fbbf24" }}>Premium Support</span>}
          </div>
          <div style={{ color:"#635e80", fontFamily:"monospace" }}>MEMBER SINCE</div>
          <div style={{ color:"#e8e3f8" }}>{user?.created_at ? new Date(user.created_at.endsWith("Z") ? user.created_at : user.created_at + "Z").toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" }) : "—"}</div>
          {!isPaid && (
            <>
              <div style={{ color:"#635e80", fontFamily:"monospace" }}>USAGE</div>
              <div style={{ color:"#e8e3f8" }}>{user?.generations_this_week || 0} / {user?.generations_limit || 2} generations this week</div>
            </>
          )}
        </div>
      </div>

      {/* Free → show both Pro and Elite upgrade options */}
      {!isPaid && (
        <div className="upgrade-grid" style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:14, marginBottom:14 }}>
          <div style={{ ...sectionCard, border:"2px solid #7c3aed", marginBottom:0, position:"relative" }}>
            <div style={{ position:"absolute", top:-10, left:16, background:"linear-gradient(135deg,#7c3aed,#4f46e5)", borderRadius:12, padding:"3px 12px", fontSize:9, fontFamily:"monospace", color:"#fff", fontWeight:"bold", letterSpacing:1 }}>MOST POPULAR</div>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:2, marginBottom:6 }}>PRO PLAN</div>
            <div style={{ fontWeight:"bold", fontSize:28, color:"#e8e3f8", marginBottom:4 }}>$19<span style={{ fontSize:14, color:"#635e80", fontWeight:"normal" }}>/mo</span></div>
            <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
              Unlimited generations, custom topics, affiliate discovery, publishing, and scheduling.
            </div>
            <div style={{ marginBottom:14 }}>
              {["Unlimited generations", "Custom topics", "Affiliate discovery", "Multi-platform publishing", "Automated scheduling"].map(f => (
                <div key={f} style={{ fontSize:11, color:"#b5b0ce", display:"flex", alignItems:"center", gap:6, padding:"3px 0" }}>
                  <span style={{ color:"#86efac" }}>✓</span> {f}
                </div>
              ))}
            </div>
            <div style={{ fontSize:11, color:"#86efac", fontFamily:"monospace", marginBottom:10 }}>7-day free trial included</div>
            <button onClick={() => setConfirmPlan("pro")} disabled={upgrading} style={{ width:"100%", background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"12px", cursor: upgrading ? "not-allowed" : "pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: upgrading ? 0.7 : 1, boxShadow:"0 4px 16px rgba(124,58,237,0.3)" }}>
              {upgrading ? "Redirecting..." : "Start Free Trial — $19/mo"}
            </button>
          </div>
          <div style={{ ...sectionCard, border:"2px solid #f59e0b", marginBottom:0, position:"relative", background:"linear-gradient(180deg,#141008,#0e0c1a)" }}>
            <div style={{ position:"absolute", top:-10, left:16, background:"linear-gradient(135deg,#f59e0b,#d97706)", borderRadius:12, padding:"3px 12px", fontSize:9, fontFamily:"monospace", color:"#fff", fontWeight:"bold", letterSpacing:1 }}>BEST VALUE</div>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#f59e0b", letterSpacing:2, marginBottom:6 }}>ELITE PLAN</div>
            <div style={{ fontWeight:"bold", fontSize:28, color:"#e8e3f8", marginBottom:4 }}>$49<span style={{ fontSize:14, color:"#635e80", fontWeight:"normal" }}>/mo</span></div>
            <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
              Everything in Pro plus priority AI, A/B testing, PDF export, white-label, and bulk scheduling.
            </div>
            <div style={{ marginBottom:14 }}>
              {["Everything in Pro", "Priority AI generation", "A/B subject testing", "PDF export", "White-label mode", "Bulk scheduling", "Premium support"].map(f => (
                <div key={f} style={{ fontSize:11, color:"#b5b0ce", display:"flex", alignItems:"center", gap:6, padding:"3px 0" }}>
                  <span style={{ color:"#fbbf24" }}>✓</span> {f}
                </div>
              ))}
            </div>
            <button onClick={() => setConfirmPlan("elite")} disabled={upgrading} style={{ width:"100%", background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:8, color:"#fff", padding:"12px", cursor: upgrading ? "not-allowed" : "pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: upgrading ? 0.7 : 1, boxShadow:"0 4px 16px rgba(245,158,11,0.3)" }}>
              {upgrading ? "Redirecting..." : "Get Elite — $49/mo"}
            </button>
          </div>
        </div>
      )}

      {/* Pro → show Elite upgrade option */}
      {isPro && !isElite && (
        <div style={{ ...sectionCard, border:"2px solid #f59e0b" }}>
          <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
            <div style={{ fontWeight:"bold", fontSize:16, color:"#e8e3f8" }}>Upgrade to Elite</div>
            <span style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", borderRadius:4, padding:"2px 8px", fontSize:9, fontFamily:"monospace", color:"#fff", fontWeight:"bold" }}>BEST VALUE</span>
          </div>
          <div style={{ fontSize:13, color:"#635e80", marginBottom:16, lineHeight:1.6 }}>
            Take your newsletters to the next level with priority AI, A/B subject line testing, PDF export, white-label mode, and bulk multi-genre scheduling for $49/month.
          </div>
          <div className="upgrade-features-grid" style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:8, marginBottom:16 }}>
            {["Priority AI generation", "A/B subject line testing", "PDF export", "White-label newsletters", "Bulk multi-genre scheduling", "Premium support badge"].map(f => (
              <div key={f} style={{ fontSize:12, color:"#b5b0ce", display:"flex", alignItems:"center", gap:6 }}>
                <span style={{ color:"#fbbf24" }}>✓</span> {f}
              </div>
            ))}
          </div>
          <button onClick={() => setConfirmPlan("elite")} disabled={upgrading} style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:8, color:"#fff", padding:"12px 28px", cursor: upgrading ? "not-allowed" : "pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold", opacity: upgrading ? 0.7 : 1 }}>
            {upgrading ? "Redirecting..." : "Upgrade to Elite — $49/mo"}
          </button>
        </div>
      )}

      {isPaid && user?.has_stripe && (
        <div style={sectionCard}>
          <div style={{ fontWeight:"bold", fontSize:16, color:"#e8e3f8", marginBottom:8 }}>Billing & Subscription</div>
          <div style={{ fontSize:13, color:"#635e80", marginBottom:16, lineHeight:1.6 }}>
            Manage your payment method, view invoices, or upgrade/downgrade your subscription.
          </div>
          <div style={{ display:"flex", gap:12, flexWrap:"wrap", alignItems:"center" }}>
            <button onClick={handleManageBilling} disabled={portalLoading} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:8, color:"#a78bfa", padding:"10px 24px", cursor: portalLoading ? "not-allowed" : "pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>
              {portalLoading ? "Loading..." : "Manage Billing"}
            </button>
            {!user?.cancel_at_period_end && (
              <button onClick={() => setShowCancelConfirm(true)} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, color:"#fca5a5", padding:"10px 24px", cursor:"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>
                Cancel Subscription
              </button>
            )}
            {user?.cancel_at_period_end && (
              <span style={{ fontSize:12, fontFamily:"monospace", color:"#fca5a5" }}>
                Your subscription is set to cancel. Access continues until end of billing period.
              </span>
            )}
          </div>

          {showCancelConfirm && (
            <div style={{ marginTop:16, background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:10, padding:"18px 20px" }}>
              <div style={{ fontWeight:"bold", fontSize:14, color:"#fca5a5", marginBottom:8 }}>Cancel your subscription?</div>
              <div style={{ fontSize:13, color:"#e8e3f8", marginBottom:16, lineHeight:1.6 }}>
                You'll keep full access to your current plan until the end of your billing period. After that, your account will revert to the Free plan.
              </div>
              <div style={{ display:"flex", gap:10 }}>
                <button onClick={handleCancelSubscription} disabled={cancelLoading} style={{ background:"#7f1d1d", border:"none", borderRadius:8, color:"#fff", padding:"10px 20px", cursor: cancelLoading ? "not-allowed" : "pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: cancelLoading ? 0.7 : 1 }}>
                  {cancelLoading ? "Cancelling..." : "Yes, Cancel"}
                </button>
                <button onClick={() => setShowCancelConfirm(false)} style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:8, color:"#a78bfa", padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>
                  Keep My Plan
                </button>
              </div>
            </div>
          )}
        </div>
      )}

      {confirmPlan && (
        <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.7)", zIndex:1000, display:"flex", alignItems:"center", justifyContent:"center" }} onClick={() => setConfirmPlan(null)}>
          <div style={{ background:"#0e0c1a", border:`2px solid ${confirmPlan === "elite" ? "#f59e0b" : "#7c3aed"}`, borderRadius:16, padding:28, maxWidth:420, width:"90%" }} onClick={e => e.stopPropagation()}>
            <div style={{ fontSize:18, fontWeight:"bold", color:"#e8e3f8", marginBottom:12 }}>
              {confirmPlan === "elite" ? "👑 Confirm Elite Plan" : "🚀 Confirm Pro Plan"}
            </div>
            <div style={{ fontSize:14, color:"#b5b0ce", marginBottom:8, lineHeight:1.7 }}>
              You are about to subscribe to the <strong style={{ color:"#e8e3f8" }}>{confirmPlan === "elite" ? "Elite" : "Pro"}</strong> plan at <strong style={{ color: confirmPlan === "elite" ? "#fbbf24" : "#a78bfa" }}>{confirmPlan === "elite" ? "$49/month" : "$19/month"}</strong>.
            </div>
            {confirmPlan === "pro" && (
              <div style={{ fontSize:12, color:"#86efac", fontFamily:"monospace", marginBottom:12 }}>
                Includes a 7-day free trial — you won't be charged until the trial ends.
              </div>
            )}
            {confirmPlan === "elite" && (
              <div style={{ fontSize:12, color:"#fbbf24", fontFamily:"monospace", marginBottom:12 }}>
                Billed immediately — no trial period for Elite.
              </div>
            )}
            <div style={{ fontSize:12, color:"#635e80", marginBottom:18, lineHeight:1.6 }}>
              You'll be redirected to Stripe's secure checkout page to complete your subscription.
            </div>
            <div style={{ display:"flex", gap:10 }}>
              <button onClick={() => { setConfirmPlan(null); handleUpgrade(confirmPlan); }} disabled={upgrading} style={{ background: confirmPlan === "elite" ? "linear-gradient(135deg,#f59e0b,#d97706)" : "linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"12px 24px", cursor: upgrading ? "not-allowed" : "pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold", opacity: upgrading ? 0.7 : 1 }}>
                {upgrading ? "Redirecting..." : confirmPlan === "elite" ? "Subscribe to Elite — $49/mo" : "Start Free Trial — $19/mo"}
              </button>
              <button onClick={() => setConfirmPlan(null)} style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:8, color:"#a78bfa", padding:"12px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace" }}>
                Cancel
              </button>
            </div>
          </div>
        </div>
      )}

      <FeedbackForm />

      <div style={sectionCard}>
        <div style={{ fontWeight:"bold", fontSize:16, color:"#e8e3f8", marginBottom:12 }}>Sign Out</div>
        <button onClick={logout} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, color:"#fca5a5", padding:"10px 24px", cursor:"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>
          Sign Out
        </button>
      </div>
    </div>
  );
}

function FeedbackForm() {
  const [message, setMessage] = useState("");
  const [sending, setSending] = useState(false);
  const [result, setResult] = useState(null);
  const [lastSent, setLastSent] = useState(0);

  async function handleSubmit() {
    if (!message.trim() || message.trim().length < 5) {
      setResult({ ok: false, text: "Please write at least 5 characters." });
      return;
    }
    const now = Date.now();
    if (now - lastSent < 60000) {
      setResult({ ok: false, text: "Please wait a minute before sending more feedback." });
      return;
    }
    setSending(true);
    setResult(null);
    try {
      const res = await apiFetch("/api/feedback", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message: message.trim() }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed to send feedback");
      setResult({ ok: true, text: "Your feedback has been sent! Thank you." });
      setMessage("");
      setLastSent(Date.now());
    } catch (e) {
      setResult({ ok: false, text: e.message });
    }
    setSending(false);
  }

  const sectionCard = { background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"20px 22px", marginBottom:14 };

  return (
    <div style={sectionCard}>
      <div style={{ fontWeight:"bold", fontSize:16, color:"#e8e3f8", marginBottom:6 }}>Send Feedback</div>
      <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
        Have a suggestion, found a bug, or want to request a feature? Let us know — your feedback goes directly to the team.
      </div>
      {result && (
        <div style={{ background: result.ok ? "#0a1a0a" : "#1c0808", border: `1px solid ${result.ok ? "#16a34a" : "#7f1d1d"}`, borderRadius:8, padding:"10px 14px", marginBottom:12, fontSize:12, color: result.ok ? "#86efac" : "#fca5a5", fontFamily:"monospace" }}>
          {result.text}
        </div>
      )}
      <textarea
        value={message}
        onChange={e => setMessage(e.target.value)}
        placeholder="Tell us what's on your mind..."
        maxLength={2000}
        rows={4}
        style={{ width:"100%", background:"#06050e", border:"1px solid #2a2448", borderRadius:8, color:"#e8e3f8", padding:"12px", fontSize:13, fontFamily:"monospace", resize:"vertical", boxSizing:"border-box", lineHeight:1.6 }}
      />
      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginTop:10 }}>
        <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>{message.length}/2000</span>
        <button onClick={handleSubmit} disabled={sending || !message.trim()} style={{
          background: sending || !message.trim() ? "#13102a" : "linear-gradient(135deg,#7c3aed,#4f46e5)",
          border:"none", borderRadius:8, color: sending || !message.trim() ? "#3a3555" : "#fff",
          padding:"10px 24px", cursor: sending || !message.trim() ? "default" : "pointer",
          fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: sending ? 0.7 : 1,
        }}>
          {sending ? "Sending..." : "Send Feedback"}
        </button>
      </div>
    </div>
  );
}

// ── Tier Gate Components ──────────────────────────────────────────────────────
function ProGate({ children, feature }) {
  const { user } = useAuth();
  if (user?.tier === "pro" || user?.tier === "elite") return children;
  return (
    <div style={{ textAlign:"center", padding:"60px 20px", background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12 }}>
      <div style={{ fontSize:40, marginBottom:16 }}>🔒</div>
      <div style={{ fontWeight:"bold", fontSize:18, color:"#e8e3f8", marginBottom:8 }}>Pro Feature</div>
      <div style={{ fontSize:13, color:"#635e80", marginBottom:20, maxWidth:400, margin:"0 auto 20px" }}>
        {feature || "This feature"} requires a Pro or Elite subscription. Upgrade for unlimited access.
      </div>
      <button onClick={() => { window.location.hash = "#account"; }} style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"12px 28px", cursor:"pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold" }}>
        Start Free Trial — $19/mo
      </button>
    </div>
  );
}

function EliteGate({ children, feature }) {
  const { user } = useAuth();
  if (user?.tier === "elite") return children;
  return (
    <div style={{ textAlign:"center", padding:"60px 20px", background:"#0e0c1a", border:"1px solid #2a1f00", borderRadius:12 }}>
      <div style={{ fontSize:40, marginBottom:16 }}>👑</div>
      <div style={{ fontWeight:"bold", fontSize:18, color:"#e8e3f8", marginBottom:8 }}>Elite Feature</div>
      <div style={{ fontSize:13, color:"#635e80", marginBottom:20, maxWidth:400, margin:"0 auto 20px" }}>
        {feature || "This feature"} is exclusive to Elite subscribers. Upgrade for the ultimate newsletter experience.
      </div>
      <button onClick={() => { window.location.hash = "#account"; }} style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:8, color:"#fff", padding:"12px 28px", cursor:"pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold" }}>
        Upgrade to Elite — $49/mo
      </button>
    </div>
  );
}

// ── Shared output store (cleared when genre changes) ──────────────────────────
const OUTPUTS = {};

// ── Genre definitions ─────────────────────────────────────────────────────────
const GENRES = [
  {
    id: "health",
    name: "Health & Wellness",
    icon: "💪",
    color: "#16a34a",
    desc: "Fitness, nutrition, mental health & holistic living",
    audience: "health-conscious readers who want to live longer, stronger lives",
    section: "THIS WEEK IN HEALTH & WELLNESS",
    ctaLine: "Join Premium for weekly meal plans, workout routines, and supplement guides.",
  },
  {
    id: "church",
    name: "Church",
    icon: "✝️",
    color: "#2563eb",
    desc: "Faith, ministry, Christian living & church growth",
    audience: "Christians, pastors, and ministry leaders seeking to grow in faith",
    section: "THIS WEEK IN FAITH & MINISTRY",
    ctaLine: "Join Premium for weekly devotionals, sermon prep tools, and ministry resources.",
  },
  {
    id: "realestate",
    name: "Real Estate",
    icon: "🏡",
    color: "#d97706",
    desc: "Property investing, housing market & financial growth",
    audience: "aspiring and active real estate investors who want to build wealth through property",
    section: "THIS WEEK IN REAL ESTATE",
    ctaLine: "Join Premium for weekly deal analysis, market forecasts, and investor interviews.",
  },
  {
    id: "gaming",
    name: "Video Games",
    icon: "🎮",
    color: "#7c3aed",
    desc: "Family-friendly games, Nintendo, co-op & clean gaming",
    audience: "families and parents who love clean, fun gaming experiences",
    section: "THIS WEEK IN FAMILY GAMING",
    ctaLine: "Join Premium for exclusive game reviews, family night guides, and early deal alerts.",
  },
  {
    id: "finance",
    name: "Financial Peace",
    icon: "💰",
    color: "#0891b2",
    desc: "Debt freedom, budgeting, investing & financial independence",
    audience: "everyday people working toward debt freedom and financial peace",
    section: "THIS WEEK IN FINANCIAL PEACE",
    ctaLine: "Join Premium for weekly budget templates, debt payoff calculators, and investor Q&As.",
  },
];

// ── Affiliate links per genre ─────────────────────────────────────────────────
const AFFILIATE_DATA = {
  health: [
    { name: "Thrive Market", url: "https://thrivemarket.com/join", commission: "$25 per referral", desc: "Organic & healthy groceries delivered at 25-50% below retail prices" },
    { name: "Athletic Greens (AG1)", url: "https://athleticgreens.com", commission: "20% recurring", desc: "Premium all-in-one daily nutritional supplement used by elite athletes" },
    { name: "MyFitnessPal Premium", url: "https://www.myfitnesspal.com/premium", commission: "$5-10 per referral", desc: "The #1 calorie tracking and nutrition planning app" },
    { name: "Amazon Health & Household", url: "https://www.amazon.com/health", commission: "1-10% per sale", desc: "Vitamins, supplements, fitness equipment, and wellness essentials" },
    { name: "Noom", url: "https://www.noom.com", commission: "20-30% per sale", desc: "Psychology-based weight loss program with personalized coaching" },
  ],
  church: [
    { name: "RightNow Media", url: "https://www.rightnowmedia.org", commission: "20% recurring", desc: "The Netflix of Bible studies — 20,000+ Christian video resources for churches" },
    { name: "Logos Bible Software", url: "https://www.logos.com", commission: "10% per sale", desc: "Professional Bible study, research, and sermon prep tools for pastors" },
    { name: "Bible Gateway Plus", url: "https://www.biblegateway.com/plus/", commission: "10-20% per sale", desc: "Ad-free Bible access, in-depth study tools, and reading plans" },
    { name: "Lifeway Resources", url: "https://www.lifeway.com", commission: "5-8% per sale", desc: "Bible studies, Sunday school curriculum, and church resources" },
    { name: "Compassion International", url: "https://www.compassion.com", commission: "Referral program", desc: "Child sponsorship and global mission support — $38/month changes lives" },
  ],
  realestate: [
    { name: "BiggerPockets Pro", url: "https://www.biggerpockets.com/pro", commission: "20-30% per sale", desc: "The #1 real estate investing community, tools, and education platform" },
    { name: "Fundrise", url: "https://fundrise.com", commission: "$10-100 per referral", desc: "Real estate crowdfunding — start investing in commercial properties for $10" },
    { name: "DealMachine", url: "https://www.dealmachine.com", commission: "20% recurring", desc: "Find off-market properties and motivated sellers with AI-powered tools" },
    { name: "PropStream", url: "https://trial.propstream.com", commission: "20% recurring", desc: "Comprehensive property data and lead generation platform for investors" },
    { name: "Roofstock", url: "https://www.roofstock.com", commission: "$500+ per closed deal", desc: "Marketplace to buy and sell single-family rental properties nationwide" },
  ],
  gaming: [
    { name: "Humble Bundle", url: "https://www.humblebundle.com", commission: "5-10% per sale", desc: "Family-friendly game bundles that donate a portion to charity" },
    { name: "Xbox Game Pass", url: "https://www.xbox.com/xbox-game-pass", commission: "$3-5 per referral", desc: "100+ family-friendly games for one low monthly price — great value" },
    { name: "Nintendo eShop Gift Cards", url: "https://www.amazon.com/nintendo-gift-card", commission: "1-3% per sale", desc: "Digital credits for Nintendo Switch — perfect for family game nights" },
    { name: "Jackbox Games", url: "https://www.jackboxgames.com", commission: "10% per sale", desc: "Hilarious party games perfect for family game nights — no controllers needed" },
    { name: "Green Man Gaming", url: "https://www.greenmangaming.com", commission: "5% per sale", desc: "Discounted PC games — huge selection of family-friendly titles" },
  ],
  finance: [
    { name: "Ramsey+ (EveryDollar)", url: "https://www.ramseysolutions.com/ramseyplus", commission: "20% per sale", desc: "Dave Ramsey's complete financial peace program — budgeting, courses, and community" },
    { name: "Acorns", url: "https://www.acorns.com/share/", commission: "$5-75 per referral", desc: "Round-up micro-investing — automatically invest your spare change" },
    { name: "Personal Capital", url: "https://www.personalcapital.com", commission: "$100+ per referral", desc: "Free wealth management dashboard and retirement planning tools" },
    { name: "Betterment", url: "https://www.betterment.com", commission: "Varies", desc: "Automated investing and retirement planning for beginners and pros alike" },
    { name: "Credit Karma", url: "https://www.creditkarma.com", commission: "$2-10 per referral", desc: "Free credit score monitoring, financial insights, and savings recommendations" },
  ],
};

// ── Genre-aware prompt generator ──────────────────────────────────────────────
const ROTATING_ANGLES = {
  health: [
    "Focus on contrarian health findings that challenge common beliefs",
    "Focus on mental health and emotional wellness breakthroughs",
    "Focus on nutrition science and gut health discoveries",
    "Focus on longevity research and anti-aging strategies",
    "Focus on fitness innovations and recovery techniques",
  ],
  church: [
    "Focus on church growth strategies and modern ministry tools",
    "Focus on faith in the workplace and Monday-to-Friday Christianity",
    "Focus on youth ministry and next-generation faith building",
    "Focus on global missions and cross-cultural ministry impact",
    "Focus on pastoral wellness, burnout prevention, and spiritual renewal",
  ],
  realestate: [
    "Focus on emerging markets and undervalued neighborhoods",
    "Focus on creative financing strategies and no-money-down deals",
    "Focus on rental property cash flow optimization",
    "Focus on commercial real estate and mixed-use opportunities",
    "Focus on market cycle timing and recession-proof investing",
  ],
  gaming: [
    "Focus on indie games and hidden gems families are missing",
    "Focus on educational games that kids actually love",
    "Focus on retro gaming revival and classic family favorites",
    "Focus on multiplayer and co-op experiences for family bonding",
    "Focus on gaming on a budget — deals, free-to-play, and smart buys",
  ],
  finance: [
    "Focus on side hustles and extra income for debt payoff acceleration",
    "Focus on investing basics for complete beginners",
    "Focus on frugal living hacks that don't feel like sacrifice",
    "Focus on financial milestones and celebrating money wins",
    "Focus on generational wealth and teaching kids about money",
  ],
};

function getRotatingAngle(genre) {
  const angles = ROTATING_ANGLES[genre] || ROTATING_ANGLES.health;
  const weekNumber = Math.floor(Date.now() / (7 * 24 * 60 * 60 * 1000));
  return angles[weekNumber % angles.length];
}

function getPrompt(stepId, genre, headlines, template) {
  const g = GENRES.find(x => x.id === genre) || GENRES[0];
  const affiliates = (AFFILIATE_DATA[genre] || []);

  const headlinesBlock = (headlines && headlines.length > 0)
    ? `\nRECENT REAL-WORLD NEWS (use these as your PRIMARY sources — cite them by name):\n${headlines.map((h, i) => `${i + 1}. "${h.title}" — ${h.source || "News"}\n   ${h.description || ""}`).join("\n")}\n`
    : "\n(No live headlines available — use your most current training knowledge for this genre.)\n";

  const affiliateBlock = affiliates.map(a => `- ${a.name} (${a.url}): ${a.desc}`).join("\n");
  const weeklyAngle = getRotatingAngle(genre);
  const angleInstruction = `\nTHIS WEEK'S ANGLE: ${weeklyAngle}. Prioritize stories and insights that align with this theme while still covering the most important developments.\n`;

  const researchPrompts = {
    health: `You are a research assistant for "Weekly Newsletter" — a health and wellness publication for ${g.audience}.
${headlinesBlock}${angleInstruction}
Summarize 5 important recent health & wellness developments readers should act on. For each story write:
- A punchy, specific headline (max 8 words)
- A 2-sentence summary with practical health impact
- One "Why it matters" line about improving daily energy, longevity, or wellbeing

Then add:
- PRODUCT OF THE WEEK: one specific wellness product or supplement (name, what it does, who benefits most)
- TIP OF THE WEEK: one actionable, evidence-based health tip readers can use today

Plain text, clearly labeled. Be specific, not generic. Avoid vague wellness speak.`,

    church: `You are a research assistant for "Weekly Newsletter" — a faith and ministry publication for ${g.audience}.
${headlinesBlock}${angleInstruction}
Summarize 5 important recent developments in Christian faith, church culture, or ministry that readers should know about. For each story write:
- A clear, faith-focused headline (max 8 words)
- A 2-sentence summary with spiritual or ministry relevance
- One "Why it matters" line connecting the story to Christian living or church growth

Then add:
- RESOURCE OF THE WEEK: one specific Christian book, Bible study, or ministry tool (name, what it does, who it's for)
- SCRIPTURE FOCUS: one verse and a 2-sentence application for the week

Plain text, clearly labeled. Keep tone warm, biblical, and encouraging.`,

    realestate: `You are a research assistant for "Weekly Newsletter" — a real estate investing publication for ${g.audience}.
${headlinesBlock}${angleInstruction}
Summarize 5 important recent real estate market developments, investing strategies, or economic signals investors should act on. For each story write:
- A punchy, deal-focused headline (max 8 words)
- A 2-sentence summary with specific market data or investor implications
- One "Why it matters" line about profit, cash flow, or portfolio impact

Then add:
- TOOL OF THE WEEK: one specific real estate investing tool or platform (name, what it does, who it's for)
- STRATEGY OF THE WEEK: one specific investing tactic or due diligence tip readers can use right now

Plain text, clearly labeled. Be data-driven and specific — cite numbers where possible.`,

    gaming: `You are a research assistant for "Weekly Newsletter" — a family gaming publication for ${g.audience}.
${headlinesBlock}${angleInstruction}
Summarize 5 important recent family-friendly gaming news items — new releases, deals, Nintendo updates, or co-op recommendations. For each story write:
- A fun, family-friendly headline (max 8 words)
- A 2-sentence summary with game age ratings and why families will love it
- One "Why it matters" line about family bonding or wholesome entertainment value

Keep all content strictly clean and family-appropriate. No violent, mature, or M-rated content.

Then add:
- GAME OF THE WEEK: one specific family-friendly game (title, platform, age rating, why families love it)
- TIP OF THE WEEK: one tip for family game nights, parental controls, or getting more from gaming time

Plain text, clearly labeled. Keep it fun and family-focused.`,

    finance: `You are a research assistant for "Weekly Newsletter" — a personal finance publication for ${g.audience} who follow Dave Ramsey-style Financial Peace principles.
${headlinesBlock}${angleInstruction}
Summarize 5 important recent personal finance developments, economic updates, or debt-freedom strategies readers should know. For each story write:
- A punchy, action-oriented headline (max 8 words)
- A 2-sentence summary with practical money impact
- One "Why it matters" line about getting out of debt, saving more, or building wealth

Then add:
- TOOL OF THE WEEK: one specific budgeting app, investing platform, or financial resource (name, what it does, who it's for)
- BABY STEP TIP: one specific Dave Ramsey Baby Step strategy or financial peace principle readers can apply this week

Plain text, clearly labeled. Be practical, debt-averse, and encouraging — avoid get-rich-quick advice.`,
  };

  const writePrompts = {
    health: `You are the editor of "Weekly Newsletter" — a health and wellness newsletter. Tone: warm, evidence-based, and motivating — like a knowledgeable friend who cuts through wellness hype.

Using this research:
${OUTPUTS.research || "Use your best current knowledge of health and wellness trends."}

Weave these affiliate recommendations naturally into the content where they genuinely fit:
${affiliateBlock}

Write a complete newsletter issue using this exact structure:

SUBJECT LINE OPTIONS:
Option 1 (curiosity): ...
Option 2 (benefit): ...

PREVIEW TEXT: (under 90 chars)

---
THE HOOK
(2-3 sentences about why THIS WEEK'S health news matters to readers personally)

${g.section}
(Each story: headline, 2-3 sentence breakdown, practical "So what?" takeaway)

PRODUCT SPOTLIGHT
(Highlight one wellness product with an affiliate link — be genuine about benefits)

WELLNESS TIP OF THE WEEK
(One specific, actionable tip the reader can do TODAY)

THE BOTTOM LINE
(3-sentence wrap-up with a motivating, forward-looking health insight)

${g.ctaLine}
---
No filler. Every sentence should help the reader feel and perform better.`,

    church: `You are the editor of "Weekly Newsletter" — a faith and ministry newsletter. Tone: warm, biblically grounded, encouraging — like a trusted pastor who keeps it practical.

Using this research:
${OUTPUTS.research || "Use your best current knowledge of Christian faith and ministry trends."}

Weave these resource recommendations naturally into the content where they genuinely fit:
${affiliateBlock}

Write a complete newsletter issue using this exact structure:

SUBJECT LINE OPTIONS:
Option 1 (curiosity): ...
Option 2 (benefit): ...

PREVIEW TEXT: (under 90 chars)

---
THE HOOK
(2-3 sentences connecting this week's theme to readers' daily faith walk)

${g.section}
(Each story: headline, 2-3 sentence breakdown, "So what for your faith?" takeaway)

RESOURCE OF THE WEEK
(Highlight one Christian resource with a recommendation — be genuine about value)

SCRIPTURE & REFLECTION
(One verse + 3-4 sentences of practical application for this week)

THE BOTTOM LINE
(3-sentence wrap-up with an encouraging, biblically grounded insight)

${g.ctaLine}
---
Keep it grounded in Scripture, practically useful, and free from denominational controversy.`,

    realestate: `You are the editor of "Weekly Newsletter" — a real estate investing newsletter. Tone: analytical, direct, and deal-focused — like a seasoned investor sharing what actually works.

Using this research:
${OUTPUTS.research || "Use your best current knowledge of real estate market conditions and investing."}

Weave these tool recommendations naturally into the content where they genuinely fit:
${affiliateBlock}

Write a complete newsletter issue using this exact structure:

SUBJECT LINE OPTIONS:
Option 1 (curiosity): ...
Option 2 (benefit): ...

PREVIEW TEXT: (under 90 chars)

---
THE HOOK
(2-3 sentences about why THIS WEEK'S market conditions create specific opportunities or risks)

${g.section}
(Each story: headline, 2-3 sentence breakdown, "Investor takeaway" — specific action or watch point)

DEAL TOOL OF THE WEEK
(Highlight one real estate platform or tool with an affiliate link — include specific use case)

STRATEGY OF THE WEEK
(One specific investing tactic, negotiation tip, or due diligence checklist item)

THE BOTTOM LINE
(3-sentence market wrap-up with a forward-looking insight for the next 90 days)

${g.ctaLine}
---
Be specific with numbers, percentages, and market data. No vague advice.`,

    gaming: `You are the editor of "Weekly Newsletter" — a family gaming newsletter. Tone: fun, enthusiastic, and parent-friendly — like an excited gamer who also cares about family values.

Using this research:
${OUTPUTS.research || "Use your best current knowledge of family-friendly games and gaming trends."}

Weave these gaming recommendations naturally into the content where they genuinely fit:
${affiliateBlock}

Keep ALL content strictly family-appropriate. No M-rated games, violence, or mature themes.

Write a complete newsletter issue using this exact structure:

SUBJECT LINE OPTIONS:
Option 1 (excitement): ...
Option 2 (family angle): ...

PREVIEW TEXT: (under 90 chars)

---
THE HOOK
(2-3 sentences about why this week is exciting for family gamers)

${g.section}
(Each story: game/news title, 2-3 sentence breakdown, "Why your family will love it" takeaway, include ESRB rating)

GAME OF THE WEEK
(Full review spotlight: title, platform, age rating, what makes it special for families)

FAMILY GAME NIGHT TIP
(One specific tip for better family gaming experiences — parental controls, cooperative play, etc.)

THE BOTTOM LINE
(3-sentence wrap-up with an exciting look at what's coming next week in family gaming)

${g.ctaLine}
---
Keep it fun, family-safe, and genuinely useful for parents and kids alike.`,

    finance: `You are the editor of "Weekly Newsletter" — a personal finance newsletter built on Financial Peace principles. Tone: direct, debt-averse, and encouraging — like Dave Ramsey if he had a newsletter column.

Using this research:
${OUTPUTS.research || "Use your best current knowledge of personal finance, debt payoff, and wealth building."}

Weave these financial tool recommendations naturally into the content where they genuinely fit:
${affiliateBlock}

Write a complete newsletter issue using this exact structure:

SUBJECT LINE OPTIONS:
Option 1 (curiosity): ...
Option 2 (action): ...

PREVIEW TEXT: (under 90 chars)

---
THE HOOK
(2-3 sentences about why THIS WEEK'S financial news affects readers' money and debt journey)

${g.section}
(Each story: headline, 2-3 sentence breakdown, "Your money move" — specific action to take)

TOOL OF THE WEEK
(Highlight one financial app or resource with an affiliate link — explain exactly how it helps)

BABY STEP SPOTLIGHT
(Focus on one of Dave Ramsey's 7 Baby Steps — explain it, give a specific tactic, celebrate wins)

THE BOTTOM LINE
(3-sentence wrap-up that motivates readers toward financial freedom, not fear)

${g.ctaLine}
---
Avoid get-rich-quick schemes. Celebrate debt payoffs. Make money simple and hopeful.`,
  };

  const socialPrompts = {
    health: `You are a social media strategist for "Weekly Newsletter" — a health and wellness newsletter for ${g.audience}.

Based on this newsletter:
${(OUTPUTS.write || "A health and wellness newsletter covering fitness, nutrition, and mental health.").substring(0, 2000)}

Create platform-specific social content:

1. TWITTER/X THREAD (8 tweets, numbered 1/8 to 8/8)
   Tweet 1: Bold health hook that stops the scroll
   Tweets 2-6: One actionable health insight per tweet
   Tweet 7: Product or tip spotlight
   Tweet 8: CTA to subscribe free — "Get this in your inbox every week →"

2. LINKEDIN POST (150-200 words, professional wellness angle, end with 3 hashtags like #WellnessAtWork #HealthyLiving #Nutrition)

3. INSTAGRAM CAPTION (casual, relatable health motivation, under 100 words, 5 health hashtags)

4. TIKTOK CAPTION (short, punchy hook for a health tip video, under 150 words, 3-5 trending health hashtags)

Label each section clearly.`,

    church: `You are a social media strategist for "Weekly Newsletter" — a faith and ministry newsletter for ${g.audience}.

Based on this newsletter:
${(OUTPUTS.write || "A Christian faith newsletter covering ministry, church growth, and biblical living.").substring(0, 2000)}

Create platform-specific social content:

1. TWITTER/X THREAD (8 tweets, numbered 1/8 to 8/8)
   Tweet 1: Faith hook or inspiring Scripture snippet
   Tweets 2-6: One ministry insight or biblical truth per tweet
   Tweet 7: Resource spotlight
   Tweet 8: CTA to subscribe free

2. LINKEDIN POST (150-200 words, professional faith-at-work angle, end with 3 hashtags like #ChristianLeadership #Faith #Ministry)

3. INSTAGRAM CAPTION (warm, devotional tone, under 100 words, 5 faith hashtags)

4. TIKTOK CAPTION (short, inspiring faith hook for a devotional video, under 150 words, 3-5 trending faith hashtags)

Label each section clearly. Keep all content biblically grounded and uplifting.`,

    realestate: `You are a social media strategist for "Weekly Newsletter" — a real estate investing newsletter for ${g.audience}.

Based on this newsletter:
${(OUTPUTS.write || "A real estate investing newsletter covering market trends, strategies, and deal analysis.").substring(0, 2000)}

Create platform-specific social content:

1. TWITTER/X THREAD (8 tweets, numbered 1/8 to 8/8)
   Tweet 1: Market stat or deal hook that grabs investor attention
   Tweets 2-6: One investing insight or strategy per tweet
   Tweet 7: Tool or resource spotlight
   Tweet 8: CTA to subscribe free

2. LINKEDIN POST (150-200 words, investor/entrepreneur angle with market data, end with 3 hashtags like #RealEstateInvesting #PassiveIncome #Wealth)

3. INSTAGRAM CAPTION (aspirational investing lifestyle, under 100 words, 5 real estate hashtags)

4. TIKTOK CAPTION (short, attention-grabbing real estate investing hook, under 150 words, 3-5 trending investing hashtags)

Label each section clearly.`,

    gaming: `You are a social media strategist for "Weekly Newsletter" — a family gaming newsletter for ${g.audience}.

Based on this newsletter:
${(OUTPUTS.write || "A family gaming newsletter covering clean games, Nintendo news, and family game nights.").substring(0, 2000)}

Create platform-specific social content. Keep ALL content family-friendly.

1. TWITTER/X THREAD (8 tweets, numbered 1/8 to 8/8)
   Tweet 1: Exciting family gaming hook
   Tweets 2-6: One game tip, review highlight, or family gaming insight per tweet
   Tweet 7: Game of the week spotlight
   Tweet 8: CTA to subscribe free

2. LINKEDIN POST (150-200 words, family wellness / screen-time balance angle, end with 3 hashtags like #FamilyGaming #GameNight #NintendoSwitch)

3. INSTAGRAM CAPTION (fun, family-friendly gaming excitement, under 100 words, 5 gaming hashtags)

4. TIKTOK CAPTION (short, exciting family gaming hook for a game review video, under 150 words, 3-5 trending gaming hashtags)

Label each section clearly.`,

    finance: `You are a social media strategist for "Weekly Newsletter" — a personal finance newsletter for ${g.audience}.

Based on this newsletter:
${(OUTPUTS.write || "A personal finance newsletter covering debt payoff, budgeting, and Financial Peace principles.").substring(0, 2000)}

Create platform-specific social content:

1. TWITTER/X THREAD (8 tweets, numbered 1/8 to 8/8)
   Tweet 1: Money mindset hook or debt-freedom stat
   Tweets 2-6: One budgeting tip, investing insight, or Baby Step breakdown per tweet
   Tweet 7: Tool or app spotlight
   Tweet 8: CTA to subscribe free

2. LINKEDIN POST (150-200 words, professional money management angle, end with 3 hashtags like #FinancialFreedom #DebtFree #PersonalFinance)

3. INSTAGRAM CAPTION (motivational debt-free journey tone, under 100 words, 5 finance hashtags)

4. TIKTOK CAPTION (short, motivational money tip hook for a finance video, under 150 words, 3-5 trending finance hashtags)

Label each section clearly.`,
  };

  const pitchPrompts = {
    health: `You are a sponsorship sales rep for "Weekly Newsletter" — a health and wellness newsletter reaching 2,000+ readers focused on fitness, nutrition, and holistic living.

Write a cold outreach email to a health or wellness brand (like a supplement company, fitness app, or healthy food brand).

Include:
- Subject line (under 8 words, curiosity-driven)
- Personal opener referencing their specific product (1 sentence)
- Audience stats: 2,000+ subscribers, 42% open rate, health-conscious adults aged 25-55
- What we offer: dedicated product feature + banner placement + social mention across Twitter, LinkedIn, and Instagram
- Pricing: $400 per issue (introductory wellness brand rate)
- Clear CTA to reply or book a 15-minute call
- Sign off as "The Weekly Newsletter Team"

Tone: Confident, peer-to-peer. Not pushy or salesy.`,

    church: `You are a sponsorship sales rep for "Weekly Newsletter" — a faith and ministry newsletter reaching 2,000+ Christian readers including pastors, worship leaders, and ministry volunteers.

Write a cold outreach email to a Christian publisher, Bible software company, or church resource provider.

Include:
- Subject line (under 8 words, ministry-focused)
- Personal opener referencing their specific product or mission (1 sentence)
- Audience stats: 2,000+ subscribers, 42% open rate, active church members and ministry leaders
- What we offer: dedicated resource feature + banner placement + faith community mention
- Pricing: $350 per issue (ministry partner rate)
- Clear CTA to reply or book a call
- Sign off as "The Weekly Newsletter Team"

Tone: Respectful, faith-aligned, mission-driven. Not corporate.`,

    realestate: `You are a sponsorship sales rep for "Weekly Newsletter" — a real estate investing newsletter reaching 2,000+ active and aspiring property investors.

Write a cold outreach email to a real estate tech company, investing platform, or property data service.

Include:
- Subject line (under 8 words, ROI-focused)
- Personal opener referencing their specific platform or tool (1 sentence)
- Audience stats: 2,000+ subscribers, 42% open rate, real estate investors with $50K+ in investable assets
- What we offer: dedicated tool feature + banner placement + investor community mention
- Pricing: $500 per issue (introductory investor platform rate)
- Clear CTA to reply or book a call
- Sign off as "The Weekly Newsletter Team"

Tone: Confident, data-driven, investor-to-investor. Speak their language.`,

    gaming: `You are a sponsorship sales rep for "Weekly Newsletter" — a family gaming newsletter reaching 2,000+ parents and families who love clean, wholesome video games.

Write a cold outreach email to a family gaming brand, game publisher, or family entertainment company.

Include:
- Subject line (under 8 words, family-fun focused)
- Personal opener referencing their specific game or product (1 sentence)
- Audience stats: 2,000+ subscribers, 42% open rate, parents aged 28-45 with children who game
- What we offer: dedicated game feature + banner placement + family gaming community mention
- Pricing: $350 per issue (family brand rate)
- Clear CTA to reply or book a call
- Sign off as "The Weekly Newsletter Team"

Tone: Enthusiastic, family-friendly, community-driven.`,

    finance: `You are a sponsorship sales rep for "Weekly Newsletter" — a personal finance newsletter reaching 2,000+ readers committed to debt freedom and Financial Peace principles.

Write a cold outreach email to a fintech app, financial education company, or wealth management platform.

Include:
- Subject line (under 8 words, money-focused)
- Personal opener referencing their specific product or mission (1 sentence)
- Audience stats: 2,000+ subscribers, 42% open rate, adults actively paying off debt or building emergency funds
- What we offer: dedicated app feature + banner placement + finance community mention
- Pricing: $450 per issue (fintech partner rate)
- Clear CTA to reply or book a call
- Sign off as "The Weekly Newsletter Team"

Tone: Confident, values-aligned, peer-to-peer. Avoid hype or get-rich language.`,
  };

  const prompts = { research: researchPrompts, write: writePrompts, social: socialPrompts, pitch: pitchPrompts };
  let prompt = (prompts[stepId] || {})[genre] || (prompts[stepId] || {}).health || "";

  if (template && stepId === "write" && template.instructions) {
    prompt += "\n\n--- TEMPLATE INSTRUCTIONS ---\n" + template.instructions;
    if (template.sample_content) {
      prompt += "\n\n--- REFERENCE SAMPLE (match this style/structure) ---\n" + template.sample_content.slice(0, 3000);
    }
  }

  return prompt;
}

// ── Helpers ───────────────────────────────────────────────────────────────────
function extractSubject(content, stepId) {
  if (stepId === "write") {
    const m = content.match(/Option 1[^:]*:\s*["""']?([^""'\n]{5,100})["""']?/i);
    if (m) return m[1].trim().replace(/^["""']|["""']$/g, "");
    const firstLine = content.split("\n").find(l => l.trim().length > 10);
    return firstLine ? firstLine.trim().substring(0, 100) : "Newsletter Draft";
  }
  const labels = { research: "Research Notes", social: "Social Content", pitch: "Sponsor Pitch" };
  return labels[stepId] || "Draft";
}

function formatDate(iso) {
  if (!iso) return "";
  const d = new Date(iso.endsWith("Z") ? iso : iso + "Z");
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

// ── Styles ────────────────────────────────────────────────────────────────────
const C = {
  card:      (hi) => ({ background:"#0e0c1a", border:`1px solid ${hi?"#8b5cf6":"#1c1830"}`, borderRadius:12, marginBottom:14, overflow:"hidden", transition:"border-color .3s" }),
  num:       { fontFamily:"monospace", fontSize:10, fontWeight:"bold", color:"#6366f1", background:"#13102a", padding:"4px 8px", borderRadius:4, flexShrink:0 },
  runBtn:    (busy) => ({ background: busy?"#1a1630":"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"8px 18px", cursor: busy?"not-allowed":"pointer", fontSize:12, fontFamily:"monospace", fontWeight:"bold", flexShrink:0, minWidth:82 }),
  copyBtn:   (ok)   => ({ background: ok?"#14532d":"#13102a", border:"1px solid #1c1830", borderRadius:6, color: ok?"#86efac":"#635e80", padding:"5px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace", margin:"10px 16px" }),
  bigCopy:   (ok)   => ({ background: ok?"#14532d":"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color: ok?"#86efac":"#fff", padding:"8px 16px", cursor:"pointer", fontSize:12, fontFamily:"monospace", fontWeight:"bold" }),
  output:    { borderTop:"1px solid #1c1830", padding:"14px 18px", fontSize:13, lineHeight:1.75, color:"#b5b0ce", whiteSpace:"pre-wrap", background:"#06050e", maxHeight:340, overflowY:"auto" },
  pre:       { padding:"14px 18px", fontSize:12, lineHeight:1.75, color:"#b5b0ce", whiteSpace:"pre-wrap", fontFamily:"monospace", background:"#06050e", maxHeight:260, overflowY:"auto" },
  err:       { margin:"0 16px 12px", padding:"10px 14px", background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, fontSize:12, color:"#fca5a5", fontFamily:"monospace" },
  hdrRow:    { padding:"13px 18px", borderBottom:"1px solid #1c1830", display:"flex", justifyContent:"space-between", alignItems:"center", flexWrap:"wrap", gap:10 },
  schedRow:  { display:"flex", gap:14, padding:"9px 0", borderBottom:"1px solid #110f1e", flexWrap:"wrap" },
  schedDay:  { fontFamily:"monospace", fontSize:11, fontWeight:"bold", color:"#6366f1", minWidth:56, paddingTop:1 },
  mCard:     { background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:16 },
  revRow:    { display:"grid", gridTemplateColumns:"1fr 1.4fr 1fr", padding:"9px 0", borderBottom:"1px solid #110f1e", fontSize:13 },
  label:     { fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:2, marginBottom:14 },
  newsBox:   { margin:"0 18px 14px", padding:"10px 14px", background:"#0a1a0a", border:"1px solid #14532d", borderRadius:8, fontSize:12, color:"#86efac" },
  newsBadge: { display:"inline-block", background:"#14532d", color:"#86efac", fontFamily:"monospace", fontSize:9, fontWeight:"bold", padding:"2px 7px", borderRadius:3, letterSpacing:1, marginBottom:7 },
};

// ── Step card ─────────────────────────────────────────────────────────────────
function Step({ id, num, icon, label, desc, genre, gLoading, setGLoading, outputs, setOutputs, template }) {
  const [err, setErr]           = useState(null);
  const [copied, setCopied]     = useState(false);
  const [newsNote, setNewsNote] = useState(null);
  const [draftSaving, setDraftSaving] = useState(false);
  const [draftSaved,  setDraftSaved]  = useState(false);
  const [draftErr,    setDraftErr]    = useState(null);
  const busy = gLoading === id;

  async function run() {
    if (gLoading) return;
    setGLoading(id); setErr(null); setNewsNote(null);
    setDraftSaved(false); setDraftErr(null);
    try {
      let headlines = [];
      if (id === "research") {
        const nr = await apiFetch(`/api/news?genre=${genre}`);
        const nd = await nr.json();
        headlines = nd.headlines || [];
        if (nd.note) setNewsNote(nd.note);
        else if (headlines.length > 0) setNewsNote(`Live news loaded: ${headlines.length} recent headlines`);
      }
      const prompt = getPrompt(id, genre, headlines, template);
      const res  = await apiFetch("/api/claude", { method:"POST", headers:{"Content-Type":"application/json"}, body: JSON.stringify({ prompt }) });
      const data = await res.json();
      if (!res.ok || data.error) throw new Error(data.error || "Server error " + res.status);
      OUTPUTS[id] = data.text;
      setOutputs(p => ({ ...p, [id]: data.text }));
    } catch(e) { setErr(e.message); }
    setGLoading(null);
  }

  function copy() {
    navigator.clipboard.writeText(outputs[id] || "").catch(()=>{});
    setCopied(true); setTimeout(()=>setCopied(false), 2000);
  }

  async function saveDraft() {
    if (draftSaving || draftSaved) return;
    setDraftSaving(true); setDraftErr(null);
    const content = outputs[id] || "";
    const subject = extractSubject(content, id);
    const social_content = id === "social" ? content : "";
    const body = { genre, subject, content, social_content };
    try {
      const res = await apiFetch("/api/drafts", { method:"POST", headers:{"Content-Type":"application/json"}, body: JSON.stringify(body) });
      if (!res.ok) { const d = await res.json(); throw new Error(d.error || "Save failed"); }
      setDraftSaved(true);
      setTimeout(() => setDraftSaved(false), 4000);
    } catch(e) { setDraftErr(e.message); }
    setDraftSaving(false);
  }

  return (
    <div style={C.card(busy)}>
      <div style={{ display:"flex", alignItems:"center", gap:12, padding:"16px 18px" }}>
        <div style={C.num}>{num}</div>
        <div style={{ fontSize:20 }}>{icon}</div>
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>{label}</div>
          <div style={{ fontSize:12, color:"#635e80", marginTop:2 }}>{desc}</div>
        </div>
        <button style={C.runBtn(busy)} onClick={run} disabled={!!gLoading}>
          {busy ? "Running…" : "▶  Run"}
        </button>
      </div>
      {newsNote && id === "research" && (
        <div style={C.newsBox}>
          <div style={C.newsBadge}>LIVE NEWS</div>
          <div>{newsNote}</div>
        </div>
      )}
      {err && <div style={C.err}>⚠ {err}</div>}
      {outputs[id] && (
        <>
          <div style={C.output}>{outputs[id]}</div>
          <div style={{ display:"flex", alignItems:"center", gap:8, padding:"8px 16px 12px", flexWrap:"wrap" }}>
            <button style={C.copyBtn(copied)} onClick={copy}>{copied?"✓ Copied!":"Copy Output"}</button>
            <button
              onClick={saveDraft}
              disabled={draftSaving || draftSaved}
              style={{ background: draftSaved?"#14532d":"#0d1117", border:`1px solid ${draftSaved?"#16a34a":"#2a2448"}`, borderRadius:6, color: draftSaved?"#86efac":"#a78bfa", padding:"5px 12px", cursor: draftSaved?"default":"pointer", fontSize:11, fontFamily:"monospace" }}
            >
              {draftSaved ? "✓ Saved to Drafts" : draftSaving ? "Saving…" : "💾 Save Draft"}
            </button>
            {draftErr && <span style={{ fontSize:11, color:"#fca5a5", fontFamily:"monospace" }}>⚠ {draftErr}</span>}
          </div>
        </>
      )}
    </div>
  );
}

// ── Status badge ──────────────────────────────────────────────────────────────
function StatusBadge({ status }) {
  const cfg = {
    pending:   { bg:"#1c1a2e", border:"#4f46e5", color:"#a78bfa", label:"● Pending" },
    approved:  { bg:"#0a1a0a", border:"#16a34a", color:"#86efac", label:"✅ Approved" },
    rejected:  { bg:"#1c0808", border:"#7f1d1d", color:"#fca5a5", label:"✗ Rejected" },
    published: { bg:"#0a1520", border:"#0891b2", color:"#67e8f9", label:"🚀 Published" },
  }[status] || { bg:"#111", border:"#333", color:"#888", label:status };
  return (
    <span style={{ background:cfg.bg, border:`1px solid ${cfg.border}`, color:cfg.color, borderRadius:4, padding:"2px 8px", fontSize:10, fontFamily:"monospace", fontWeight:"bold" }}>
      {cfg.label}
    </span>
  );
}

// ── HTML Sanitizer ───────────────────────────────────────────────────────────
const SAFE_TAGS = new Set(["p","h1","h2","h3","h4","b","strong","i","em","a","ul","ol","li","br","hr","div","span","blockquote","pre","code","sub","sup"]);
const SAFE_ATTRS = { a: new Set(["href","target","rel"]), "*": new Set([]) };
const SAFE_SCHEMES = /^(https?:|mailto:|#|\/)/i;

function sanitizeHtml(html) {
  if (!html) return "";
  const doc = new DOMParser().parseFromString(html, "text/html");
  function clean(node) {
    const children = Array.from(node.childNodes);
    for (const child of children) {
      if (child.nodeType === 3) continue;
      if (child.nodeType === 1) {
        const tag = child.tagName.toLowerCase();
        if (!SAFE_TAGS.has(tag)) {
          while (child.firstChild) node.insertBefore(child.firstChild, child);
          node.removeChild(child);
          continue;
        }
        const allowedAttrs = SAFE_ATTRS[tag] || SAFE_ATTRS["*"];
        for (const attr of Array.from(child.attributes)) {
          if (!allowedAttrs.has(attr.name)) { child.removeAttribute(attr.name); continue; }
          if (attr.name === "href" && !SAFE_SCHEMES.test(attr.value)) child.setAttribute("href", "#");
        }
        if (tag === "a") { child.setAttribute("target", "_blank"); child.setAttribute("rel", "noopener noreferrer"); }
        clean(child);
      } else {
        node.removeChild(child);
      }
    }
  }
  clean(doc.body);
  return DOMPurify.sanitize(doc.body.innerHTML);
}

// ── Rich Editor ──────────────────────────────────────────────────────────────
function RichEditor({ value, onChange }) {
  const editorRef = useRef(null);
  const [sourceMode, setSourceMode] = useState(false);
  const [sourceText, setSourceText] = useState("");
  const lastHtml = useRef(value || "");

  useEffect(() => {
    if (!sourceMode && editorRef.current && value !== undefined && value !== lastHtml.current) {
      const safe = sanitizeHtml(value || "");
      editorRef.current.innerHTML = safe;
      lastHtml.current = safe;
    }
  }, [value, sourceMode]);

  useEffect(() => {
    if (sourceMode) setSourceText(lastHtml.current);
  }, [sourceMode]);

  function handleInput() {
    if (editorRef.current) {
      const html = editorRef.current.innerHTML;
      lastHtml.current = html;
      if (onChange) onChange(html);
    }
  }

  function exec(cmd, val) {
    if (editorRef.current) editorRef.current.focus();
    document.execCommand(cmd, false, val || null);
    handleInput();
  }

  function handleLink() {
    const sel = window.getSelection();
    const existing = sel && sel.anchorNode ? (() => {
      let node = sel.anchorNode;
      while (node && node !== editorRef.current) {
        if (node.tagName === "A") return node.href;
        node = node.parentNode;
      }
      return null;
    })() : null;
    const url = prompt("Enter URL:", existing || "https://");
    if (url === null) return;
    if (url === "") { exec("unlink"); return; }
    if (!SAFE_SCHEMES.test(url)) { alert("Only http, https, and mailto links are allowed."); return; }
    exec("createLink", url);
  }

  function switchToRich() {
    const safe = sanitizeHtml(sourceText);
    setSourceMode(false);
    lastHtml.current = safe;
    if (onChange) onChange(safe);
    setTimeout(() => {
      if (editorRef.current) editorRef.current.innerHTML = safe;
    }, 0);
  }

  const tbBtn = (label, cmd, val) => React.createElement("button", {
    key: label,
    onMouseDown: e => { e.preventDefault(); exec(cmd, val); },
    style: { background:"#13102a", border:"1px solid #2a2448", borderRadius:4, color:"#b5b0ce", padding:"4px 8px", cursor:"pointer", fontSize:12, fontFamily:"monospace", lineHeight:1, minWidth:28, textAlign:"center" },
    title: label,
  }, label);

  const toolbarStyle = {
    display:"flex", gap:4, padding:"8px 12px", background:"#0a0817", borderBottom:"1px solid #1c1830",
    flexWrap:"wrap", alignItems:"center",
    overflowX:"auto", WebkitOverflowScrolling:"touch",
  };

  const editorStyle = {
    minHeight:220, padding:"14px 18px", background:"#06050e", color:"#b5b0ce",
    fontSize:13, lineHeight:1.7, fontFamily:"'Inter',system-ui,sans-serif",
    outline:"none", overflowY:"auto", maxHeight:500, wordBreak:"break-word",
  };

  const sourceStyle = {
    width:"100%", minHeight:220, padding:"14px 18px", background:"#06050e", color:"#b5b0ce",
    fontSize:12, lineHeight:1.7, fontFamily:"monospace", border:"none", outline:"none",
    resize:"vertical", boxSizing:"border-box", maxHeight:500,
  };

  return React.createElement("div", { style:{ borderBottom:"1px solid #1c1830" } },
    React.createElement("div", { style:toolbarStyle },
      tbBtn("B", "bold"),
      tbBtn("I", "italic"),
      tbBtn("H2", "formatBlock", "h2"),
      tbBtn("H3", "formatBlock", "h3"),
      tbBtn("P", "formatBlock", "p"),
      React.createElement("span", { style:{ width:1, height:20, background:"#2a2448", margin:"0 2px" } }),
      tbBtn("• List", "insertUnorderedList"),
      tbBtn("1. List", "insertOrderedList"),
      React.createElement("span", { style:{ width:1, height:20, background:"#2a2448", margin:"0 2px" } }),
      React.createElement("button", {
        onMouseDown: e => { e.preventDefault(); handleLink(); },
        style: { background:"#13102a", border:"1px solid #2a2448", borderRadius:4, color:"#67e8f9", padding:"4px 8px", cursor:"pointer", fontSize:12, fontFamily:"monospace", lineHeight:1, minWidth:28 },
        title: "Insert Link",
      }, "🔗"),
      tbBtn("—", "insertHorizontalRule"),
      React.createElement("div", { style:{ marginLeft:"auto" } },
        React.createElement("button", {
          onClick: () => sourceMode ? switchToRich() : setSourceMode(true),
          style: { background: sourceMode?"#1e1a3a":"#13102a", border:`1px solid ${sourceMode?"#8b5cf6":"#2a2448"}`, borderRadius:4, color: sourceMode?"#a78bfa":"#635e80", padding:"4px 10px", cursor:"pointer", fontSize:11, fontFamily:"monospace" },
        }, sourceMode ? "Rich Edit" : "< > Source"),
      ),
    ),
    sourceMode
      ? React.createElement("textarea", {
          value: sourceText,
          onChange: e => { setSourceText(e.target.value); lastHtml.current = e.target.value; if (onChange) onChange(e.target.value); },
          style: sourceStyle,
        })
      : React.createElement("div", {
          ref: editorRef,
          contentEditable: true,
          onInput: handleInput,
          onBlur: handleInput,
          style: editorStyle,
          suppressContentEditableWarning: true,
          dangerouslySetInnerHTML: { __html: sanitizeHtml(value || "") },
        }),
  );
}

// ── Onboarding Wizard ────────────────────────────────────────────────────────
function OnboardingWizard({ user, onComplete }) {
  const [step, setStep] = useState(0);
  const [selectedGenre, setSelectedGenre] = useState(null);
  const [generating, setGenerating] = useState(false);
  const [genResult, setGenResult] = useState(null);
  const [genError, setGenError] = useState(null);
  const [draftSaved, setDraftSaved] = useState(false);
  const genLock = useRef(false);

  const genres = [
    { id: "health", icon: "💪", name: "Health & Wellness", desc: "Nutrition, fitness, mental health tips", color: "#16a34a" },
    { id: "church", icon: "⛪", name: "Faith & Ministry", desc: "Church leadership, devotionals", color: "#8b5cf6" },
    { id: "realestate", icon: "🏠", name: "Real Estate", desc: "Investing, market analysis", color: "#0891b2" },
    { id: "gaming", icon: "🎮", name: "Family Gaming", desc: "Reviews, family game nights", color: "#d97706" },
    { id: "finance", icon: "💰", name: "Personal Finance", desc: "Budgeting, investing, debt-free", color: "#16a34a" },
  ];

  const finish = async (navigateTo) => {
    try {
      await apiFetch("/api/auth/onboarding-complete", { method: "POST" });
    } catch(e) {}
    if (selectedGenre) {
      try { localStorage.setItem("onboarding_genre", selectedGenre); } catch(e) {}
    }
    onComplete(navigateTo);
  };

  async function generateFirstNewsletter() {
    if (!selectedGenre || genLock.current) return;
    genLock.current = true;
    setGenerating(true);
    setGenError(null);
    setGenResult(null);
    setDraftSaved(false);
    try {
      const prompt = `Write a short, engaging sample newsletter intro (3-4 paragraphs) for a "${genres.find(g => g.id === selectedGenre)?.name}" newsletter. Include a catchy subject line on the first line prefixed with "Subject: ". Make it feel real and valuable. Keep it under 300 words.`;
      const res = await apiFetch("/api/claude", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ prompt, genre: selectedGenre }),
      });
      const data = await res.json();
      if (!res.ok || data.error) throw new Error(data.error || "Generation failed");
      setGenResult(data.text);
      const subMatch = data.text.match(/Subject:\s*(.+)/i);
      const subject = subMatch ? subMatch[1].trim() : "My First Newsletter";
      const saveRes = await apiFetch("/api/drafts", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ genre: selectedGenre, subject, content: data.text }),
      });
      if (saveRes.ok) {
        setDraftSaved(true);
      } else {
        setGenError("Newsletter generated but could not be saved. You can try again.");
      }
    } catch(e) {
      setGenError(e.message);
    }
    setGenerating(false);
    genLock.current = false;
  }

  const steps = [
    {
      title: "Welcome to Newsletter Engine!",
      icon: "🚀",
      content: (
        <div style={{ textAlign:"center", padding:"20px 0" }}>
          <div style={{ fontSize:64, marginBottom:20 }}>🚀</div>
          <h2 style={{ color:"#e8e3f8", fontSize:24, margin:"0 0 12px" }}>Welcome, {user.email.split("@")[0]}!</h2>
          <p style={{ color:"#a78bfa", fontSize:15, lineHeight:1.6, maxWidth:400, margin:"0 auto" }}>
            Let's get you set up to create amazing AI-powered newsletters in minutes. We'll walk you through choosing a genre, generating your first newsletter, and getting ready to publish.
          </p>
          <div style={{ display:"flex", gap:16, justifyContent:"center", marginTop:28, flexWrap:"wrap" }}>
            {[
              { icon:"🔍", label:"AI Research" },
              { icon:"✍️", label:"Auto-Write" },
              { icon:"📱", label:"Social Posts" },
              { icon:"📡", label:"Publish" },
            ].map(f => (
              <div key={f.label} style={{ background:"#13102a", border:"1px solid #1c1830", borderRadius:10, padding:"14px 18px", textAlign:"center", minWidth:80 }}>
                <div style={{ fontSize:24, marginBottom:6 }}>{f.icon}</div>
                <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>{f.label}</div>
              </div>
            ))}
          </div>
        </div>
      ),
    },
    {
      title: "Pick Your Genre",
      icon: "📰",
      content: (
        <div style={{ padding:"10px 0" }}>
          <p style={{ color:"#a78bfa", fontSize:13, marginBottom:16, textAlign:"center" }}>
            Choose a genre for your first newsletter. This is what you'll generate in the next step!
          </p>
          <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(200px, 1fr))", gap:10 }}>
            {genres.map(g => {
              const sel = selectedGenre === g.id;
              return (
                <button key={g.id} onClick={() => setSelectedGenre(g.id)} style={{
                  background: sel ? "#1e1a3a" : "#0e0c1a",
                  border: `2px solid ${sel ? "#8b5cf6" : "#1c1830"}`,
                  borderRadius:10, padding:"14px", cursor:"pointer", textAlign:"left",
                  transition: "all 0.2s",
                }}>
                  <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:6 }}>
                    <span style={{ fontSize:22 }}>{g.icon}</span>
                    <span style={{ color: sel ? "#e8e3f8" : "#a78bfa", fontSize:14, fontWeight:"bold", fontFamily:"monospace" }}>{g.name}</span>
                    {sel && <span style={{ marginLeft:"auto", color:"#8b5cf6", fontSize:18 }}>✓</span>}
                  </div>
                  <div style={{ color:"#635e80", fontSize:11, fontFamily:"monospace" }}>{g.desc}</div>
                </button>
              );
            })}
          </div>
          {!selectedGenre && (
            <p style={{ color:"#635e80", fontSize:11, fontFamily:"monospace", textAlign:"center", marginTop:12 }}>
              Select a genre to continue
            </p>
          )}
        </div>
      ),
    },
    {
      title: "Generate Your First Newsletter",
      icon: "✍️",
      content: (
        <div style={{ padding:"10px 0" }}>
          {!genResult && !generating && (
            <div style={{ textAlign:"center" }}>
              <div style={{ fontSize:48, marginBottom:16 }}>✍️</div>
              <p style={{ color:"#a78bfa", fontSize:14, lineHeight:1.6, maxWidth:380, margin:"0 auto 20px" }}>
                Ready to see the magic? Click the button below to generate a sample newsletter for <strong style={{ color:"#e8e3f8" }}>{genres.find(g => g.id === selectedGenre)?.name || "your genre"}</strong>.
              </p>
              <button onClick={generateFirstNewsletter} style={{
                background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:10,
                color:"#fff", padding:"14px 32px", cursor:"pointer", fontSize:15, fontFamily:"monospace",
                fontWeight:"bold", boxShadow:"0 4px 20px rgba(124,58,237,0.3)",
              }}>
                ▶ Generate My First Newsletter
              </button>
              {genError && (
                <div style={{ marginTop:14, padding:"10px 14px", background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, fontSize:12, color:"#fca5a5", fontFamily:"monospace" }}>
                  {genError}
                </div>
              )}
            </div>
          )}
          {generating && (
            <div style={{ textAlign:"center", padding:"20px 0" }}>
              <div style={{ fontSize:40, marginBottom:12, animation:"pulse 1.5s infinite" }}>✍️</div>
              <p style={{ color:"#a78bfa", fontSize:14, fontFamily:"monospace" }}>AI is writing your newsletter...</p>
              <p style={{ color:"#635e80", fontSize:12, fontFamily:"monospace" }}>This takes about 15-30 seconds</p>
              <div style={{ width:200, height:4, background:"#1c1830", borderRadius:2, margin:"16px auto", overflow:"hidden" }}>
                <div style={{ width:"60%", height:"100%", background:"linear-gradient(90deg,#7c3aed,#4f46e5)", borderRadius:2, animation:"loading 1.5s ease-in-out infinite" }} />
              </div>
            </div>
          )}
          {genResult && (
            <div>
              {draftSaved && (
                <div style={{ background:"#0a1a0a", border:"1px solid #16a34a", borderRadius:8, padding:"10px 14px", marginBottom:14, display:"flex", alignItems:"center", gap:8 }}>
                  <span style={{ fontSize:16 }}>✅</span>
                  <span style={{ fontSize:12, color:"#86efac", fontFamily:"monospace", fontWeight:"bold" }}>Newsletter generated and saved to your Drafts!</span>
                </div>
              )}
              <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:10, padding:"14px 18px", maxHeight:220, overflowY:"auto", fontSize:12, color:"#b5b0ce", fontFamily:"monospace", lineHeight:1.7, whiteSpace:"pre-wrap" }}>
                {genResult.slice(0, 600)}{genResult.length > 600 ? "..." : ""}
              </div>
              <p style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", marginTop:8, textAlign:"center" }}>
                You can review and edit the full draft in the Drafts tab
              </p>
            </div>
          )}
        </div>
      ),
    },
    {
      title: "You're All Set!",
      icon: "🎉",
      content: (
        <div style={{ textAlign:"center", padding:"20px 0" }}>
          <div style={{ fontSize:64, marginBottom:20 }}>🎉</div>
          <h2 style={{ color:"#e8e3f8", fontSize:22, margin:"0 0 12px" }}>
            {draftSaved ? "Your First Newsletter is Ready!" : "Ready to Build Your Newsletter!"}
          </h2>
          <p style={{ color:"#a78bfa", fontSize:14, lineHeight:1.6, maxWidth:420, margin:"0 auto 20px" }}>
            {draftSaved
              ? "Your newsletter draft is waiting in the Drafts tab. Review it, approve it, and publish it to your audience!"
              : "Head to the Weekly Engine tab to generate your first newsletter. Free accounts get 2 generations per week."
            }
          </p>
          <div style={{ display:"flex", gap:10, justifyContent:"center", flexWrap:"wrap", marginBottom:20 }}>
            {draftSaved && (
              <button onClick={() => finish("drafts")} style={{
                background:"linear-gradient(135deg,#16a34a,#0d7a35)", border:"none", borderRadius:8,
                color:"#fff", padding:"12px 22px", cursor:"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold",
              }}>
                📋 Review My Draft
              </button>
            )}
            <button onClick={() => finish(user.role === "owner" ? "settings" : "engine")} style={{
              background:"#0e0c1a", border:"1px solid #4f46e5", borderRadius:8,
              color:"#a78bfa", padding:"12px 22px", cursor:"pointer", fontSize:13, fontFamily:"monospace",
            }}>
              {user.role === "owner" ? "📡 Connect a Platform" : "⚡ Go to Engine"}
            </button>
          </div>
          <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:"16px", maxWidth:360, margin:"0 auto" }}>
            <div style={{ fontSize:12, fontFamily:"monospace", color:"#635e80", marginBottom:8 }}>Available platforms:</div>
            <div style={{ display:"flex", gap:10, justifyContent:"center", flexWrap:"wrap" }}>
              {[
                { icon:"🐝", name:"Beehiiv" },
                { icon:"📝", name:"Medium" },
                { icon:"🐦", name:"Twitter/X" },
                { icon:"💼", name:"LinkedIn" },
                { icon:"📸", name:"Instagram" },
                { icon:"🎵", name:"TikTok" },
                { icon:"📘", name:"Facebook" },
              ].map(p => (
                <div key={p.name} style={{ background:"#13102a", border:"1px solid #1c1830", borderRadius:6, padding:"6px 10px", fontSize:11, color:"#635e80", fontFamily:"monospace" }}>
                  {p.icon} {p.name}
                </div>
              ))}
            </div>
          </div>
        </div>
      ),
    },
  ];

  const isLast = step === steps.length - 1;
  const canAdvance = step !== 1 || selectedGenre;

  return (
    <div style={{ minHeight:"100vh", background:"#07060f", display:"flex", alignItems:"center", justifyContent:"center", padding:20 }}>
      <style>{`
        @keyframes loading { 0%{transform:translateX(-100%)} 50%{transform:translateX(100%)} 100%{transform:translateX(-100%)} }
        @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.5} }
      `}</style>
      <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:16, maxWidth:560, width:"100%", overflow:"hidden" }}>
        <div style={{ background:"linear-gradient(135deg,#1e1a3a,#0e0c1a)", padding:"24px 28px", borderBottom:"1px solid #1c1830" }}>
          <div style={{ display:"flex", alignItems:"center", gap:10 }}>
            <span style={{ fontSize:22 }}>{steps[step].icon}</span>
            <h3 style={{ color:"#e8e3f8", fontSize:18, margin:0, fontFamily:"monospace" }}>{steps[step].title}</h3>
          </div>
          <div style={{ display:"flex", gap:6, marginTop:14 }}>
            {steps.map((_, i) => (
              <div key={i} style={{
                flex:1, height:4, borderRadius:2,
                background: i <= step ? "linear-gradient(90deg,#7c3aed,#4f46e5)" : "#1c1830",
                transition:"background 0.3s",
              }} />
            ))}
          </div>
        </div>
        <div style={{ padding:"20px 28px" }}>
          {steps[step].content}
        </div>
        <div style={{ display:"flex", justifyContent:"space-between", padding:"16px 28px", borderTop:"1px solid #1c1830" }}>
          {step > 0 ? (
            <button onClick={() => setStep(step - 1)} style={{
              background:"transparent", border:"1px solid #1c1830", borderRadius:8, color:"#635e80",
              padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace"
            }}>← Back</button>
          ) : (
            <button onClick={() => finish()} style={{
              background:"transparent", border:"none", color:"#635e80",
              padding:"10px 20px", cursor:"pointer", fontSize:12, fontFamily:"monospace"
            }}>Skip</button>
          )}
          {step === 2 && !genResult && !generating ? (
            <button onClick={() => setStep(step + 1)} style={{
              background:"transparent", border:"1px solid #1c1830", borderRadius:8,
              color:"#635e80", padding:"10px 20px", cursor:"pointer", fontSize:12, fontFamily:"monospace",
            }}>Skip this step →</button>
          ) : step === 2 && generating ? (
            <span style={{ color:"#635e80", fontSize:11, fontFamily:"monospace", padding:"10px 20px" }}>Please wait...</span>
          ) : (
            <button onClick={isLast ? () => finish() : () => setStep(step + 1)} disabled={!canAdvance} style={{
              background: isLast ? "linear-gradient(135deg,#7c3aed,#4f46e5)" : canAdvance ? "#1e1a3a" : "#13102a",
              border: isLast ? "none" : `1px solid ${canAdvance ? "#8b5cf6" : "#2a2448"}`, borderRadius:8,
              color: canAdvance ? "#fff" : "#3a3555", padding:"10px 24px", cursor: canAdvance ? "pointer" : "default",
              fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: canAdvance ? 1 : 0.5,
            }}>{isLast ? "🚀 Start Exploring!" : "Next →"}</button>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Content Calendar ─────────────────────────────────────────────────────────
function SocialContentPanel({ socialContent, subject }) {
  const [showSocial, setShowSocial] = useState(false);
  const [copied, setCopied] = useState(null);

  const raw = socialContent || "";
  const twitterMatch = raw.match(/TWITTER\/X THREAD[\s\S]*?(?=\n\n\d+\.\s*LINKEDIN|\n\nLINKEDIN|$)/i);
  const linkedinMatch = raw.match(/LINKEDIN POST[\s\S]*?(?=\n\n\d+\.\s*(?:INSTAGRAM|TIKTOK)|$)/i);
  const instagramMatch = raw.match(/INSTAGRAM CAPTION[\s\S]*?(?=\n\n\d+\.\s*(?:TIKTOK)|$)/i);
  const tiktokMatch = raw.match(/TIKTOK (?:CAPTION|SCRIPT)[\s\S]*/i);
  const twitterText = twitterMatch ? twitterMatch[0].replace(/^\d+\.\s*TWITTER\/X THREAD[^\n]*\n*/i, "").trim() : "";
  const linkedinText = linkedinMatch ? linkedinMatch[0].replace(/^\d+\.\s*LINKEDIN POST[^\n]*\n*/i, "").trim() : "";
  const instagramText = instagramMatch ? instagramMatch[0].replace(/^\d+\.\s*INSTAGRAM CAPTION[^\n]*\n*/i, "").trim() : "";
  const tiktokText = tiktokMatch ? tiktokMatch[0].replace(/^\d+\.\s*TIKTOK (?:CAPTION|SCRIPT)[^\n]*\n*/i, "").trim() : "";

  if (!twitterText && !linkedinText && !instagramText && !tiktokText) return null;

  const copyText = (text, label) => {
    navigator.clipboard.writeText(text).then(() => {
      setCopied(label);
      setTimeout(() => setCopied(null), 2000);
    });
  };
  const shareToTwitter = () => {
    const firstTweet = twitterText.split("\n").filter(l => l.trim())[0] || subject;
    window.open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(firstTweet)}`, "_blank");
  };
  const shareToLinkedIn = () => {
    window.open(`https://www.linkedin.com/feed/?shareActive=true`, "_blank");
  };

  return (
    <div style={{ margin:"0 18px 12px" }}>
      <button onClick={() => setShowSocial(!showSocial)} style={{
        background:"#0a0a1e", border:"1px solid #2563eb", borderRadius: showSocial ? "8px 8px 0 0" : 8, color:"#60a5fa", padding:"8px 14px",
        cursor:"pointer", fontSize:12, fontFamily:"monospace", width:"100%", textAlign:"left", display:"flex", alignItems:"center", gap:8
      }}>
        <span style={{ fontSize:16 }}>📱</span>
        <span style={{ flex:1, fontWeight:"bold" }}>Social Content</span>
        <span style={{ fontSize:10, color:"#635e80" }}>
          {[twitterText && "𝕏 Thread", linkedinText && "LinkedIn", instagramText && "Instagram", tiktokText && "TikTok"].filter(Boolean).join(" + ")}
        </span>
        <span style={{ fontSize:14 }}>{showSocial ? "▾" : "▸"}</span>
      </button>
      {showSocial && (
        <div style={{ background:"#0a0a1e", border:"1px solid #2563eb", borderTop:"none", borderRadius:"0 0 8px 8px", padding:"14px" }}>
          {twitterText && (
            <div style={{ marginBottom: linkedinText || instagramText || tiktokText ? 16 : 0 }}>
              <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
                <span style={{ fontSize:14 }}>𝕏</span>
                <span style={{ fontSize:12, fontFamily:"monospace", color:"#60a5fa", fontWeight:"bold" }}>Twitter/X Thread</span>
                <button onClick={() => copyText(twitterText, "twitter")} style={{
                  background:"#13102a", border:"1px solid #4f46e5", borderRadius:4, color:"#a78bfa",
                  padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace", marginLeft:"auto"
                }}>{copied === "twitter" ? "✓ Copied!" : "📋 Copy All"}</button>
                <button onClick={shareToTwitter} style={{
                  background:"#0a1520", border:"1px solid #1d9bf0", borderRadius:4, color:"#1d9bf0",
                  padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace"
                }}>↗ Open Twitter</button>
              </div>
              <pre style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:6, padding:"10px 12px",
                color:"#c8c3de", fontSize:11, fontFamily:"monospace", whiteSpace:"pre-wrap", wordBreak:"break-word",
                maxHeight:200, overflow:"auto", margin:0, lineHeight:1.5
              }}>{twitterText}</pre>
            </div>
          )}
          {linkedinText && (
            <div style={{ marginBottom: instagramText || tiktokText ? 16 : 0 }}>
              <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
                <span style={{ fontSize:14, color:"#0a66c2" }}>in</span>
                <span style={{ fontSize:12, fontFamily:"monospace", color:"#60a5fa", fontWeight:"bold" }}>LinkedIn Post</span>
                <button onClick={() => copyText(linkedinText, "linkedin")} style={{
                  background:"#13102a", border:"1px solid #4f46e5", borderRadius:4, color:"#a78bfa",
                  padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace", marginLeft:"auto"
                }}>{copied === "linkedin" ? "✓ Copied!" : "📋 Copy"}</button>
                <button onClick={shareToLinkedIn} style={{
                  background:"#0a1520", border:"1px solid #0a66c2", borderRadius:4, color:"#0a66c2",
                  padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace"
                }}>↗ Open LinkedIn</button>
              </div>
              <pre style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:6, padding:"10px 12px",
                color:"#c8c3de", fontSize:11, fontFamily:"monospace", whiteSpace:"pre-wrap", wordBreak:"break-word",
                maxHeight:200, overflow:"auto", margin:0, lineHeight:1.5
              }}>{linkedinText}</pre>
            </div>
          )}
          {instagramText && (
            <div style={{ marginBottom: tiktokText ? 16 : 0 }}>
              <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
                <span style={{ fontSize:14 }}>📸</span>
                <span style={{ fontSize:12, fontFamily:"monospace", color:"#60a5fa", fontWeight:"bold" }}>Instagram Caption</span>
                <button onClick={() => copyText(instagramText, "instagram")} style={{
                  background:"#13102a", border:"1px solid #4f46e5", borderRadius:4, color:"#a78bfa",
                  padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace", marginLeft:"auto"
                }}>{copied === "instagram" ? "✓ Copied!" : "📋 Copy"}</button>
              </div>
              <pre style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:6, padding:"10px 12px",
                color:"#c8c3de", fontSize:11, fontFamily:"monospace", whiteSpace:"pre-wrap", wordBreak:"break-word",
                maxHeight:200, overflow:"auto", margin:0, lineHeight:1.5
              }}>{instagramText}</pre>
            </div>
          )}
          {tiktokText && (
            <div>
              <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
                <span style={{ fontSize:14 }}>🎵</span>
                <span style={{ fontSize:12, fontFamily:"monospace", color:"#60a5fa", fontWeight:"bold" }}>TikTok Caption</span>
                <button onClick={() => copyText(tiktokText, "tiktok")} style={{
                  background:"#13102a", border:"1px solid #4f46e5", borderRadius:4, color:"#a78bfa",
                  padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace", marginLeft:"auto"
                }}>{copied === "tiktok" ? "✓ Copied!" : "📋 Copy"}</button>
              </div>
              <pre style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:6, padding:"10px 12px",
                color:"#c8c3de", fontSize:11, fontFamily:"monospace", whiteSpace:"pre-wrap", wordBreak:"break-word",
                maxHeight:200, overflow:"auto", margin:0, lineHeight:1.5
              }}>{tiktokText}</pre>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function ContentCalendar({ drafts, scheduleDays, onSelectDraft }) {
  const [calMonth, setCalMonth] = useState(() => { const n = new Date(); return new Date(n.getFullYear(), n.getMonth(), 1); });
  const [popover, setPopover] = useState(null);

  const year = calMonth.getFullYear();
  const month = calMonth.getMonth();
  const firstDay = new Date(year, month, 1).getDay();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const today = new Date();
  const todayStr = `${today.getFullYear()}-${String(today.getMonth()+1).padStart(2,"0")}-${String(today.getDate()).padStart(2,"0")}`;
  const monthLabel = calMonth.toLocaleDateString("en-US", { month:"long", year:"numeric" });

  const dayNames = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
  const statusColors = {
    pending:   { bg:"#1a1500", border:"#d97706", color:"#fbbf24" },
    approved:  { bg:"#0a1520", border:"#0891b2", color:"#67e8f9" },
    published: { bg:"#0a1a0a", border:"#16a34a", color:"#86efac" },
    rejected:  { bg:"#1c0808", border:"#7f1d1d", color:"#fca5a5" },
  };

  const draftsByDate = {};
  (drafts || []).forEach(d => {
    const dateStr = (d.published_at || d.created_at || "").substring(0, 10);
    if (dateStr) {
      if (!draftsByDate[dateStr]) draftsByDate[dateStr] = [];
      draftsByDate[dateStr].push(d);
    }
  });

  const scheduleDaySet = new Set((scheduleDays || []).filter(d => typeof d === "number" && d >= 0));

  const cells = [];
  for (let i = 0; i < firstDay; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);
  while (cells.length % 7 !== 0) cells.push(null);

  const prevMonth = () => setCalMonth(new Date(year, month - 1, 1));
  const nextMonth = () => setCalMonth(new Date(year, month + 1, 1));

  return React.createElement("div", { style:{ position:"relative" } },
    React.createElement("div", { style:{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:14 } },
      React.createElement("button", { onClick:prevMonth, style:{ background:"#13102a", border:"1px solid #2a2448", borderRadius:6, color:"#b5b0ce", padding:"6px 12px", cursor:"pointer", fontSize:14, fontFamily:"monospace" } }, "‹"),
      React.createElement("span", { style:{ fontSize:16, fontWeight:"bold", color:"#e8e3f8", fontFamily:"monospace" } }, monthLabel),
      React.createElement("button", { onClick:nextMonth, style:{ background:"#13102a", border:"1px solid #2a2448", borderRadius:6, color:"#b5b0ce", padding:"6px 12px", cursor:"pointer", fontSize:14, fontFamily:"monospace" } }, "›"),
    ),
    React.createElement("div", { style:{ display:"grid", gridTemplateColumns:"repeat(7,1fr)", gap:2, marginBottom:4 } },
      ...dayNames.map(dn => React.createElement("div", { key:dn, style:{ textAlign:"center", fontSize:10, fontFamily:"monospace", color:"#635e80", padding:"4px 0", fontWeight:"bold" } }, dn)),
    ),
    React.createElement("div", { style:{ display:"grid", gridTemplateColumns:"repeat(7,1fr)", gap:2 } },
      ...cells.map((day, idx) => {
        if (day === null) return React.createElement("div", { key:"e"+idx, style:{ minHeight:70, background:"#06050e", borderRadius:4 } });
        const dateStr = `${year}-${String(month+1).padStart(2,"0")}-${String(day).padStart(2,"0")}`;
        const dayDrafts = draftsByDate[dateStr] || [];
        const dow = new Date(year, month, day).getDay();
        const isScheduled = scheduleDaySet.has(dow);
        const isToday = dateStr === todayStr;

        return React.createElement("div", {
          key:day,
          onClick: () => dayDrafts.length > 0 ? setPopover(popover === dateStr ? null : dateStr) : null,
          style:{
            minHeight:70, background: isToday ? "#1e1a3a" : "#0e0c1a",
            border: `1px solid ${isToday ? "#8b5cf6" : isScheduled ? "#4f46e544" : "#1c1830"}`,
            borderRadius:6, padding:"4px 5px", cursor: dayDrafts.length > 0 ? "pointer" : "default",
            position:"relative", overflow:"hidden",
          },
        },
          React.createElement("div", { style:{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:2 } },
            React.createElement("span", { style:{ fontSize:11, fontFamily:"monospace", color: isToday ? "#a78bfa" : "#635e80", fontWeight: isToday ? "bold" : "normal" } }, day),
            isScheduled && React.createElement("span", { style:{ fontSize:8, background:"#4f46e533", color:"#a78bfa", borderRadius:2, padding:"1px 3px", fontFamily:"monospace" } }, "⚡"),
          ),
          ...dayDrafts.slice(0, 3).map((d, di) => {
            const sc = statusColors[d.status] || statusColors.pending;
            return React.createElement("div", {
              key:di,
              style:{ fontSize:9, fontFamily:"monospace", color:sc.color, background:sc.bg, border:`1px solid ${sc.border}44`, borderRadius:3, padding:"1px 4px", marginBottom:1, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" },
            }, d.subject ? d.subject.substring(0, 20) : d.genre);
          }),
          dayDrafts.length > 3 && React.createElement("div", { style:{ fontSize:8, color:"#635e80", fontFamily:"monospace", textAlign:"center" } }, `+${dayDrafts.length - 3} more`),
        );
      }),
    ),
    React.createElement("div", { style:{ display:"flex", gap:12, justifyContent:"center", marginTop:12, flexWrap:"wrap" } },
      ...[
        { label:"Pending", color:"#fbbf24" },
        { label:"Approved", color:"#67e8f9" },
        { label:"Published", color:"#86efac" },
        { label:"Rejected", color:"#fca5a5" },
        { label:"Scheduled", color:"#a78bfa", icon:"⚡" },
      ].map(l => React.createElement("div", { key:l.label, style:{ display:"flex", alignItems:"center", gap:4, fontSize:10, color:"#635e80", fontFamily:"monospace" } },
        React.createElement("span", { style:{ width:8, height:8, borderRadius:2, background:l.color, display:"inline-block" } }),
        l.icon ? l.icon + " " + l.label : l.label,
      )),
    ),
    popover && draftsByDate[popover] && React.createElement("div", {
      style:{ position:"fixed", inset:0, zIndex:999, display:"flex", alignItems:"center", justifyContent:"center", background:"rgba(0,0,0,.5)" },
      onClick: () => setPopover(null),
    },
      React.createElement("div", {
        style:{ background:"#0e0c1a", border:"1px solid #4f46e5", borderRadius:12, padding:18, maxWidth:400, width:"90%", maxHeight:"60vh", overflowY:"auto" },
        onClick: e => e.stopPropagation(),
      },
        React.createElement("div", { style:{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:12 } },
          React.createElement("span", { style:{ fontWeight:"bold", color:"#e8e3f8", fontSize:14, fontFamily:"monospace" } },
            new Date(popover + "T12:00:00").toLocaleDateString("en-US", { weekday:"long", month:"long", day:"numeric" })
          ),
          React.createElement("button", { onClick:() => setPopover(null), style:{ background:"none", border:"none", color:"#635e80", cursor:"pointer", fontSize:16 } }, "×"),
        ),
        ...draftsByDate[popover].map((d, i) => {
          const sc = statusColors[d.status] || statusColors.pending;
          return React.createElement("div", {
            key:i,
            onClick: () => { setPopover(null); if (onSelectDraft) onSelectDraft(d.id); },
            style:{ display:"flex", alignItems:"center", gap:8, padding:"8px 10px", background:sc.bg, border:`1px solid ${sc.border}44`, borderRadius:8, marginBottom:6, cursor:"pointer" },
          },
            React.createElement("div", { style:{ flex:1 } },
              React.createElement("div", { style:{ fontSize:12, color:"#e8e3f8", fontWeight:"bold" } }, d.subject || "(no subject)"),
              React.createElement("div", { style:{ fontSize:10, color:"#635e80", fontFamily:"monospace" } }, d.genre + " · " + d.status),
            ),
            React.createElement("span", { style:{ fontSize:10, color:sc.color, fontFamily:"monospace" } }, "View →"),
          );
        }),
      ),
    ),
  );
}

// ── Drafts tab ────────────────────────────────────────────────────────────────
function DraftsTab({ onTemplateSaved }) {
  const [drafts,         setDrafts]       = useState([]);
  const [stats,          setStats]        = useState({ total:0, pending:0, approved:0, rejected:0, published:0, publishedThisMonth:0 });
  const [filter,         setFilter]       = useState("all");
  const [expandedId,     setExpanded]     = useState(null);
  const [editMap,        setEditMap]      = useState({});
  const [socialMap,      setSocialMap]    = useState({});
  const [busy,           setBusy]         = useState({});
  const [loading,        setLoading]      = useState(true);
  const [apiErr,         setApiErr]       = useState(null);
  const [platforms,      setPlatforms]    = useState({});
  const [publishBusy,    setPublishBusy]  = useState({});
  const [publishErrors,  setPublishErr]   = useState({});
  const [publishResults, setPublishRes]   = useState({});
  const [publishSelect,  setPublishSel]   = useState({});
  const [beehiivInfo,    setBeehiivInfo]  = useState({ logs: [], connected: false, autoPublishEnabled: false, publishMode: "draft", lastSuccess: null, lastError: null });
  const [showActivity,   setShowActivity] = useState(false);
  const [abResults,      setAbResults]    = useState({});
  const [abLoading,      setAbLoading]    = useState({});
  const [exportLoading,  setExportLoading]= useState({});
  const [wlModal,        setWlModal]      = useState(null);
  const [wlForm,         setWlForm]       = useState({ brandName:"", brandColor:"#7c3aed", logoUrl:"", footerText:"" });
  const [wlLoading,      setWlLoading]    = useState(false);
  const [wlResult,       setWlResult]     = useState(null);
  const [tmplModal,      setTmplModal]    = useState(null);
  const [tmplName,       setTmplName]     = useState("");
  const [tmplSaving,     setTmplSaving]   = useState(false);
  const [tmplMsg,        setTmplMsg]      = useState(null);
  const [viewMode,       setViewMode]     = useState("list");
  const [scheduleDays,   setScheduleDays] = useState([]);

  useEffect(() => { loadAll(); loadScheduleDays(); }, []);

  async function loadAll() {
    setLoading(true); setApiErr(null);
    try {
      const [dRes, sRes, platRes, bhRes] = await Promise.all([
        apiFetch("/api/drafts"),
        apiFetch("/api/drafts/stats"),
        apiFetch("/api/platforms").catch(() => ({ ok: false })),
        apiFetch("/api/beehiiv/activity").catch(() => ({ ok: false })),
      ]);
      if (!dRes.ok) throw new Error(`Drafts list error: ${dRes.status}`);
      if (!sRes.ok) throw new Error(`Stats error: ${sRes.status}`);
      const dData = await dRes.json();
      const sData = await sRes.json();
      const platData = platRes.ok ? await platRes.json() : { platforms: [] };
      const bhData = bhRes.ok ? await bhRes.json() : { logs: [], connected: false, autoPublishEnabled: false, publishMode: "draft", lastSuccess: null, lastError: null };
      setDrafts(dData.drafts || []);
      setStats(sData);
      setBeehiivInfo(bhData);
      const pMap = {};
      (platData.platforms || []).forEach(p => { pMap[p.id] = p; });
      setPlatforms(pMap);
    } catch(e) { setApiErr("Failed to load drafts: " + e.message); }
    setLoading(false);
  }

  async function loadScheduleDays() {
    try {
      const res = await apiFetch("/api/scheduler/status");
      if (res.ok) {
        const data = await res.json();
        const dayNums = [];
        if (data.bulkSchedule && data.bulkSchedule.enabled && Array.isArray(data.bulkSchedule.dayNumbers)) {
          dayNums.push(...data.bulkSchedule.dayNumbers);
        }
        if (dayNums.length === 0 && data.scheduleEnabled && typeof data.scheduleDay === "number") {
          dayNums.push(data.scheduleDay);
        }
        setScheduleDays(dayNums);
      }
    } catch(e) {}
  }

  async function updateDraft(id, changes) {
    setBusy(p => ({...p, [id]: true}));
    try {
      const res = await apiFetch(`/api/drafts/${id}`, {
        method: "PATCH",
        headers: {"Content-Type":"application/json"},
        body: JSON.stringify(changes),
      });
      if (!res.ok) { const d = await res.json(); throw new Error(d.error || "Update failed"); }
      // Re-fetch list + stats from server for accurate UI state
      const [dRes, sRes] = await Promise.all([apiFetch("/api/drafts"), apiFetch("/api/drafts/stats")]);
      const dData = await dRes.json();
      const sData = await sRes.json();
      setDrafts(dData.drafts || []);
      setStats(sData);
      if (changes.content !== undefined) {
        setEditMap(p => ({...p, [id]: sanitizeHtml(changes.content)}));
      }
    } catch(e) { alert("Error: " + e.message); }
    setBusy(p => ({...p, [id]: false}));
  }

  async function deleteDraft(id) {
    if (!window.confirm("Delete this draft permanently?")) return;
    setBusy(p => ({...p, [id]: true}));
    try {
      const res = await apiFetch(`/api/drafts/${id}`, { method: "DELETE" });
      if (!res.ok) { const d = await res.json(); throw new Error(d.error || `Delete failed: ${res.status}`); }
      if (expandedId === id) setExpanded(null);
      await loadAll();
    } catch(e) { alert("Delete failed: " + e.message); }
    setBusy(p => ({...p, [id]: false}));
  }

  async function saveAsTemplate(draftId) {
    if (!tmplName.trim()) return;
    setTmplSaving(true);
    setTmplMsg(null);
    try {
      const res = await apiFetch("/api/templates", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: tmplName.trim(), draft_id: draftId }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      setTmplMsg("Template saved!");
      if (onTemplateSaved) onTemplateSaved();
      setTimeout(() => { setTmplModal(null); setTmplName(""); setTmplMsg(null); }, 1500);
    } catch (err) {
      setTmplMsg("Error: " + err.message);
    }
    setTmplSaving(false);
  }

  function togglePlatformSelect(draftId, platformId) {
    setPublishSel(p => {
      const cur = p[draftId] || [];
      const next = cur.includes(platformId) ? cur.filter(x => x !== platformId) : [...cur, platformId];
      return { ...p, [draftId]: next };
    });
  }

  async function publishDraft(id) {
    const selectedPlatforms = publishSelect[id] || Object.keys(platforms).filter(p => platforms[p].configured);
    if (selectedPlatforms.length === 0) { alert("Select at least one platform to publish to."); return; }
    setPublishBusy(p => ({...p, [id]: true}));
    setPublishErr(p => ({...p, [id]: null}));
    setPublishRes(p => ({...p, [id]: null}));
    try {
      const res = await apiFetch(`/api/drafts/${id}/publish`, {
        method: "POST",
        headers: {"Content-Type":"application/json"},
        body: JSON.stringify({ platforms: selectedPlatforms }),
      });
      const data = await res.json();
      if (res.status === 400) throw new Error(data.error || "Publish failed");
      if (data.platformResults) setPublishRes(p => ({...p, [id]: data.platformResults}));
      if (!data.success && !data.platformResults) throw new Error(data.error || "Publish failed");
      const [dRes, sRes] = await Promise.all([apiFetch("/api/drafts"), apiFetch("/api/drafts/stats")]);
      const dData = await dRes.json();
      const sData = await sRes.json();
      setDrafts(dData.drafts || []);
      setStats(sData);
    } catch(e) {
      setPublishErr(p => ({...p, [id]: e.message}));
    }
    setPublishBusy(p => ({...p, [id]: false}));
  }

  const { user } = useAuth();
  const isEliteUser = user?.tier === "elite";

  async function handleAbTest(draft, e) {
    if (e) e.stopPropagation();
    setAbLoading(p => ({...p, [draft.id]: true}));
    try {
      const res = await apiFetch("/api/elite/ab-subjects", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ subject: draft.subject, genre: draft.genre }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed");
      setAbResults(p => ({...p, [draft.id]: data }));
    } catch(err) {
      setAbResults(p => ({...p, [draft.id]: { error: err.message } }));
    }
    setAbLoading(p => ({...p, [draft.id]: false}));
  }

  async function handleExport(draftId, e) {
    if (e) e.stopPropagation();
    setExportLoading(p => ({...p, [draftId]: true}));
    try {
      const res = await apiFetch("/api/elite/pdf-export", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ draftId }),
      });
      if (!res.ok) { const d = await res.json(); throw new Error(d.error || "Failed"); }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `newsletter-${draftId}.pdf`;
      a.click();
      URL.revokeObjectURL(url);
      setExportLoading(p => ({...p, [draftId]: "done"}));
      setTimeout(() => setExportLoading(p => ({...p, [draftId]: false})), 3000);
      return;
    } catch(err) {
      alert("Export error: " + err.message);
    }
    setExportLoading(p => ({...p, [draftId]: false}));
  }

  async function handleWhiteLabel(e) {
    if (e) e.preventDefault();
    setWlLoading(true);
    try {
      const res = await apiFetch("/api/elite/white-label", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ draftId: wlModal, ...wlForm }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed");
      setWlResult(data.html);
    } catch(err) {
      alert("White-label error: " + err.message);
    }
    setWlLoading(false);
  }

  const [bhPublishMode, setBhPublishMode] = useState({});

  async function publishToBeehiiv(id, mode, e) {
    if (e) e.stopPropagation();
    setPublishBusy(p => ({...p, [id]: true}));
    setPublishErr(p => ({...p, [id]: null}));
    setPublishRes(p => ({...p, [id]: null}));
    try {
      if (mode && mode !== beehiivInfo.publishMode) {
        const modeRes = await apiFetch("/api/settings", {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ beehiiv_publish_mode: mode }),
        });
        if (!modeRes.ok) throw new Error("Failed to update publish mode");
      }
      const res = await apiFetch(`/api/drafts/${id}/publish`, {
        method: "POST",
        headers: {"Content-Type":"application/json"},
        body: JSON.stringify({ platforms: ["beehiiv"] }),
      });
      const data = await res.json();
      if (res.status === 400) throw new Error(data.error || "Publish failed");
      if (data.platformResults) setPublishRes(p => ({...p, [id]: data.platformResults}));
      if (!data.success && !data.platformResults) throw new Error(data.error || "Publish failed");
      await loadAll();
    } catch(e2) {
      setPublishErr(p => ({...p, [id]: e2.message}));
    }
    setPublishBusy(p => ({...p, [id]: false}));
  }

  function textToHtml(text) {
    if (!text) return "";
    if (/<[a-z][\s\S]*>/i.test(text)) return text;
    return text
      .split(/\n{2,}/)
      .map(block => {
        const trimmed = block.trim();
        if (!trimmed) return "";
        if (/^#{3}\s/.test(trimmed)) return "<h3>" + trimmed.replace(/^#{3}\s+/, "") + "</h3>";
        if (/^#{2}\s/.test(trimmed)) return "<h2>" + trimmed.replace(/^#{2}\s+/, "") + "</h2>";
        if (/^#{1}\s/.test(trimmed)) return "<h2>" + trimmed.replace(/^#{1}\s+/, "") + "</h2>";
        if (/^[-*]\s/.test(trimmed)) {
          const items = trimmed.split("\n").map(l => "<li>" + l.replace(/^[-*]\s+/, "") + "</li>").join("");
          return "<ul>" + items + "</ul>";
        }
        if (/^\d+[.)]\s/.test(trimmed)) {
          const items = trimmed.split("\n").map(l => "<li>" + l.replace(/^\d+[.)]\s+/, "") + "</li>").join("");
          return "<ol>" + items + "</ol>";
        }
        const lines = trimmed.split("\n").join("<br>");
        return "<p>" + lines + "</p>";
      })
      .join("\n");
  }

  async function loadFullContent(id) {
    if (editMap[id] !== undefined) return;
    try {
      const res = await apiFetch(`/api/drafts/${id}`);
      const d = await res.json();
      setEditMap(p => ({...p, [id]: textToHtml(d.content)}));
      if (d.social_content) {
        setSocialMap(p => ({...p, [id]: d.social_content}));
      }
    } catch(e) {}
  }

  function toggleExpand(id) {
    if (expandedId === id) { setExpanded(null); return; }
    setExpanded(id);
    loadFullContent(id);
  }

  const genreMap = {};
  GENRES.forEach(g => { genreMap[g.id] = g; });

  const filtered = filter === "all" ? drafts : drafts.filter(d => d.status === filter);

  const genreOrder = GENRES.map(g => g.id);
  const grouped = genreOrder.reduce((acc, gId) => {
    const items = filtered.filter(d => d.genre === gId);
    if (items.length > 0) acc.push({ genre: genreMap[gId] || { id:gId, icon:"📄", name:gId, color:"#635e80" }, items });
    return acc;
  }, []);
  const knownGenres = new Set(genreOrder);
  const customItems = filtered.filter(d => !knownGenres.has(d.genre));
  const customGrouped = {};
  customItems.forEach(d => {
    const key = d.genre;
    if (!customGrouped[key]) customGrouped[key] = [];
    customGrouped[key].push(d);
  });
  Object.entries(customGrouped).forEach(([key, items]) => {
    const displayName = key.startsWith("custom_") ? key.replace("custom_", "").replace(/_/g, " ").replace(/\b\w/g, c => c.toUpperCase()) : key;
    grouped.push({ genre: { id: key, icon: "🌐", name: displayName, color: "#8b5cf6" }, items });
  });

  const statItems = [
    { label:"Total", value:stats.total, color:"#a78bfa" },
    { label:"Pending",   value:stats.pending,   color:"#a78bfa" },
    { label:"Approved",  value:stats.approved,  color:"#86efac" },
    { label:"Rejected",  value:stats.rejected,  color:"#fca5a5" },
    { label:"Published this month", value:stats.publishedThisMonth, color:"#67e8f9" },
  ];

  const filterBtns = [
    {id:"all",     label:`All (${stats.total})`},
    {id:"pending", label:`Pending (${stats.pending})`},
    {id:"approved",label:`Approved (${stats.approved})`},
    {id:"rejected",label:`Rejected (${stats.rejected})`},
  ];

  if (loading) return <div style={{ textAlign:"center", padding:60, color:"#635e80", fontFamily:"monospace" }}>Loading drafts…</div>;
  if (apiErr)  return <div style={{ padding:20, background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, color:"#fca5a5", fontFamily:"monospace" }}>⚠ {apiErr}</div>;

  return (
    <div>
      {/* Stats bar */}
      <div className="stats-bar" style={{ display:"flex", gap:10, flexWrap:"wrap", marginBottom:20 }}>
        {statItems.map(s => (
          <div key={s.label} style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:"12px 18px", flex:"1 1 100px", minWidth:90, textAlign:"center" }}>
            <div style={{ fontSize:22, fontWeight:"bold", color:s.color, fontFamily:"monospace" }}>{s.value}</div>
            <div style={{ fontSize:10, color:"#635e80", fontFamily:"monospace", marginTop:2 }}>{s.label.toUpperCase()}</div>
          </div>
        ))}
      </div>

      {/* Beehiiv connection status — always visible */}
      <div style={{ background: beehiivInfo.connected ? "#0a1a0a" : "#0e0c1a", border: "1px solid " + (beehiivInfo.connected ? "#16a34a44" : "#7f1d1d44"), borderRadius:10, padding:"10px 16px", marginBottom:14 }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, flexWrap:"wrap" }}>
          <span style={{ display:"inline-block", width:8, height:8, borderRadius:"50%", background: beehiivInfo.connected ? "#16a34a" : "#ef4444", boxShadow: "0 0 6px " + (beehiivInfo.connected ? "#16a34a88" : "#ef444488") }} />
          <span style={{ fontSize:12, color: beehiivInfo.connected ? "#86efac" : "#fca5a5", fontFamily:"monospace", fontWeight:"bold" }}>
            🐝 Beehiiv {beehiivInfo.connected ? "connected" : "not connected"}
          </span>
          {beehiivInfo.connected && (
            <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>
              {beehiivInfo.autoPublishEnabled ? "Auto-publish ON" : "Manual publish"} · {beehiivInfo.publishMode === "live" ? "Live mode" : "Draft mode"}
            </span>
          )}
          {!beehiivInfo.connected && (
            <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>
              Go to Settings to connect your Beehiiv account
            </span>
          )}
          {beehiivInfo.connected && (
            <button onClick={() => setShowActivity(!showActivity)} style={{ marginLeft:"auto", background:"transparent", border:"1px solid #16a34a44", borderRadius:5, color:"#86efac", padding:"3px 10px", cursor:"pointer", fontSize:10, fontFamily:"monospace" }}>
              {showActivity ? "Hide Activity" : "View Activity"}
            </button>
          )}
        </div>
        {/* Last success / last error summary */}
        {beehiivInfo.connected && (beehiivInfo.lastSuccess || beehiivInfo.lastError) && (
          <div style={{ display:"flex", gap:16, marginTop:8, flexWrap:"wrap" }}>
            {beehiivInfo.lastSuccess && (
              <div style={{ fontSize:10, color:"#86efac", fontFamily:"monospace" }}>
                Last publish: "{beehiivInfo.lastSuccess.subject || "untitled"}" — {beehiivInfo.lastSuccess.published_at ? new Date(beehiivInfo.lastSuccess.published_at).toLocaleDateString("en-US", { month:"short", day:"numeric", hour:"numeric", minute:"2-digit" }) : "—"}
                {beehiivInfo.lastSuccess.platform_url && (<>{" "}<a href={beehiivInfo.lastSuccess.platform_url} target="_blank" rel="noreferrer" style={{ color:"#67e8f9", textDecoration:"none" }}>View →</a></>)}
              </div>
            )}
            {beehiivInfo.lastError && (
              <div style={{ fontSize:10, color:"#fca5a5", fontFamily:"monospace" }}>
                Last error: "{beehiivInfo.lastError.subject || "untitled"}" — {beehiivInfo.lastError.error || "unknown error"} ({beehiivInfo.lastError.published_at ? new Date(beehiivInfo.lastError.published_at).toLocaleDateString("en-US", { month:"short", day:"numeric", hour:"numeric", minute:"2-digit" }) : "—"})
              </div>
            )}
          </div>
        )}
      </div>

      {/* Beehiiv activity log */}
      {showActivity && beehiivInfo.logs.length > 0 && (
        <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:"14px 16px", marginBottom:14 }}>
          <div style={{ fontWeight:"bold", fontSize:12, color:"#e8e3f8", marginBottom:10, fontFamily:"monospace" }}>Recent Beehiiv Publishes</div>
          {beehiivInfo.logs.map((log, i) => (
            <div key={i} style={{ display:"flex", alignItems:"center", gap:8, padding:"6px 0", borderTop: i > 0 ? "1px solid #1c1830" : "none", flexWrap:"wrap" }}>
              <span style={{ fontSize:11, color: log.status === "published" ? "#86efac" : "#fca5a5", fontFamily:"monospace", fontWeight:"bold" }}>
                {log.status === "published" ? "✅" : "⚠"} {log.status}
              </span>
              <span style={{ fontSize:11, color:"#b5b0ce", fontFamily:"monospace", flex:1, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>
                {log.subject || "(no subject)"}
              </span>
              {log.platform_url && (
                <a href={log.platform_url} target="_blank" rel="noreferrer" style={{ fontSize:10, color:"#67e8f9", fontFamily:"monospace", textDecoration:"none" }}>View →</a>
              )}
              {log.error && <span style={{ fontSize:10, color:"#fca5a5", fontFamily:"monospace" }}>{log.error}</span>}
              <span style={{ fontSize:10, color:"#635e80", fontFamily:"monospace" }}>
                {log.published_at ? new Date(log.published_at).toLocaleDateString("en-US", { month:"short", day:"numeric", hour:"numeric", minute:"2-digit" }) : "—"}
              </span>
            </div>
          ))}
        </div>
      )}
      {showActivity && beehiivInfo.logs.length === 0 && (
        <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:"14px 16px", marginBottom:14, textAlign:"center" }}>
          <div style={{ fontSize:12, color:"#635e80", fontFamily:"monospace" }}>No Beehiiv publishes yet. Approve a draft to get started.</div>
        </div>
      )}

      {/* View toggle + Filter tabs */}
      <div style={{ display:"flex", gap:6, flexWrap:"wrap", marginBottom:18, alignItems:"center" }}>
        <div style={{ display:"flex", gap:0, marginRight:8 }}>
          <button onClick={() => setViewMode("list")} style={{ background: viewMode==="list"?"#1e1a3a":"transparent", border:`1px solid ${viewMode==="list"?"#8b5cf6":"#1c1830"}`, borderRadius:"6px 0 0 6px", color: viewMode==="list"?"#a78bfa":"#635e80", padding:"5px 10px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>☰ List</button>
          <button onClick={() => setViewMode("calendar")} style={{ background: viewMode==="calendar"?"#1e1a3a":"transparent", border:`1px solid ${viewMode==="calendar"?"#8b5cf6":"#1c1830"}`, borderRadius:"0 6px 6px 0", color: viewMode==="calendar"?"#a78bfa":"#635e80", padding:"5px 10px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>📅 Calendar</button>
        </div>
        {viewMode === "list" && filterBtns.map(b => (
          <button key={b.id} onClick={() => setFilter(b.id)} style={{
            background: filter === b.id ? "#1e1a3a" : "transparent",
            border: `1px solid ${filter === b.id ? "#8b5cf6" : "#1c1830"}`,
            borderRadius:6, color: filter === b.id ? "#a78bfa" : "#635e80",
            padding:"5px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace",
          }}>{b.label}</button>
        ))}
        <button onClick={loadAll} style={{ background:"transparent", border:"1px solid #1c1830", borderRadius:6, color:"#635e80", padding:"5px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace", marginLeft:"auto" }}>↻ Refresh</button>
      </div>

      {/* Calendar view */}
      {viewMode === "calendar" && (
        <ContentCalendar
          drafts={drafts}
          scheduleDays={scheduleDays}
          onSelectDraft={id => { setFilter("all"); setViewMode("list"); setExpanded(id); loadFullContent(id); }}
        />
      )}

      {/* Draft list — grouped by genre */}
      {viewMode === "list" && filtered.length === 0 && (
        <div style={{ textAlign:"center", padding:"40px 20px", color:"#635e80", background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12 }}>
          <div style={{ fontSize:32, marginBottom:12 }}>📭</div>
          <div style={{ fontWeight:"bold", color:"#e8e3f8", marginBottom:6 }}>No drafts yet</div>
          <div style={{ fontSize:13 }}>Run a step in the Weekly Engine, then click "💾 Save Draft"</div>
        </div>
      )}

      {viewMode === "list" && grouped.map(({ genre:g, items }) => (
        <div key={g.id} style={{ marginBottom:24 }}>
          {/* Genre section header */}
          <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:10, paddingBottom:6, borderBottom:`2px solid ${g.color}22` }}>
            <span style={{ fontSize:18 }}>{g.icon}</span>
            <span style={{ fontWeight:"bold", fontSize:13, color:g.color, fontFamily:"monospace", letterSpacing:"0.05em" }}>{g.name.toUpperCase()}</span>
            <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>— {items.length} draft{items.length !== 1 ? "s" : ""}</span>
          </div>

          {items.map(draft => {
            const isOpen = expandedId === draft.id;
            const editContent = editMap[draft.id];
            const isBusy = !!busy[draft.id];
            const isPubBusy = !!publishBusy[draft.id];
            const pubErr = publishErrors[draft.id];
            const pubRes = publishResults[draft.id];
            const configuredPlatforms = Object.keys(platforms).filter(p => platforms[p].configured);

            return (
              <div key={draft.id} style={{ background:"#0e0c1a", border:`1px solid ${isOpen?"#4f46e5":"#1c1830"}`, borderRadius:12, marginBottom:10, overflow:"hidden", transition:"border-color .2s" }}>
                {/* Card header */}
                <div style={{ display:"flex", alignItems:"center", gap:10, padding:"14px 18px", cursor:"pointer" }} onClick={() => toggleExpand(draft.id)}>
                  <span style={{ fontSize:18 }}>{g.icon}</span>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div className="draft-header-badges" style={{ display:"flex", alignItems:"center", gap:8, flexWrap:"wrap", marginBottom:4 }}>
                      <span style={{ background:g.color, borderRadius:3, color:"#fff", fontSize:9, fontFamily:"monospace", fontWeight:"bold", padding:"1px 6px" }}>{g.name.toUpperCase()}</span>
                      <StatusBadge status={draft.status} />
                      {draft.engine_tier === "elite" ? (
                        <span style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", borderRadius:3, color:"#fff", fontSize:9, fontFamily:"monospace", fontWeight:"bold", padding:"1px 6px", letterSpacing:0.5 }}>👑 ELITE ENGINE</span>
                      ) : draft.engine_tier === "pro" ? (
                        <span style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", borderRadius:3, color:"#fff", fontSize:9, fontFamily:"monospace", fontWeight:"bold", padding:"1px 6px", letterSpacing:0.5 }}>⚡ PRO ENGINE</span>
                      ) : (
                        <span style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:3, color:"#635e80", fontSize:9, fontFamily:"monospace", fontWeight:"bold", padding:"1px 6px" }}>FREE ENGINE</span>
                      )}
                      <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>{formatDate(draft.created_at)}</span>
                      {(draft.publishStatuses || []).filter(ps => ps.status === "published").map(ps => {
                        const icons = { beehiiv:"🐝", medium:"📝", facebook:"📘", twitter:"🐦", linkedin:"💼", instagram:"📸", tiktok:"🎵" };
                        return ps.platform_url ? (
                          <a key={ps.platform} href={ps.platform_url} target="_blank" rel="noreferrer"
                             onClick={e => e.stopPropagation()}
                             style={{ fontSize:10, color:"#67e8f9", fontFamily:"monospace", textDecoration:"none", border:"1px solid #0891b2", borderRadius:3, padding:"1px 7px" }}>
                            {icons[ps.platform]||"📡"} {ps.platform} →
                          </a>
                        ) : (
                          <span key={ps.platform} onClick={e => e.stopPropagation()} style={{ fontSize:10, color:"#86efac", fontFamily:"monospace", border:"1px solid #16a34a44", borderRadius:3, padding:"1px 7px" }}>
                            {icons[ps.platform]||"📡"} {ps.platform} ✓
                          </span>
                        );
                      })}
                      {(draft.publishStatuses || []).filter(ps => ps.status === "failed").map(ps => {
                        const icons = { beehiiv:"🐝", medium:"📝", facebook:"📘", twitter:"🐦", linkedin:"💼", instagram:"📸", tiktok:"🎵" };
                        return (
                          <span key={ps.platform} onClick={e => e.stopPropagation()} title={ps.error || "Publish failed"} style={{ fontSize:10, color:"#fca5a5", fontFamily:"monospace", border:"1px solid #7f1d1d44", borderRadius:3, padding:"1px 7px" }}>
                            {icons[ps.platform]||"📡"} {ps.platform} ✕
                          </span>
                        );
                      })}
                    </div>
                    <div style={{ fontSize:13, color:"#e8e3f8", fontWeight:"bold", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{draft.subject || "(no subject)"}</div>
                  </div>
                  {/* One-click Beehiiv publish with inline mode selector */}
                  {draft.status === "approved" && beehiivInfo.connected && !(draft.publishStatuses || []).some(ps => ps.platform === "beehiiv" && ps.status === "published") && (() => {
                    const draftMode = bhPublishMode[draft.id] || beehiivInfo.publishMode || "draft";
                    return (
                      <div style={{ display:"flex", alignItems:"center", gap:0, flexShrink:0 }} onClick={e => e.stopPropagation()}>
                        <select
                          value={draftMode}
                          onChange={e => setBhPublishMode(p => ({...p, [draft.id]: e.target.value}))}
                          style={{ background:"#1c1830", border:"1px solid #d97706", borderRight:"none", borderRadius:"6px 0 0 6px", color:"#fbbf24", padding:"5px 4px", fontSize:10, fontFamily:"monospace", cursor:"pointer", appearance:"auto", outline:"none" }}
                        >
                          <option value="draft">Draft</option>
                          <option value="live">Live</option>
                        </select>
                        <button
                          onClick={(e) => publishToBeehiiv(draft.id, draftMode, e)}
                          disabled={!!publishBusy[draft.id]}
                          style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"1px solid #d97706", borderRadius:"0 6px 6px 0", color:"#fff", padding:"5px 12px", cursor: publishBusy[draft.id] ? "default" : "pointer", fontSize:11, fontFamily:"monospace", fontWeight:"bold", whiteSpace:"nowrap", opacity: publishBusy[draft.id] ? 0.6 : 1 }}
                        >
                          {publishBusy[draft.id] ? "Sending…" : "🐝 Publish"}
                        </button>
                      </div>
                    );
                  })()}
                  <span style={{ color:"#635e80", fontSize:12, flexShrink:0 }}>{isOpen ? "▲" : "▼"}</span>
                </div>

                {/* Expanded content */}
                {isOpen && (
                  <div style={{ borderTop:"1px solid #1c1830" }}>
                    {editContent !== undefined ? (
                      <RichEditor
                        value={editContent}
                        onChange={html => setEditMap(p => ({...p, [draft.id]: html}))}
                      />
                    ) : (
                      <div style={{ padding:"14px 18px", color:"#635e80", fontFamily:"monospace", fontSize:12 }}>Loading…</div>
                    )}
                    <div className="draft-actions" style={{ display:"flex", gap:8, padding:"12px 18px", flexWrap:"wrap", alignItems:"center" }}>
                      <button
                        onClick={() => updateDraft(draft.id, { content: sanitizeHtml(editContent) })}
                        disabled={isBusy || editContent === undefined}
                        style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:6, color:"#a78bfa", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                      >💾 Save Edits</button>
                      {draft.status !== "approved" && (
                        <button
                          onClick={() => updateDraft(draft.id, { status:"approved" })}
                          disabled={isBusy}
                          style={{ background:"#0a1a0a", border:"1px solid #16a34a", borderRadius:6, color:"#86efac", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                        >✅ Approve</button>
                      )}
                      {draft.status !== "rejected" && (
                        <button
                          onClick={() => updateDraft(draft.id, { status:"rejected" })}
                          disabled={isBusy}
                          style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                        >✗ Reject</button>
                      )}
                      {draft.status === "approved" && configuredPlatforms.length > 0 && (
                        <button
                          onClick={() => publishDraft(draft.id)}
                          disabled={isBusy || isPubBusy}
                          style={{ background:"#0a1520", border:"1px solid #0891b2", borderRadius:6, color:"#67e8f9", padding:"6px 14px", cursor: !isPubBusy?"pointer":"default", fontSize:12, fontFamily:"monospace" }}
                        >{isPubBusy ? "Publishing…" : "📡 Publish"}</button>
                      )}
                      {draft.status === "approved" && configuredPlatforms.length === 0 && (
                        <button
                          onClick={() => updateDraft(draft.id, { status:"published" })}
                          disabled={isBusy}
                          style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:6, color:"#635e80", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                        >🚀 Mark Published</button>
                      )}
                      {isEliteUser && (
                        <>
                          <button
                            onClick={(e) => handleAbTest(draft, e)}
                            disabled={!!abLoading[draft.id]}
                            style={{ background:"#1a1500", border:"1px solid #d97706", borderRadius:6, color:"#fbbf24", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                          >{abLoading[draft.id] ? "Generating…" : "🔀 A/B Test"}</button>
                          <button
                            onClick={(e) => handleExport(draft.id, e)}
                            disabled={!!exportLoading[draft.id] && exportLoading[draft.id] !== "done"}
                            style={{ background: exportLoading[draft.id] === "done" ? "#0a1a0a" : "#1a1500", border:`1px solid ${exportLoading[draft.id] === "done" ? "#16a34a" : "#d97706"}`, borderRadius:6, color: exportLoading[draft.id] === "done" ? "#86efac" : "#fbbf24", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                          >{exportLoading[draft.id] === "done" ? "✅ Downloaded" : exportLoading[draft.id] ? "Exporting…" : "📄 Export PDF"}</button>
                          <button
                            onClick={() => { setWlModal(draft.id); setWlResult(null); }}
                            style={{ background:"#1a1500", border:"1px solid #d97706", borderRadius:6, color:"#fbbf24", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                          >🏷 White-Label</button>
                        </>
                      )}
                      {(draft.status === "approved" || draft.status === "published") && (
                        <button
                          onClick={() => { setTmplModal(draft.id); setTmplName(""); setTmplMsg(null); }}
                          style={{ background:"#0a0817", border:"1px solid #6366f1", borderRadius:6, color:"#a5b4fc", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}
                        >📐 Save as Template</button>
                      )}
                      <button
                        onClick={() => deleteDraft(draft.id)}
                        disabled={isBusy}
                        style={{ background:"transparent", border:"1px solid #2a1010", borderRadius:6, color:"#7f1d1d", padding:"6px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace", marginLeft:"auto" }}
                      >🗑 Delete</button>
                    </div>
                    {/* Social Content Panel */}
                    {socialMap[draft.id] && (
                      <SocialContentPanel socialContent={socialMap[draft.id]} subject={draft.subject} />
                    )}
                    {/* A/B Test Results */}
                    {abResults[draft.id] && !abResults[draft.id].error && (
                      <div style={{ margin:"0 18px 12px", background:"#1a1500", border:"1px solid #d97706", borderRadius:8, padding:"12px 14px" }}>
                        <div style={{ fontSize:11, fontFamily:"monospace", color:"#fbbf24", fontWeight:"bold", marginBottom:8 }}>🔀 A/B Subject Line Variants</div>
                        <div style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", marginBottom:8 }}>Original: "{abResults[draft.id].original}"</div>
                        {(abResults[draft.id].variants || []).map((v, i) => (
                          <div key={i} style={{ background:"#0e0c1a", borderRadius:6, padding:"8px 12px", marginBottom:6, display:"flex", alignItems:"center", gap:10 }}>
                            <span style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", borderRadius:3, color:"#fff", fontSize:9, fontFamily:"monospace", fontWeight:"bold", padding:"1px 6px", flexShrink:0 }}>{v.variant || String.fromCharCode(65+i)}</span>
                            <div style={{ flex:1 }}>
                              <div style={{ fontSize:12, color:"#e8e3f8", fontFamily:"monospace" }}>{v.subject}</div>
                              <div style={{ fontSize:10, color:"#635e80", fontFamily:"monospace" }}>{v.trigger} — {v.rationale}</div>
                            </div>
                            <button onClick={() => updateDraft(draft.id, { subject: v.subject })} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:4, color:"#a78bfa", padding:"3px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace", flexShrink:0 }}>Use</button>
                          </div>
                        ))}
                      </div>
                    )}
                    {abResults[draft.id]?.error && (
                      <div style={{ margin:"0 18px 12px", background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, padding:"10px 14px", fontSize:12, fontFamily:"monospace", color:"#fca5a5" }}>
                        A/B Test Error: {abResults[draft.id].error}
                      </div>
                    )}
                    {draft.status === "approved" && configuredPlatforms.length > 1 && (
                      <div style={{ padding:"6px 18px 10px", display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
                        <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>Publish to:</span>
                        {configuredPlatforms.map(pId => {
                          const sel = publishSelect[draft.id];
                          const checked = sel ? sel.includes(pId) : true;
                          const pInfo = platforms[pId] || {};
                          const icons = { beehiiv:"🐝", medium:"📝", facebook:"📘", twitter:"🐦", linkedin:"💼", instagram:"📸", tiktok:"🎵" };
                          return (
                            <button key={pId} onClick={() => togglePlatformSelect(draft.id, pId)} style={{ background: checked?"#13102a":"transparent", border:`1px solid ${checked?"#4f46e5":"#2a2448"}`, borderRadius:4, color: checked?"#a78bfa":"#635e80", padding:"3px 10px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>
                              {checked ? "☑" : "☐"} {icons[pId]||""} {pInfo.name||pId}
                            </button>
                          );
                        })}
                      </div>
                    )}
                    {(isBusy || isPubBusy) && <div style={{ padding:"8px 18px 12px", fontSize:12, color:"#635e80", fontFamily:"monospace" }}>{isPubBusy?"Publishing to platforms…":"Saving…"}</div>}
                    {pubErr && (
                      <div style={{ margin:"0 18px 12px", background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, padding:"10px 14px", fontSize:12, fontFamily:"monospace", color:"#fca5a5" }}>
                        ⚠ Publish Error: {pubErr}
                      </div>
                    )}
                    {pubRes && (
                      <div style={{ margin:"0 18px 12px" }}>
                        {Object.entries(pubRes).map(([pId, r]) => (
                          <div key={pId} style={{ background: r.success?"#0a1a0a":"#1c0808", border:`1px solid ${r.success?"#16a34a":"#7f1d1d"}`, borderRadius:6, padding:"8px 12px", marginBottom:4, fontSize:12, fontFamily:"monospace", color: r.success?"#86efac":"#fca5a5", display:"flex", alignItems:"center", gap:8 }}>
                            <span>{r.success ? "✅" : "⚠"} {(platforms[pId]||{}).name || pId}</span>
                            {r.platformUrl && <a href={r.platformUrl} target="_blank" rel="noreferrer" style={{ color:"#67e8f9", textDecoration:"none", marginLeft:"auto" }}>View →</a>}
                            {r.error && <span style={{ marginLeft:"auto" }}>{r.error}</span>}
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      ))}

      {/* Save as Template Modal */}
      {tmplModal && (
        <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.7)", zIndex:1000, display:"flex", alignItems:"center", justifyContent:"center" }} onClick={() => setTmplModal(null)}>
          <div style={{ background:"#0e0c1a", border:"1px solid #6366f1", borderRadius:16, padding:28, maxWidth:420, width:"90%" }} onClick={e => e.stopPropagation()}>
            <div style={{ fontSize:16, fontWeight:"bold", color:"#e8e3f8", marginBottom:6 }}>📐 Save as Template</div>
            <div style={{ fontSize:12, color:"#635e80", marginBottom:16, lineHeight:1.5 }}>Save this newsletter's style and structure as a reusable template for future generations.</div>
            <div style={{ marginBottom:16 }}>
              <label style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", display:"block", marginBottom:4, textTransform:"uppercase", letterSpacing:".05em" }}>TEMPLATE NAME</label>
              <input
                value={tmplName}
                onChange={e => setTmplName(e.target.value)}
                placeholder="e.g. Weekly Roundup, Deep Dive, Quick Tips"
                autoFocus
                style={{ width:"100%", background:"#06050e", border:"1px solid #2a2448", borderRadius:6, color:"#e8e3f8", padding:"10px 12px", fontSize:13, fontFamily:"monospace", boxSizing:"border-box" }}
              />
            </div>
            <div style={{ display:"flex", gap:10, alignItems:"center" }}>
              <button
                onClick={() => saveAsTemplate(tmplModal)}
                disabled={tmplSaving || !tmplName.trim()}
                style={{ background:"linear-gradient(135deg,#6366f1,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"10px 20px", cursor: tmplSaving || !tmplName.trim() ? "not-allowed" : "pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: tmplSaving || !tmplName.trim() ? 0.6 : 1 }}
              >{tmplSaving ? "Saving..." : "Save Template"}</button>
              <button onClick={() => setTmplModal(null)} style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:8, color:"#635e80", padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace" }}>Cancel</button>
              {tmplMsg && <span style={{ fontSize:12, fontFamily:"monospace", color: tmplMsg.startsWith("Error") ? "#fca5a5" : "#86efac" }}>{tmplMsg}</span>}
            </div>
          </div>
        </div>
      )}

      {/* White-Label Modal */}
      {wlModal && (
        <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.7)", zIndex:1000, display:"flex", alignItems:"center", justifyContent:"center" }} onClick={() => setWlModal(null)}>
          <div style={{ background:"#0e0c1a", border:"1px solid #d97706", borderRadius:16, padding:28, maxWidth:500, width:"90%", maxHeight:"80vh", overflow:"auto" }} onClick={e => e.stopPropagation()}>
            <div style={{ fontSize:16, fontWeight:"bold", color:"#e8e3f8", marginBottom:16 }}>🏷 White-Label Newsletter</div>
            {!wlResult ? (
              <form onSubmit={handleWhiteLabel}>
                <div style={{ marginBottom:12 }}>
                  <label style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", display:"block", marginBottom:4 }}>BRAND NAME</label>
                  <input value={wlForm.brandName} onChange={e => setWlForm(p => ({...p, brandName: e.target.value}))} placeholder="Your Brand" style={{ width:"100%", background:"#06050e", border:"1px solid #2a2448", borderRadius:6, color:"#e8e3f8", padding:"8px 12px", fontSize:13, fontFamily:"monospace", boxSizing:"border-box" }} />
                </div>
                <div style={{ marginBottom:12 }}>
                  <label style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", display:"block", marginBottom:4 }}>BRAND COLOR</label>
                  <input type="color" value={wlForm.brandColor} onChange={e => setWlForm(p => ({...p, brandColor: e.target.value}))} style={{ width:60, height:36, border:"1px solid #2a2448", borderRadius:6, cursor:"pointer", background:"#06050e" }} />
                </div>
                <div style={{ marginBottom:12 }}>
                  <label style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", display:"block", marginBottom:4 }}>LOGO URL (optional)</label>
                  <input value={wlForm.logoUrl} onChange={e => setWlForm(p => ({...p, logoUrl: e.target.value}))} placeholder="https://..." style={{ width:"100%", background:"#06050e", border:"1px solid #2a2448", borderRadius:6, color:"#e8e3f8", padding:"8px 12px", fontSize:13, fontFamily:"monospace", boxSizing:"border-box" }} />
                </div>
                <div style={{ marginBottom:16 }}>
                  <label style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", display:"block", marginBottom:4 }}>FOOTER TEXT</label>
                  <input value={wlForm.footerText} onChange={e => setWlForm(p => ({...p, footerText: e.target.value}))} placeholder="© 2026 Your Brand" style={{ width:"100%", background:"#06050e", border:"1px solid #2a2448", borderRadius:6, color:"#e8e3f8", padding:"8px 12px", fontSize:13, fontFamily:"monospace", boxSizing:"border-box" }} />
                </div>
                <div style={{ display:"flex", gap:10 }}>
                  <button type="submit" disabled={wlLoading} style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:8, color:"#fff", padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>
                    {wlLoading ? "Generating…" : "Generate White-Label"}
                  </button>
                  <button type="button" onClick={() => setWlModal(null)} style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:8, color:"#635e80", padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace" }}>Cancel</button>
                </div>
              </form>
            ) : (
              <div>
                <div style={{ fontSize:12, color:"#86efac", fontFamily:"monospace", marginBottom:12 }}>White-label HTML generated successfully!</div>
                <div style={{ background:"#fff", borderRadius:8, padding:16, maxHeight:300, overflow:"auto", marginBottom:12 }}>
                  <div dangerouslySetInnerHTML={{ __html: wlResult }} />
                </div>
                <div style={{ display:"flex", gap:10 }}>
                  <button onClick={() => { navigator.clipboard.writeText(wlResult); }} style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:8, color:"#fff", padding:"8px 16px", cursor:"pointer", fontSize:12, fontFamily:"monospace", fontWeight:"bold" }}>Copy HTML</button>
                  <button onClick={() => { const blob = new Blob([wlResult], {type:"text/html"}); const u = URL.createObjectURL(blob); const a = document.createElement("a"); a.href=u; a.download="newsletter-whitelabel.html"; a.click(); URL.revokeObjectURL(u); }} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:8, color:"#a78bfa", padding:"8px 16px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>Download HTML</button>
                  <button onClick={() => setWlModal(null)} style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:8, color:"#635e80", padding:"8px 16px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>Close</button>
                </div>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// ── Beehiiv Setup Wizard ─────────────────────────────────────────────────────
function BeehiivWizard({ form, setForm, fld, platformStatus, setPlatformStatus, testing, testResults, testPlatform, disconnectPlatform, save, saving, saveMsg, toggleAutoPublish, inputStyle, labelStyle, sectionCard }) {
  const [wizardStep, setWizardStep] = useState(platformStatus.beehiiv.configured ? 3 : 0);
  const [wizardTesting, setWizardTesting] = useState(false);
  const [wizardTestResult, setWizardTestResult] = useState(null);
  const [bhStatus, setBhStatus] = useState({ lastSuccess: null, lastError: null });

  const isConnected = platformStatus.beehiiv.configured;

  useEffect(() => {
    if (isConnected) {
      setWizardStep(3);
      apiFetch("/api/beehiiv/activity").then(r => r.ok ? r.json() : null).then(d => {
        if (d) setBhStatus({ lastSuccess: d.lastSuccess, lastError: d.lastError });
      }).catch(() => {});
    } else {
      setWizardStep(0);
    }
  }, [isConnected]);
  const autoEnabled = (form.auto_publish_platforms||"").split(",").includes("beehiiv");

  async function wizardTestAndSave() {
    setWizardTesting(true);
    setWizardTestResult(null);
    try {
      const saved = await save();
      if (!saved) {
        setWizardTestResult({ ok: false, msg: "Failed to save settings — check the error above and try again" });
        setWizardTesting(false);
        return;
      }
      await new Promise(r => setTimeout(r, 500));
      const res = await apiFetch("/api/beehiiv/test", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          api_key: form.beehiiv_api_key || undefined,
          pub_id: form.beehiiv_publication_id || undefined,
        }),
      });
      const data = await res.json();
      if (data.success) {
        setWizardTestResult({ ok: true, msg: "Connected to \"" + (data.publication?.name || "your publication") + "\"" });
        setPlatformStatus(ps => ({ ...ps, beehiiv: { configured: true, keySet: true } }));
        setWizardStep(3);
      } else {
        setWizardTestResult({ ok: false, msg: data.error || "Connection failed" });
      }
    } catch (e) {
      setWizardTestResult({ ok: false, msg: e.message || "Connection failed" });
    }
    setWizardTesting(false);
  }

  if (isConnected && wizardStep === 3) {
    return (
      <div style={{ ...sectionCard, border: "1px solid #16a34a44" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:22 }}>🐝</span>
          <div>
            <div style={{ fontWeight:"bold", fontSize:15, color:"#e8e3f8" }}>Beehiiv</div>
            <div style={{ fontSize:11, color:"#86efac", fontFamily:"monospace" }}>Connected and ready</div>
          </div>
          <div style={{ marginLeft:"auto", display:"flex", alignItems:"center", gap:6 }}>
            <span style={{ display:"inline-block", width:8, height:8, borderRadius:"50%", background:"#16a34a", boxShadow:"0 0 6px #16a34a88" }} />
            <span style={{ fontSize:10, fontFamily:"monospace", color:"#86efac", fontWeight:"bold" }}>CONNECTED</span>
          </div>
        </div>

        <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12, marginBottom:16 }}>
          <div style={{ background:"#06050e", borderRadius:8, padding:"12px 14px" }}>
            <div style={{ fontSize:10, color:"#635e80", fontFamily:"monospace", marginBottom:4 }}>PUBLISH MODE</div>
            <div style={{ display:"flex", gap:6 }}>
              {[["draft","📝 Draft — review in Beehiiv first"],["live","🚀 Live — publish immediately"]].map(([v,l]) => (
                <button key={v} onClick={() => { setForm(f=>({...f,beehiiv_publish_mode:v})); }} style={{ background: form.beehiiv_publish_mode===v?"#13102a":"transparent", border: "1px solid " + (form.beehiiv_publish_mode===v?"#8b5cf6":"#2a2448"), borderRadius:6, color: form.beehiiv_publish_mode===v?"#a78bfa":"#635e80", padding:"6px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace", flex:1, textAlign:"center" }}>{l}</button>
              ))}
            </div>
          </div>
          <div style={{ background:"#06050e", borderRadius:8, padding:"12px 14px" }}>
            <div style={{ fontSize:10, color:"#635e80", fontFamily:"monospace", marginBottom:4 }}>AUTO-PUBLISH</div>
            <button onClick={() => toggleAutoPublish("beehiiv")} style={{ background: autoEnabled?"#0a1a0a":"#13102a", border: "1px solid " + (autoEnabled?"#16a34a":"#2a2448"), borderRadius:6, color: autoEnabled?"#86efac":"#635e80", padding:"8px 16px", cursor:"pointer", fontSize:12, fontFamily:"monospace", width:"100%" }}>
              {autoEnabled ? "ON — auto-publish when approved" : "OFF — manual publish only"}
            </button>
          </div>
        </div>

        {/* Last success / last error in Settings */}
        {(bhStatus.lastSuccess || bhStatus.lastError) && (
          <div style={{ background:"#06050e", borderRadius:8, padding:"10px 14px", marginBottom:12 }}>
            {bhStatus.lastSuccess && (
              <div style={{ fontSize:10, color:"#86efac", fontFamily:"monospace", marginBottom: bhStatus.lastError ? 4 : 0 }}>
                Last publish: "{bhStatus.lastSuccess.subject || "untitled"}" — {bhStatus.lastSuccess.published_at ? new Date(bhStatus.lastSuccess.published_at).toLocaleDateString("en-US", { month:"short", day:"numeric", hour:"numeric", minute:"2-digit" }) : "—"}
                {bhStatus.lastSuccess.platform_url && (<>{" "}<a href={bhStatus.lastSuccess.platform_url} target="_blank" rel="noreferrer" style={{ color:"#67e8f9", textDecoration:"none" }}>View →</a></>)}
              </div>
            )}
            {bhStatus.lastError && (
              <div style={{ fontSize:10, color:"#fca5a5", fontFamily:"monospace" }}>
                Last error: "{bhStatus.lastError.subject || "untitled"}" — {bhStatus.lastError.error || "unknown"} ({bhStatus.lastError.published_at ? new Date(bhStatus.lastError.published_at).toLocaleDateString("en-US", { month:"short", day:"numeric", hour:"numeric", minute:"2-digit" }) : "—"})
              </div>
            )}
          </div>
        )}

        <div style={{ display:"flex", gap:8, alignItems:"center" }}>
          <button onClick={() => testPlatform("beehiiv")} disabled={testing.beehiiv} style={{ background:"#0a1520", border:"1px solid #0891b2", borderRadius:6, color:"#67e8f9", padding:"7px 16px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>
            {testing.beehiiv ? "Testing…" : "Test Connection"}
          </button>
          <button onClick={() => disconnectPlatform("beehiiv")} disabled={saving} style={{ background:"transparent", border:"1px solid #7f1d1d44", borderRadius:6, color:"#fca5a5", padding:"7px 16px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>
            Disconnect
          </button>
          <button onClick={save} disabled={saving} style={{ background:"#13102a", border:"1px solid #8b5cf6", borderRadius:6, color:"#a78bfa", padding:"7px 16px", cursor:"pointer", fontSize:11, fontFamily:"monospace", marginLeft:"auto" }}>
            {saving ? "Saving…" : "Save Changes"}
          </button>
          {testResults.beehiiv && <span style={{ fontSize:11, fontFamily:"monospace", color: testResults.beehiiv.ok?"#86efac":"#fca5a5" }}>{testResults.beehiiv.msg}</span>}
        </div>
      </div>
    );
  }

  const steps = [
    { num: 1, title: "Get your Beehiiv API key" },
    { num: 2, title: "Enter your Publication ID" },
    { num: 3, title: "Test & connect" },
  ];

  return (
    <div style={{ ...sectionCard, border: "1px solid #4f46e544" }}>
      <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:18 }}>
        <span style={{ fontSize:22 }}>🐝</span>
        <div>
          <div style={{ fontWeight:"bold", fontSize:15, color:"#e8e3f8" }}>Connect Beehiiv</div>
          <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>3 quick steps to connect your newsletter</div>
        </div>
      </div>

      {/* Progress steps */}
      <div style={{ display:"flex", gap:0, marginBottom:20 }}>
        {steps.map((s, i) => (
          <div key={s.num} style={{ flex:1, display:"flex", alignItems:"center" }}>
            <div style={{ display:"flex", alignItems:"center", gap:6 }}>
              <div style={{ width:24, height:24, borderRadius:"50%", background: wizardStep >= i ? "linear-gradient(135deg,#7c3aed,#4f46e5)" : "#1c1830", display:"flex", alignItems:"center", justifyContent:"center", fontSize:11, color: wizardStep >= i ? "#fff" : "#635e80", fontWeight:"bold", fontFamily:"monospace" }}>
                {wizardStep > i ? "✓" : s.num}
              </div>
              <span style={{ fontSize:11, color: wizardStep >= i ? "#e8e3f8" : "#635e80", fontFamily:"monospace" }}>{s.title}</span>
            </div>
            {i < steps.length - 1 && <div style={{ flex:1, height:1, background: wizardStep > i ? "#4f46e5" : "#1c1830", margin:"0 8px" }} />}
          </div>
        ))}
      </div>

      {/* Step 1: API Key */}
      {wizardStep === 0 && (
        <div>
          <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:10, padding:"16px 18px", marginBottom:16 }}>
            <div style={{ fontSize:13, color:"#e8e3f8", fontWeight:"bold", marginBottom:10 }}>How to find your API key:</div>
            <ol style={{ margin:"0 0 0 16px", padding:0, fontSize:12, color:"#b5b0ce", lineHeight:2, fontFamily:"monospace" }}>
              <li>Log in to <span style={{ color:"#a78bfa" }}>app.beehiiv.com</span></li>
              <li>Go to <span style={{ color:"#a78bfa" }}>Settings</span> (gear icon, bottom-left)</li>
              <li>Click <span style={{ color:"#a78bfa" }}>Integrations</span> in the sidebar</li>
              <li>Find the <span style={{ color:"#a78bfa" }}>API</span> section and click <span style={{ color:"#a78bfa" }}>Create New API Key</span></li>
              <li>Give it a name (e.g. "Newsletter Engine") and copy the key</li>
            </ol>
          </div>
          <label style={labelStyle}>Paste your API key</label>
          <input type="password" value={form.beehiiv_api_key} onChange={fld("beehiiv_api_key")} placeholder="bh_xxxxxxxxxxxxxxxxxxxx" style={{ ...inputStyle, marginBottom:14 }} autoComplete="new-password" />
          <button onClick={() => setWizardStep(1)} disabled={!form.beehiiv_api_key && !platformStatus.beehiiv.keySet} style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"10px 24px", cursor: (form.beehiiv_api_key || platformStatus.beehiiv.keySet) ? "pointer" : "default", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: (form.beehiiv_api_key || platformStatus.beehiiv.keySet) ? 1 : 0.5 }}>
            Next Step →
          </button>
        </div>
      )}

      {/* Step 2: Publication ID */}
      {wizardStep === 1 && (
        <div>
          <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:10, padding:"16px 18px", marginBottom:16 }}>
            <div style={{ fontSize:13, color:"#e8e3f8", fontWeight:"bold", marginBottom:10 }}>How to find your Publication ID:</div>
            <ol style={{ margin:"0 0 0 16px", padding:0, fontSize:12, color:"#b5b0ce", lineHeight:2, fontFamily:"monospace" }}>
              <li>In Beehiiv, go to <span style={{ color:"#a78bfa" }}>Settings</span></li>
              <li>Click on your <span style={{ color:"#a78bfa" }}>publication name</span> at the top</li>
              <li>Look at the URL: <span style={{ color:"#a78bfa" }}>app.beehiiv.com/publications/<strong>pub_xxxxx</strong>/...</span></li>
              <li>Copy the part that starts with <span style={{ color:"#a78bfa" }}>pub_</span></li>
            </ol>
          </div>
          <label style={labelStyle}>Paste your Publication ID</label>
          <input type="text" value={form.beehiiv_publication_id} onChange={fld("beehiiv_publication_id")} placeholder="pub_xxxxxxxxxxxxxxxx" style={{ ...inputStyle, marginBottom:14 }} />
          <div style={{ display:"flex", gap:8 }}>
            <button onClick={() => setWizardStep(0)} style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:8, color:"#635e80", padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace" }}>
              ← Back
            </button>
            <button onClick={() => setWizardStep(2)} disabled={!form.beehiiv_publication_id} style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"10px 24px", cursor: form.beehiiv_publication_id ? "pointer" : "default", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: form.beehiiv_publication_id ? 1 : 0.5 }}>
              Next Step →
            </button>
          </div>
        </div>
      )}

      {/* Step 3: Test Connection */}
      {wizardStep === 2 && (
        <div>
          <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:10, padding:"16px 18px", marginBottom:16 }}>
            <div style={{ fontSize:13, color:"#e8e3f8", fontWeight:"bold", marginBottom:8 }}>Ready to connect!</div>
            <div style={{ fontSize:12, color:"#b5b0ce", lineHeight:1.6, fontFamily:"monospace" }}>
              We'll save your credentials and test the connection to your Beehiiv publication. This verifies that your API key and Publication ID are correct.
            </div>
          </div>
          <div style={{ marginBottom:14 }}>
            <label style={labelStyle}>Publish Mode</label>
            <div style={{ fontSize:11, color:"#635e80", marginBottom:8, fontFamily:"monospace" }}>Choose how newsletters appear in Beehiiv:</div>
            <div style={{ display:"flex", gap:8 }}>
              {[["draft","📝 Draft","Sends as a draft in Beehiiv — you review and publish from there"],["live","🚀 Live","Publishes immediately to your subscribers"]].map(([v,l,desc]) => (
                <button key={v} onClick={() => setForm(f=>({...f,beehiiv_publish_mode:v}))} style={{ background: form.beehiiv_publish_mode===v?"#13102a":"transparent", border: "1px solid " + (form.beehiiv_publish_mode===v?"#8b5cf6":"#2a2448"), borderRadius:8, color: form.beehiiv_publish_mode===v?"#a78bfa":"#635e80", padding:"10px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace", flex:1, textAlign:"left" }}>
                  <div style={{ fontWeight:"bold" }}>{l}</div>
                  <div style={{ fontSize:10, marginTop:4, opacity:0.8 }}>{desc}</div>
                </button>
              ))}
            </div>
          </div>
          {wizardTestResult && (
            <div style={{ background: wizardTestResult.ok ? "#0a1a0a" : "#1c0808", border: "1px solid " + (wizardTestResult.ok ? "#16a34a" : "#7f1d1d"), borderRadius:8, padding:"10px 14px", marginBottom:14, fontSize:12, color: wizardTestResult.ok ? "#86efac" : "#fca5a5", fontFamily:"monospace" }}>
              {wizardTestResult.ok ? "✅" : "⚠"} {wizardTestResult.msg}
            </div>
          )}
          <div style={{ display:"flex", gap:8 }}>
            <button onClick={() => setWizardStep(1)} style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:8, color:"#635e80", padding:"10px 20px", cursor:"pointer", fontSize:13, fontFamily:"monospace" }}>
              ← Back
            </button>
            <button onClick={wizardTestAndSave} disabled={wizardTesting} style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:8, color:"#fff", padding:"10px 28px", cursor: wizardTesting ? "default" : "pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: wizardTesting ? 0.7 : 1 }}>
              {wizardTesting ? "Connecting…" : "Save & Test Connection"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function CustomTopicScheduler({ sectionCard, labelStyle }) {
  const [topics, setTopics] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => { loadTopics(); }, []);

  async function loadTopics() {
    setLoading(true);
    try {
      const res = await apiFetch("/api/custom-topics");
      if (res.ok) {
        const data = await res.json();
        setTopics(data.topics || []);
      }
    } catch(e) { console.error("loadCustomTopics:", e.message); }
    setLoading(false);
  }

  async function toggleSchedule(id, currentEnabled) {
    try {
      const res = await apiFetch(`/api/custom-topics/${id}/schedule`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ schedule_enabled: !currentEnabled }),
      });
      if (res.ok) await loadTopics();
    } catch(e) { console.error("toggleSchedule:", e.message); }
  }

  async function deleteTopic(id) {
    if (!window.confirm("Remove this saved topic?")) return;
    try {
      const res = await apiFetch(`/api/custom-topics/${id}`, { method: "DELETE" });
      if (res.ok) await loadTopics();
    } catch(e) { console.error("deleteTopic:", e.message); }
  }

  const scheduledCount = topics.filter(t => t.schedule_enabled === 1).length;

  return (
    <div style={sectionCard}>
      <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:6 }}>📋 Custom Topic Scheduling</div>
      <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
        Enable auto-generation for your saved custom topics. When the scheduler runs, it will also generate newsletters for any enabled topics using live web research.
        {scheduledCount > 0 && <span style={{ color:"#86efac", fontFamily:"monospace", marginLeft:6 }}>{scheduledCount} topic{scheduledCount !== 1 ? "s" : ""} enabled</span>}
      </div>

      {loading ? (
        <div style={{ fontSize:12, color:"#635e80", fontFamily:"monospace" }}>Loading topics...</div>
      ) : topics.length === 0 ? (
        <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"16px", textAlign:"center" }}>
          <div style={{ fontSize:12, color:"#635e80", lineHeight:1.6 }}>
            No custom topics saved yet. Go to the Discover tab and generate a newsletter for any topic — it will be saved here automatically.
          </div>
        </div>
      ) : (
        <div>
          {topics.map(t => (
            <div key={t.id} style={{ display:"flex", alignItems:"center", gap:12, padding:"10px 12px", background:"#06050e", border:"1px solid #2a2448", borderRadius:8, marginBottom:8 }}>
              <span style={{ fontSize:16 }}>{t.icon || "📰"}</span>
              <div style={{ flex:1 }}>
                <div style={{ fontSize:13, color:"#e8e3f8", fontWeight:"bold" }}>{t.name}</div>
                {t.audience && <div style={{ fontSize:11, color:"#635e80" }}>{t.audience}</div>}
              </div>
              <button
                onClick={() => toggleSchedule(t.id, t.schedule_enabled === 1)}
                style={{
                  background: t.schedule_enabled === 1 ? "#0a1a0a" : "transparent",
                  border: `1px solid ${t.schedule_enabled === 1 ? "#16a34a" : "#2a2448"}`,
                  borderRadius:6,
                  color: t.schedule_enabled === 1 ? "#86efac" : "#635e80",
                  padding:"6px 14px", cursor:"pointer", fontSize:11, fontFamily:"monospace", fontWeight:"bold",
                }}
              >
                {t.schedule_enabled === 1 ? "✅ Scheduled" : "○ Enable"}
              </button>
              <button
                onClick={() => deleteTopic(t.id)}
                style={{ background:"transparent", border:"1px solid #2a1010", borderRadius:6, color:"#7f1d1d", padding:"6px 10px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}
              >
                Remove
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Settings Tab ──────────────────────────────────────────────────────────────
function SettingsTab() {
  const [form, setForm] = useState({
    owner_email: "", schedule_day: "1", schedule_hour: "7", schedule_enabled: "false",
    beehiiv_api_key: "", beehiiv_publication_id: "", beehiiv_publish_mode: "draft",
    medium_token: "", medium_publish_status: "draft",
    facebook_page_token: "", facebook_page_id: "",
    twitter_api_key: "", twitter_api_secret: "", twitter_access_token: "", twitter_access_secret: "",
    linkedin_access_token: "",
    instagram_access_token: "", instagram_account_id: "",
    tiktok_access_token: "",
    auto_publish_platforms: "",
  });
  const formRef = useRef(form);
  formRef.current = form;

  const [smtp, setSmtp] = useState(false);
  const [platformStatus, setPlatformStatus] = useState({
    beehiiv: { configured: false, keySet: false },
    medium: { configured: false, tokenSet: false },
    facebook: { configured: false, tokenSet: false },
    twitter: { configured: false, keySet: false },
    linkedin: { configured: false, tokenSet: false },
    instagram: { configured: false, tokenSet: false },
    tiktok: { configured: false, tokenSet: false },
  });
  const [testing, setTesting] = useState({});
  const [testResults, setTestResults] = useState({});
  const [saving, setSaving]     = useState(false);
  const [saveMsg, setSaveMsg]   = useState(null);
  const [scheduler, setScheduler] = useState({ isRunning:false, lastRun:null, nextRun:null, currentTask:null, lastCount:0 });
  const [runStatus, setRunStatus] = useState(null);
  const [tick, setTick] = useState(0);

  function fld(key) { return function(e) { setForm(f => ({...f, [key]: e.target.value})); }; }

  function loadScheduler() {
    return apiFetch("/api/scheduler/status").then(r=>r.json()).then(d => setScheduler(d)).catch(()=>{});
  }

  useEffect(() => {
    Promise.all([
      apiFetch("/api/settings").then(r=>r.json()),
      apiFetch("/api/scheduler/status").then(r=>r.json()),
    ]).then(([s, sch]) => {
      setForm(f => ({
        ...f,
        owner_email: s.owner_email||"",
        schedule_day: s.schedule_day||"1",
        schedule_hour: s.schedule_hour||"7",
        schedule_enabled: s.schedule_enabled||"false",
        beehiiv_api_key: "",
        beehiiv_publication_id: s.beehiiv_publication_id||"",
        beehiiv_publish_mode: s.beehiiv_publish_mode||"draft",
        medium_token: "",
        medium_publish_status: s.medium_publish_status||"draft",
        facebook_page_token: "",
        facebook_page_id: s.facebook_page_id||"",
        twitter_api_key: "", twitter_api_secret: "", twitter_access_token: "", twitter_access_secret: "",
        linkedin_access_token: "",
        instagram_access_token: "", instagram_account_id: s.instagram_account_id||"",
        tiktok_access_token: "",
        auto_publish_platforms: s.auto_publish_platforms||"",
      }));
      setSmtp(!!s.smtp_configured);
      setPlatformStatus({
        beehiiv: { configured: !!s.beehiiv_configured, keySet: !!s.beehiiv_api_key_set },
        medium: { configured: !!s.medium_configured, tokenSet: !!s.medium_token_set },
        facebook: { configured: !!s.facebook_configured, tokenSet: !!s.facebook_token_set },
        twitter: { configured: !!s.twitter_configured, keySet: !!s.twitter_key_set },
        linkedin: { configured: !!s.linkedin_configured, tokenSet: !!s.linkedin_token_set },
        instagram: { configured: !!s.instagram_configured, tokenSet: !!s.instagram_token_set },
        tiktok: { configured: !!s.tiktok_configured, tokenSet: !!s.tiktok_token_set },
      });
      setScheduler(sch);
    }).catch(()=>{});

    const tickIv = setInterval(() => setTick(t => t + 1), 60000);
    return () => clearInterval(tickIv);
  }, []);

  // Poll scheduler status when running
  useEffect(() => {
    if (!scheduler.isRunning) return;
    const iv = setInterval(() => {
      apiFetch("/api/scheduler/status").then(r=>r.json()).then(d => {
        setScheduler(d);
        if (!d.isRunning) {
          clearInterval(iv);
          setRunStatus(d.lastCount > 0 ? `✅ Done! ${d.lastCount} draft${d.lastCount!==1?"s":""} generated and saved to Drafts.` : "⚠ Run completed but no drafts were saved — check server logs.");
        }
      }).catch(()=>{});
    }, 3000);
    return () => clearInterval(iv);
  }, [scheduler.isRunning]);

  async function save() {
    setSaving(true); setSaveMsg(null);
    const latestForm = formRef.current;
    let success = false;
    try {
      const payload = { ...latestForm };
      if (latestForm.auto_publish_platforms) {
        payload.auto_publish_platforms = latestForm.auto_publish_platforms.split(",").filter(Boolean);
      }
      const res  = await apiFetch("/api/settings", { method:"PUT", headers:{"Content-Type":"application/json"}, body: JSON.stringify(payload) });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Save failed");
      setScheduler(data.schedulerState || scheduler);
      if (data.settings) {
        setPlatformStatus({
          beehiiv: { configured: !!data.settings.beehiiv_configured, keySet: !!data.settings.beehiiv_api_key_set },
          medium: { configured: !!data.settings.medium_configured, tokenSet: !!data.settings.medium_token_set },
          facebook: { configured: !!data.settings.facebook_configured, tokenSet: !!data.settings.facebook_token_set },
          twitter: { configured: !!data.settings.twitter_configured, keySet: !!data.settings.twitter_key_set },
          linkedin: { configured: !!data.settings.linkedin_configured, tokenSet: !!data.settings.linkedin_token_set },
          instagram: { configured: !!data.settings.instagram_configured, tokenSet: !!data.settings.instagram_token_set },
          tiktok: { configured: !!data.settings.tiktok_configured, tokenSet: !!data.settings.tiktok_token_set },
        });
      }
      setForm(f => ({...f, beehiiv_api_key: "", medium_token: "", facebook_page_token: "", twitter_api_key: "", twitter_api_secret: "", twitter_access_token: "", twitter_access_secret: "", linkedin_access_token: "", instagram_access_token: "", tiktok_access_token: ""}));
      setSaveMsg("✅ Settings saved!");
      success = true;
    } catch(e) { setSaveMsg("⚠ " + e.message); }
    setSaving(false);
    setTimeout(() => setSaveMsg(null), 4000);
    return success;
  }

  async function testPlatform(platformId) {
    setTesting(t => ({...t, [platformId]: true}));
    setTestResults(r => ({...r, [platformId]: null}));
    try {
      const res = await apiFetch("/api/platforms/" + platformId + "/test", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Connection failed");
      setTestResults(r => ({...r, [platformId]: { ok: data.success, msg: data.success ? "✅ Connected!" : ("⚠ " + (data.error || "Failed")) }}));
    } catch(e) {
      setTestResults(r => ({...r, [platformId]: { ok: false, msg: "⚠ " + e.message }}));
    }
    setTesting(t => ({...t, [platformId]: false}));
  }

  function toggleAutoPublish(platformId) {
    setForm(f => {
      const current = (f.auto_publish_platforms||"").split(",").filter(Boolean);
      const next = current.includes(platformId) ? current.filter(p => p !== platformId) : [...current, platformId];
      return { ...f, auto_publish_platforms: next.join(",") };
    });
  }

  async function disconnectPlatform(platformId) {
    if (!window.confirm(`Disconnect ${platformId}? This will clear all saved credentials for this platform.`)) return;
    setSaving(true); setSaveMsg(null);
    try {
      const clearKey = "clear_" + platformId;
      const res = await apiFetch("/api/settings", { method:"PUT", headers:{"Content-Type":"application/json"}, body: JSON.stringify({ [clearKey]: true }) });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Disconnect failed");
      if (data.settings) {
        setPlatformStatus({
          beehiiv: { configured: !!data.settings.beehiiv_configured, keySet: !!data.settings.beehiiv_api_key_set },
          medium: { configured: !!data.settings.medium_configured, tokenSet: !!data.settings.medium_token_set },
          facebook: { configured: !!data.settings.facebook_configured, tokenSet: !!data.settings.facebook_token_set },
          twitter: { configured: !!data.settings.twitter_configured, keySet: !!data.settings.twitter_key_set },
          linkedin: { configured: !!data.settings.linkedin_configured, tokenSet: !!data.settings.linkedin_token_set },
          instagram: { configured: !!data.settings.instagram_configured, tokenSet: !!data.settings.instagram_token_set },
          tiktok: { configured: !!data.settings.tiktok_configured, tokenSet: !!data.settings.tiktok_token_set },
        });
      }
      if (platformId === "beehiiv") setForm(f => ({...f, beehiiv_api_key:"", beehiiv_publication_id:""}));
      if (platformId === "medium") setForm(f => ({...f, medium_token:""}));
      if (platformId === "facebook") setForm(f => ({...f, facebook_page_token:"", facebook_page_id:""}));
      if (platformId === "twitter") setForm(f => ({...f, twitter_api_key:"", twitter_api_secret:"", twitter_access_token:"", twitter_access_secret:""}));
      if (platformId === "linkedin") setForm(f => ({...f, linkedin_access_token:""}));
      if (platformId === "instagram") setForm(f => ({...f, instagram_access_token:"", instagram_account_id:""}));
      if (platformId === "tiktok") setForm(f => ({...f, tiktok_access_token:""}));
      setSaveMsg("✅ " + platformId + " disconnected");
    } catch(e) { setSaveMsg("⚠ " + e.message); }
    setSaving(false);
    setTimeout(() => setSaveMsg(null), 4000);
  }

  async function runNow() {
    if (scheduler.isRunning) return;
    setRunStatus("🚀 Generation started — running Research + Write + Social for all 5 genres. This takes 3-7 minutes. Stay on this page to track progress.");
    try {
      const res  = await apiFetch("/api/scheduler/run-now", { method:"POST" });
      const data = await res.json();
      if (res.status === 409) { setRunStatus("⚠ " + data.error); return; }
      if (!res.ok) { setRunStatus("⚠ " + (data.error || "Failed to start")); return; }
      await loadScheduler();
    } catch(e) { setRunStatus("⚠ " + e.message); }
  }

  function formatTime(iso) {
    if (!iso) return "—";
    try { return new Date(iso).toLocaleString(); } catch { return iso; }
  }

  function formatCountdown(iso, _tick) {
    if (!iso) return "—";
    try {
      const diff = new Date(iso) - new Date();
      if (diff <= 0) return "any moment";
      const h = Math.floor(diff / 3600000);
      const m = Math.floor((diff % 3600000) / 60000);
      if (h > 48) return Math.ceil(h/24) + " days";
      if (h > 0) return h + "h " + m + "m";
      return m + "m";
    } catch { return "—"; }
  }

  const DAYS = [["0","Sunday"],["1","Monday"],["2","Tuesday"],["3","Wednesday"],["4","Thursday"],["5","Friday"],["6","Saturday"]];
  const HOURS = Array.from({length:24},(_,i) => {
    const label = i === 0 ? "12:00 AM" : i < 12 ? i + ":00 AM" : i === 12 ? "12:00 PM" : (i-12) + ":00 PM";
    return [String(i), label];
  });

  const inputStyle = { background:"#06050e", border:"1px solid #2a2448", borderRadius:6, color:"#e8e3f8", padding:"8px 12px", fontSize:13, fontFamily:"monospace", width:"100%", boxSizing:"border-box" };
  const labelStyle = { display:"block", fontSize:11, color:"#635e80", fontFamily:"monospace", marginBottom:5, textTransform:"uppercase", letterSpacing:".05em" };
  const sectionCard = { background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"20px 22px", marginBottom:14 };

  return (
    <div>
      {/* Status bar */}
      <div style={{ display:"flex", gap:10, flexWrap:"wrap", marginBottom:18 }}>
        {[
          { label:"Last Run", value:formatTime(scheduler.lastRun), color:"#a78bfa" },
          { label:"Next Run", value:scheduler.nextRun ? formatCountdown(scheduler.nextRun, tick) : (form.schedule_enabled==="true"?"Calculating…":"Scheduler off"), color: form.schedule_enabled==="true"?"#86efac":"#635e80" },
          { label:"Status", value: scheduler.isRunning ? "🔄 Running" : "● Idle", color: scheduler.isRunning?"#67e8f9":"#635e80" },
        ].map(s => (
          <div key={s.label} style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:"12px 18px", flex:"1 1 120px", minWidth:110, textAlign:"center" }}>
            <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", marginBottom:4 }}>{s.label}</div>
            <div style={{ fontSize:14, color:s.color, fontWeight:"bold", fontFamily:"monospace" }}>{s.value}</div>
          </div>
        ))}
      </div>

      {/* Running progress */}
      {scheduler.isRunning && (
        <div style={{ background:"#0a1520", border:"1px solid #0891b2", borderRadius:10, padding:"14px 18px", marginBottom:14 }}>
          <div style={{ fontSize:12, color:"#67e8f9", fontFamily:"monospace", marginBottom:6 }}>
            🔄 GENERATING — DO NOT REFRESH
          </div>
          <div style={{ fontSize:13, color:"#e8e3f8" }}>{scheduler.currentTask || "Working…"}</div>
          <div style={{ marginTop:8, height:4, background:"#1c1830", borderRadius:2, overflow:"hidden" }}>
            <div style={{ height:"100%", background:"linear-gradient(90deg,#4f46e5,#8b5cf6)", animation:"pulse 1.5s ease-in-out infinite", width:"60%" }} />
          </div>
        </div>
      )}

      {/* Run status message */}
      {runStatus && !scheduler.isRunning && (
        <div style={{ background: runStatus.startsWith("✅")?"#0a1a0a":"#1c0808", border:`1px solid ${runStatus.startsWith("✅")?"#16a34a":"#7f1d1d"}`, borderRadius:10, padding:"12px 18px", marginBottom:14, fontSize:13, color: runStatus.startsWith("✅")?"#86efac":"#fca5a5", fontFamily:"monospace" }}>
          {runStatus}
        </div>
      )}

      {/* Schedule & Email settings */}
      <div style={sectionCard}>
        <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:16 }}>⚙️ Schedule & Notifications</div>
        <div className="settings-grid-3" style={{ display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:14, marginBottom:14 }}>
          <div>
            <label style={labelStyle}>Notification Email</label>
            <input type="email" value={form.owner_email} onChange={fld("owner_email")} placeholder="you@email.com" style={{ ...inputStyle, gridColumn:"1 / span 3" }} />
          </div>
          <div>
            <label style={labelStyle}>Run Day</label>
            <select value={form.schedule_day} onChange={fld("schedule_day")} style={inputStyle}>
              {DAYS.map(([v,l]) => <option key={v} value={v}>{l}</option>)}
            </select>
          </div>
          <div>
            <label style={labelStyle}>Run Time</label>
            <select value={form.schedule_hour} onChange={fld("schedule_hour")} style={inputStyle}>
              {HOURS.map(([v,l]) => <option key={v} value={v}>{l}</option>)}
            </select>
          </div>
        </div>
        <div style={{ marginBottom:16 }}>
          <label style={labelStyle}>Auto-Schedule</label>
          <div style={{ display:"flex", gap:8 }}>
            {[["true","✅ Enabled"],["false","○ Disabled"]].map(([v,l]) => (
              <button key={v} onClick={() => setForm(f=>({...f, schedule_enabled:v}))} style={{ background: form.schedule_enabled===v?"#13102a":"transparent", border:`1px solid ${form.schedule_enabled===v?"#8b5cf6":"#2a2448"}`, borderRadius:6, color: form.schedule_enabled===v?"#a78bfa":"#635e80", padding:"7px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>{l}</button>
            ))}
          </div>
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={save} disabled={saving} style={{ background:"#13102a", border:"1px solid #8b5cf6", borderRadius:6, color:"#a78bfa", padding:"8px 20px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
            {saving ? "Saving…" : "💾 Save Settings"}
          </button>
          {saveMsg && <span style={{ fontSize:12, fontFamily:"monospace", color: saveMsg.startsWith("✅")?"#86efac":"#fca5a5" }}>{saveMsg}</span>}
        </div>
      </div>

      {/* Manual run */}
      <div style={sectionCard}>
        <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:8 }}>🚀 Run All Genres Now</div>
        <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
          Immediately generate newsletters for all 5 starter genres plus any scheduled custom topics — Research + Write + Social. Each new draft is saved as "Pending" in the Drafts tab.
        </div>
        <button
          onClick={runNow}
          disabled={scheduler.isRunning}
          style={{ background: scheduler.isRunning?"#0e0c1a":"#0a1520", border:`1px solid ${scheduler.isRunning?"#2a2448":"#0891b2"}`, borderRadius:6, color: scheduler.isRunning?"#635e80":"#67e8f9", padding:"10px 22px", cursor: scheduler.isRunning?"default":"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}
        >
          {scheduler.isRunning ? "⏳ Running… check progress above" : "▶ Run All Genres + Custom Topics Now"}
        </button>
      </div>

      <CustomTopicScheduler sectionCard={sectionCard} labelStyle={labelStyle} />

      {/* SMTP status */}
      <div style={sectionCard}>
        <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:10 }}>📧 Email Status</div>
        <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:12 }}>
          <span style={{ fontSize:14 }}>{smtp ? "✅" : "⚠"}</span>
          <span style={{ fontSize:13, color: smtp?"#86efac":"#fca5a5", fontFamily:"monospace" }}>
            {smtp ? "SMTP configured — email notifications active" : "SMTP not configured — emails will be skipped"}
          </span>
        </div>
        {!smtp && (
          <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Set these environment variables to enable email notifications:<br/>
            <span style={{ color:"#a78bfa" }}>SMTP_HOST</span> — e.g. smtp.gmail.com<br/>
            <span style={{ color:"#a78bfa" }}>SMTP_PORT</span> — e.g. 587<br/>
            <span style={{ color:"#a78bfa" }}>SMTP_USER</span> — your Gmail address<br/>
            <span style={{ color:"#a78bfa" }}>SMTP_PASS</span> — Gmail App Password (not your regular password)<br/>
          </div>
        )}
      </div>

      {/* Publishing Platforms */}
      <div style={{ fontWeight:"bold", fontSize:16, color:"#e8e3f8", marginBottom:12, marginTop:6 }}>📡 Publishing Platforms</div>

      {/* Beehiiv Setup Wizard */}
      <BeehiivWizard
        form={form} setForm={setForm} fld={fld}
        platformStatus={platformStatus} setPlatformStatus={setPlatformStatus}
        testing={testing} testResults={testResults}
        testPlatform={testPlatform} disconnectPlatform={disconnectPlatform}
        save={save} saving={saving} saveMsg={saveMsg}
        toggleAutoPublish={toggleAutoPublish}
        inputStyle={inputStyle} labelStyle={labelStyle} sectionCard={sectionCard}
      />

      {/* Medium */}
      <div style={{ ...sectionCard, border: platformStatus.medium.configured ? "1px solid #4f46e544" : "1px solid #1c1830" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:18 }}>📝</span>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>Medium</div>
          <span style={{ marginLeft:"auto", background: platformStatus.medium.configured?"#0a1a0a":"#1c0808", border:`1px solid ${platformStatus.medium.configured?"#16a34a":"#7f1d1d"}`, borderRadius:4, color: platformStatus.medium.configured?"#86efac":"#fca5a5", fontSize:10, fontFamily:"monospace", fontWeight:"bold", padding:"2px 8px" }}>
            {platformStatus.medium.configured ? "CONNECTED" : "NOT CONFIGURED"}
          </span>
        </div>
        <div className="settings-grid-2" style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:14, marginBottom:14 }}>
          <div>
            <label style={labelStyle}>Integration Token{platformStatus.medium.tokenSet ? " (saved — leave blank to keep)" : ""}</label>
            <input type="password" value={form.medium_token} onChange={fld("medium_token")} placeholder={platformStatus.medium.tokenSet ? "••••••••• (saved)" : "Paste your Medium token"} style={inputStyle} autoComplete="new-password" />
          </div>
          <div>
            <label style={labelStyle}>Publish Status</label>
            <select value={form.medium_publish_status} onChange={fld("medium_publish_status")} style={inputStyle}>
              <option value="draft">Draft</option>
              <option value="public">Public</option>
              <option value="unlisted">Unlisted</option>
            </select>
          </div>
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={() => testPlatform("medium")} disabled={testing.medium || !platformStatus.medium.configured} style={{ background:"#0a1520", border:`1px solid ${platformStatus.medium.configured?"#0891b2":"#2a2448"}`, borderRadius:6, color: platformStatus.medium.configured?"#67e8f9":"#635e80", padding:"8px 18px", cursor: platformStatus.medium.configured?"pointer":"default", fontSize:12, fontFamily:"monospace" }}>
            {testing.medium ? "Testing…" : "🔌 Test"}
          </button>
          {platformStatus.medium.configured && (
            <button onClick={() => disconnectPlatform("medium")} disabled={saving} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"8px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
              ✕ Disconnect
            </button>
          )}
          {testResults.medium && <span style={{ fontSize:12, fontFamily:"monospace", color: testResults.medium.ok?"#86efac":"#fca5a5" }}>{testResults.medium.msg}</span>}
        </div>
        {!platformStatus.medium.configured && (
          <div style={{ marginTop:12, background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Get your token: Medium → Settings → Security and apps → Integration tokens
          </div>
        )}
      </div>

      {/* Facebook */}
      <div style={{ ...sectionCard, border: platformStatus.facebook.configured ? "1px solid #4f46e544" : "1px solid #1c1830" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:18 }}>📘</span>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>Facebook Page</div>
          <span style={{ marginLeft:"auto", background: platformStatus.facebook.configured?"#0a1a0a":"#1c0808", border:`1px solid ${platformStatus.facebook.configured?"#16a34a":"#7f1d1d"}`, borderRadius:4, color: platformStatus.facebook.configured?"#86efac":"#fca5a5", fontSize:10, fontFamily:"monospace", fontWeight:"bold", padding:"2px 8px" }}>
            {platformStatus.facebook.configured ? "CONNECTED" : "NOT CONFIGURED"}
          </span>
        </div>
        <div className="settings-grid-2" style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:14, marginBottom:14 }}>
          <div>
            <label style={labelStyle}>Page Access Token{platformStatus.facebook.tokenSet ? " (saved — leave blank to keep)" : ""}</label>
            <input type="password" value={form.facebook_page_token} onChange={fld("facebook_page_token")} placeholder={platformStatus.facebook.tokenSet ? "••••••••• (saved)" : "Paste your page token"} style={inputStyle} autoComplete="new-password" />
          </div>
          <div>
            <label style={labelStyle}>Page ID</label>
            <input type="text" value={form.facebook_page_id} onChange={fld("facebook_page_id")} placeholder="Your Facebook Page ID" style={inputStyle} />
          </div>
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={() => testPlatform("facebook")} disabled={testing.facebook || !platformStatus.facebook.configured} style={{ background:"#0a1520", border:`1px solid ${platformStatus.facebook.configured?"#0891b2":"#2a2448"}`, borderRadius:6, color: platformStatus.facebook.configured?"#67e8f9":"#635e80", padding:"8px 18px", cursor: platformStatus.facebook.configured?"pointer":"default", fontSize:12, fontFamily:"monospace" }}>
            {testing.facebook ? "Testing…" : "🔌 Test"}
          </button>
          {platformStatus.facebook.configured && (
            <button onClick={() => disconnectPlatform("facebook")} disabled={saving} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"8px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
              ✕ Disconnect
            </button>
          )}
          {testResults.facebook && <span style={{ fontSize:12, fontFamily:"monospace", color: testResults.facebook.ok?"#86efac":"#fca5a5" }}>{testResults.facebook.msg}</span>}
        </div>
        {!platformStatus.facebook.configured && (
          <div style={{ marginTop:12, background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Get credentials: Facebook Developer → Your App → Page Access Token
          </div>
        )}
      </div>

      {/* Twitter / X */}
      <div style={{ ...sectionCard, border: platformStatus.twitter.configured ? "1px solid #4f46e544" : "1px solid #1c1830" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:18 }}>🐦</span>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>Twitter / X</div>
          <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>(Social Content)</span>
          <span style={{ marginLeft:"auto", background: platformStatus.twitter.configured?"#0a1a0a":"#1c0808", border:`1px solid ${platformStatus.twitter.configured?"#16a34a":"#7f1d1d"}`, borderRadius:4, color: platformStatus.twitter.configured?"#86efac":"#fca5a5", fontSize:10, fontFamily:"monospace", fontWeight:"bold", padding:"2px 8px" }}>
            {platformStatus.twitter.configured ? "CONNECTED" : "NOT CONFIGURED"}
          </span>
        </div>
        <div className="settings-grid-2" style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:14, marginBottom:14 }}>
          <div>
            <label style={labelStyle}>API Key (Consumer Key){platformStatus.twitter.keySet ? " (saved — leave blank to keep)" : ""}</label>
            <input type="password" value={form.twitter_api_key} onChange={fld("twitter_api_key")} placeholder={platformStatus.twitter.keySet ? "••••••••• (saved)" : "Your Twitter API key"} style={inputStyle} autoComplete="new-password" />
          </div>
          <div>
            <label style={labelStyle}>API Secret (Consumer Secret)</label>
            <input type="password" value={form.twitter_api_secret} onChange={fld("twitter_api_secret")} placeholder={platformStatus.twitter.keySet ? "••••••••• (saved)" : "Your Twitter API secret"} style={inputStyle} autoComplete="new-password" />
          </div>
          <div>
            <label style={labelStyle}>Access Token</label>
            <input type="password" value={form.twitter_access_token} onChange={fld("twitter_access_token")} placeholder={platformStatus.twitter.keySet ? "••••••••• (saved)" : "Your access token"} style={inputStyle} autoComplete="new-password" />
          </div>
          <div>
            <label style={labelStyle}>Access Token Secret</label>
            <input type="password" value={form.twitter_access_secret} onChange={fld("twitter_access_secret")} placeholder={platformStatus.twitter.keySet ? "••••••••• (saved)" : "Your access token secret"} style={inputStyle} autoComplete="new-password" />
          </div>
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={() => testPlatform("twitter")} disabled={testing.twitter || !platformStatus.twitter.configured} style={{ background:"#0a1520", border:`1px solid ${platformStatus.twitter.configured?"#0891b2":"#2a2448"}`, borderRadius:6, color: platformStatus.twitter.configured?"#67e8f9":"#635e80", padding:"8px 18px", cursor: platformStatus.twitter.configured?"pointer":"default", fontSize:12, fontFamily:"monospace" }}>
            {testing.twitter ? "Testing…" : "🔌 Test"}
          </button>
          {platformStatus.twitter.configured && (
            <button onClick={() => disconnectPlatform("twitter")} disabled={saving} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"8px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
              ✕ Disconnect
            </button>
          )}
          {testResults.twitter && <span style={{ fontSize:12, fontFamily:"monospace", color: testResults.twitter.ok?"#86efac":"#fca5a5" }}>{testResults.twitter.msg}</span>}
        </div>
        {!platformStatus.twitter.configured && (
          <div style={{ marginTop:12, background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Get credentials: Twitter Developer Portal → Your App → Keys and tokens. Requires "Read and Write" permissions. Posts your generated Twitter/X thread content.
          </div>
        )}
      </div>

      {/* LinkedIn */}
      <div style={{ ...sectionCard, border: platformStatus.linkedin.configured ? "1px solid #4f46e544" : "1px solid #1c1830" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:18 }}>💼</span>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>LinkedIn</div>
          <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>(Social Content)</span>
          <span style={{ marginLeft:"auto", background: platformStatus.linkedin.configured?"#0a1a0a":"#1c0808", border:`1px solid ${platformStatus.linkedin.configured?"#16a34a":"#7f1d1d"}`, borderRadius:4, color: platformStatus.linkedin.configured?"#86efac":"#fca5a5", fontSize:10, fontFamily:"monospace", fontWeight:"bold", padding:"2px 8px" }}>
            {platformStatus.linkedin.configured ? "CONNECTED" : "NOT CONFIGURED"}
          </span>
        </div>
        <div style={{ marginBottom:14 }}>
          <label style={labelStyle}>Access Token{platformStatus.linkedin.tokenSet ? " (saved — leave blank to keep)" : ""}</label>
          <input type="password" value={form.linkedin_access_token} onChange={fld("linkedin_access_token")} placeholder={platformStatus.linkedin.tokenSet ? "••••••••• (saved)" : "Your LinkedIn access token"} style={inputStyle} autoComplete="new-password" />
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={() => testPlatform("linkedin")} disabled={testing.linkedin || !platformStatus.linkedin.configured} style={{ background:"#0a1520", border:`1px solid ${platformStatus.linkedin.configured?"#0891b2":"#2a2448"}`, borderRadius:6, color: platformStatus.linkedin.configured?"#67e8f9":"#635e80", padding:"8px 18px", cursor: platformStatus.linkedin.configured?"pointer":"default", fontSize:12, fontFamily:"monospace" }}>
            {testing.linkedin ? "Testing…" : "🔌 Test"}
          </button>
          {platformStatus.linkedin.configured && (
            <button onClick={() => disconnectPlatform("linkedin")} disabled={saving} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"8px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
              ✕ Disconnect
            </button>
          )}
          {testResults.linkedin && <span style={{ fontSize:12, fontFamily:"monospace", color: testResults.linkedin.ok?"#86efac":"#fca5a5" }}>{testResults.linkedin.msg}</span>}
        </div>
        {!platformStatus.linkedin.configured && (
          <div style={{ marginTop:12, background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Get your token: LinkedIn Developer → Your App → Auth → Access token. Requires "w_member_social" and "r_liteprofile" permissions. Posts your generated LinkedIn content.
          </div>
        )}
      </div>

      {/* Instagram */}
      <div style={{ ...sectionCard, border: platformStatus.instagram.configured ? "1px solid #4f46e544" : "1px solid #1c1830" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:18 }}>📸</span>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>Instagram</div>
          <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>(Social Content)</span>
          <span style={{ marginLeft:"auto", background: platformStatus.instagram.configured?"#0a1a0a":"#1c0808", border:`1px solid ${platformStatus.instagram.configured?"#16a34a":"#7f1d1d"}`, borderRadius:4, color: platformStatus.instagram.configured?"#86efac":"#fca5a5", fontSize:10, fontFamily:"monospace", fontWeight:"bold", padding:"2px 8px" }}>
            {platformStatus.instagram.configured ? "CONNECTED" : "NOT CONFIGURED"}
          </span>
        </div>
        <div style={{ marginBottom:14 }}>
          <label style={labelStyle}>Access Token{platformStatus.instagram.tokenSet ? " (saved — leave blank to keep)" : ""}</label>
          <input type="password" value={form.instagram_access_token} onChange={fld("instagram_access_token")} placeholder={platformStatus.instagram.tokenSet ? "••••••••• (saved)" : "Your Instagram Graph API access token"} style={inputStyle} autoComplete="new-password" />
        </div>
        <div style={{ marginBottom:14 }}>
          <label style={labelStyle}>Account ID</label>
          <input type="text" value={form.instagram_account_id} onChange={fld("instagram_account_id")} placeholder="Your Instagram Business Account ID" style={inputStyle} />
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={() => testPlatform("instagram")} disabled={testing.instagram || !platformStatus.instagram.configured} style={{ background:"#0a1520", border:`1px solid ${platformStatus.instagram.configured?"#0891b2":"#2a2448"}`, borderRadius:6, color: platformStatus.instagram.configured?"#67e8f9":"#635e80", padding:"8px 18px", cursor: platformStatus.instagram.configured?"pointer":"default", fontSize:12, fontFamily:"monospace" }}>
            {testing.instagram ? "Testing…" : "🔌 Test"}
          </button>
          {platformStatus.instagram.configured && (
            <button onClick={() => disconnectPlatform("instagram")} disabled={saving} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"8px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
              ✕ Disconnect
            </button>
          )}
          {testResults.instagram && <span style={{ fontSize:12, fontFamily:"monospace", color: testResults.instagram.ok?"#86efac":"#fca5a5" }}>{testResults.instagram.msg}</span>}
        </div>
        {!platformStatus.instagram.configured && (
          <div style={{ marginTop:12, background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Requires a Facebook App with Instagram Graph API enabled. Get your token from Meta Developer Portal → Your App → Graph API Explorer. Account ID is your Instagram Business Account ID (found via the /me/accounts endpoint). Note: Instagram requires an image to publish — caption-only posts are not supported. Your generated captions can be copied from the Social Content panel.
          </div>
        )}
      </div>

      {/* TikTok */}
      <div style={{ ...sectionCard, border: platformStatus.tiktok.configured ? "1px solid #4f46e544" : "1px solid #1c1830" }}>
        <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14 }}>
          <span style={{ fontSize:18 }}>🎵</span>
          <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>TikTok</div>
          <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>(Social Content)</span>
          <span style={{ marginLeft:"auto", background: platformStatus.tiktok.configured?"#0a1a0a":"#1c0808", border:`1px solid ${platformStatus.tiktok.configured?"#16a34a":"#7f1d1d"}`, borderRadius:4, color: platformStatus.tiktok.configured?"#86efac":"#fca5a5", fontSize:10, fontFamily:"monospace", fontWeight:"bold", padding:"2px 8px" }}>
            {platformStatus.tiktok.configured ? "CONNECTED" : "NOT CONFIGURED"}
          </span>
        </div>
        <div style={{ marginBottom:14 }}>
          <label style={labelStyle}>Access Token{platformStatus.tiktok.tokenSet ? " (saved — leave blank to keep)" : ""}</label>
          <input type="password" value={form.tiktok_access_token} onChange={fld("tiktok_access_token")} placeholder={platformStatus.tiktok.tokenSet ? "••••••••• (saved)" : "Your TikTok access token"} style={inputStyle} autoComplete="new-password" />
        </div>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <button onClick={() => testPlatform("tiktok")} disabled={testing.tiktok || !platformStatus.tiktok.configured} style={{ background:"#0a1520", border:`1px solid ${platformStatus.tiktok.configured?"#0891b2":"#2a2448"}`, borderRadius:6, color: platformStatus.tiktok.configured?"#67e8f9":"#635e80", padding:"8px 18px", cursor: platformStatus.tiktok.configured?"pointer":"default", fontSize:12, fontFamily:"monospace" }}>
            {testing.tiktok ? "Testing…" : "🔌 Test"}
          </button>
          {platformStatus.tiktok.configured && (
            <button onClick={() => disconnectPlatform("tiktok")} disabled={saving} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:6, color:"#fca5a5", padding:"8px 18px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
              ✕ Disconnect
            </button>
          )}
          {testResults.tiktok && <span style={{ fontSize:12, fontFamily:"monospace", color: testResults.tiktok.ok?"#86efac":"#fca5a5" }}>{testResults.tiktok.msg}</span>}
        </div>
        {!platformStatus.tiktok.configured && (
          <div style={{ marginTop:12, background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px 14px", fontSize:12, color:"#635e80", fontFamily:"monospace", lineHeight:1.8 }}>
            Get your token: TikTok Developer Portal → Your App → Manage → Sandbox/Production. Requires "video.publish" scope. Posts your generated TikTok captions.
          </div>
        )}
      </div>

      {/* Auto-Publish — simplified */}
      <div style={sectionCard}>
        <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:10 }}>🔄 Auto-Publish on Approval</div>
        <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
          When you approve a draft, it will automatically be published to your connected platforms. No extra clicks needed.
        </div>
        <div style={{ display:"flex", gap:12, flexWrap:"wrap", marginBottom:14 }}>
          {[
            { id:"beehiiv", label:"🐝 Beehiiv", configured: platformStatus.beehiiv.configured },
            { id:"medium", label:"📝 Medium", configured: platformStatus.medium.configured },
            { id:"facebook", label:"📘 Facebook", configured: platformStatus.facebook.configured },
            { id:"twitter", label:"🐦 Twitter/X", configured: platformStatus.twitter.configured },
            { id:"linkedin", label:"💼 LinkedIn", configured: platformStatus.linkedin.configured },
            { id:"instagram", label:"📸 Instagram", configured: platformStatus.instagram.configured },
            { id:"tiktok", label:"🎵 TikTok", configured: platformStatus.tiktok.configured },
          ].map(p => {
            const checked = (form.auto_publish_platforms||"").split(",").includes(p.id);
            return (
              <button key={p.id} onClick={() => p.configured && toggleAutoPublish(p.id)} disabled={!p.configured} style={{ background: checked?"#13102a":"transparent", border:`1px solid ${checked?"#8b5cf6":p.configured?"#2a2448":"#1c1830"}`, borderRadius:6, color: checked?"#a78bfa":p.configured?"#635e80":"#3a3555", padding:"8px 16px", cursor: p.configured?"pointer":"default", fontSize:12, fontFamily:"monospace", opacity: p.configured?1:0.5 }}>
                {checked ? "☑" : "☐"} {p.label}{!p.configured ? " (not connected)" : ""}
              </button>
            );
          })}
        </div>
        {platformStatus.beehiiv.configured && (form.auto_publish_platforms||"").split(",").includes("beehiiv") && (
          <div style={{ background:"#0a1a0a", border:"1px solid #16a34a44", borderRadius:8, padding:"10px 14px", fontSize:12, color:"#86efac", fontFamily:"monospace" }}>
            Beehiiv auto-publish is ON — approved drafts will be sent to Beehiiv as {form.beehiiv_publish_mode === "live" ? "live posts" : "drafts for review"}.
          </div>
        )}
      </div>

      {/* Bulk Multi-Genre Scheduling (Elite) */}
      <EliteGate feature="Bulk multi-genre scheduling">
        <BulkScheduleSection />
      </EliteGate>

      <FeedbackViewer />

      {/* Save all */}
      <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:20 }}>
        <button onClick={save} disabled={saving} style={{ background:"#13102a", border:"1px solid #8b5cf6", borderRadius:6, color:"#a78bfa", padding:"10px 24px", cursor:"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>
          {saving ? "Saving…" : "💾 Save All Settings"}
        </button>
        {saveMsg && <span style={{ fontSize:12, fontFamily:"monospace", color: saveMsg.startsWith("✅")?"#86efac":"#fca5a5" }}>{saveMsg}</span>}
      </div>
    </div>
  );
}

function FeedbackViewer() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);
  const [deleteId, setDeleteId] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => { loadFeedback(); }, []);

  async function loadFeedback() {
    setLoading(true);
    setError(null);
    try {
      const res = await apiFetch("/api/feedback");
      if (res.ok) {
        const data = await res.json();
        setItems(data.feedback || []);
      } else {
        setError("Failed to load feedback");
      }
    } catch(e) {
      setError("Failed to load feedback");
    }
    setLoading(false);
  }

  async function deleteFeedback(id) {
    setError(null);
    try {
      const res = await apiFetch(`/api/feedback/${id}`, { method: "DELETE" });
      if (res.ok) {
        setItems(prev => prev.filter(f => f.id !== id));
        setDeleteId(null);
      } else {
        setError("Failed to delete feedback item");
      }
    } catch(e) {
      setError("Failed to delete feedback item");
    }
  }

  const sectionCard = { background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"20px 22px", marginBottom:14 };
  const tierColors = { elite: { bg:"linear-gradient(135deg,#f59e0b,#d97706)", color:"#fff" }, pro: { bg:"linear-gradient(135deg,#7c3aed,#4f46e5)", color:"#fff" }, free: { bg:"#13102a", color:"#635e80" } };

  return (
    <div style={sectionCard}>
      <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:4 }}>📬 User Feedback</div>
      <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
        Feedback submitted by your users from the Account tab.
      </div>
      {error && (
        <div style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, padding:"10px 14px", marginBottom:10, fontSize:12, color:"#fca5a5", fontFamily:"monospace" }}>
          {error}
        </div>
      )}
      {loading ? (
        <div style={{ color:"#635e80", fontSize:12, fontFamily:"monospace" }}>Loading...</div>
      ) : items.length === 0 ? (
        <div style={{ textAlign:"center", padding:"20px", color:"#635e80", fontSize:13, fontFamily:"monospace" }}>
          No feedback received yet
        </div>
      ) : (
        <div style={{ maxHeight:400, overflowY:"auto" }}>
          {items.map(fb => {
            const tc = tierColors[fb.user_tier] || tierColors.free;
            return (
              <div key={fb.id} style={{ background:"#06050e", border:"1px solid #1c1830", borderRadius:10, padding:"14px 16px", marginBottom:8 }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:8 }}>
                  <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                    <span style={{ color:"#e8e3f8", fontSize:13, fontFamily:"monospace", fontWeight:"bold" }}>{fb.user_email}</span>
                    <span style={{ background:tc.bg, color:tc.color, borderRadius:4, padding:"2px 8px", fontSize:9, fontFamily:"monospace", fontWeight:"bold" }}>{(fb.user_tier||"free").toUpperCase()}</span>
                  </div>
                  <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                    <span style={{ fontSize:10, color:"#635e80", fontFamily:"monospace" }}>{new Date(fb.created_at + "Z").toLocaleString()}</span>
                    {deleteId === fb.id ? (
                      <span style={{ display:"flex", gap:4 }}>
                        <button onClick={() => deleteFeedback(fb.id)} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:4, color:"#fca5a5", padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace" }}>Yes</button>
                        <button onClick={() => setDeleteId(null)} style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:4, color:"#635e80", padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace" }}>No</button>
                      </span>
                    ) : (
                      <button onClick={() => setDeleteId(fb.id)} style={{ background:"transparent", border:"1px solid #1c1830", borderRadius:4, color:"#3a3555", padding:"2px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace" }}>×</button>
                    )}
                  </div>
                </div>
                <div style={{ fontSize:13, color:"#b5b0ce", lineHeight:1.7, whiteSpace:"pre-wrap", wordBreak:"break-word" }}>{fb.message}</div>
              </div>
            );
          })}
        </div>
      )}
      {items.length > 0 && (
        <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", marginTop:8 }}>
          {items.length} feedback message{items.length !== 1 ? "s" : ""}
        </div>
      )}
    </div>
  );
}

function BulkScheduleSection() {
  const [schedule, setSchedule] = useState({ genres:[], days:[], enabled:false });
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [msg, setMsg] = useState(null);
  const [selectedGenres, setSelectedGenres] = useState([]);
  const [selectedDays, setSelectedDays] = useState([]);

  useEffect(() => {
    apiFetch("/api/elite/bulk-schedule").then(r => r.json()).then(d => {
      setSchedule(d.schedule || { genres:[], days:[], enabled:false });
      setSelectedGenres(d.schedule?.genres || []);
      setSelectedDays(d.schedule?.days || []);
      setLoading(false);
    }).catch(() => setLoading(false));
  }, []);

  function toggleGenre(g) {
    setSelectedGenres(p => p.includes(g) ? p.filter(x=>x!==g) : [...p, g]);
  }
  function toggleDay(d) {
    setSelectedDays(p => p.includes(d) ? p.filter(x=>x!==d) : [...p, d]);
  }

  async function saveBulkSchedule() {
    setSaving(true); setMsg(null);
    try {
      const res = await apiFetch("/api/elite/bulk-schedule", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ genres: selectedGenres, scheduleDays: selectedDays }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed");
      setSchedule(data.schedule);
      setMsg(data.message);
    } catch(err) { setMsg("Error: " + err.message); }
    setSaving(false);
  }

  if (loading) return <div style={{ color:"#635e80", fontSize:12, fontFamily:"monospace", padding:16 }}>Loading bulk schedule...</div>;

  const DAYS = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"];
  const sectionCard = { background:"#0e0c1a", border:"1px solid #d97706", borderRadius:12, padding:"20px 22px", marginBottom:14 };

  return (
    <div style={sectionCard}>
      <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:4, display:"flex", alignItems:"center", gap:8 }}>
        📅 Bulk Multi-Genre Scheduling
        <span style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", borderRadius:4, padding:"2px 8px", fontSize:9, fontFamily:"monospace", color:"#fff", fontWeight:"bold" }}>ELITE</span>
      </div>
      <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
        Schedule multiple genres to generate newsletters across different days of the week automatically.
      </div>
      <div style={{ marginBottom:14 }}>
        <div style={{ fontSize:10, fontFamily:"monospace", color:"#635e80", letterSpacing:2, marginBottom:8 }}>SELECT GENRES</div>
        <div style={{ display:"flex", gap:6, flexWrap:"wrap" }}>
          {GENRES.map(g => (
            <button key={g.id} onClick={() => toggleGenre(g.id)} style={{ background: selectedGenres.includes(g.id) ? g.color : "transparent", border:`1px solid ${selectedGenres.includes(g.id) ? g.color : "#2a2448"}`, borderRadius:16, color: selectedGenres.includes(g.id) ? "#fff" : "#635e80", padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>
              {g.icon} {g.name}
            </button>
          ))}
        </div>
      </div>
      <div style={{ marginBottom:14 }}>
        <div style={{ fontSize:10, fontFamily:"monospace", color:"#635e80", letterSpacing:2, marginBottom:8 }}>SELECT DAYS</div>
        <div style={{ display:"flex", gap:6, flexWrap:"wrap" }}>
          {DAYS.map(d => (
            <button key={d} onClick={() => toggleDay(d)} style={{ background: selectedDays.includes(d) ? "#f59e0b" : "transparent", border:`1px solid ${selectedDays.includes(d) ? "#f59e0b" : "#2a2448"}`, borderRadius:16, color: selectedDays.includes(d) ? "#fff" : "#635e80", padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace", textTransform:"capitalize" }}>
              {d.slice(0,3)}
            </button>
          ))}
        </div>
      </div>
      <div style={{ display:"flex", alignItems:"center", gap:10 }}>
        <button onClick={saveBulkSchedule} disabled={saving || selectedGenres.length === 0 || selectedDays.length === 0} style={{ background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none", borderRadius:8, color:"#fff", padding:"10px 20px", cursor: saving?"default":"pointer", fontSize:13, fontFamily:"monospace", fontWeight:"bold", opacity: saving || selectedGenres.length === 0 || selectedDays.length === 0 ? 0.5 : 1 }}>
          {saving ? "Saving…" : "Save Bulk Schedule"}
        </button>
        {msg && <span style={{ fontSize:12, fontFamily:"monospace", color: msg.startsWith("Error") ? "#fca5a5" : "#86efac" }}>{msg}</span>}
      </div>
      {schedule.enabled && (
        <div style={{ marginTop:12, background:"#1a1500", border:"1px solid #d9770644", borderRadius:8, padding:"10px 14px", fontSize:12, color:"#fbbf24", fontFamily:"monospace" }}>
          Active: {schedule.genres.length} genres scheduled across {schedule.days.map(d => d.slice(0,3)).join(", ")}
        </div>
      )}
    </div>
  );
}

// ── Discover Tab ─────────────────────────────────────────────────────────────
function DiscoverTab() {
  const [searchQuery, setSearchQuery] = useState("");
  const [searching, setSearching] = useState(false);
  const [results, setResults] = useState([]);
  const [searchErr, setSearchErr] = useState(null);
  const [savedAffiliates, setSavedAffiliates] = useState([]);
  const [affiliateTopics, setAffiliateTopics] = useState([]);
  const [activeSection, setActiveSection] = useState("generate");
  const [saving, setSaving] = useState({});
  const [saveSuccess, setSaveSuccess] = useState({});
  const [generating, setGenerating] = useState(false);
  const [genStep, setGenStep] = useState(null);
  const [genTopic, setGenTopic] = useState("");
  const [genAudience, setGenAudience] = useState("");
  const [genResult, setGenResult] = useState(null);
  const [genErr, setGenErr] = useState(null);
  const [editingAffiliate, setEditingAffiliate] = useState(null);
  const [editForm, setEditForm] = useState({});
  const [deleteConfirm, setDeleteConfirm] = useState(null);
  const [filterTopic, setFilterTopic] = useState("all");
  const [contentHistory, setContentHistory] = useState([]);
  const [searchSources, setSearchSources] = useState(null);
  const [folders, setFolders] = useState([]);
  const [activeFolder, setActiveFolder] = useState("all");
  const [newFolderName, setNewFolderName] = useState("");
  const [creatingFolder, setCreatingFolder] = useState(false);
  const [renamingFolder, setRenamingFolder] = useState(null);
  const [renameFolderName, setRenameFolderName] = useState("");
  const [deleteFolderConfirm, setDeleteFolderConfirm] = useState(null);
  const [customTopics, setCustomTopics] = useState([]);
  const [savingTopic, setSavingTopic] = useState(false);

  useEffect(() => {
    loadAffiliates();
    loadTopics();
    loadHistory();
    loadFolders();
    loadCustomTopics();
  }, []);

  async function loadAffiliates() {
    try {
      const res = await apiFetch("/api/affiliates");
      if (!res.ok) return;
      const data = await res.json();
      setSavedAffiliates(data.affiliates || []);
    } catch(e) { console.error("loadAffiliates:", e.message); }
  }

  async function loadTopics() {
    try {
      const res = await apiFetch("/api/affiliates/topics");
      if (!res.ok) return;
      const data = await res.json();
      setAffiliateTopics(data.topics || []);
    } catch(e) { console.error("loadTopics:", e.message); }
  }

  async function loadHistory() {
    try {
      const res = await apiFetch("/api/content-history");
      if (!res.ok) return;
      const data = await res.json();
      setContentHistory(data.history || []);
    } catch(e) { console.error("loadHistory:", e.message); }
  }

  async function loadFolders() {
    try {
      const res = await apiFetch("/api/affiliate-folders");
      if (!res.ok) return;
      const data = await res.json();
      setFolders(data.folders || []);
    } catch(e) { console.error("loadFolders:", e.message); }
  }

  async function createFolder() {
    if (!newFolderName.trim()) return;
    setCreatingFolder(true);
    try {
      const res = await apiFetch("/api/affiliate-folders", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: newFolderName.trim() }),
      });
      if (!res.ok) { const d = await res.json(); alert(d.error || "Failed"); setCreatingFolder(false); return; }
      setNewFolderName("");
      loadFolders();
    } catch(e) { alert(e.message); }
    setCreatingFolder(false);
  }

  async function renameFolder(id) {
    if (!renameFolderName.trim()) return;
    try {
      const res = await apiFetch(`/api/affiliate-folders/${id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: renameFolderName.trim() }),
      });
      if (!res.ok) { const d = await res.json(); alert(d.error || "Failed"); return; }
      setRenamingFolder(null);
      setRenameFolderName("");
      loadFolders();
    } catch(e) { alert(e.message); }
  }

  async function deleteFolder(id) {
    try {
      const res = await apiFetch(`/api/affiliate-folders/${id}`, { method: "DELETE" });
      if (!res.ok) { const d = await res.json(); alert(d.error || "Failed"); return; }
      setDeleteFolderConfirm(null);
      if (activeFolder === id) setActiveFolder("all");
      loadFolders();
      loadAffiliates();
    } catch(e) { alert(e.message); }
  }

  async function moveToFolder(affiliateId, folderId) {
    try {
      const res = await apiFetch(`/api/affiliates/${affiliateId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ folder_id: folderId }),
      });
      if (!res.ok) { const d = await res.json(); alert(d.error || "Failed"); return; }
      loadAffiliates();
      loadFolders();
    } catch(e) { alert(e.message); }
  }

  async function loadCustomTopics() {
    try {
      const res = await apiFetch("/api/custom-topics");
      if (!res.ok) return;
      const data = await res.json();
      setCustomTopics(data.topics || []);
    } catch(e) { console.error("loadCustomTopics:", e.message); }
  }

  async function doSearch() {
    if (!searchQuery.trim() || searching) return;
    setSearching(true);
    setSearchErr(null);
    setResults([]);
    try {
      const res = await apiFetch("/api/discover/search", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ query: searchQuery.trim() }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Search failed");
      setResults(data.results || []);
      setSearchSources(data.sources || null);
      if (!genTopic) setGenTopic(searchQuery.trim());
    } catch(e) {
      setSearchErr(e.message);
    }
    setSearching(false);
  }

  async function saveAffiliate(item) {
    const key = item.name;
    setSaving(p => ({ ...p, [key]: true }));
    try {
      const res = await apiFetch("/api/affiliates", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          topic: genTopic || searchQuery.trim(),
          name: item.name,
          url: item.website || "",
          referral_url: "",
          commission: item.commission || "",
          description: item.description || "",
          program_url: item.affiliate_url || "",
          has_affiliate: item.has_affiliate === true,
        }),
      });
      if (!res.ok) {
        const d = await res.json();
        throw new Error(d.error || "Save failed");
      }
      setSaveSuccess(p => ({ ...p, [key]: true }));
      setTimeout(() => setSaveSuccess(p => ({ ...p, [key]: false })), 3000);
      await loadAffiliates();
      await loadTopics();
    } catch(e) {
      alert("Error: " + e.message);
    }
    setSaving(p => ({ ...p, [key]: false }));
  }

  function handleGenerateForCompany(companyName) {
    setGenTopic(companyName);
    setActiveSection("generate");
  }

  async function deleteAffiliate(id) {
    try {
      const res = await apiFetch(`/api/affiliates/${id}`, { method: "DELETE" });
      if (!res.ok) {
        const d = await res.json();
        throw new Error(d.error || "Delete failed");
      }
      setDeleteConfirm(null);
      await loadAffiliates();
      await loadTopics();
    } catch(e) {
      alert("Delete failed: " + e.message);
    }
  }

  async function updateAffiliate(id) {
    try {
      const res = await apiFetch(`/api/affiliates/${id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(editForm),
      });
      if (!res.ok) {
        const d = await res.json();
        throw new Error(d.error || "Update failed");
      }
      setEditingAffiliate(null);
      setEditForm({});
      await loadAffiliates();
    } catch(e) {
      alert("Update failed: " + e.message);
    }
  }

  async function saveCustomTopic() {
    if (!genTopic.trim() || savingTopic) return;
    setSavingTopic(true);
    try {
      const res = await apiFetch("/api/custom-topics", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: genTopic.trim(), audience: genAudience.trim() || undefined }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Save failed");
      await loadCustomTopics();
    } catch(e) {
      if (!e.message.includes("already exists")) alert("Error: " + e.message);
    }
    setSavingTopic(false);
  }

  async function generateNewsletter() {
    if (!genTopic.trim() || generating) return;
    setGenerating(true);
    setGenStep("researching");
    setGenErr(null);
    setGenResult(null);
    let stepTimer, stepTimer2;
    try {
      stepTimer = setTimeout(() => setGenStep("writing"), 15000);
      stepTimer2 = setTimeout(() => setGenStep("social"), 45000);
      const res = await apiFetch("/api/discover/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ topic: genTopic.trim(), audience: genAudience.trim() || undefined }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Generation failed");
      setGenResult(data);
      try { await saveCustomTopic(); } catch(_) {}
      await loadHistory();
    } catch(e) {
      setGenErr(e.message);
    } finally {
      clearTimeout(stepTimer);
      clearTimeout(stepTimer2);
      setGenerating(false);
      setGenStep(null);
    }
  }

  const inputStyle = { background:"#06050e", border:"1px solid #2a2448", borderRadius:8, color:"#e8e3f8", padding:"10px 14px", fontSize:13, fontFamily:"monospace", width:"100%", boxSizing:"border-box" };
  const sectionCard = { background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"20px 22px", marginBottom:14 };
  const sectionBtns = [
    { id:"generate", icon:"✨", label:"Research & Generate" },
    { id:"search", icon:"🌐", label:"Search Companies" },
    { id:"affiliates", icon:"🏢", label:"My Companies" },
    { id:"history", icon:"📚", label:"Content History" },
  ];

  const folderFilteredAffiliates = activeFolder === "all" ? savedAffiliates : activeFolder === "uncategorized" ? savedAffiliates.filter(a => !a.folder_id) : savedAffiliates.filter(a => a.folder_id === activeFolder);
  const filteredAffiliates = filterTopic === "all" ? folderFilteredAffiliates : folderFilteredAffiliates.filter(a => a.topic === filterTopic);
  const uniqueTopicsFromAffiliates = [...new Set(folderFilteredAffiliates.map(a => a.topic))];
  const uncategorizedCount = savedAffiliates.filter(a => !a.folder_id).length;

  return (
    <div>
      <div style={{ display:"flex", gap:6, flexWrap:"wrap", marginBottom:20 }}>
        {sectionBtns.map(b => (
          <button key={b.id} onClick={() => setActiveSection(b.id)} style={{
            background: activeSection === b.id ? "#1e1a3a" : "transparent",
            border: `1px solid ${activeSection === b.id ? "#8b5cf6" : "#1c1830"}`,
            borderRadius:8, color: activeSection === b.id ? "#a78bfa" : "#635e80",
            padding:"8px 16px", cursor:"pointer", fontSize:12, fontFamily:"monospace",
            display:"flex", alignItems:"center", gap:6,
          }}>
            <span>{b.icon}</span>{b.label}
          </button>
        ))}
      </div>

      {activeSection === "search" && (
        <div>
          <div style={{ ...sectionCard, borderColor:"#2a2448", background:"linear-gradient(180deg,#0e0c1a,#06050e)" }}>
            <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:8 }}>
              <span style={{ fontSize:28 }}>🌐</span>
              <div>
                <div style={{ fontWeight:"bold", fontSize:17, color:"#e8e3f8" }}>Search Any Company or Industry</div>
                <div style={{ fontSize:12, color:"#635e80", lineHeight:1.5 }}>
                  Search the internet for any company, brand, or niche. We'll find affiliate programs, commission rates, and signup links — or let you write a newsletter even without an affiliate program.
                </div>
              </div>
            </div>
            <div className="search-input-row" style={{ display:"flex", gap:10, marginBottom:8, marginTop:14 }}>
              <input
                type="text"
                value={searchQuery}
                onChange={e => setSearchQuery(e.target.value)}
                onKeyDown={e => e.key === "Enter" && doSearch()}
                placeholder='Search any company or industry... e.g. "Nike", "SaaS tools", "pet supplies"'
                style={{ ...inputStyle, flex:1, padding:"14px 18px", fontSize:14, borderColor:"#4f46e5", borderRadius:10 }}
              />
              <button
                onClick={doSearch}
                disabled={searching || !searchQuery.trim()}
                style={{
                  background: searching ? "#1a1630" : "linear-gradient(135deg,#7c3aed,#4f46e5)",
                  border:"none", borderRadius:10, color:"#fff", padding:"14px 28px",
                  cursor: searching ? "not-allowed" : "pointer", fontSize:14, fontFamily:"monospace", fontWeight:"bold",
                  whiteSpace:"nowrap", minWidth:130, boxShadow: searching ? "none" : "0 4px 16px rgba(124,58,237,0.3)",
                }}
              >
                {searching ? "Searching..." : "Search"}
              </button>
            </div>
            <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", display:"flex", gap:16, flexWrap:"wrap" }}>
              <span>Try: <span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setSearchQuery("fitness supplements")}>fitness supplements</span></span>
              <span><span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setSearchQuery("web hosting")}>web hosting</span></span>
              <span><span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setSearchQuery("online education")}>online education</span></span>
              <span><span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setSearchQuery("home automation")}>home automation</span></span>
            </div>
          </div>

          {searchErr && (
            <div style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, padding:"12px 16px", marginBottom:14, fontSize:12, color:"#fca5a5", fontFamily:"monospace" }}>
              {searchErr}
            </div>
          )}

          {searching && (
            <div style={{ ...sectionCard, textAlign:"center", padding:"50px 20px" }}>
              <div style={{ fontSize:32, marginBottom:14 }}>🔍</div>
              <div style={{ color:"#a78bfa", fontFamily:"monospace", fontSize:14, fontWeight:"bold" }}>Searching the web for companies...</div>
              <div style={{ fontSize:12, color:"#635e80", marginTop:8, lineHeight:1.6 }}>Researching affiliate programs, commission rates, and company details.<br/>This usually takes 15-30 seconds.</div>
              <div style={{ marginTop:16, height:4, background:"#1c1830", borderRadius:2, overflow:"hidden", maxWidth:300, margin:"16px auto 0" }}>
                <div style={{ height:"100%", background:"linear-gradient(90deg,#4f46e5,#8b5cf6,#4f46e5)", width:"80%", animation:"pulse 1.5s ease-in-out infinite" }} />
              </div>
            </div>
          )}

          {!searching && results.length === 0 && !searchErr && searchQuery.trim() === "" && (
            <div style={{ ...sectionCard, textAlign:"center", padding:"40px 20px" }}>
              <div style={{ fontSize:32, marginBottom:12 }}>🏢</div>
              <div style={{ fontWeight:"bold", color:"#e8e3f8", marginBottom:8, fontSize:15 }}>Discover Companies & Affiliate Programs</div>
              <div style={{ fontSize:13, color:"#635e80", lineHeight:1.7, maxWidth:440, margin:"0 auto" }}>
                Type any company name, industry, or niche in the search bar above. We'll search the internet to find real companies, check if they have affiliate programs, and show you how to get started.
              </div>
            </div>
          )}

          {!searching && results.length === 0 && !searchErr && searchQuery.trim() !== "" && (
            <div style={{ ...sectionCard, textAlign:"center", padding:"40px 20px" }}>
              <div style={{ fontSize:32, marginBottom:12 }}>🔎</div>
              <div style={{ fontWeight:"bold", color:"#e8e3f8", marginBottom:8, fontSize:15 }}>No Companies Found</div>
              <div style={{ fontSize:13, color:"#635e80", lineHeight:1.7, maxWidth:440, margin:"0 auto", marginBottom:16 }}>
                We couldn't find companies matching "<span style={{ color:"#a78bfa" }}>{searchQuery}</span>". Try these tips:
              </div>
              <div style={{ display:"inline-block", textAlign:"left", fontSize:12, color:"#b5b0ce", lineHeight:1.8 }}>
                <div>Use broader terms (e.g. "fitness" instead of "CrossFit gym near me")</div>
                <div>Try industry names (e.g. "web hosting", "pet supplies", "beauty")</div>
                <div>Search for specific companies by name (e.g. "Amazon", "Shopify")</div>
              </div>
              <div style={{ marginTop:16 }}>
                <button onClick={() => { setSearchQuery(""); setResults([]); }} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:8, color:"#a78bfa", padding:"8px 20px", cursor:"pointer", fontSize:12, fontFamily:"monospace" }}>
                  Clear Search
                </button>
              </div>
            </div>
          )}

          {results.length > 0 && !searching && (
            <div>
              <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:14, flexWrap:"wrap" }}>
                <div style={{ fontSize:11, fontFamily:"monospace", color:"#635e80", letterSpacing:2 }}>FOUND {results.length} COMPANIES</div>
                {searchSources && (
                  <span style={{ fontSize:10, fontFamily:"monospace", padding:"2px 8px", borderRadius:4, background: searchSources.method === "web_search_enriched" ? "#0a1a0a" : "#1a150a", border: `1px solid ${searchSources.method === "web_search_enriched" ? "#16a34a" : "#ca8a04"}`, color: searchSources.method === "web_search_enriched" ? "#86efac" : "#fde047" }}>
                    {searchSources.method === "web_search_enriched" ? `${searchSources.webResults || 0} web results sourced` : "AI knowledge"}
                  </span>
                )}
                <span style={{ fontSize:10, fontFamily:"monospace", padding:"2px 8px", borderRadius:4, background:"#0a1a0a", border:"1px solid #16a34a", color:"#86efac" }}>
                  {results.filter(r => r.has_affiliate).length} with affiliate programs
                </span>
                {results.filter(r => !r.has_affiliate).length > 0 && (
                  <span style={{ fontSize:10, fontFamily:"monospace", padding:"2px 8px", borderRadius:4, background:"#1a150a", border:"1px solid #ca8a04", color:"#fde047" }}>
                    {results.filter(r => !r.has_affiliate).length} without programs
                  </span>
                )}
                <div style={{ flex:1, height:1, background:"#1c1830" }} />
              </div>
              <div className="discover-results-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(340px,1fr))", gap:12 }}>
                {results.map((item, i) => (
                  <div key={i} style={{
                    background:"#0e0c1a",
                    border: item.has_affiliate ? "1px solid #16a34a" : "1px solid #ca8a04",
                    borderRadius:12, padding:"16px 18px", transition:"border-color .2s", position:"relative",
                  }}>
                    {item.has_affiliate ? (
                      <div style={{ position:"absolute", top:-8, right:14, background:"#0a1a0a", border:"1px solid #16a34a", borderRadius:10, padding:"2px 10px", fontSize:9, fontFamily:"monospace", fontWeight:"bold", color:"#86efac", letterSpacing:1 }}>
                        AFFILIATE PROGRAM
                      </div>
                    ) : (
                      <div style={{ position:"absolute", top:-8, right:14, background:"#1a150a", border:"1px solid #ca8a04", borderRadius:10, padding:"2px 10px", fontSize:9, fontFamily:"monospace", fontWeight:"bold", color:"#fde047", letterSpacing:1 }}>
                        NO AFFILIATE PROGRAM
                      </div>
                    )}
                    <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", marginBottom:8, marginTop:6 }}>
                      <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>{item.name}</div>
                      {item.confidence && (
                        <span style={{ fontSize:8, fontFamily:"monospace", padding:"2px 6px", borderRadius:3, background: item.confidence === "verified" ? "#0a1a0a" : item.confidence === "likely" ? "#1a150a" : item.confidence === "no_program" ? "#1a150a" : "#1a0a0a", border: `1px solid ${item.confidence === "verified" ? "#16a34a" : item.confidence === "likely" ? "#ca8a04" : item.confidence === "no_program" ? "#ca8a04" : "#635e80"}`, color: item.confidence === "verified" ? "#86efac" : item.confidence === "likely" ? "#fde047" : item.confidence === "no_program" ? "#fde047" : "#b5b0ce" }}>
                          {item.confidence.toUpperCase().replace("_", " ")}
                        </span>
                      )}
                    </div>
                    <div style={{ fontSize:12, color:"#b5b0ce", lineHeight:1.5, marginBottom:10 }}>{item.description}</div>

                    {item.has_affiliate && item.commission && item.commission !== "N/A" && (
                      <div style={{ display:"flex", alignItems:"center", gap:6, marginBottom:8 }}>
                        <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>Commission:</span>
                        <span style={{ fontSize:12, color:"#86efac", fontFamily:"monospace", fontWeight:"bold" }}>{item.commission}</span>
                      </div>
                    )}

                    {!item.has_affiliate && (
                      <div style={{ background:"#1a150a", border:"1px solid #78620d", borderRadius:8, padding:"10px 12px", marginBottom:10 }}>
                        <div style={{ fontSize:12, color:"#fde047", fontFamily:"monospace", fontWeight:"bold", marginBottom:4 }}>No Affiliate Program Available</div>
                        <div style={{ fontSize:11, color:"#b5a060", lineHeight:1.5 }}>
                          This company doesn't currently offer an affiliate or referral program, but you can still feature them in your newsletter for great content.
                        </div>
                      </div>
                    )}

                    {item.newsletter_angle && (
                      <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:6, padding:"8px 10px", marginBottom:10 }}>
                        <div style={{ fontSize:9, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:1, marginBottom:4 }}>NEWSLETTER ANGLE</div>
                        <div style={{ fontSize:11, color:"#b5b0ce", lineHeight:1.5 }}>{item.newsletter_angle}</div>
                      </div>
                    )}

                    <div style={{ display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
                      {item.has_affiliate && item.affiliate_url && /^https?:\/\//i.test(item.affiliate_url) && (
                        <a href={item.affiliate_url} target="_blank" rel="noopener noreferrer"
                          style={{ fontSize:11, color:"#86efac", fontFamily:"monospace", textDecoration:"none", background:"#0a1a0a", border:"1px solid #16a34a", borderRadius:6, padding:"6px 12px", fontWeight:"bold" }}>
                          Get Affiliate Link
                        </a>
                      )}
                      {item.website && /^https?:\/\//i.test(item.website) && (
                        <a href={item.website} target="_blank" rel="noopener noreferrer"
                          style={{ fontSize:11, color:"#8b5cf6", fontFamily:"monospace", textDecoration:"none", border:"1px solid #4f46e5", borderRadius:6, padding:"6px 12px" }}>
                          Visit Website
                        </a>
                      )}
                      <button
                        onClick={() => saveAffiliate(item)}
                        disabled={saving[item.name] || saveSuccess[item.name]}
                        style={{
                          background: saveSuccess[item.name] ? "#0a1a0a" : "#13102a",
                          border: `1px solid ${saveSuccess[item.name] ? "#16a34a" : "#4f46e5"}`,
                          borderRadius:6, color: saveSuccess[item.name] ? "#86efac" : "#a78bfa",
                          padding:"6px 12px", cursor: saveSuccess[item.name] ? "default" : "pointer",
                          fontSize:11, fontFamily:"monospace",
                        }}
                      >
                        {saveSuccess[item.name] ? "Saved!" : saving[item.name] ? "Saving..." : "Save Company"}
                      </button>
                      {!item.has_affiliate && (
                        <button
                          onClick={() => handleGenerateForCompany(item.name)}
                          style={{
                            background:"linear-gradient(135deg,#f59e0b,#d97706)", border:"none",
                            borderRadius:6, color:"#fff", padding:"6px 12px", cursor:"pointer",
                            fontSize:11, fontFamily:"monospace", fontWeight:"bold",
                          }}
                        >
                          Generate Newsletter Anyway
                        </button>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      )}

      {activeSection === "affiliates" && (
        <div>
          <div style={sectionCard}>
            <div style={{ fontWeight:"bold", fontSize:15, color:"#e8e3f8", marginBottom:6 }}>My Saved Companies</div>
            <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
              Companies with affiliate programs are automatically included in your newsletters. Companies without programs are still featured for great content — no affiliate links needed.
            </div>

            <div style={{ display:"flex", gap:6, flexWrap:"wrap", marginBottom:10 }}>
              <button onClick={() => { setActiveFolder("all"); setFilterTopic("all"); }} style={{
                background: activeFolder === "all" ? "#1e1a3a" : "transparent",
                border: `1px solid ${activeFolder === "all" ? "#8b5cf6" : "#1c1830"}`,
                borderRadius:6, color: activeFolder === "all" ? "#a78bfa" : "#635e80",
                padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace",
              }}>All ({savedAffiliates.length})</button>
              <button onClick={() => { setActiveFolder("uncategorized"); setFilterTopic("all"); }} style={{
                background: activeFolder === "uncategorized" ? "#1e1a3a" : "transparent",
                border: `1px solid ${activeFolder === "uncategorized" ? "#8b5cf6" : "#1c1830"}`,
                borderRadius:6, color: activeFolder === "uncategorized" ? "#a78bfa" : "#635e80",
                padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace",
              }}>Uncategorized ({uncategorizedCount})</button>
              {folders.map(f => (
                <div key={f.id} style={{ display:"inline-flex", alignItems:"center", gap:0 }}>
                  {renamingFolder === f.id ? (
                    <div style={{ display:"inline-flex", alignItems:"center", gap:4 }}>
                      <input type="text" value={renameFolderName} onChange={e => setRenameFolderName(e.target.value)}
                        onKeyDown={e => { if (e.key === "Enter") renameFolder(f.id); if (e.key === "Escape") { setRenamingFolder(null); setRenameFolderName(""); } }}
                        autoFocus style={{ background:"#06050e", border:"1px solid #4f46e5", borderRadius:4, color:"#e8e3f8", padding:"3px 8px", fontSize:11, fontFamily:"monospace", width:100 }} />
                      <button onClick={() => renameFolder(f.id)} style={{ background:"transparent", border:"none", color:"#86efac", cursor:"pointer", fontSize:11, fontFamily:"monospace", padding:"2px 4px" }}>OK</button>
                      <button onClick={() => { setRenamingFolder(null); setRenameFolderName(""); }} style={{ background:"transparent", border:"none", color:"#635e80", cursor:"pointer", fontSize:11, fontFamily:"monospace", padding:"2px 4px" }}>X</button>
                    </div>
                  ) : (
                    <button onClick={() => { setActiveFolder(f.id); setFilterTopic("all"); }} style={{
                      background: activeFolder === f.id ? "#1e1a3a" : "transparent",
                      border: `1px solid ${activeFolder === f.id ? "#8b5cf6" : "#1c1830"}`,
                      borderRadius:6, color: activeFolder === f.id ? "#a78bfa" : "#635e80",
                      padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace",
                      borderTopRightRadius: 0, borderBottomRightRadius: 0,
                    }}>{f.name} ({f.link_count})</button>
                  )}
                  {renamingFolder !== f.id && (
                    <div style={{ display:"inline-flex", borderLeft:"none" }}>
                      <button onClick={() => { setRenamingFolder(f.id); setRenameFolderName(f.name); }}
                        title="Rename folder"
                        style={{ background: activeFolder === f.id ? "#1e1a3a" : "transparent", border: `1px solid ${activeFolder === f.id ? "#8b5cf6" : "#1c1830"}`, borderLeft:"none", color:"#635e80", cursor:"pointer", fontSize:9, fontFamily:"monospace", padding:"4px 5px", borderRadius:0 }}>
                        ✏️
                      </button>
                      {deleteFolderConfirm === f.id ? (
                        <>
                          <button onClick={() => deleteFolder(f.id)}
                            style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderLeft:"none", color:"#fca5a5", cursor:"pointer", fontSize:9, fontFamily:"monospace", padding:"4px 5px", borderRadius:0 }}>
                            Yes
                          </button>
                          <button onClick={() => setDeleteFolderConfirm(null)}
                            style={{ background:"transparent", border:"1px solid #1c1830", borderLeft:"none", color:"#635e80", cursor:"pointer", fontSize:9, fontFamily:"monospace", padding:"4px 5px", borderRadius:"0 6px 6px 0" }}>
                            No
                          </button>
                        </>
                      ) : (
                        <button onClick={() => setDeleteFolderConfirm(f.id)}
                          title="Delete folder"
                          style={{ background: activeFolder === f.id ? "#1e1a3a" : "transparent", border: `1px solid ${activeFolder === f.id ? "#8b5cf6" : "#1c1830"}`, borderLeft:"none", color:"#7f1d1d", cursor:"pointer", fontSize:9, fontFamily:"monospace", padding:"4px 5px", borderRadius:"0 6px 6px 0" }}>
                          🗑️
                        </button>
                      )}
                    </div>
                  )}
                </div>
              ))}
              <div style={{ display:"inline-flex", alignItems:"center", gap:4 }}>
                <input type="text" value={newFolderName} onChange={e => setNewFolderName(e.target.value)}
                  onKeyDown={e => { if (e.key === "Enter") createFolder(); }}
                  placeholder="+ New folder" style={{ background:"transparent", border:"1px dashed #2a2448", borderRadius:6, color:"#a78bfa", padding:"4px 10px", fontSize:11, fontFamily:"monospace", width:100 }} />
                {newFolderName.trim() && (
                  <button onClick={createFolder} disabled={creatingFolder} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:4, color:"#a78bfa", padding:"3px 8px", cursor:"pointer", fontSize:10, fontFamily:"monospace" }}>
                    Add
                  </button>
                )}
              </div>
            </div>

            {uniqueTopicsFromAffiliates.length > 0 && (
              <div style={{ display:"flex", gap:6, flexWrap:"wrap", marginBottom:14 }}>
                <span style={{ fontSize:10, color:"#635e80", fontFamily:"monospace", alignSelf:"center", marginRight:4 }}>Topic:</span>
                <button onClick={() => setFilterTopic("all")} style={{
                  background: filterTopic === "all" ? "#1e1a3a" : "transparent",
                  border: `1px solid ${filterTopic === "all" ? "#8b5cf6" : "#1c1830"}`,
                  borderRadius:6, color: filterTopic === "all" ? "#a78bfa" : "#635e80",
                  padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace",
                }}>All ({folderFilteredAffiliates.length})</button>
                {uniqueTopicsFromAffiliates.map(t => {
                  const count = folderFilteredAffiliates.filter(a => a.topic === t).length;
                  return (
                    <button key={t} onClick={() => setFilterTopic(t)} style={{
                      background: filterTopic === t ? "#1e1a3a" : "transparent",
                      border: `1px solid ${filterTopic === t ? "#8b5cf6" : "#1c1830"}`,
                      borderRadius:6, color: filterTopic === t ? "#a78bfa" : "#635e80",
                      padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace",
                    }}>{t} ({count})</button>
                  );
                })}
              </div>
            )}
          </div>

          {filteredAffiliates.length === 0 && (
            <div style={{ textAlign:"center", padding:"40px 20px", color:"#635e80", background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12 }}>
              <div style={{ fontSize:32, marginBottom:12 }}>{activeFolder !== "all" && activeFolder !== "uncategorized" ? "📂" : "🏢"}</div>
              <div style={{ fontWeight:"bold", color:"#e8e3f8", marginBottom:6 }}>
                {savedAffiliates.length === 0 ? "No companies saved yet" : activeFolder !== "all" ? "This folder is empty" : "No matching companies"}
              </div>
              <div style={{ fontSize:13 }}>
                {savedAffiliates.length === 0 ? "Use the Search tab to find companies and save them to your library" : activeFolder !== "all" && activeFolder !== "uncategorized" ? "Move companies into this folder using the folder dropdown on each card" : "Try adjusting your filters"}
              </div>
            </div>
          )}

          {filteredAffiliates.map(aff => {
            const hasAff = aff.has_affiliate === 1 || aff.has_affiliate === true;
            return (
            <div key={aff.id} style={{ background:"#0e0c1a", border: `1px solid ${hasAff ? "#16a34a" : "#ca8a04"}`, borderRadius:12, padding:"16px 18px", marginBottom:10, position:"relative" }}>
              <div style={{ position:"absolute", top:-8, right:14, background: hasAff ? "#0a1a0a" : "#1a150a", border: `1px solid ${hasAff ? "#16a34a" : "#ca8a04"}`, borderRadius:10, padding:"2px 10px", fontSize:9, fontFamily:"monospace", fontWeight:"bold", color: hasAff ? "#86efac" : "#fde047", letterSpacing:1 }}>
                {hasAff ? "HAS AFFILIATE" : "NO AFFILIATE"}
              </div>
              <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", marginBottom:6, marginTop:4 }}>
                <div>
                  <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>{aff.name}</div>
                  <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", marginTop:2 }}>Topic: {aff.topic}</div>
                </div>
                <div style={{ display:"flex", alignItems:"center", gap:6 }}>
                  {hasAff && aff.commission && (
                    <span style={{ fontSize:11, color:"#86efac", fontFamily:"monospace", fontWeight:"bold" }}>{aff.commission}</span>
                  )}
                </div>
              </div>
              <div style={{ fontSize:12, color:"#b5b0ce", lineHeight:1.5, marginBottom:8 }}>{aff.description}</div>

              {editingAffiliate === aff.id ? (
                <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"12px", marginBottom:8 }}>
                  <div style={{ marginBottom:8 }}>
                    <label style={{ display:"block", fontSize:10, color:"#635e80", fontFamily:"monospace", marginBottom:4, textTransform:"uppercase" }}>Your Referral URL</label>
                    <input type="text" value={editForm.referral_url || ""} onChange={e => setEditForm(f => ({...f, referral_url: e.target.value}))} placeholder="Paste your unique affiliate link here" style={inputStyle} />
                  </div>
                  <div style={{ marginBottom:8 }}>
                    <label style={{ display:"block", fontSize:10, color:"#635e80", fontFamily:"monospace", marginBottom:4, textTransform:"uppercase" }}>Commission</label>
                    <input type="text" value={editForm.commission || ""} onChange={e => setEditForm(f => ({...f, commission: e.target.value}))} placeholder="e.g. 20% per sale" style={inputStyle} />
                  </div>
                  <div style={{ display:"flex", gap:8 }}>
                    <button onClick={() => updateAffiliate(aff.id)} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:6, color:"#a78bfa", padding:"6px 14px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>Save</button>
                    <button onClick={() => { setEditingAffiliate(null); setEditForm({}); }} style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:6, color:"#635e80", padding:"6px 14px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>Cancel</button>
                  </div>
                </div>
              ) : (
                <div style={{ display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
                  {(aff.has_affiliate === 1 || aff.has_affiliate === true) ? (
                    aff.referral_url ? (
                      <div style={{ fontSize:11, color:"#86efac", fontFamily:"monospace", background:"#0a1a0a", border:"1px solid #16a34a", borderRadius:4, padding:"3px 8px" }}>
                        Referral link set
                      </div>
                    ) : (
                      <div style={{ fontSize:11, color:"#fca5a5", fontFamily:"monospace", background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:4, padding:"3px 8px" }}>
                        No referral link yet
                      </div>
                    )
                  ) : (
                    <div style={{ fontSize:11, color:"#fde047", fontFamily:"monospace", background:"#1a150a", border:"1px solid #ca8a04", borderRadius:4, padding:"3px 8px" }}>
                      Content partner — no affiliate program
                    </div>
                  )}
                  {(aff.has_affiliate === 1 || aff.has_affiliate === true) && aff.program_url && /^https?:\/\//i.test(aff.program_url) && (
                    <a href={aff.program_url} target="_blank" rel="noopener noreferrer"
                      style={{ fontSize:11, color:"#8b5cf6", fontFamily:"monospace", textDecoration:"none", border:"1px solid #4f46e5", borderRadius:4, padding:"3px 8px" }}>
                      Sign Up
                    </a>
                  )}
                  <select value={aff.folder_id || ""} onChange={e => moveToFolder(aff.id, e.target.value ? Number(e.target.value) : null)}
                    style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:4, color:"#a78bfa", padding:"3px 6px", cursor:"pointer", fontSize:10, fontFamily:"monospace", maxWidth:120 }}>
                    <option value="">Uncategorized</option>
                    {folders.map(f => <option key={f.id} value={f.id}>{f.name}</option>)}
                  </select>
                  <button onClick={() => { setEditingAffiliate(aff.id); setEditForm({ referral_url: aff.referral_url, commission: aff.commission }); }}
                    style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:4, color:"#635e80", padding:"3px 8px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>
                    Edit
                  </button>
                  {deleteConfirm === aff.id ? (
                    <>
                      <span style={{ fontSize:11, color:"#fca5a5", fontFamily:"monospace" }}>Delete?</span>
                      <button onClick={() => deleteAffiliate(aff.id)} style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:4, color:"#fca5a5", padding:"3px 8px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>Yes</button>
                      <button onClick={() => setDeleteConfirm(null)} style={{ background:"transparent", border:"1px solid #2a2448", borderRadius:4, color:"#635e80", padding:"3px 8px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>No</button>
                    </>
                  ) : (
                    <button onClick={() => setDeleteConfirm(aff.id)} style={{ background:"transparent", border:"1px solid #2a1010", borderRadius:4, color:"#7f1d1d", padding:"3px 8px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>Delete</button>
                  )}
                </div>
              )}
            </div>
          );
          })}
        </div>
      )}

      {activeSection === "generate" && (
        <div>
          <div style={{ ...sectionCard, borderColor:"#2a2448", background:"linear-gradient(180deg,#0e0c1a,#06050e)" }}>
            <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:10 }}>
              <span style={{ fontSize:28 }}>✨</span>
              <div>
                <div style={{ fontWeight:"bold", fontSize:17, color:"#e8e3f8" }}>Research & Generate Newsletter</div>
                <div style={{ fontSize:12, color:"#635e80", lineHeight:1.5 }}>
                  Type any topic and get a polished newsletter draft. The AI researches live web data, writes the newsletter, and creates social content — all in one step.
                </div>
              </div>
            </div>
            <div style={{ marginBottom:12, marginTop:14 }}>
              <label style={{ display:"block", fontSize:10, color:"#635e80", fontFamily:"monospace", marginBottom:5, textTransform:"uppercase", letterSpacing:".05em" }}>Topic</label>
              <input
                type="text"
                value={genTopic}
                onChange={e => setGenTopic(e.target.value)}
                onKeyDown={e => e.key === "Enter" && generateNewsletter()}
                placeholder='e.g. "AI trends", "remote work tips", "home gardening"'
                style={{ ...inputStyle, padding:"14px 18px", fontSize:14, borderColor:"#4f46e5", borderRadius:10 }}
              />
            </div>
            <div style={{ marginBottom:14 }}>
              <label style={{ display:"block", fontSize:10, color:"#635e80", fontFamily:"monospace", marginBottom:5, textTransform:"uppercase", letterSpacing:".05em" }}>Target Audience (optional)</label>
              <input
                type="text"
                value={genAudience}
                onChange={e => setGenAudience(e.target.value)}
                onKeyDown={e => e.key === "Enter" && generateNewsletter()}
                placeholder='e.g. "busy professionals who want actionable tips"'
                style={inputStyle}
              />
            </div>
            {genTopic.trim() && !generating && (
              <div style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:8, padding:"10px 14px", marginBottom:14 }}>
                <div style={{ fontSize:10, fontFamily:"monospace", color:"#8b5cf6", letterSpacing:1, marginBottom:6 }}>GENERATION PREVIEW</div>
                <div style={{ fontSize:12, color:"#b5b0ce", lineHeight:1.5 }}>
                  {(() => {
                    const topicAffiliates = savedAffiliates.filter(a => a.topic.toLowerCase() === genTopic.trim().toLowerCase());
                    const withAff = topicAffiliates.filter(a => a.has_affiliate === 1 || a.has_affiliate === true);
                    const withoutAff = topicAffiliates.filter(a => a.has_affiliate === 0 || a.has_affiliate === false);
                    const topicHistory = contentHistory.filter(h => h.topic.toLowerCase() === genTopic.trim().toLowerCase());
                    return (
                      <>
                        <span style={{ color:"#86efac" }}>{withAff.length}</span> with affiliate link{withAff.length !== 1 ? "s" : ""}
                        {withoutAff.length > 0 && (<>{" | "}<span style={{ color:"#fde047" }}>{withoutAff.length}</span> without affiliate{withoutAff.length !== 1 ? "s" : ""}</>)}
                        {" | "}
                        <span style={{ color:"#a78bfa" }}>{topicHistory.length}</span> previous issue{topicHistory.length !== 1 ? "s" : ""} tracked for uniqueness
                        {" | "}
                        <span style={{ color:"#86efac" }}>Live web research enabled</span>
                      </>
                    );
                  })()}
                </div>
              </div>
            )}
            <div style={{ display:"flex", gap:10, flexWrap:"wrap" }}>
              <button
                onClick={generateNewsletter}
                disabled={generating || !genTopic.trim()}
                style={{
                  background: generating ? "#1a1630" : "linear-gradient(135deg,#7c3aed,#4f46e5)",
                  border:"none", borderRadius:10, color:"#fff", padding:"14px 32px",
                  cursor: generating ? "not-allowed" : "pointer", fontSize:15, fontFamily:"monospace", fontWeight:"bold",
                  boxShadow: generating ? "none" : "0 4px 16px rgba(124,58,237,0.3)",
                }}
              >
                {generating ? "Generating..." : "Research & Generate"}
              </button>
            </div>
            <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", display:"flex", gap:16, flexWrap:"wrap", marginTop:12 }}>
              <span>Try: <span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setGenTopic("AI trends")}>AI trends</span></span>
              <span><span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setGenTopic("remote work tips")}>remote work tips</span></span>
              <span><span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setGenTopic("home gardening")}>home gardening</span></span>
              <span><span style={{ color:"#a78bfa", cursor:"pointer" }} onClick={() => setGenTopic("personal finance")}>personal finance</span></span>
            </div>
          </div>

          {generating && (
            <div style={{ ...sectionCard, padding:"28px 22px" }}>
              <div style={{ fontSize:12, color:"#a78bfa", fontFamily:"monospace", fontWeight:"bold", marginBottom:16, letterSpacing:1 }}>GENERATING YOUR NEWSLETTER</div>
              {[
                { id:"researching", icon:"🔍", label:"Researching live web data", desc:"Searching news, articles, and trends" },
                { id:"writing", icon:"✍️", label:"Writing newsletter", desc:"AI crafting your full newsletter with pro techniques" },
                { id:"social", icon:"📣", label:"Creating social content", desc:"Generating platform-specific social posts" },
              ].map((step, i) => {
                const isActive = genStep === step.id;
                const isPast = (genStep === "writing" && step.id === "researching") || (genStep === "social" && (step.id === "researching" || step.id === "writing"));
                return (
                  <div key={step.id} style={{ display:"flex", alignItems:"center", gap:12, marginBottom:14, opacity: isPast ? 0.5 : 1 }}>
                    <div style={{
                      width:32, height:32, borderRadius:"50%",
                      background: isPast ? "#0a1a0a" : isActive ? "linear-gradient(135deg,#7c3aed,#4f46e5)" : "#1c1830",
                      border: isPast ? "2px solid #16a34a" : isActive ? "2px solid #8b5cf6" : "2px solid #2a2448",
                      display:"flex", alignItems:"center", justifyContent:"center", fontSize:14, flexShrink:0,
                    }}>
                      {isPast ? "✓" : step.icon}
                    </div>
                    <div>
                      <div style={{ fontSize:13, color: isActive ? "#e8e3f8" : isPast ? "#86efac" : "#635e80", fontWeight: isActive ? "bold" : "normal" }}>{step.label}</div>
                      <div style={{ fontSize:11, color:"#635e80" }}>{step.desc}</div>
                    </div>
                    {isActive && (
                      <div style={{ marginLeft:"auto", width:60, height:4, background:"#1c1830", borderRadius:2, overflow:"hidden" }}>
                        <div style={{ height:"100%", background:"linear-gradient(90deg,#4f46e5,#8b5cf6,#4f46e5)", width:"80%", animation:"pulse 1.5s ease-in-out infinite" }} />
                      </div>
                    )}
                  </div>
                );
              })}
              <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", textAlign:"center", marginTop:8 }}>This usually takes 1-2 minutes. Please stay on this page.</div>
            </div>
          )}

          {genErr && (
            <div style={{ background:"#1c0808", border:"1px solid #7f1d1d", borderRadius:8, padding:"12px 16px", marginBottom:14, fontSize:12, color:"#fca5a5", fontFamily:"monospace" }}>
              {genErr}
            </div>
          )}

          {genResult && (
            <div>
              <div style={{ ...sectionCard, border:"1px solid #16a34a" }}>
                <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:4 }}>
                  <span style={{ fontSize:18 }}>✅</span>
                  <div style={{ flex:1 }}>
                    <div style={{ fontWeight:"bold", fontSize:14, color:"#86efac" }}>Newsletter Generated!</div>
                    <div style={{ fontSize:12, color:"#635e80" }}>
                      Saved as draft — topic: {genResult.topic} | Draft #{genResult.draft?.id}
                      {genResult.sources && (
                        <span style={{ marginLeft:8, fontSize:10, fontFamily:"monospace", padding:"2px 8px", borderRadius:4, background: genResult.sources.method === "web_research" ? "#0a1a0a" : "#1a150a", border: `1px solid ${genResult.sources.method === "web_research" ? "#16a34a" : "#ca8a04"}`, color: genResult.sources.method === "web_research" ? "#86efac" : "#fde047" }}>
                          {genResult.sources.method === "web_research" ? `${genResult.sources.webResults} web sources used` : "AI knowledge"}
                        </span>
                      )}
                    </div>
                  </div>
                </div>
              </div>

              <div style={{ ...sectionCard }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:10 }}>
                  <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>Newsletter Content</div>
                  <button onClick={() => { navigator.clipboard.writeText(genResult.newsletter || ""); }} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:6, color:"#a78bfa", padding:"5px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>Copy</button>
                </div>
                <div style={{ background:"#06050e", borderRadius:8, padding:"14px 18px", fontSize:12, lineHeight:1.7, color:"#b5b0ce", whiteSpace:"pre-wrap", maxHeight:400, overflowY:"auto", fontFamily:"monospace" }}>
                  {genResult.newsletter}
                </div>
              </div>

              <div style={{ ...sectionCard }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:10 }}>
                  <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>Social Media Content</div>
                  <button onClick={() => { navigator.clipboard.writeText(genResult.social || ""); }} style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:6, color:"#a78bfa", padding:"5px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}>Copy</button>
                </div>
                <div style={{ background:"#06050e", borderRadius:8, padding:"14px 18px", fontSize:12, lineHeight:1.7, color:"#b5b0ce", whiteSpace:"pre-wrap", maxHeight:300, overflowY:"auto", fontFamily:"monospace" }}>
                  {genResult.social}
                </div>
              </div>
            </div>
          )}

          {!generating && !genResult && customTopics.length > 0 && (
            <div style={sectionCard}>
              <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:10 }}>Your Saved Topics</div>
              <div style={{ fontSize:12, color:"#635e80", marginBottom:12, lineHeight:1.5 }}>
                Click any saved topic to quickly generate a fresh newsletter. Enable scheduling in Settings to auto-generate weekly.
              </div>
              <div style={{ display:"flex", gap:8, flexWrap:"wrap" }}>
                {customTopics.map(ct => (
                  <button key={ct.id} onClick={() => { setGenTopic(ct.name); if (ct.audience) setGenAudience(ct.audience); }}
                    style={{
                      background: genTopic === ct.name ? "#1e1a3a" : "#13102a",
                      border: `1px solid ${genTopic === ct.name ? "#8b5cf6" : "#2a2448"}`,
                      borderRadius:8, color: genTopic === ct.name ? "#a78bfa" : "#b5b0ce",
                      padding:"8px 14px", cursor:"pointer", fontSize:12, fontFamily:"monospace",
                      display:"flex", alignItems:"center", gap:6,
                    }}>
                    <span>{ct.icon || "📰"}</span>{ct.name}
                    {ct.schedule_enabled === 1 && <span style={{ fontSize:9, color:"#86efac" }}>AUTO</span>}
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>
      )}

      {activeSection === "history" && (
        <div>
          <div style={sectionCard}>
            <div style={{ fontWeight:"bold", fontSize:15, color:"#e8e3f8", marginBottom:6 }}>Content History</div>
            <div style={{ fontSize:12, color:"#635e80", marginBottom:14, lineHeight:1.6 }}>
              The AI tracks every newsletter it generates to make sure it never repeats itself. Here's a log of what's been created so far.
            </div>
          </div>

          {contentHistory.length === 0 ? (
            <div style={{ textAlign:"center", padding:"40px 20px", color:"#635e80", background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12 }}>
              <div style={{ fontSize:32, marginBottom:12 }}>📚</div>
              <div style={{ fontWeight:"bold", color:"#e8e3f8", marginBottom:6 }}>No content generated yet</div>
              <div style={{ fontSize:13 }}>Generate a custom newsletter and it will appear here</div>
            </div>
          ) : (
            contentHistory.map(h => (
              <div key={h.id} style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"14px 18px", marginBottom:10 }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:6 }}>
                  <div>
                    <span style={{ fontWeight:"bold", fontSize:13, color:"#e8e3f8" }}>{h.topic}</span>
                    <span style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", marginLeft:10 }}>
                      {new Date(h.created_at.endsWith("Z") ? h.created_at : h.created_at + "Z").toLocaleDateString("en-US", { month:"short", day:"numeric", year:"numeric" })}
                    </span>
                  </div>
                </div>
                {h.summary && <div style={{ fontSize:12, color:"#b5b0ce", marginBottom:4 }}>{h.summary}</div>}
                {h.headlines && (
                  <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace", lineHeight:1.5 }}>
                    {h.headlines.split("\n").slice(0, 3).map((hl, i) => (
                      <div key={i}>- {hl}</div>
                    ))}
                    {h.headlines.split("\n").length > 3 && <div>...and {h.headlines.split("\n").length - 3} more</div>}
                  </div>
                )}
              </div>
            ))
          )}
        </div>
      )}
    </div>
  );
}

// ── Chart Helper ──────────────────────────────────────────────────────────────
function ChartCanvas({ type, data, options, height }) {
  const canvasRef = useRef(null);
  const chartRef = useRef(null);

  useEffect(() => {
    if (!canvasRef.current || !window.Chart) return;
    if (chartRef.current) chartRef.current.destroy();
    chartRef.current = new window.Chart(canvasRef.current, {
      type,
      data,
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { labels: { color: "#b5b0ce", font: { family: "monospace", size: 11 } } } },
        scales: {
          x: { ticks: { color: "#635e80", font: { family: "monospace", size: 10 } }, grid: { color: "rgba(99,94,128,0.15)" } },
          y: { ticks: { color: "#635e80", font: { family: "monospace", size: 10 } }, grid: { color: "rgba(99,94,128,0.15)" }, beginAtZero: true },
        },
        ...options,
      },
    });
    return () => { if (chartRef.current) chartRef.current.destroy(); };
  }, [type, JSON.stringify(data), JSON.stringify(options)]);

  return React.createElement("div", { style: { height: height || 260, position: "relative" } },
    React.createElement("canvas", { ref: canvasRef })
  );
}

// ── Analytics Tab ─────────────────────────────────────────────────────────────
function AnalyticsTab() {
  const { user } = useAuth();
  const [overview, setOverview] = useState(null);
  const [genreData, setGenreData] = useState(null);
  const [earningsData, setEarningsData] = useState(null);
  const [affiliateData, setAffiliateData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [activeSection, setActiveSection] = useState("overview");

  const [earningForm, setEarningForm] = useState({ source: "beehiiv_ads", amount: "", description: "", month: new Date().toISOString().slice(0, 7) });
  const [earningMsg, setEarningMsg] = useState(null);
  const [savingEarning, setSavingEarning] = useState(false);

  const [clickForm, setClickForm] = useState({ affiliate_link_id: "", clicks: "", commissions: "", month: new Date().toISOString().slice(0, 7) });
  const [clickMsg, setClickMsg] = useState(null);
  const [savingClick, setSavingClick] = useState(false);

  const [beehiivEstimate, setBeehiivEstimate] = useState({ subscribers: 0, cpm: 0, issues_per_month: 4, open_rate: 40, estimated_monthly: 0 });
  const [estimateForm, setEstimateForm] = useState({ subscribers: "", cpm: "", issues_per_month: "4", open_rate: "40" });
  const [estimateMsg, setEstimateMsg] = useState(null);

  useEffect(() => { loadAll(); }, []);

  async function loadAll() {
    setLoading(true);
    try {
      const responses = await Promise.all([
        apiFetch("/api/analytics/overview"),
        apiFetch("/api/analytics/genre-performance"),
        apiFetch("/api/analytics/earnings"),
        apiFetch("/api/analytics/affiliate-performance"),
        apiFetch("/api/analytics/beehiiv-estimate"),
      ]);
      const [ov, gp, ea, af, be] = await Promise.all(responses.map(r => r.ok ? r.json() : null));
      if (ov) setOverview(ov);
      if (gp) setGenreData(gp);
      if (ea) setEarningsData(ea);
      if (af) setAffiliateData(af);
      if (be) {
        setBeehiivEstimate(be);
        setEstimateForm({ subscribers: String(be.subscribers || ""), cpm: String(be.cpm || ""), issues_per_month: String(be.issues_per_month || "4"), open_rate: String(be.open_rate || "40") });
      }
    } catch (err) {
      console.error("Analytics load error:", err);
    }
    setLoading(false);
  }

  async function addEarning(e) {
    e.preventDefault();
    setSavingEarning(true);
    setEarningMsg(null);
    try {
      const res = await apiFetch("/api/analytics/earnings", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(earningForm),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      setEarningMsg("Earning logged!");
      setEarningForm(f => ({ ...f, amount: "", description: "" }));
      loadAll();
    } catch (err) {
      setEarningMsg("Error: " + err.message);
    }
    setSavingEarning(false);
  }

  async function deleteEarning(id) {
    if (!confirm("Delete this earning entry?")) return;
    await apiFetch(`/api/analytics/earnings/${id}`, { method: "DELETE" });
    loadAll();
  }

  async function saveBeehiivEstimate(e) {
    e.preventDefault();
    setEstimateMsg(null);
    try {
      const res = await apiFetch("/api/analytics/beehiiv-estimate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(estimateForm),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      setBeehiivEstimate(data);
      setEstimateMsg("Estimate updated!");
    } catch (err) {
      setEstimateMsg("Error: " + err.message);
    }
  }

  async function logAffiliateClick(e) {
    e.preventDefault();
    setSavingClick(true);
    setClickMsg(null);
    try {
      const res = await apiFetch("/api/analytics/affiliate-click", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(clickForm),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      setClickMsg("Clicks/commissions logged!");
      setClickForm(f => ({ ...f, clicks: "", commissions: "" }));
      loadAll();
    } catch (err) {
      setClickMsg("Error: " + err.message);
    }
    setSavingClick(false);
  }

  const sectionCard = { background: "#0e0c1a", border: "1px solid #1c1830", borderRadius: 12, padding: "20px 22px", marginBottom: 14 };
  const inputStyle = { background: "#06050e", border: "1px solid #2a2448", borderRadius: 8, color: "#e8e3f8", padding: "10px 14px", fontSize: 13, fontFamily: "monospace", width: "100%", boxSizing: "border-box" };
  const labelStyle = { display: "block", fontSize: 10, color: "#635e80", fontFamily: "monospace", marginBottom: 4, textTransform: "uppercase", letterSpacing: ".05em" };

  if (loading) {
    return React.createElement("div", { style: { color: "#635e80", fontSize: 14, fontFamily: "monospace", textAlign: "center", padding: 40 } }, "Loading analytics...");
  }

  const SOURCE_LABELS = { beehiiv_ads: "Beehiiv Ads", affiliate: "Affiliate", sponsorship: "Sponsorship", digital_product: "Digital Product", other: "Other" };
  const SOURCE_COLORS = { beehiiv_ads: "#8b5cf6", affiliate: "#f59e0b", sponsorship: "#10b981", digital_product: "#3b82f6", other: "#6b7280" };

  const GENRE_COLORS = { health: "#10b981", church: "#8b5cf6", realestate: "#f59e0b", gaming: "#ef4444", finance: "#3b82f6" };

  const sections = [
    { id: "overview", label: "Overview" },
    { id: "genres", label: "Genre Performance" },
    { id: "earnings", label: "Revenue & Earnings" },
    { id: "affiliates", label: "Affiliate Tracking" },
  ];

  return React.createElement("div", null,
    React.createElement("div", { style: { display: "flex", gap: 8, marginBottom: 20, flexWrap: "wrap" } },
      sections.map(s =>
        React.createElement("button", {
          key: s.id,
          onClick: () => setActiveSection(s.id),
          style: {
            background: activeSection === s.id ? "linear-gradient(135deg,#7c3aed,#4f46e5)" : "#0e0c1a",
            border: activeSection === s.id ? "none" : "1px solid #2a2448",
            borderRadius: 8, color: activeSection === s.id ? "#fff" : "#635e80",
            padding: "8px 16px", cursor: "pointer", fontSize: 12, fontFamily: "monospace", fontWeight: "bold",
          }
        }, s.label)
      )
    ),

    activeSection === "overview" && React.createElement("div", null,
      React.createElement("div", { className: "analytics-summary-grid", style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 12, marginBottom: 20 } },
        [
          { label: "Total Drafts", value: overview?.totalDrafts || 0, icon: "📄", color: "#8b5cf6" },
          { label: "Published", value: overview?.publishedDrafts || 0, icon: "📡", color: "#10b981" },
          { label: "Beehiiv Posts", value: overview?.beehiivPublishes || 0, icon: "🐝", color: "#f59e0b" },
          { label: "Total Earnings", value: "$" + (overview?.totalEarnings || 0).toFixed(2), icon: "💰", color: "#86efac" },
          { label: "Top Genre", value: overview?.topGenre || "—", icon: "🏆", color: "#fbbf24" },
          { label: "Affiliate Clicks", value: overview?.affiliateClicks || 0, icon: "🔗", color: "#a78bfa" },
        ].map(card =>
          React.createElement("div", {
            key: card.label,
            style: { ...sectionCard, textAlign: "center", marginBottom: 0 }
          },
            React.createElement("div", { style: { fontSize: 24, marginBottom: 6 } }, card.icon),
            React.createElement("div", { style: { fontSize: 20, fontWeight: "bold", color: card.color, fontFamily: "monospace" } }, card.value),
            React.createElement("div", { style: { fontSize: 10, color: "#635e80", fontFamily: "monospace", marginTop: 4, textTransform: "uppercase", letterSpacing: 1 } }, card.label)
          )
        )
      ),

      genreData && genreData.genreStats.length > 0 && React.createElement("div", { style: sectionCard },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Drafts by Genre"),
        React.createElement(ChartCanvas, {
          type: "bar",
          height: 240,
          data: {
            labels: genreData.genreStats.map(g => g.genre),
            datasets: [
              { label: "Published", data: genreData.genreStats.map(g => g.published), backgroundColor: "#10b981" },
              { label: "Approved", data: genreData.genreStats.map(g => g.approved), backgroundColor: "#8b5cf6" },
              { label: "Pending", data: genreData.genreStats.map(g => g.pending), backgroundColor: "#f59e0b" },
            ],
          },
        })
      ),

      earningsData && earningsData.bySource.length > 0 && React.createElement("div", { style: sectionCard },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Earnings by Source"),
        React.createElement(ChartCanvas, {
          type: "doughnut",
          height: 220,
          data: {
            labels: earningsData.bySource.map(s => SOURCE_LABELS[s.source] || s.source),
            datasets: [{
              data: earningsData.bySource.map(s => s.total),
              backgroundColor: earningsData.bySource.map(s => SOURCE_COLORS[s.source] || "#6b7280"),
            }],
          },
          options: { scales: undefined },
        })
      )
    ),

    activeSection === "genres" && React.createElement("div", null,
      genreData && genreData.genreStats.length > 0 ? React.createElement("div", null,
        React.createElement("div", { style: sectionCard },
          React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Genre Performance Comparison"),
          React.createElement(ChartCanvas, {
            type: "bar",
            height: 280,
            data: {
              labels: genreData.genreStats.map(g => g.genre),
              datasets: [
                { label: "Total", data: genreData.genreStats.map(g => g.total), backgroundColor: "#4f46e5" },
                { label: "Published", data: genreData.genreStats.map(g => g.published), backgroundColor: "#10b981" },
                { label: "Approved", data: genreData.genreStats.map(g => g.approved), backgroundColor: "#8b5cf6" },
                { label: "Pending", data: genreData.genreStats.map(g => g.pending), backgroundColor: "#f59e0b" },
              ],
            },
          })
        ),

        genreData.monthlyActivity.length > 0 && React.createElement("div", { style: sectionCard },
          React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Monthly Activity Trend"),
          (() => {
            const months = [...new Set(genreData.monthlyActivity.map(m => m.month))].sort();
            const genres = [...new Set(genreData.monthlyActivity.map(m => m.genre))];
            const colorPalette = ["#8b5cf6", "#10b981", "#f59e0b", "#ef4444", "#3b82f6", "#a855f7", "#f97316", "#06b6d4"];
            return React.createElement(ChartCanvas, {
              type: "line",
              height: 260,
              data: {
                labels: months,
                datasets: genres.map((g, i) => ({
                  label: g,
                  data: months.map(m => {
                    const entry = genreData.monthlyActivity.find(a => a.month === m && a.genre === g);
                    return entry ? entry.count : 0;
                  }),
                  borderColor: GENRE_COLORS[g] || colorPalette[i % colorPalette.length],
                  backgroundColor: "transparent",
                  tension: 0.3,
                })),
              },
            });
          })()
        ),

        genreData.starterGenreStats.length > 0 && genreData.customGenreStats.length > 0 && React.createElement("div", { style: sectionCard },
          React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Starter vs Custom Genres"),
          React.createElement("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 } },
            React.createElement("div", null,
              React.createElement("div", { style: { fontSize: 10, color: "#635e80", fontFamily: "monospace", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 } }, "Starter Genres"),
              genreData.starterGenreStats.map(g =>
                React.createElement("div", { key: g.genre, style: { display: "flex", justifyContent: "space-between", padding: "6px 0", borderBottom: "1px solid #1c1830" } },
                  React.createElement("span", { style: { color: "#e8e3f8", fontSize: 13 } }, g.genre),
                  React.createElement("span", { style: { color: "#86efac", fontFamily: "monospace", fontSize: 12 } }, g.total + " drafts")
                )
              )
            ),
            React.createElement("div", null,
              React.createElement("div", { style: { fontSize: 10, color: "#635e80", fontFamily: "monospace", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 } }, "Custom/Discovered"),
              genreData.customGenreStats.map(g =>
                React.createElement("div", { key: g.genre, style: { display: "flex", justifyContent: "space-between", padding: "6px 0", borderBottom: "1px solid #1c1830" } },
                  React.createElement("span", { style: { color: "#e8e3f8", fontSize: 13 } }, g.genre),
                  React.createElement("span", { style: { color: "#fbbf24", fontFamily: "monospace", fontSize: 12 } }, g.total + " drafts")
                )
              )
            )
          )
        ),

        React.createElement("div", { style: sectionCard },
          React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 12 } }, "Genre Details"),
          genreData.genreStats.map(g =>
            React.createElement("div", { key: g.genre, style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "10px 0", borderBottom: "1px solid #1c1830" } },
              React.createElement("div", null,
                React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8" } }, g.genre),
                React.createElement("div", { style: { fontSize: 11, color: "#635e80", fontFamily: "monospace" } }, "First: " + (g.first_draft || "—").slice(0, 10) + " | Last: " + (g.last_draft || "—").slice(0, 10))
              ),
              React.createElement("div", { style: { display: "flex", gap: 16, textAlign: "center" } },
                React.createElement("div", null,
                  React.createElement("div", { style: { fontSize: 16, fontWeight: "bold", color: "#4f46e5" } }, g.total),
                  React.createElement("div", { style: { fontSize: 9, color: "#635e80", fontFamily: "monospace" } }, "TOTAL")
                ),
                React.createElement("div", null,
                  React.createElement("div", { style: { fontSize: 16, fontWeight: "bold", color: "#10b981" } }, g.published),
                  React.createElement("div", { style: { fontSize: 9, color: "#635e80", fontFamily: "monospace" } }, "PUB")
                ),
                React.createElement("div", null,
                  React.createElement("div", { style: { fontSize: 16, fontWeight: "bold", color: "#8b5cf6" } }, g.approved),
                  React.createElement("div", { style: { fontSize: 9, color: "#635e80", fontFamily: "monospace" } }, "APPR")
                )
              )
            )
          )
        )
      ) : React.createElement("div", { style: { ...sectionCard, textAlign: "center", padding: 40 } },
        React.createElement("div", { style: { fontSize: 32, marginBottom: 12 } }, "📊"),
        React.createElement("div", { style: { color: "#635e80", fontSize: 14 } }, "No genre data yet. Generate some newsletters to see performance charts!")
      )
    ),

    activeSection === "earnings" && React.createElement("div", null,
      React.createElement("div", { style: { ...sectionCard, border: "1px solid #059669" } },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#86efac", marginBottom: 6 } }, "Beehiiv Estimated Earnings Calculator"),
        React.createElement("div", { style: { fontSize: 11, color: "#635e80", fontFamily: "monospace", marginBottom: 14 } }, "Estimate monthly ad revenue based on your subscriber count and CPM rate"),
        React.createElement("form", { onSubmit: saveBeehiivEstimate, style: { display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 12, marginBottom: 14 } },
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Subscribers"),
            React.createElement("input", {
              type: "number", min: "0", required: true,
              value: estimateForm.subscribers,
              onChange: e => setEstimateForm(f => ({ ...f, subscribers: e.target.value })),
              placeholder: "5000", style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "CPM Rate ($)"),
            React.createElement("input", {
              type: "number", step: "0.01", min: "0", required: true,
              value: estimateForm.cpm,
              onChange: e => setEstimateForm(f => ({ ...f, cpm: e.target.value })),
              placeholder: "5.00", style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Issues/Month"),
            React.createElement("input", {
              type: "number", min: "1", max: "30",
              value: estimateForm.issues_per_month,
              onChange: e => setEstimateForm(f => ({ ...f, issues_per_month: e.target.value })),
              style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Open Rate (%)"),
            React.createElement("input", {
              type: "number", min: "1", max: "100",
              value: estimateForm.open_rate,
              onChange: e => setEstimateForm(f => ({ ...f, open_rate: e.target.value })),
              style: inputStyle
            })
          )
        ),
        React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 16 } },
          React.createElement("button", {
            type: "submit", onClick: saveBeehiivEstimate,
            style: { background: "linear-gradient(135deg,#059669,#10b981)", border: "none", borderRadius: 8, color: "#fff", padding: "10px 24px", cursor: "pointer", fontSize: 13, fontFamily: "monospace", fontWeight: "bold" }
          }, "Calculate & Save"),
          React.createElement("div", { style: { fontSize: 18, fontWeight: "bold", color: "#86efac", fontFamily: "monospace" } },
            "Est. Monthly: $" + (beehiivEstimate.estimated_monthly || 0).toFixed(2)
          ),
          estimateMsg && React.createElement("span", { style: { fontSize: 12, color: estimateMsg.startsWith("Error") ? "#fca5a5" : "#86efac", fontFamily: "monospace" } }, estimateMsg)
        )
      ),

      React.createElement("div", { style: { ...sectionCard, border: "1px solid #4f46e5" } },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Log Earning"),
        React.createElement("form", { onSubmit: addEarning, style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 } },
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Source"),
            React.createElement("select", {
              value: earningForm.source,
              onChange: e => setEarningForm(f => ({ ...f, source: e.target.value })),
              style: inputStyle
            },
              React.createElement("option", { value: "beehiiv_ads" }, "Beehiiv Ads"),
              React.createElement("option", { value: "affiliate" }, "Affiliate Commission"),
              React.createElement("option", { value: "sponsorship" }, "Sponsorship"),
              React.createElement("option", { value: "digital_product" }, "Digital Product"),
              React.createElement("option", { value: "other" }, "Other")
            )
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Amount ($)"),
            React.createElement("input", {
              type: "number", step: "0.01", min: "0", required: true,
              value: earningForm.amount,
              onChange: e => setEarningForm(f => ({ ...f, amount: e.target.value })),
              placeholder: "0.00", style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Description"),
            React.createElement("input", {
              type: "text",
              value: earningForm.description,
              onChange: e => setEarningForm(f => ({ ...f, description: e.target.value })),
              placeholder: "e.g. March ad revenue", style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Month"),
            React.createElement("input", {
              type: "month",
              value: earningForm.month,
              onChange: e => setEarningForm(f => ({ ...f, month: e.target.value })),
              style: inputStyle
            })
          ),
          React.createElement("div", { style: { gridColumn: "1 / -1" } },
            React.createElement("button", {
              type: "submit", disabled: savingEarning,
              style: { background: "linear-gradient(135deg,#7c3aed,#4f46e5)", border: "none", borderRadius: 8, color: "#fff", padding: "10px 24px", cursor: savingEarning ? "not-allowed" : "pointer", fontSize: 13, fontFamily: "monospace", fontWeight: "bold", opacity: savingEarning ? 0.7 : 1 }
            }, savingEarning ? "Saving..." : "Log Earning"),
            earningMsg && React.createElement("span", { style: { marginLeft: 12, fontSize: 12, color: earningMsg.startsWith("Error") ? "#fca5a5" : "#86efac", fontFamily: "monospace" } }, earningMsg)
          )
        )
      ),

      React.createElement("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 } },
        React.createElement("div", { style: sectionCard },
          React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Earnings by Source"),
          earningsData && earningsData.bySource.length > 0
            ? earningsData.bySource.map(s =>
                React.createElement("div", { key: s.source, style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 0", borderBottom: "1px solid #1c1830" } },
                  React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } },
                    React.createElement("div", { style: { width: 10, height: 10, borderRadius: "50%", background: SOURCE_COLORS[s.source] || "#6b7280" } }),
                    React.createElement("span", { style: { color: "#e8e3f8", fontSize: 13 } }, SOURCE_LABELS[s.source] || s.source)
                  ),
                  React.createElement("span", { style: { color: "#86efac", fontFamily: "monospace", fontSize: 13, fontWeight: "bold" } }, "$" + s.total.toFixed(2))
                )
              )
            : React.createElement("div", { style: { color: "#635e80", fontSize: 12, fontFamily: "monospace" } }, "No earnings logged yet")
        ),

        React.createElement("div", { style: sectionCard },
          React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Monthly Breakdown"),
          earningsData && earningsData.byMonth.length > 0
            ? React.createElement(ChartCanvas, {
                type: "bar",
                height: 200,
                data: {
                  labels: earningsData.byMonth.map(m => m.month).reverse(),
                  datasets: [{ label: "Earnings ($)", data: earningsData.byMonth.map(m => m.total).reverse(), backgroundColor: "#8b5cf6" }],
                },
              })
            : React.createElement("div", { style: { color: "#635e80", fontSize: 12, fontFamily: "monospace" } }, "No monthly data yet")
        )
      ),

      earningsData && earningsData.entries.length > 0 && React.createElement("div", { style: sectionCard },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 12 } }, "Recent Entries"),
        earningsData.entries.slice(0, 20).map(entry =>
          React.createElement("div", { key: entry.id, style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 0", borderBottom: "1px solid #1c1830" } },
            React.createElement("div", null,
              React.createElement("div", { style: { fontSize: 13, color: "#e8e3f8" } }, (SOURCE_LABELS[entry.source] || entry.source) + (entry.description ? " — " + entry.description : "")),
              React.createElement("div", { style: { fontSize: 10, color: "#635e80", fontFamily: "monospace" } }, entry.month + " | " + (entry.created_at || "").slice(0, 10))
            ),
            React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } },
              React.createElement("span", { style: { color: "#86efac", fontFamily: "monospace", fontSize: 14, fontWeight: "bold" } }, "$" + entry.amount.toFixed(2)),
              React.createElement("button", {
                onClick: () => deleteEarning(entry.id),
                style: { background: "none", border: "none", color: "#ef4444", cursor: "pointer", fontSize: 14, padding: "2px 6px" }
              }, "×")
            )
          )
        )
      )
    ),

    activeSection === "affiliates" && React.createElement("div", null,
      React.createElement("div", { style: { ...sectionCard, border: "1px solid #f59e0b" } },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Log Affiliate Clicks & Commissions"),
        React.createElement("form", { onSubmit: logAffiliateClick, style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 } },
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Affiliate Link"),
            React.createElement("select", {
              value: clickForm.affiliate_link_id,
              onChange: e => setClickForm(f => ({ ...f, affiliate_link_id: e.target.value })),
              required: true, style: inputStyle
            },
              React.createElement("option", { value: "" }, "Select a link..."),
              affiliateData && affiliateData.performance.map(link =>
                React.createElement("option", { key: link.id, value: link.id }, link.name + " (" + link.topic + ")")
              )
            )
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Month"),
            React.createElement("input", {
              type: "month", value: clickForm.month,
              onChange: e => setClickForm(f => ({ ...f, month: e.target.value })),
              style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Clicks"),
            React.createElement("input", {
              type: "number", min: "0",
              value: clickForm.clicks,
              onChange: e => setClickForm(f => ({ ...f, clicks: e.target.value })),
              placeholder: "0", style: inputStyle
            })
          ),
          React.createElement("div", null,
            React.createElement("label", { style: labelStyle }, "Commission ($)"),
            React.createElement("input", {
              type: "number", step: "0.01", min: "0",
              value: clickForm.commissions,
              onChange: e => setClickForm(f => ({ ...f, commissions: e.target.value })),
              placeholder: "0.00", style: inputStyle
            })
          ),
          React.createElement("div", { style: { gridColumn: "1 / -1" } },
            React.createElement("button", {
              type: "submit", disabled: savingClick,
              style: { background: "linear-gradient(135deg,#f59e0b,#d97706)", border: "none", borderRadius: 8, color: "#fff", padding: "10px 24px", cursor: savingClick ? "not-allowed" : "pointer", fontSize: 13, fontFamily: "monospace", fontWeight: "bold", opacity: savingClick ? 0.7 : 1 }
            }, savingClick ? "Saving..." : "Log Click Data"),
            clickMsg && React.createElement("span", { style: { marginLeft: 12, fontSize: 12, color: clickMsg.startsWith("Error") ? "#fca5a5" : "#86efac", fontFamily: "monospace" } }, clickMsg)
          )
        )
      ),

      affiliateData && affiliateData.monthlyClicks.length > 0 && React.createElement("div", { style: sectionCard },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 14 } }, "Monthly Affiliate Trends"),
        React.createElement(ChartCanvas, {
          type: "line",
          height: 240,
          data: {
            labels: affiliateData.monthlyClicks.map(m => m.month).reverse(),
            datasets: [
              { label: "Clicks", data: affiliateData.monthlyClicks.map(m => m.clicks).reverse(), borderColor: "#f59e0b", backgroundColor: "transparent", tension: 0.3, yAxisID: "y" },
              { label: "Commissions ($)", data: affiliateData.monthlyClicks.map(m => m.commissions).reverse(), borderColor: "#10b981", backgroundColor: "transparent", tension: 0.3, yAxisID: "y1" },
            ],
          },
          options: {
            scales: {
              x: { ticks: { color: "#635e80", font: { family: "monospace", size: 10 } }, grid: { color: "rgba(99,94,128,0.15)" } },
              y: { type: "linear", position: "left", ticks: { color: "#f59e0b", font: { family: "monospace", size: 10 } }, grid: { color: "rgba(99,94,128,0.15)" }, beginAtZero: true },
              y1: { type: "linear", position: "right", ticks: { color: "#10b981", font: { family: "monospace", size: 10 } }, grid: { drawOnChartArea: false }, beginAtZero: true },
            },
          },
        })
      ),

      React.createElement("div", { style: sectionCard },
        React.createElement("div", { style: { fontWeight: "bold", fontSize: 14, color: "#e8e3f8", marginBottom: 12 } }, "Affiliate Link Performance"),
        affiliateData && affiliateData.performance.length > 0
          ? affiliateData.performance.map(link =>
              React.createElement("div", { key: link.id, style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "10px 0", borderBottom: "1px solid #1c1830" } },
                React.createElement("div", null,
                  React.createElement("div", { style: { fontWeight: "bold", fontSize: 13, color: "#e8e3f8" } }, link.name),
                  React.createElement("div", { style: { fontSize: 11, color: "#635e80", fontFamily: "monospace" } }, link.topic)
                ),
                React.createElement("div", { style: { display: "flex", gap: 20, textAlign: "center" } },
                  React.createElement("div", null,
                    React.createElement("div", { style: { fontSize: 16, fontWeight: "bold", color: "#f59e0b" } }, link.total_clicks),
                    React.createElement("div", { style: { fontSize: 9, color: "#635e80", fontFamily: "monospace" } }, "CLICKS")
                  ),
                  React.createElement("div", null,
                    React.createElement("div", { style: { fontSize: 16, fontWeight: "bold", color: "#10b981" } }, "$" + (link.total_commissions || 0).toFixed(2)),
                    React.createElement("div", { style: { fontSize: 9, color: "#635e80", fontFamily: "monospace" } }, "EARNED")
                  )
                )
              )
            )
          : React.createElement("div", { style: { color: "#635e80", fontSize: 12, fontFamily: "monospace", textAlign: "center", padding: 20 } }, "No affiliate links yet. Add links from the Discover tab, then log clicks and commissions here.")
      )
    )
  );
}

// ── Root App ──────────────────────────────────────────────────────────────────
function AppInner() {
  const { user } = useAuth();
  const validTabs = ["engine","prompts","drafts","discover","monetize","affiliates","analytics","guide","settings","account"];
  function tabFromHash() {
    const h = window.location.hash.replace("#","").split("?")[0].toLowerCase();
    return validTabs.includes(h) ? h : "engine";
  }
  const [tab, setTab] = useState(() => {
    try {
      const nav = localStorage.getItem("onboarding_navigate");
      if (nav) {
        localStorage.removeItem("onboarding_navigate");
        return validTabs.includes(nav) ? nav : tabFromHash();
      }
    } catch(e) {}
    return tabFromHash();
  });
  useEffect(() => {
    function onHash() { setTab(tabFromHash()); }
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  const [activeGenre, setActiveGenre] = useState(() => {
    try {
      const g = localStorage.getItem("onboarding_genre");
      if (g) {
        localStorage.removeItem("onboarding_genre");
        return g;
      }
    } catch(e) {}
    return "health";
  });
  const [outputs, setOutputs]     = useState({});
  const [gLoading, setGLoading]   = useState(null);
  const [copied, setCopied]       = useState({});
  const [templates, setTemplates] = useState([]);
  const [activeTemplate, setActiveTemplate] = useState(null);
  const [tmplLoading, setTmplLoading] = useState(false);
  const [showTmplMgmt, setShowTmplMgmt] = useState(false);

  const genre = GENRES.find(g => g.id === activeGenre) || GENRES[0];
  const isPro = user?.tier === "pro" || user?.tier === "elite";
  const isElite = user?.tier === "elite";

  useEffect(() => { loadTemplates(); }, []);

  async function loadTemplates() {
    setTmplLoading(true);
    try {
      const res = await apiFetch("/api/templates");
      if (res.ok) {
        const data = await res.json();
        setTemplates(data.templates || []);
      }
    } catch (e) {
      console.error("Failed to load templates:", e);
    }
    setTmplLoading(false);
  }

  async function deleteTemplate(id) {
    if (!confirm("Delete this template?")) return;
    try {
      const res = await apiFetch(`/api/templates/${id}`, { method: "DELETE" });
      if (!res.ok) {
        const data = await res.json();
        alert("Failed to delete template: " + (data.error || "Unknown error"));
        return;
      }
      if (activeTemplate && activeTemplate.id === id) setActiveTemplate(null);
      loadTemplates();
    } catch (e) {
      alert("Failed to delete template: " + e.message);
    }
  }

  function selectGenre(id) {
    if (id === activeGenre) return;
    Object.keys(OUTPUTS).forEach(k => delete OUTPUTS[k]);
    setOutputs({});
    setGLoading(null);
    setActiveGenre(id);
  }

  function cp(key, text) {
    navigator.clipboard.writeText(text).catch(()=>{});
    setCopied(p=>({...p,[key]:true}));
    setTimeout(()=>setCopied(p=>({...p,[key]:false})),2000);
  }

  const isOwner = user && user.role === "owner";
  const TABS  = [
    ["engine","⚡ Engine"],
    ["discover","🌐 Discover"],
    ["drafts","📁 Drafts"],
    ["prompts","📋 Prompts"],
    ["monetize","💰 Monetize"],
    ["affiliates","🔗 Affiliates"],
    ["analytics","📊 Analytics"],
    ["guide","🗺 Guide"],
    ...(isOwner ? [["settings","⚙️ Settings"]] : []),
    ["account","👤 Account"],
  ];

  const STEPS = [
    {id:"research",num:"01",icon:"🔍",label:"Research",         desc:"Fetch this week's top headlines + summarize"},
    {id:"write",   num:"02",icon:"✍️", label:"Write Newsletter", desc:"Generate your full newsletter issue"},
    {id:"social",  num:"03",icon:"📣",label:"Social Content",   desc:"Create platform-specific posts to grow subscribers"},
    {id:"pitch",   num:"04",icon:"💰",label:"Sponsor Pitch",    desc:"Cold email to land a paying sponsor"},
  ];

  const PROMPTS = STEPS.map(s => ({
    key: s.id,
    label: `${s.icon} ${s.label} Prompt`,
    text: getPrompt(s.id, activeGenre, []),
  }));

  const wrap  = { maxWidth:820, margin:"0 auto", padding:"28px 16px 60px" };
  const intro = { color:"#635e80", fontSize:13, lineHeight:1.7, marginBottom:24, marginTop:0 };

  const MOBILE_TABS = [
    ["engine","⚡","Engine"],
    ["discover","🌐","Discover"],
    ["drafts","📁","Drafts"],
    ["monetize","💰","Monetize"],
    ["more","☰","More"],
  ];

  const MORE_TABS = [
    ["prompts","📋","Prompts"],
    ["affiliates","🔗","Affiliates"],
    ["analytics","📊","Analytics"],
    ["guide","🗺️","Guide"],
    ["settings","⚙️","Settings"],
    ["account","👤","Account"],
  ];

  const [moreOpen, setMoreOpen] = React.useState(false);

  return (
    <div className="app-content" style={{ minHeight:"100vh", background:"#07060f", color:"#b5b0ce", fontFamily:"Georgia, serif" }}>

      {/* Header */}
      <div style={{ background:"linear-gradient(180deg,#100d1f 0%,#07060f 100%)", borderBottom:"1px solid #1c1830", padding:"16px 16px 12px", position:"relative", overflow:"hidden" }}>
        <div style={{ position:"absolute", inset:0, background:"radial-gradient(ellipse at 50% -10%,rgba(100,60,240,.13) 0%,transparent 60%)", pointerEvents:"none" }} />
        <div className="header-inner" style={{ maxWidth:820, margin:"0 auto", display:"flex", alignItems:"center", justifyContent:"space-between", flexWrap:"wrap", gap:10 }}>
          <div>
            <div style={{ display:"inline-block", background:"linear-gradient(90deg,#7c3aed,#4f46e5)", borderRadius:4, padding:"2px 8px", fontSize:8, fontFamily:"monospace", letterSpacing:3, color:"#fff", fontWeight:"bold", marginBottom:4 }}>WEEKLY NEWSLETTER ENGINE</div>
            <h1 style={{ fontSize:22, fontWeight:"bold", background:"linear-gradient(135deg,#fff 30%,#a78bfa 100%)", WebkitBackgroundClip:"text", WebkitTextFillColor:"transparent", letterSpacing:-0.5, margin:0 }}>Weekly Newsletter</h1>
          </div>
          <div className="header-right" style={{ display:"flex", alignItems:"center", gap:12 }}>
            <span style={{ background: isElite ? "linear-gradient(135deg,#f59e0b,#d97706)" : isPro ? "linear-gradient(135deg,#7c3aed,#4f46e5)" : "#13102a", border: isPro ? "none" : "1px solid #2a2448", borderRadius:6, color: isPro ? "#fff" : "#635e80", padding:"3px 12px", fontSize:10, fontFamily:"monospace", fontWeight:"bold" }}>{isElite ? "👑 ELITE" : isPro ? "PRO" : "FREE"}</span>
            <span style={{ fontSize:12, color:"#635e80", fontFamily:"monospace", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap", maxWidth:180 }}>{user?.email}</span>
          </div>
        </div>
      </div>

      {/* Desktop Tabs */}
      <div className="desktop-tabs">
        {TABS.map(([id,lbl])=>(
          <button key={id} onClick={()=>{setTab(id);window.location.hash=id;}} style={{ background:"none", border:"none", borderBottom: tab===id?"2px solid #8b5cf6":"2px solid transparent", color: tab===id?"#a78bfa":"#635e80", padding:"13px 14px", cursor:"pointer", fontSize:11, fontFamily:"monospace", letterSpacing:.5, whiteSpace:"nowrap", transition:"all .2s" }}>{lbl}</button>
        ))}
      </div>

      {/* Bottom Nav (Mobile) */}
      <nav className="bottom-nav">
        {MOBILE_TABS.map(([id,icon,label])=>{
          const isMoreActive = id === "more" && MORE_TABS.some(([tid])=>tid===tab);
          return (
            <button key={id} className={(tab===id||isMoreActive)?"active":""} onClick={()=>{
              if (id === "more") { setMoreOpen(!moreOpen); }
              else { setTab(id); window.location.hash=id; setMoreOpen(false); }
            }}>
              <span className="nav-icon">{icon}</span>
              <span>{label}</span>
            </button>
          );
        })}
        {moreOpen && (
          <div className="more-menu" style={{ position:"absolute", bottom:"100%", right:0, background:"#0a0817", border:"1px solid #1c1830", borderRadius:"12px 12px 0 0", padding:"8px 0", minWidth:180, boxShadow:"0 -4px 20px rgba(0,0,0,.5)" }}>
            {MORE_TABS.map(([id,icon,label])=>{
              if (id === "settings" && !isOwner) return null;
              return (
                <button key={id} onClick={()=>{setTab(id);window.location.hash=id;setMoreOpen(false);}} style={{ display:"flex", alignItems:"center", gap:10, width:"100%", background: tab===id?"#13102a":"none", border:"none", color: tab===id?"#a78bfa":"#b5b0ce", padding:"10px 16px", cursor:"pointer", fontSize:13, fontFamily:"monospace" }}>
                  <span style={{ fontSize:16 }}>{icon}</span>
                  <span>{label}</span>
                </button>
              );
            })}
          </div>
        )}
      </nav>

      {/* Genre Selector — shown on engine and prompts tabs */}
      {(tab === "engine" || tab === "prompts") && (
        <div style={{ background:"#09071a", borderBottom:"1px solid #1c1830", padding:"14px 16px" }}>
          <div style={{ maxWidth:820, margin:"0 auto" }}>
            <div style={{ fontSize:10, fontFamily:"monospace", color:"#635e80", letterSpacing:2, marginBottom:10 }}>SELECT YOUR NEWSLETTER GENRE</div>
            <div className="genre-selector-wrap" style={{ overflow:"auto" }}>
            <div style={{ display:"flex", gap:8, flexWrap:"wrap" }}>
              {GENRES.map(g => (
                <button
                  key={g.id}
                  onClick={() => selectGenre(g.id)}
                  style={{
                    background: activeGenre === g.id ? g.color : "transparent",
                    border: `1px solid ${activeGenre === g.id ? g.color : "#2a2448"}`,
                    borderRadius: 20,
                    color: activeGenre === g.id ? "#fff" : "#635e80",
                    padding: "6px 14px",
                    cursor: "pointer",
                    fontSize: 12,
                    fontFamily: "monospace",
                    fontWeight: activeGenre === g.id ? "bold" : "normal",
                    transition: "all .2s",
                    display: "flex",
                    alignItems: "center",
                    gap: 6,
                  }}
                >
                  <span>{g.icon}</span>
                  <span>{g.name}</span>
                </button>
              ))}
            </div>
            </div>
            {activeGenre && (
              <div style={{ marginTop:10, fontSize:12, color:"#635e80" }}>
                <span style={{ color: genre.color, fontWeight:"bold" }}>{genre.icon} {genre.name}</span>
                {" — "}{genre.desc}
              </div>
            )}
          </div>
        </div>
      )}

      <div className="wrap-content" style={wrap}>

        {/* ENGINE */}
        {tab==="engine" && <>
          {!isPro && user && (
            <div style={{ background:"#0a0817", border:"1px solid #2a2448", borderRadius:10, padding:"10px 16px", marginBottom:16, display:"flex", alignItems:"center", justifyContent:"space-between", flexWrap:"wrap", gap:8 }}>
              <div style={{ fontSize:12, color:"#635e80", fontFamily:"monospace" }}>
                Free plan: {user.generations_this_week || 0}/{user.generations_limit || 2} generations used this week
              </div>
              <button onClick={() => { setTab("account"); window.location.hash = "account"; }} style={{ background:"linear-gradient(135deg,#7c3aed,#4f46e5)", border:"none", borderRadius:6, color:"#fff", padding:"5px 14px", cursor:"pointer", fontSize:11, fontFamily:"monospace", fontWeight:"bold" }}>Upgrade</button>
            </div>
          )}
          <p style={intro}>
            Select your genre above, then run each step in order. The AI fetches live news and writes everything — you review and publish. Takes about 5 minutes.
          </p>
          <div style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:12, padding:"14px 18px", marginBottom:14 }}>
            <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between", gap:10, flexWrap:"wrap" }}>
              <div style={{ display:"flex", alignItems:"center", gap:10, flex:1, minWidth:0 }}>
                <span style={{ fontSize:14 }}>📐</span>
                {templates.length > 0 ? (
                  <select
                    value={activeTemplate ? activeTemplate.id : ""}
                    onChange={e => {
                      const id = parseInt(e.target.value);
                      setActiveTemplate(id ? templates.find(t => t.id === id) || null : null);
                    }}
                    style={{ background:"#06050e", border:"1px solid #2a2448", borderRadius:6, color:"#e8e3f8", padding:"7px 12px", fontSize:12, fontFamily:"monospace", flex:1, minWidth:0, maxWidth:300 }}
                  >
                    <option value="">No template (default style)</option>
                    {templates.filter(t => !t.genre || t.genre === activeGenre || t.genre === "").map(t => (
                      <option key={t.id} value={t.id}>{t.name}{t.genre ? ` (${t.genre})` : ""}</option>
                    ))}
                    {templates.filter(t => t.genre && t.genre !== activeGenre && t.genre !== "").length > 0 && (
                      <option disabled>── Other genres ──</option>
                    )}
                    {templates.filter(t => t.genre && t.genre !== activeGenre && t.genre !== "").map(t => (
                      <option key={t.id} value={t.id}>{t.name} ({t.genre})</option>
                    ))}
                  </select>
                ) : (
                  <span style={{ fontSize:12, color:"#635e80", fontFamily:"monospace" }}>No templates yet — save one from your Drafts tab</span>
                )}
              </div>
              {activeTemplate && (
                <div style={{ fontSize:11, color:"#a5b4fc", fontFamily:"monospace", display:"flex", alignItems:"center", gap:6 }}>
                  <span style={{ color:"#86efac" }}>✓</span> Template: {activeTemplate.name}
                </div>
              )}
              <button
                onClick={() => setShowTmplMgmt(!showTmplMgmt)}
                style={{ background:"#13102a", border:"1px solid #2a2448", borderRadius:6, color:"#635e80", padding:"5px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}
              >{templates.length > 0 ? "Manage" : "View"}</button>
            </div>
          </div>
          {showTmplMgmt && (
            <div style={{ background:"#0e0c1a", border:"1px solid #6366f1", borderRadius:12, padding:"18px", marginBottom:14 }}>
              <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:14 }}>
                <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>📐 My Templates</div>
                <button onClick={() => setShowTmplMgmt(false)} style={{ background:"none", border:"none", color:"#635e80", cursor:"pointer", fontSize:16 }}>×</button>
              </div>
              {templates.length === 0 ? (
                <div style={{ fontSize:12, color:"#635e80", fontFamily:"monospace", padding:"12px 0" }}>No templates yet. Save an approved or published draft as a template to get started.</div>
              ) : (
                templates.map(t => (
                  <div key={t.id} style={{ display:"flex", justifyContent:"space-between", alignItems:"center", padding:"10px 0", borderBottom:"1px solid #1c1830" }}>
                    <div>
                      <div style={{ fontSize:13, color:"#e8e3f8", fontWeight:"bold" }}>{t.name}</div>
                      <div style={{ fontSize:11, color:"#635e80", fontFamily:"monospace" }}>
                        {t.genre || "Any genre"} · Created {formatDate(t.created_at)}
                        {t.instructions && <span> · {t.instructions.slice(0, 60)}...</span>}
                      </div>
                    </div>
                    <div style={{ display:"flex", gap:8 }}>
                      <button
                        onClick={() => { setActiveTemplate(t); setShowTmplMgmt(false); }}
                        style={{ background:"#13102a", border:"1px solid #4f46e5", borderRadius:6, color:"#a78bfa", padding:"4px 12px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}
                      >Use</button>
                      <button
                        onClick={() => deleteTemplate(t.id)}
                        style={{ background:"none", border:"1px solid #2a1010", borderRadius:6, color:"#7f1d1d", padding:"4px 10px", cursor:"pointer", fontSize:11, fontFamily:"monospace" }}
                      >×</button>
                    </div>
                  </div>
                ))
              )}
            </div>
          )}
          {STEPS.map(s=>(
            <Step
              key={s.id + activeGenre + (activeTemplate ? activeTemplate.id : "")}
              {...s}
              genre={activeGenre}
              gLoading={gLoading}
              setGLoading={setGLoading}
              outputs={outputs}
              setOutputs={setOutputs}
              template={activeTemplate}
            />
          ))}
          <div style={C.card(false)}>
            <div style={{ padding:"18px 20px" }}>
              <div style={C.label}>WEEKLY AUTOMATION SCHEDULE</div>
              {[
                ["MON","Run Step 01 — Research (fetches live news + summarizes, 2 min)"],
                ["TUE","Run Step 02 — Write Newsletter, review & tweak (10 min)"],
                ["WED","Paste into Beehiiv, schedule for Thursday 8am delivery"],
                ["THU","Run Step 03 — Social Content, post for subscriber growth"],
                ["FRI","Run Step 04 — Sponsor Pitch, send to 3–5 brands in your genre"],
                ["SAT–SUN","Check metrics, reply to readers, plan next week's theme"],
              ].map(([d,t])=>(
                <div key={d} style={C.schedRow}><div style={C.schedDay}>{d}</div><div style={{ fontSize:13, color:"#b5b0ce" }}>{t}</div></div>
              ))}
            </div>
          </div>
        </>}

        {/* DISCOVER */}
        {tab==="discover" && <>
          <p style={intro}>
            Type any topic and instantly research it using live web data, then generate a polished newsletter draft with social content — all in one step. Save topics for recurring auto-generation.
          </p>
          {isPro ? <DiscoverTab /> : <ProGate feature="Custom topic search and affiliate discovery" />}
        </>}

        {/* DRAFTS */}
        {tab==="drafts" && <>
          <p style={intro}>Every draft you save from the Weekly Engine or Discover tab appears here. Review, edit, approve, or reject before publishing.</p>
          <DraftsTab onTemplateSaved={loadTemplates} />
        </>}

        {/* PROMPTS */}
        {tab==="prompts" && <>
          <p style={intro}>These are the exact prompts powering the <strong style={{color:"#a78bfa"}}>{genre.icon} {genre.name}</strong> engine. Copy into Claude, ChatGPT, or use in Make.com / Zapier.</p>
          {PROMPTS.map(p=>(
            <div key={p.key} style={C.card(false)}>
              <div style={C.hdrRow}>
                <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>{p.label}</div>
                <button style={C.copyBtn(copied[p.key])} onClick={()=>cp(p.key,p.text)}>{copied[p.key]?"✓ Copied!":"Copy"}</button>
              </div>
              <pre style={C.pre}>{p.text}</pre>
            </div>
          ))}
        </>}

        {/* MONETIZE */}
        {tab==="monetize" && <>
          <p style={intro}>Four revenue streams you can stack across all 5 genres. Each runs mostly on autopilot once set up.</p>
          <div className="monetize-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(210px,1fr))", gap:12, marginBottom:14 }}>
            {[
              {icon:"🤝",title:"Sponsorships",        desc:"Brands in your genre pay to reach your audience. Use the Sponsor Pitch step every Friday. Real rates start at $350-$500/issue.",amt:"$350 – $2,000 / issue"},
              {icon:"💎",title:"Premium Tier ($9/mo)", desc:"Lock bonus content behind a Beehiiv paywall — extra tips, resources, and community for your genre. Set once, earn forever.", amt:"$900/mo at 100 paid subs"},
              {icon:"🔗",title:"Affiliate Links",      desc:"Genre-specific affiliate programs earn 10-30% recurring commission. See the Affiliates tab for your genre's full link library.",amt:"10–30% recurring / sale"},
              {icon:"📦",title:"Digital Products",     desc:"Sell genre-specific guides, templates, and mini-courses to your list. Use Claude to create them in minutes. Sell on Gumroad.", amt:"$27 – $297 / product"},
            ].map(m=>(
              <div key={m.title} style={C.mCard}>
                <div style={{ fontSize:24, marginBottom:8 }}>{m.icon}</div>
                <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8", marginBottom:4 }}>{m.title}</div>
                <div style={{ fontSize:12, color:"#635e80", lineHeight:1.5 }}>{m.desc}</div>
                <div style={{ fontSize:13, color:"#86efac", fontWeight:"bold", marginTop:8, fontFamily:"monospace" }}>{m.amt}</div>
              </div>
            ))}
          </div>
          <div style={{ ...C.card(false), border:"1px solid #4f46e5" }}>
            <div style={{ padding:"18px 20px" }}>
              <div style={C.label}>REVENUE PROJECTION (PER GENRE)</div>
              {[["Month 1","500 subs","$0 — building audience"],["Month 3","1,200 subs","$600 – $1,500"],["Month 6","3,000 subs","$3,000 – $6,000"],["Month 12","8,000+ subs","$8,000 – $18,000"]].map(([p,s,r])=>(
                <div key={p} style={C.revRow}>
                  <div style={{ fontFamily:"monospace", color:"#635e80" }}>{p}</div>
                  <div>{s}</div>
                  <div style={{ color:"#86efac", fontWeight:"bold" }}>{r}</div>
                </div>
              ))}
            </div>
          </div>
        </>}

        {/* AFFILIATES */}
        {tab==="affiliates" && <>
          <p style={intro}>Every affiliate link below is injected automatically into your newsletter when you run the Write step. These are real affiliate programs with active commission structures.</p>
          {GENRES.map(g => (
            <div key={g.id} style={{ marginBottom:20 }}>
              <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:10 }}>
                <div style={{ fontSize:20 }}>{g.icon}</div>
                <div>
                  <div style={{ fontWeight:"bold", fontSize:15, color:"#e8e3f8" }}>{g.name}</div>
                  <div style={{ fontSize:11, color:"#635e80" }}>{g.desc}</div>
                </div>
              </div>
              <div className="affiliate-grid" style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(280px,1fr))", gap:10 }}>
                {(AFFILIATE_DATA[g.id] || []).map(a => (
                  <div key={a.name} style={{ background:"#0e0c1a", border:"1px solid #1c1830", borderRadius:10, padding:"12px 14px" }}>
                    <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", marginBottom:4 }}>
                      <div style={{ fontWeight:"bold", fontSize:13, color:"#e8e3f8" }}>{a.name}</div>
                      <div style={{ fontSize:10, color:"#86efac", fontFamily:"monospace", fontWeight:"bold", textAlign:"right", minWidth:80 }}>{a.commission}</div>
                    </div>
                    <div style={{ fontSize:12, color:"#635e80", lineHeight:1.5, marginBottom:8 }}>{a.desc}</div>
                    <a
                      href={a.url}
                      target="_blank"
                      rel="noopener noreferrer"
                      style={{ fontSize:11, color:"#8b5cf6", fontFamily:"monospace", textDecoration:"none", wordBreak:"break-all" }}
                    >
                      {a.url}
                    </a>
                  </div>
                ))}
              </div>
            </div>
          ))}
          <div style={{ background:"#0e0c1a", border:"1px solid #4f46e5", borderRadius:12, padding:"16px 20px", marginTop:8 }}>
            <div style={C.label}>AFFILIATE LINK SETUP REQUIRED</div>
            <div style={{ fontSize:13, color:"#b5b0ce", lineHeight:1.7 }}>
              The links above are the brands' standard websites. To earn commissions, you must sign up for each brand's affiliate program separately and replace the URLs above with your unique affiliate tracking links. Most programs are free to join and approve within 1-3 business days.
            </div>
          </div>
        </>}

        {/* ANALYTICS */}
        {tab==="analytics" && <>
          <p style={intro}>Track your newsletter performance, revenue, and affiliate earnings across all genres. Log your income and see trends over time.</p>
          <AnalyticsTab />
        </>}

        {/* SETTINGS */}
        {tab==="settings" && <>
          <p style={intro}>Configure your weekly auto-schedule, manage custom topic scheduling, and set up notification emails. Run all genres and custom topics on demand or let the scheduler handle it automatically.</p>
          <SettingsTab />
        </>}

        {/* ACCOUNT */}
        {tab==="account" && <>
          <p style={intro}>Manage your account, subscription plan, and billing.</p>
          <AccountTab />
        </>}

        {/* GUIDE */}
        {tab==="guide" && <>
          <p style={intro}>Your step-by-step launch plan — from zero to your first sponsorship check across any of your 5 genres.</p>
          {[
            {num:"01",title:"Set Up Beehiiv (Free)",    time:"30 min",   tasks:["Go to beehiiv.com and sign up free","Name your newsletter — pick one genre to start (e.g. 'Financial Peace Weekly')","Write your welcome email using the Prompts tab for your genre","Subscribe page headline: 'The [Genre] newsletter for people who want [specific outcome]'"]},
            {num:"02",title:"Set Up NewsAPI (Free)",    time:"10 min",   tasks:["Go to newsapi.org and create a free account (100 req/day free)","Copy your API key from the dashboard","Add it to your Replit Secrets as NEWS_API_KEY","Now Research step pulls real live headlines every time you run it"]},
            {num:"03",title:"Create Your Lead Magnet",  time:"1 hour",   tasks:["Ask Claude to write a free guide specific to your genre (e.g. '10 Debt-Free Tips' or '5 Best Family Games of the Year')","Offer it free in exchange for email signup","Upload to Beehiiv as gated content — this 3x's your signup conversion rate"]},
            {num:"04",title:"Send Your First Issue",    time:"15 min",   tasks:["Select your genre in the Weekly Engine","Run Steps 01-02 to generate your newsletter","Review, tweak, and paste into Beehiiv","Send to your first subscribers — start with friends and social followers"]},
            {num:"05",title:"Grow to 500 Subscribers",  time:"Weeks 2–4",tasks:["Post the social content from Step 03 across Twitter, LinkedIn, and Instagram 3x/week","Enable Beehiiv referral program to reward subscribers who refer others","Share your free lead magnet in 3 relevant Reddit/Facebook communities","Target: 500 subscribers in 30 days"]},
            {num:"06",title:"Land Your First Sponsor",  time:"Week 6",   tasks:["At 500+ subs, run Step 04 — Sponsor Pitch — and send to 10 brands in your genre","Use the Affiliates tab to identify potential sponsors to reach out to","Charge $350-$500 for first sponsorship (introductory rate)","One sponsor per issue = $1,400-$2,000/month at 4 issues/month"]},
          ].map(item=>(
            <div key={item.num} style={C.card(false)}>
              <div style={{ padding:"16px 18px" }}>
                <div style={{ display:"flex", gap:12 }}>
                  <div style={{ ...C.num, height:"fit-content" }}>{item.num}</div>
                  <div style={{ flex:1 }}>
                    <div style={{ display:"flex", justifyContent:"space-between", flexWrap:"wrap", gap:6, marginBottom:10 }}>
                      <div style={{ fontWeight:"bold", fontSize:14, color:"#e8e3f8" }}>{item.title}</div>
                      <div style={{ fontSize:11, color:"#6366f1", fontFamily:"monospace" }}>⏱ {item.time}</div>
                    </div>
                    {item.tasks.map((t,i)=>(
                      <div key={i} style={{ fontSize:13, color:"#b5b0ce", lineHeight:1.6, marginBottom:5 }}>
                        <span style={{ color:"#8b5cf6", marginRight:8 }}>›</span>{t}
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            </div>
          ))}
        </>}

      </div>
    </div>
  );
}

function App() {
  const [user, setUser] = useState(undefined);
  const [authMode, setAuthMode] = useState(null);
  const [loading, setLoading] = useState(true);
  const [showOnboarding, setShowOnboarding] = useState(false);

  const refreshUser = useCallback(() => {
    apiFetch("/api/auth/me").then(r => r.json()).then(data => {
      setUser(data.user || null);
    }).catch(() => setUser(null));
  }, []);

  useEffect(() => {
    apiFetch("/api/auth/me").then(r => r.json()).then(data => {
      setUser(data.user || null);
      if (data.user && !data.user.onboarding_complete) {
        setShowOnboarding(true);
      }
      setLoading(false);
    }).catch(() => {
      setUser(null);
      setLoading(false);
    });
  }, []);

  function handleAuthSuccess(u, isNew) {
    setUser(u);
    setAuthMode(null);
    if (isNew || !u.onboarding_complete) {
      setShowOnboarding(true);
    }
  }

  function logout() {
    apiFetch("/api/auth/logout", { method: "POST" }).then(() => {
      setUser(null);
      setAuthMode(null);
    });
  }

  if (loading) {
    return (
      <div style={{ minHeight:"100vh", background:"#07060f", display:"flex", alignItems:"center", justifyContent:"center" }}>
        <div style={{ color:"#635e80", fontFamily:"monospace", fontSize:14 }}>Loading...</div>
      </div>
    );
  }

  if (!user && authMode) {
    return <AuthPage mode={authMode} onSwitch={() => setAuthMode(authMode === "login" ? "register" : "login")} onSuccess={handleAuthSuccess} />;
  }

  if (!user) {
    return <LandingPage onShowAuth={setAuthMode} />;
  }

  if (showOnboarding) {
    return (
      <OnboardingWizard
        user={user}
        onComplete={(navigateTo) => {
          setShowOnboarding(false);
          refreshUser();
          if (navigateTo) {
            try { localStorage.setItem("onboarding_navigate", navigateTo); } catch(e) {}
          }
        }}
      />
    );
  }

  return (
    <AuthContext.Provider value={{ user, refreshUser, logout }}>
      <AppInner />
    </AuthContext.Provider>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
