/* DonorLens — landing page composition, tweaks, and render. */
const { useState, useEffect, useRef } = React;
const App = window.DonorLensApp;
const LensMark = window.LensMark;

/* simple single-hue concentric "lens" badge for feature cards (circles only) */
function FMark({ hue = 33, size = 46 }) {
  const ringsL = [0.62, 0.7, 0.78, 0.86];
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" aria-hidden="true">
      {ringsL.map((l, i) => (
        <circle key={i} cx="50" cy="50" r={44 - i * 8.5} fill="none"
          stroke={`oklch(${l} 0.13 ${hue})`} strokeWidth="6" />
      ))}
      <circle cx="50" cy="50" r="9" fill={`oklch(0.4 0.12 ${hue})`} />
    </svg>
  );
}

function DownloadIcon() {
  return (<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12M7 11l5 5 5-5M5 21h14" /></svg>);
}
function PlayIcon() {
  return (<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z" /></svg>);
}

/* ---------------- nav ---------------- */
function Nav() {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const f = () => setScrolled(window.scrollY > 8);
    window.addEventListener('scroll', f); f();
    return () => window.removeEventListener('scroll', f);
  }, []);
  return (
    <nav className={'nav' + (scrolled ? ' scrolled' : '')}>
      <div className="wrap nav-inner">
        <a className="brand" href="#top"><LensMark size={30} /><span><span className="b-don">Donor</span><span className="b-lens">Lens</span></span></a>
        <div className="nav-links">
          <a href="#features">Product</a>
          <a href="#how">How it works</a>
          <a href="#uses">Use cases</a>
          <a href="#services">Consulting</a>
          <a href="#about">About</a>
        </div>
        <div className="nav-cta">
          <a className="btn btn-ghost" href="#contact">Talk to us</a>
          <a className="btn btn-primary" href="#contact"><DownloadIcon />Download</a>
        </div>
      </div>
    </nav>
  );
}

/* ---------------- hero ---------------- */
function Hero({ headline }) {
  const parts = headline.split('|');
  return (
    <header className="hero" id="top">
      <div className="hero-glow" />
      <div className="wrap hero-grid">
        <div className="hero-copy">
          <span className="hero-kick"><LensMark size={18} />AI donor analyst · desktop app</span>
          <h1>{parts[0]}{parts[1] && <><br /><span className="accent">{parts[1]}</span></>}</h1>
          <p className="hero-sub">An AI analyst for your donor database. Ask a question in plain English — <q>which major donors have lapsed?</q> — and get a clear, sourced answer, whatever CRM your data lives in.</p>
          <div className="hero-cta">
            <a className="btn btn-primary" href="#contact"><DownloadIcon />Download the app</a>
            <a className="btn btn-ghost" href="#how"><PlayIcon />See what it does</a>
          </div>
          <div className="hero-micro">
            <span><span className="d" />Runs on your desktop</span>
            <span><span className="d" />Your donor data stays local</span>
          </div>
        </div>
        <div className="hero-art">
          <App variant="hero" startKey="lapsed" />
        </div>
      </div>
    </header>
  );
}

/* ---------------- crm strip ---------------- */
function CrmStrip() {
  return (
    <div className="crm">
      <div className="wrap crm-inner">
        <span className="crm-label">One view over a fragmented data world</span>
        <div className="crm-logos">
          <span className="crm-logo"><LensMark size={18} />Raiser’s Edge</span>
          <span className="crm-logo">Salesforce NPSP <span className="soon">on the roadmap</span></span>
          <span className="crm-logo">Bloomerang <span className="soon">on the roadmap</span></span>
        </div>
      </div>
    </div>
  );
}

/* ---------------- features ---------------- */
const FEATURES = [
  { hue: 350, t: 'Ask in plain English', d: 'No query language, no report builder. Ask the way you’d ask a colleague and get an answer back in seconds.' },
  { hue: 250, t: 'Works across CRMs', d: 'Raiser’s Edge today, with Salesforce NPSP and Bloomerang on the roadmap — one clear view over a fragmented data world.' },
  { hue: 33, t: 'Answers you can act on', d: 'Lapsed major donors, prospect lists, giving trends, portfolio health — packaged as scenarios, not raw rows.' },
  { hue: 150, t: 'Private by design', d: 'The desktop app keeps donor data and analysis on your machine. Only the model credentials live in the backend.' },
];
function Features() {
  return (
    <section className="section" id="features">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="eyebrow">The app</span>
          <h2 style={{ marginTop: 14 }}>Built for the way fundraisers actually work</h2>
          <p className="lead">Most nonprofits sit on years of donor history they can’t easily use. DonorLens turns that history into answers — without a consultant, an analyst hire, or a single line of query syntax.</p>
        </div>
        <div className="feature-grid">
          {FEATURES.map((f, i) => (
            <div className="feature reveal" key={i} style={{ animationDelay: (i * 70) + 'ms' }}>
              <FMark hue={f.hue} />
              <h3>{f.t}</h3>
              <p>{f.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------------- how it works ---------------- */
const STEPS = [
  { t: 'Connect your database', d: 'Point DonorLens at your CRM export or live connection. It reads your constituents, gifts, appeals and actions — and keeps the data on your machine.' },
  { t: 'Ask in everyday language', d: 'Type or speak a question the way you’d ask a colleague. No fields, no filters, no report builder to learn.' },
  { t: 'Get a sourced answer', d: 'A summary, a table, a chart, or a finished document — every answer shows where the numbers came from, so you can trust it and act.' },
];
function How() {
  return (
    <section className="how section" id="how">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="eyebrow">How it works</span>
          <h2 style={{ marginTop: 14 }}>Like a fundraising analyst on staff</h2>
          <p className="lead">A smart, tireless analyst who already knows your database and will answer any question you ask — in seconds, in everyday language. Try it right here.</p>
        </div>
        <div className="how-grid">
          <div className="steps reveal">
            {STEPS.map((s, i) => (
              <div className="step" key={i}>
                <div className="step-num">{i + 1}</div>
                <div><h3>{s.t}</h3><p>{s.d}</p></div>
              </div>
            ))}
          </div>
          <div className="reveal">
            <App variant="full" startKey="spring" />
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------------- use cases ---------------- */
const USES = [
  { q: 'Which lapsed donors gave over $1,000 last year?', tag: 'Re-engagement' },
  { q: 'How is the spring appeal pacing vs. goal?', tag: 'Appeal tracking' },
  { q: 'Draft the board fundraising summary for Q2.', tag: 'Reporting' },
  { q: 'Who are my top prospect upgrades this quarter?', tag: 'Major gifts' },
  { q: 'What’s our donor retention compared to last year?', tag: 'Donor health' },
  { q: 'Which first-time donors should we steward now?', tag: 'Stewardship' },
];
function UseCases() {
  return (
    <section className="section" id="uses">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="eyebrow">Use cases</span>
          <h2 style={{ marginTop: 14 }}>The questions are already in your data</h2>
          <p className="lead">Who’s about to lapse, who could give more, how the appeal is really doing. Ask, and get an answer, a table, a chart, or a finished document.</p>
        </div>
        <div className="uc-grid">
          {USES.map((u, i) => (
            <div className="uc reveal" key={i} style={{ animationDelay: (i % 3 * 70) + 'ms' }}>
              <LensMark size={26} />
              <div className="uc-q">{u.q}</div>
              <div className="uc-tag">{u.tag}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------------- services / consulting ---------------- */
const SVCS = [
  { t: 'Data cleanup & migration', d: 'Cleaning, de-duping and organizing years of donor history — and steady hands through a CRM migration.' },
  { t: 'CRM implementation', d: 'Implementing or optimizing Raiser’s Edge, NPSP and more so your system fits how your team works.' },
  { t: 'Fundraising dashboards', d: 'Board-ready dashboards and reports that surface the numbers that actually move strategy.' },
  { t: 'Prospect research', d: 'Identifying major-gift prospects and upgrade opportunities hiding in your existing file.' },
  { t: 'Workflow automation', d: 'Automating the repetitive data work so your team spends time on relationships, not spreadsheets.' },
  { t: 'Data-driven strategy', d: 'Turning analysis into a fundraising plan — priorities, portfolios, and measurable goals.' },
];
function Services() {
  return (
    <section className="section" id="services">
      <div className="wrap">
        <div className="svc reveal">
          <span className="eyebrow" style={{ color: 'var(--accent)' }}>Consulting</span>
          <h2 style={{ marginTop: 14 }}>Want a partner, not just a tool?</h2>
          <p className="lead">The app puts answers in your hands. When you want hands-on help, our team brings the expertise and technology to help you work smarter — not harder.</p>
          <div className="svc-grid">
            {SVCS.map((s, i) => (
              <div className="svc-item" key={i}>
                <h4><LensMark size={16} />{s.t}</h4>
                <p>{s.d}</p>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------------- founders / about ---------------- */
const FOUNDERS = [
  {
    initials: 'MB', name: 'Marko Bajic', role: 'Co-Founder & Chief Technology Officer',
    bio: 'A technology executive and software architect with more than two decades building large-scale data, analytics and AI platforms — leading engineering for organizations including Qualtrics, Clarabridge, KeyBank and Verint. He’s architected systems processing hundreds of millions of interactions a year.',
    tags: ['Cloud & data platforms', 'Machine learning', 'Enterprise architecture', 'AI analytics'],
  },
  {
    initials: 'AT', name: 'Amy Tomchin', role: 'Co-Founder & Chief Strategy Officer',
    bio: 'More than two decades in nonprofit advancement, fundraising strategy and donor research. She’s helped organizations strengthen fundraising by turning complex donor data into action — across major and principal gifts, prospect research, CRM implementation and advancement analytics.',
    tags: ['Major & principal gifts', 'Prospect research', 'Advancement analytics', 'Fundraising strategy'],
  },
];
function Founders() {
  return (
    <section className="section" id="about" style={{ background: 'var(--paper-2)', borderTop: '1px solid var(--line-soft)' }}>
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="eyebrow">About us</span>
          <h2 style={{ marginTop: 14 }}>Enterprise data expertise, pointed at philanthropy</h2>
          <p className="lead">We spent careers designing, scaling and optimizing enterprise data and AI platforms serving hundreds of customers. We bring that same data-driven mindset to fundraising — to help nonprofits uncover opportunities and maximize their impact.</p>
        </div>
        <div className="founder-grid">
          {FOUNDERS.map((f, i) => (
            <div className="founder reveal" key={i} style={{ animationDelay: (i * 90) + 'ms' }}>
              <div className="founder-top">
                <div className="founder-photo">{f.initials}</div>
                <div>
                  <div className="founder-name">{f.name}</div>
                  <div className="founder-role">{f.role}</div>
                </div>
              </div>
              <p className="founder-bio">{f.bio}</p>
              <div className="founder-tags">
                {f.tags.map((t, j) => <span className="founder-tag" key={j}>{t}</span>)}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------------- contact / final cta ---------------- */
function Contact() {
  return (
    <section className="cta" id="contact">
      <div className="cta-lens"><LensMark size={420} /></div>
      <div className="wrap">
        <h2>See your donors <span className="accent">clearly</span>.</h2>
        <p className="lead">Download the desktop app, or talk to us about putting your donor data to work. Either way, let’s discuss your next steps.</p>
        <div className="cta-row">
          <a className="btn btn-primary" href="#"><DownloadIcon />Download the app</a>
          <a className="btn btn-ghost" href="#">Book a conversation</a>
        </div>
        <div className="cta-mail"><LensMark size={18} />hello@donorlens.com</div>
      </div>
    </section>
  );
}

/* ---------------- footer ---------------- */
function Footer() {
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-inner">
          <div className="footer-brand">
            <a className="brand" href="#top"><LensMark size={28} /><span><span className="b-don">Donor</span><span className="b-lens">Lens</span></span></a>
            <p>An AI donor analyst and a fundraising data consultancy — helping nonprofits spend less time managing data and more time advancing their mission.</p>
          </div>
          <div className="footer-cols">
            <div className="footer-col">
              <h5>Product</h5>
              <a href="#features">Features</a><a href="#how">How it works</a><a href="#uses">Use cases</a><a href="#contact">Download</a>
            </div>
            <div className="footer-col">
              <h5>Company</h5>
              <a href="#services">Consulting</a><a href="#about">About</a><a href="#contact">Contact</a>
            </div>
            <div className="footer-col">
              <h5>Connects to</h5>
              <a href="#">Raiser’s Edge</a><a href="#">Salesforce NPSP</a><a href="#">Bloomerang</a>
            </div>
          </div>
        </div>
        <div className="footer-base">
          <span>© 2026 DonorLens. All rights reserved.</span>
          <span>Privacy · Terms · Your donor data stays local</span>
        </div>
      </div>
    </footer>
  );
}

/* ---------------- tweaks + root ---------------- */
const ACCENTS = {
  '#D9694A': { deep: 'oklch(0.515 0.142 33)', hue: 33 },   // coral (default)
  '#D6356B': { deep: 'oklch(0.49 0.17 5)', hue: 5 },        // brand magenta
  '#5A57B0': { deep: 'oklch(0.45 0.13 285)', hue: 285 },    // brand indigo
  '#2F8F86': { deep: 'oklch(0.46 0.08 190)', hue: 190 },    // teal
};
const FONT_HEADS = {
  Rounded: "'Plus Jakarta Sans', system-ui, sans-serif",
  Editorial: "'Fraunces', Georgia, serif",
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#D9694A",
  "colorAmount": "balanced",
  "headingStyle": "Rounded",
  "heroLayout": "split",
  "headline": "See your donors|clearly."
}/*EDITMODE-END*/;

function useReveal() {
  useEffect(() => {
    const armed = new WeakSet();
    const reveal = () => {
      const vh = window.innerHeight;
      let remaining = 0;
      document.querySelectorAll('.reveal').forEach((el) => {
        if (armed.has(el)) return;
        const r = el.getBoundingClientRect();
        if (r.top < vh * 0.92) {
          armed.add(el);
          el.classList.add('in');
          // failsafe: once the entrance has had time to play, drop the animation so the
          // element rests on its visible base state — guarantees content shows even where
          // the animation clock is throttled/frozen (headless capture, background tabs).
          setTimeout(() => { el.style.animation = 'none'; }, 820);
        } else remaining++;
      });
      return remaining;
    };
    reveal();
    // poll (scroll events are unreliable in some embeds); self-terminates when done
    const iv = setInterval(() => { if (reveal() === 0) clearInterval(iv); }, 160);
    const onScroll = () => reveal();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => { clearInterval(iv); window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); };
  }, []);
}

function Root() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useReveal();

  const acc = ACCENTS[t.accent] || ACCENTS['#D9694A'];
  const rootStyle = {
    '--accent': t.accent,
    '--accent-deep': acc.deep,
    '--accent-tint': `color-mix(in oklab, ${t.accent} 11%, white)`,
    '--accent-tint2': `color-mix(in oklab, ${t.accent} 20%, white)`,
    '--font-head': FONT_HEADS[t.headingStyle] || FONT_HEADS.Rounded,
  };

  return (
    <div className="dl-root" data-color={t.colorAmount} data-hero={t.heroLayout} style={rootStyle}>
      <Nav />
      <Hero headline={t.headline} />
      <CrmStrip />
      <Features />
      <How />
      <UseCases />
      <Services />
      <Founders />
      <Contact />
      <Footer />

      <TweaksPanel>
        <TweakSection label="Brand" />
        <TweakColor label="Accent color" value={t.accent}
          options={['#D9694A', '#D6356B', '#5A57B0', '#2F8F86']}
          onChange={(v) => setTweak('accent', v)} />
        <TweakRadio label="Color amount" value={t.colorAmount}
          options={['calm', 'balanced', 'vivid']}
          onChange={(v) => setTweak('colorAmount', v)} />
        <TweakSection label="Type" />
        <TweakRadio label="Headings" value={t.headingStyle}
          options={['Rounded', 'Editorial']}
          onChange={(v) => setTweak('headingStyle', v)} />
        <TweakSection label="Layout" />
        <TweakRadio label="Hero" value={t.heroLayout}
          options={['split', 'below']}
          onChange={(v) => setTweak('heroLayout', v)} />
        <TweakSection label="Copy" />
        <TweakText label="Headline" value={t.headline}
          onChange={(v) => setTweak('headline', v)} />
        <div style={{ fontSize: 11, color: '#9a948c', padding: '2px 2px 0', lineHeight: 1.4 }}>
          Use “|” to split the headline onto a second, accented line.
        </div>
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<Root />);
