// Polycode marketing — page sections
//
// Composes the marketing site from the brand primitives + the hero app mock.
// Sections (in order):
//   <Nav/>
//   <Hero/>
//   <ProvidersStrip/>     "Works with everything you already pay for"
//   <Receipts/>           4 stat cells
//   <FanOut/>             feature: parallel fan-out (animated mini)
//   <Inspector/>          feature: per-provider trace
//   <Native/>             feature: HIG-first / native macOS
//   <BYOK/>               feature: bring your own keys, on-device option
//   <FeatureGrid/>        catch-all: 6 smaller cards
//   <Pricing/>            one-time purchase
//   <FAQ/>
//   <Footer/>

// ─────────────────────────────────────────────────────────────────────
function Nav() {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const onS = () => setScrolled(window.scrollY > 8);
    window.addEventListener('scroll', onS, { passive: true });
    return () => window.removeEventListener('scroll', onS);
  }, []);
  return (
    <nav className={"mk-nav" + (scrolled ? ' scrolled' : '')}>
      <div className="mk-container row">
        <a href="#" aria-label="Polycode home" style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
          <PolycodeWordmark height={22}/>
          <span style={{
            display: 'inline-flex', alignItems: 'center',
            height: 20, padding: '0 8px',
            borderRadius: 999,
            background: 'rgba(193,80,46,0.10)',
            color: 'var(--pc-accent-solid)',
            fontFamily: 'var(--pc-font-mono)',
            fontSize: 10.5, fontWeight: 500,
            letterSpacing: '0.04em', textTransform: 'uppercase',
            border: '0.5px solid rgba(193,80,46,0.22)',
          }}>Coming soon</span>
        </a>
        <div className="links">
          <a href="#features">Features</a>
          <a href="#providers">Providers</a>
          <a href="#privacy">Privacy</a>
          <a href="#pricing">Pricing</a>
          <a href="#faq">FAQ</a>
        </div>
        <div className="spacer"/>
        <div className="actions">
          <a href="#waitlist" className="btn btn-primary" style={{ height: 40 }}>
            <Icon name="sparkles" size={14} color="white"/>
            Notify me
          </a>
        </div>
      </div>
    </nav>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Hero() {
  return (
    <section className="hero">
      <div className="mk-container">
        <div className="hero-grid">
          <div style={{ maxWidth: 920, margin: '0 auto', textAlign: 'center' }}>
            <span className="mk-eyebrow" style={{ marginBottom: 22, justifyContent: 'center' }}>
              For macOS Sonoma & later
            </span>
            <h1 className="mk-hero-h" style={{ margin: '14px 0 0' }}>
              Many minds.
              <br/>
              <span className="mk-ink-grad">One reply.</span>
            </h1>
            <p className="mk-lede" style={{ margin: '24px auto 0', maxWidth: 640 }}>
              Polycode fans every prompt out to Claude, GPT, Gemini, Apple Intelligence
              and more — in parallel — then synthesizes a single answer with the trace
              kept honest. Native macOS. Bring your own keys.
            </p>
            <div className="hero-cta" style={{ justifyContent: 'center' }}>
              <a href="#waitlist" className="btn btn-primary btn-lg">
                <Icon name="sparkles" size={16} color="white"/>
                Notify me at launch
              </a>
              <button type="button" className="btn btn-ghost btn-lg" disabled aria-disabled="true" style={{ cursor: 'not-allowed', opacity: 0.7 }}>
                <Icon name="apple" size={15}/>
                TestFlight · Coming soon
              </button>
            </div>
            <div className="hero-meta" style={{ justifyContent: 'center' }}>
              <span style={{ color: 'var(--pc-accent-solid)', fontWeight: 500 }}>Lock in launch pricing</span>
              <span className="dot"/>
              <span>Coming soon to the Mac App Store</span>
              <span className="dot"/>
              <span>Universal · Apple Silicon + Intel</span>
            </div>
          </div>

          {/* Animated app mock */}
          <div style={{ maxWidth: 1180, margin: '24px auto 0', width: '100%' }}>
            <HeroAppMock/>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function ProvidersStrip() {
  const provs = ['anthropic','openai','gemini','foundation','ollama','xai','openrouter','compat'];
  return (
    <section id="providers" className="mk-section tight">
      <div className="mk-container">
        <div style={{
          padding: '36px 24px',
          background: 'var(--pc-surface-sidebar)',
          borderRadius: 'var(--pc-radius-prominent)',
          border: '0.5px solid var(--pc-border-subtle)',
          display: 'flex', flexDirection: 'column', gap: 22,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
            <span className="mk-eyebrow">Providers</span>
            <h2 style={{
              margin: 0, fontSize: 'clamp(20px, 2vw, 26px)',
              fontWeight: 600, letterSpacing: '-0.014em', color: 'var(--pc-content-primary)',
            }}>
              Works with the keys you already have.
            </h2>
          </div>
          <div className="providers-row" style={{ gap: 14 }}>
            {provs.map((p) => (
              <span key={p} className="provider-chip" style={{ height: 36, fontSize: 13.5 }}>
                <ProviderTile provider={p} size={22}/>
                {PROVIDERS[p].name}
              </span>
            ))}
            <span className="provider-chip" style={{
              height: 36, fontSize: 13.5,
              background: 'transparent',
              boxShadow: 'inset 0 0 0 1px var(--pc-border-standard)',
              color: 'var(--pc-content-secondary)',
            }}>
              <Icon name="plus" size={14}/>
              Anything OpenAI-compatible
            </span>
          </div>
          <div style={{
            fontSize: 13, color: 'var(--pc-content-tertiary)',
            display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap',
            paddingTop: 4,
          }}>
            <ProviderTile provider="openrouter" size={16}/>
            <span>
              Or bring a single <span style={{ color: 'var(--pc-content-secondary)', fontWeight: 500 }}>OpenRouter</span> key — one signup covers most of the cloud.
            </span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Receipts() {
  return (
    <section className="mk-section tight">
      <div className="mk-container">
        <div className="receipts">
          <div className="stat">
            <span className="n mk-numeric">8</span>
            <span className="lbl">providers shipped</span>
          </div>
          <div className="stat">
            <span className="n mk-numeric">≤ 1.4s</span>
            <span className="lbl">typical fan-out</span>
          </div>
          <div className="stat">
            <span className="n">0</span>
            <span className="lbl">additional subscriptions</span>
          </div>
          <div className="stat">
            <span className="n mk-numeric">100%</span>
            <span className="lbl">your keys, your billing</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
// Compact looping fan-out illustration used inside FanOut feature panel.
function MiniFanOut() {
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    let raf, t0 = performance.now();
    const tick = (now) => { setT(((now - t0)/1000) % 6); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf);
  }, []);
  // Bars stream then settle, looping every 6s.
  const provs = HERO_PROV;
  return (
    <div style={{
      background: 'var(--pc-surface-elevated)',
      borderRadius: 'var(--pc-radius-prominent)',
      border: '0.5px solid var(--pc-border-subtle)',
      padding: 22,
      boxShadow: 'var(--pc-shadow-soft)',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        fontFamily: FONT_MONO, fontSize: 11, color: 'var(--pc-content-tertiary)',
        textTransform: 'uppercase', letterSpacing: '0.10em', fontWeight: 600,
        marginBottom: 14,
      }}>
        <Icon name="zap" size={12} color="var(--pc-accent-solid)"/>
        Fan-out · in flight
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {provs.map((p, i) => {
          const start = 0.2 + i * 0.06;
          const dur = (p.ms / 1500) * 1.6;
          const prog = ec(cl((t - start) / dur, 0, 1));
          const settled = prog >= 1;
          return (
            <div key={p.p} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <ProviderTile provider={p.p} size={20}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 13, fontWeight: 600, color: 'var(--pc-content-primary)',
                  display: 'flex', alignItems: 'center', gap: 5,
                }}>
                  {p.full}
                  {p.primary && <Icon name="crown" size={10} color="var(--pc-accent-solid)" strokeWidth={2.2}/>}
                </div>
                <div style={{
                  marginTop: 5, height: 4, borderRadius: 2,
                  background: 'rgba(28,25,21,0.06)', overflow: 'hidden',
                }}>
                  <div style={{
                    width: `${prog * 100}%`, height: '100%',
                    background: settled ? 'var(--pc-status-success)' : (p.primary ? 'var(--pc-accent-solid)' : p.col),
                    transition: settled ? 'background 200ms' : 'none',
                    borderRadius: 2,
                  }}/>
                </div>
              </div>
              <span style={{
                fontFamily: FONT_MONO, fontSize: 11, fontWeight: 600,
                color: settled ? 'var(--pc-status-success)' : 'var(--pc-content-tertiary)',
                minWidth: 56, textAlign: 'right', fontVariantNumeric: 'tabular-nums',
              }}>
                {settled ? `✓ ${p.ms}ms` : `${Math.floor(prog * p.ms)}ms`}
              </span>
            </div>
          );
        })}
      </div>
      <div style={{
        marginTop: 16, padding: '11px 14px',
        background: 'var(--pc-surface-sidebar)',
        borderRadius: 'var(--pc-radius-card)',
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <PolycodeIcon size={26}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--pc-content-primary)' }}>
            Synthesize → primary
          </div>
          <div style={{ fontSize: 11.5, color: 'var(--pc-content-tertiary)', fontFamily: FONT_MONO }}>
            tool-less · resolves disagreement
          </div>
        </div>
        <span style={{
          padding: '4px 9px', borderRadius: 4,
          background: 'rgba(46,125,91,0.10)', color: 'var(--pc-status-success)',
          fontSize: 11, fontWeight: 600, fontFamily: FONT_MONO, letterSpacing: '0.04em',
        }}>4/4 · 1.42s</span>
      </div>
    </div>
  );
}

function FanOut() {
  return (
    <section id="features" className="mk-section">
      <div className="mk-container">
        <div className="section-head">
          <div className="title">
            <span className="mk-eyebrow">Plurality, not picking</span>
            <h2 className="mk-section-h">
              Every prompt asks <em style={{ fontStyle:'normal' }} className="mk-ink-grad">every model</em>.
              Then we settle it.
            </h2>
          </div>
          <p className="mk-lede" style={{ alignSelf: 'end' }}>
            One question fans out to as many providers as you've configured. Replies arrive in parallel —
            you watch them land — and a primary peer synthesizes them into a single answer. No more
            tab-juggling between Claude and GPT.
          </p>
        </div>
        <div style={{
          display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 56, alignItems: 'center',
        }} className="resp-2col">
          <MiniFanOut/>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
            <FeaturePoint
              icon="route"
              title="Parallel by default"
              body="Reads (synthesis) fan out to every configured provider. Native writes are primary-only — your write tools never run twice."
            />
            <FeaturePoint
              icon="crown"
              title="A primary peer chooses the words"
              body="Pick the model whose voice you trust most. It reads every reply, then writes the consensus you actually see."
            />
            <FeaturePoint
              icon="sparkles"
              title="Disagreement is surfaced, not buried"
              body="When the panel splits, Polycode shows you who dissented and why — inline, with one click to read the full minority report."
            />
          </div>
        </div>
      </div>
      <style>{`
        @media (max-width: 900px) { .resp-2col { grid-template-columns: 1fr !important; gap: 32px !important; } }
      `}</style>
    </section>
  );
}

function FeaturePoint({ icon, title, body }) {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <span style={{
        flexShrink: 0, width: 36, height: 36, borderRadius: 'var(--pc-radius-card)',
        background: 'var(--pc-surface-inset)',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        color: 'var(--pc-accent-solid)',
      }}>
        <Icon name={icon} size={18}/>
      </span>
      <div>
        <h3 style={{
          margin: 0, fontSize: 18, fontWeight: 600, letterSpacing: '-0.012em',
          color: 'var(--pc-content-primary)',
        }}>{title}</h3>
        <p style={{
          margin: '6px 0 0', fontSize: 15, lineHeight: 1.55,
          color: 'var(--pc-content-secondary)',
        }}>{body}</p>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────
function InspectorFeature() {
  return (
    <section className="mk-section" style={{ background: 'var(--pc-surface-sidebar)' }}>
      <div className="mk-container">
        <div className="section-head">
          <div className="title">
            <span className="mk-eyebrow">Trace, don't hide</span>
            <h2 className="mk-section-h">
              See <em className="mk-ink-grad" style={{ fontStyle:'normal' }}>who said what</em>.
              Down to the token.
            </h2>
          </div>
          <p className="mk-lede" style={{ alignSelf: 'end' }}>
            Hit <span className="kbd">⌘⇧I</span> and the inspector slides in. Each provider gets a card:
            status, latency, in/out tokens, dollar cost, the resolved model id, and the full response —
            ready to copy, share, or pin to disk.
          </p>
        </div>

        <div className="trace-grid">
          <TraceMock/>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
            <FeaturePoint icon="eye" title="Per-exchange, not per-session"
              body="Every fan-out renders its own trace card stack. Scrub back through your conversation; the receipts go with it."/>
            <FeaturePoint icon="shield" title="Costs you can audit"
              body="Token-priced per provider with tabular figures. No mystery bills, no marked-up resale — just what your keys actually spent."/>
            <FeaturePoint icon="cpu" title="Tool calls included"
              body="Approve, reject, or replay individual tool calls. Polycode is the only client we know that lets you do this from the trace."/>
          </div>
        </div>
      </div>
    </section>
  );
}

function TraceMock() {
  return (
    <div className="trace-card">
      <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:14 }}>
        <Icon name="inspector" size={14} color="var(--pc-content-secondary)"/>
        <span style={{ fontSize: 13, fontWeight: 600 }}>Provider trace</span>
        <span style={{ fontFamily: FONT_MONO, fontSize: 11, color: 'var(--pc-content-tertiary)' }}>· flaky test triage · turn 3</span>
        <div style={{ flex: 1 }}/>
        <span style={{ fontFamily: FONT_MONO, fontSize: 11, color: 'var(--pc-content-tertiary)' }}>1.42s · 4/4</span>
      </div>
      <div style={{
        padding: '12px 14px', borderRadius: 'var(--pc-radius-standard)',
        background: 'var(--pc-surface-elevated)',
        boxShadow: 'inset 0 0 0 0.5px var(--pc-border-subtle)',
        marginBottom: 10,
      }}>
        <div style={{ display:'flex', alignItems:'center', gap:9, marginBottom: 8 }}>
          <PolycodeIcon size={22}/>
          <div style={{ fontSize: 13, fontWeight: 600 }}>Consensus reached</div>
          <div style={{ flex: 1 }}/>
          <span style={{ fontFamily: FONT_MONO, fontSize: 11, color: 'var(--pc-content-tertiary)' }}>94%</span>
        </div>
        <div style={{ height: 4, borderRadius: 2, background: 'rgba(28,25,21,0.06)', overflow: 'hidden' }}>
          <div style={{ width: '94%', height: '100%', background: 'var(--pc-accent-gradient)' }}/>
        </div>
      </div>
      {HERO_PROV.map((p, i) => {
        const expanded = p.p === 'openai';
        return (
          <div key={p.p} style={{
            background: 'var(--pc-surface-elevated)', borderRadius: 'var(--pc-radius-standard)',
            boxShadow: p.primary ? 'inset 0 0 0 1.25px var(--pc-accent-solid)' : 'inset 0 0 0 0.5px var(--pc-border-subtle)',
            padding: '11px 13px', marginBottom: 8,
          }}>
            <div style={{ display:'flex', alignItems:'center', gap:9 }}>
              <ProviderTile provider={p.p} size={22}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 600, display:'flex', alignItems:'center', gap:5 }}>
                  {p.full}
                  {p.primary && <Icon name="crown" size={10} color="var(--pc-accent-solid)" strokeWidth={2.2}/>}
                </div>
                <div style={{ fontSize: 11, color: 'var(--pc-content-tertiary)', fontFamily: FONT_MONO, marginTop: 1 }}>
                  847 in · 412 out · $0.00{(2 + i)}
                </div>
              </div>
              <span style={{
                padding: '2px 8px', borderRadius: 4,
                background: 'rgba(46,125,91,0.10)', color: 'var(--pc-status-success)',
                fontSize: 11, fontWeight: 600, fontFamily: FONT_MONO,
              }}>✓ {p.ms}ms</span>
              <Icon name="chevronR" size={11} color="var(--pc-content-tertiary)"
                style={{ marginLeft: 4, transform: expanded ? 'rotate(90deg)' : 'none' }}/>
            </div>
            {expanded && (
              <div style={{
                marginTop: 9, padding: '9px 10px',
                borderTop: '0.5px solid var(--pc-border-subtle)',
              }}>
                <div style={{
                  display:'flex', alignItems:'center', gap:6, marginBottom: 6,
                  fontSize: 9.5, fontWeight: 600, fontFamily: FONT_MONO, letterSpacing: '0.05em',
                  color: 'var(--pc-content-tertiary)', textTransform: 'uppercase',
                }}>
                  <span>Individual reply</span>
                  <span style={{ opacity: 0.4 }}>·</span>
                  <span style={{ color: 'var(--pc-status-warning)' }}>dissents on quarantine</span>
                </div>
                <div style={{ fontSize: 12, lineHeight: 1.5, color: 'var(--pc-content-secondary)' }}>
                  Don't quarantine yet — first add a <span style={{
                    fontFamily: FONT_MONO, fontSize: 11, background: 'rgba(28,25,21,0.05)',
                    padding: '0.5px 4px', borderRadius: 3,
                  }}>retry(3, backoff: .exp)</span> wrapper. Most CI flakes are transient network races.
                </div>
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Native() {
  return (
    <section className="mk-section">
      <div className="mk-container">
        <div className="section-head">
          <div className="title">
            <span className="mk-eyebrow">Built for the platform</span>
            <h2 className="mk-section-h">A native macOS app — not a web wrapper.</h2>
          </div>
          <p className="mk-lede" style={{ alignSelf: 'end' }}>
            SwiftUI from titlebar to inspector. Hardened runtime, App Sandbox, MAS distribution.
            Quick Look, drag-and-drop, system services, Spotlight indexing for sessions —
            it acts like the rest of your computer because it's built like the rest of your computer.
          </p>
        </div>

        <div className="feature-grid">
          <div className="feature-card">
            <span className="ico"><Icon name="panel" size={18} color="var(--pc-accent-solid)"/></span>
            <h3>SwiftUI, top to bottom</h3>
            <p>26 / 22 / 17 / 15 / 13 — HIG type scale. Sentence case. Visual-effect titlebar.
            No Electron, no Tauri, no bloated web-shell chrome.</p>
          </div>
          <div className="feature-card">
            <span className="ico"><Icon name="lock" size={18} color="var(--pc-accent-solid)"/></span>
            <h3>Sandboxed by default</h3>
            <p>App Sandbox + hardened runtime. Files are entitlements, not implicit reads.
            Polycode can't see anything you didn't grant.</p>
          </div>
          <div className="feature-card">
            <span className="ico"><Icon name="cpu" size={18} color="var(--pc-accent-solid)"/></span>
            <h3>On-device, when you want it</h3>
            <p>Apple Intelligence Foundation Models route everything through the Neural Engine —
            zero network, zero spend, sub-half-second turnarounds.</p>
          </div>
          <div className="feature-card">
            <span className="ico"><Icon name="zap" size={18} color="var(--pc-accent-solid)"/></span>
            <h3>Spotlight-fast sessions</h3>
            <p>Sessions are indexed by Core Spotlight. <span className="kbd">⌘F</span> in the sidebar
            or just hit Spotlight from anywhere — every conversation is searchable.</p>
          </div>
          <div className="feature-card">
            <span className="ico"><Icon name="route" size={18} color="var(--pc-accent-solid)"/></span>
            <h3>MCP, first-class</h3>
            <p>Model Context Protocol servers attach as tools. Polycode shows status, capabilities,
            and per-server latency right in the sidebar strip.</p>
          </div>
          <div className="feature-card">
            <span className="ico"><Icon name="home" size={18} color="var(--pc-accent-solid)"/></span>
            <h3>Local-first, by design</h3>
            <p>Conversations live in a local SQLite store you can read, back up, or move.
            No cloud sync we control — your conversations stay on your Mac.</p>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function BYOK() {
  return (
    <section id="privacy" className="mk-section" style={{ background: 'var(--pc-surface-sidebar)' }}>
      <div className="mk-container">
        <div className="byok">
          <div>
            <span className="mk-eyebrow">Bring your own keys</span>
            <h2 className="mk-section-h" style={{ margin: '14px 0 22px' }}>
              Your money. Your keys. <em className="mk-ink-grad" style={{ fontStyle:'normal' }}>Your prompts.</em>
            </h2>
            <p className="mk-lede" style={{ marginBottom: 20 }}>
              Polycode never sees your traffic. Keys live in the macOS Keychain, requests go directly
              from your machine to the providers you've authorized, and we couldn't read your conversations
              even if we wanted to — there's no server in the loop.
            </p>
            <ul className="checklist">
              <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
                Keys stored in the system Keychain — never on disk in plaintext, never on our servers.</li>
              <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
                Direct calls to provider APIs. No proxy, no rewriting, no middleman markup.</li>
              <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
                Anonymous diagnostics are on by default and fully documented — toggle them off in Settings, no account required.</li>
              <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
                Run <span className="mk-mono" style={{ fontSize: '0.95em', verticalAlign: 'baseline' }}>ollama</span>, <span className="mk-mono" style={{ fontSize: '0.95em', verticalAlign: 'baseline' }}>LM Studio</span>, or any local OpenAI-compatible endpoint entirely offline if you want zero network at all.</li>
            </ul>
          </div>
          <KeyMock/>
        </div>
      </div>
    </section>
  );
}

function KeyMock() {
  const rows = [
    { p: 'anthropic',  label:'Claude',         val: 'sk-ant-•••••••••••••3a9f',     status: 'ok',    note: 'validated · 4 models' },
    { p: 'openai',     label:'GPT-5',          val: 'sk-•••••••••••••••••2c0e',     status: 'ok',    note: 'validated · 12 models' },
    { p: 'gemini',     label:'Gemini',         val: 'AIza••••••••••••••••Vp1q',    status: 'ok',    note: 'validated · 6 models' },
    { p: 'foundation', label:'Apple Intelligence', val: 'on-device · Neural Engine',  status: 'ok',    note: 'no key required' },
    { p: 'ollama',     label:'Ollama',         val: 'http://localhost:11434',       status: 'warn',  note: 'reachable · 3 models loaded' },
    { p: 'compat',     label:'OpenAI-compatible', val: 'add an endpoint…',          status: 'muted', note: 'optional' },
  ];
  return (
    <div className="key-card">
      <div style={{
        display:'flex', alignItems:'center', gap: 10, marginBottom: 8,
        padding: '0 4px',
      }}>
        <Icon name="lock" size={14} color="var(--pc-content-secondary)"/>
        <span style={{ fontSize: 13.5, fontWeight: 600 }}>Providers</span>
        <span style={{ fontFamily: FONT_MONO, fontSize: 11, color: 'var(--pc-content-tertiary)' }}>· 4 active · keychain</span>
        <div style={{ flex: 1 }}/>
        <span style={{
          fontFamily: FONT_MONO, fontSize: 10, color: 'var(--pc-content-tertiary)',
          padding: '2px 7px', background: 'var(--pc-surface-inset)', borderRadius: 4,
        }}>⌘,</span>
      </div>
      {rows.map((r) => (
        <div key={r.p} className="key-row">
          <ProviderTile provider={r.p} size={26}/>
          <div className="info">
            <div className="name">{r.label}</div>
            <div className="val">{r.val}</div>
          </div>
          <div style={{ textAlign: 'right' }}>
            <span className={`pip ${r.status}`}>
              {r.status === 'ok' ? '✓ valid' : r.status === 'warn' ? '◇ local' : '+ add'}
            </span>
            <div style={{ fontSize: 10.5, color: 'var(--pc-content-tertiary)', marginTop: 4 }}>{r.note}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Pricing() {
  return (
    <section id="pricing" className="mk-section tall">
      <div className="mk-container">
        <div className="section-head" style={{ gridTemplateColumns: '1fr', textAlign: 'center', alignItems: 'center' }}>
          <div className="title" style={{ alignItems: 'center' }}>
            <span className="mk-eyebrow" style={{ alignSelf: 'center' }}>Launch price</span>
            <h2 className="mk-section-h">Buy it once. Keep it forever.</h2>
            <p className="mk-lede" style={{ marginTop: 4, textAlign: 'center', marginInline: 'auto' }}>
              No subscription. No per-seat. No usage tax. Pay once, then bring your own keys —
              you'll spend on the providers you actually use.
            </p>
          </div>
        </div>

        <div className="pricing-card">
          <div style={{
            display: 'flex', alignItems: 'center', gap: 14, marginBottom: 6,
          }}>
            <PolycodeIcon size={48}/>
            <div>
              <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.014em' }}>Polycode</div>
              <div style={{ fontSize: 12.5, color: 'var(--pc-content-tertiary)', fontFamily: FONT_MONO }}>macOS Sonoma & later</div>
            </div>
          </div>
          <div className="price" style={{ marginTop: 22 }}>
            <span className="cur">$</span>
            <span className="amt">39</span>
            <span className="once">one time</span>
          </div>
          <ul className="checklist">
            <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
              Universal binary for Apple Silicon and Intel Macs.</li>
            <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
              Unlimited providers, unlimited sessions, unlimited keys.</li>
            <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
              All future updates included. Forever.</li>
            <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
              Family Sharing supported. Up to 5 family members on one purchase.</li>
            <li><span className="check"><Icon name="check" size={11} strokeWidth={2.5}/></span>
              <span className="muted">Provider costs are billed by the providers themselves.</span></li>
          </ul>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 28 }}>
            <a href="#waitlist" className="btn btn-primary btn-lg" style={{ justifyContent: 'center' }}>
              <Icon name="sparkles" size={15} color="white"/>
              Join the waitlist for launch pricing
            </a>
            <button type="button" className="btn btn-ghost btn-lg" disabled aria-disabled="true" style={{ justifyContent: 'center', cursor: 'not-allowed', opacity: 0.7 }}>
              <Icon name="apple" size={15}/>
              TestFlight · Coming soon
            </button>
          </div>
          <div style={{
            marginTop: 14, fontSize: 12, color: 'var(--pc-content-tertiary)', textAlign: 'center',
          }}>
            Coming soon to the Mac App Store.
          </div>
          <div style={{
            marginTop: 18, paddingTop: 16,
            borderTop: '0.5px solid var(--pc-border-subtle)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, flexWrap: 'wrap',
            fontSize: 12, color: 'var(--pc-content-tertiary)',
          }}>
            Questions? Email <span className="mk-mono" style={{ fontSize: '0.95em', verticalAlign: 'baseline' }}>about@polycode.me</span>.
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function FAQ() {
  const items = [
    { q: 'Why pay for a chat client when ChatGPT and Claude have native apps?',
      a: "Because no single provider's app shows you what the other providers would have said. Polycode's whole shape is the comparison — fan-out, dissent, consensus. The official apps are great if you've already picked a horse; Polycode is for the times you haven't." },
    { q: 'Do I need accounts with every provider?',
      a: "No. Configure as many or as few as you want. With zero keys, you can still run Apple Intelligence on-device and Ollama against a local model. Most users start with one paid provider plus on-device, then add others as needed." },
    { q: 'Can I just use OpenRouter for everything?',
      a: "Yes, and for most people that's the fastest way to get the full fan-out experience. One OpenRouter key covers Anthropic, OpenAI, Gemini, xAI, Mistral, Meta, DeepSeek, and dozens more — one signup, one invoice, no juggling. The tradeoffs: OpenRouter sits in the network path between you and the upstream provider (so it's not as direct as a per-provider key), and most upstreams carry a small markup on top of the underlying API price. Apple Intelligence and local providers like Ollama or LM Studio aren't routed through OpenRouter — those still run on-device for free." },
    { q: 'Will my prompts ever leave my machine through your servers?',
      a: "No. Polycode talks directly to the providers you authorize. We don't run a proxy, we don't see your traffic, and we don't have a way to inspect, log, or train on your conversations." },
    { q: 'How does fan-out cost compare to using one model?',
      a: "It costs roughly N× one model where N is the number of configured providers — the same prompt is sent to each. The trace card shows exact tokens and dollars per provider, so you always know what you spent." },
    { q: 'What about MCP servers and tool calls?',
      a: "Polycode is a first-class MCP host. Connect a server, its tools appear inline on the consensus model, you can approve or reject calls per-exchange, and the trace records which provider's plan was actually executed." },
    { q: 'When will an iPad / iPhone app ship?',
      a: "Not yet on the public roadmap. The current app leans hard on macOS-only affordances — three-column layout, Inspector, Spotlight indexing, MCP processes — and we'd rather ship one native app well than three thin ones." },
  ];
  return (
    <section id="faq" className="mk-section" style={{ background: 'var(--pc-surface-sidebar)' }}>
      <div className="mk-narrow">
        <div className="section-head" style={{ gridTemplateColumns: '1fr', alignItems: 'start' }}>
          <div className="title">
            <span className="mk-eyebrow">FAQ</span>
            <h2 className="mk-section-h">Plain answers.</h2>
          </div>
        </div>
        <div className="faq">
          {items.map((it, i) => (
            <details key={i}>
              <summary>
                <span>{it.q}</span>
                <span className="marker"><Icon name="plus" size={14} strokeWidth={2}/></span>
              </summary>
              <div>{it.a}</div>
            </details>
          ))}
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Waitlist() {
  const [email, setEmail] = React.useState('');
  const [state, setState] = React.useState('idle'); // idle | submitting | success | error
  const [error, setError] = React.useState('');
  const onSubmit = async (e) => {
    e.preventDefault();
    setError('');
    const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    if (!ok) { setError('That doesn\u2019t look like an email address.'); setState('error'); return; }
    setState('submitting');
    try {
      const res = await fetch('/api/waitlist', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ email }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok || !data.ok) {
        setError(data.error === 'invalid_email'
          ? 'That doesn’t look like an email address.'
          : 'Something went wrong. Please try again in a moment.');
        setState('error');
        return;
      }
      setState('success');
    } catch {
      setError('Couldn’t reach the server. Check your connection and try again.');
      setState('error');
    }
  };
  return (
    <section id="waitlist" className="mk-section tight" style={{ background: 'var(--pc-surface-canvas)' }}>
      <div className="mk-container">
        <div className="waitlist-card">
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
            <PolycodeIcon size={36}/>
            <span className="mk-eyebrow">Stay up to date</span>
          </div>
          <h2 style={{
            margin: '0 0 10px',
            fontSize: 'clamp(26px, 2.4vw, 34px)', fontWeight: 600,
            letterSpacing: '-0.020em', lineHeight: 1.1,
            color: 'var(--pc-content-primary)',
          }}>
            Stay up to date with Polycode.
          </h2>
          <p className="mk-body" style={{ margin: '0 0 22px', maxWidth: '52ch' }}>
            One email per release. No drip campaign, no growth hacks — just changelogs,
            new-provider announcements, and the occasional behind-the-scenes note.
          </p>

          {state === 'success' ? (
            <div className="waitlist-success">
              <span className="check"><Icon name="check" size={14} color="white" strokeWidth={2.5}/></span>
              <div>
                <div style={{ fontWeight: 600 }}>You're on the list.</div>
                <div style={{ color: 'var(--pc-content-secondary)', fontSize: 13, marginTop: 2 }}>
                  We'll keep <span className="mk-mono" style={{ fontSize: 12.5 }}>{email}</span> in the loop on every Polycode release.
                </div>
              </div>
            </div>
          ) : (
            <form className="waitlist-form" onSubmit={onSubmit} noValidate>
              <input
                type="email" required
                value={email}
                onChange={(e) => { setEmail(e.target.value); setState('idle'); setError(''); }}
                placeholder="you@yourdomain.com"
                aria-label="Email address"
                disabled={state === 'submitting'}
              />
              <button type="submit" className="btn btn-primary" disabled={state === 'submitting'}>
                {state === 'submitting' ? 'Saving…' : 'Notify me'}
                {state !== 'submitting' && <Icon name="arrowRight" size={14} color="white" strokeWidth={2}/>}
              </button>
            </form>
          )}

          {error && <div className="waitlist-error">{error}</div>}

          <ul className="waitlist-perks">
            <li><Icon name="check" size={11} color="var(--pc-status-success)" strokeWidth={2.5}/> First in line for the public launch on the Mac App Store</li>
            <li><Icon name="check" size={11} color="var(--pc-status-success)" strokeWidth={2.5}/> Eligible for early TestFlight invites as seats open up</li>
            <li><Icon name="lock" size={11} color="var(--pc-content-tertiary)"/> No spam, unsubscribe in one click</li>
          </ul>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Download() {
  return (
    <section id="testflight" className="cap-section">
      <div className="mk-narrow" style={{ textAlign: 'center' }}>
        <div style={{ display: 'inline-flex', justifyContent: 'center' }}>
          <PolycodeIcon size={88}/>
        </div>
        <h2 className="mk-mega-h" style={{ marginTop: 28 }}>
          Talk to <span className="mk-ink-grad">all of them</span>.
          <br/>Read just one.
        </h2>
        <p className="mk-lede" style={{ margin: '20px auto 0', maxWidth: 540 }}>
          Polycode is coming to the Mac App Store. Get on the waitlist to lock in launch pricing — or join the TestFlight beta to try it first.
        </p>
        <div className="hero-cta" style={{ justifyContent: 'center' }}>
          <a href="#waitlist" className="btn btn-primary btn-lg">
            <Icon name="sparkles" size={16} color="white"/>
            Notify me at launch
          </a>
          <button type="button" className="btn btn-ghost btn-lg" disabled aria-disabled="true" style={{ cursor: 'not-allowed', opacity: 0.7 }}>
            <Icon name="apple" size={16}/>
            TestFlight · Coming soon
          </button>
        </div>
        <div className="hero-meta" style={{ justifyContent: 'center', marginTop: 22 }}>
          <span>Universal · Apple Silicon + Intel</span>
          <span className="dot"/>
          <span>macOS Sonoma & later</span>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer className="mk-footer">
      <div className="mk-container">
        <div className="grid">
          <div>
            <PolycodeWordmark height={22}/>
            <p style={{
              marginTop: 16,
              fontSize: 13.5, lineHeight: 1.55,
              color: 'var(--pc-content-secondary)', maxWidth: '52ch',
            }}>
              A native macOS chat client. Many minds, one reply. Built with respect for your
              keys, your money, and your laptop fans.
            </p>
          </div>
        </div>
        <div className="credits">
          <span>© 2026 Polycode. All rights reserved.</span>
          <span>Made on a Mac · Apple, the Apple logo, and macOS are trademarks of Apple Inc.</span>
        </div>
      </div>
    </footer>
  );
}

// ─────────────────────────────────────────────────────────────────────
function Site() {
  return (
    <React.Fragment>
      <Nav/>
      <main>
        <Hero/>
        <ProvidersStrip/>
        <Receipts/>
        <FanOut/>
        <InspectorFeature/>
        <Native/>
        <BYOK/>
        <Pricing/>
        <FAQ/>
        <Waitlist/>
        <Download/>
      </main>
      <Footer/>
    </React.Fragment>
  );
}

Object.assign(window, { Site });
