// Landing page — getfossyl.dev

function Landing() {
  const { go } = useNav();
  const { authed } = useAuth();
  const { toast } = useToast();
  const featuresRef = useRef(null);
  const howRef = useRef(null);
  const pricingRef = useRef(null);
  const scrollTo = (ref) => ref.current && ref.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
  const ctaPrimary = () => go(authed ? 'upload' : 'signup');
  const onComingSoon = (label) => toast(`${label} — coming soon`);
  return (
    <div style={{ background: 'var(--bg)', color: 'var(--ink)' }}>
      <TopNav
        onCta={() => go('signup')}
        onLogin={() => go('login')}
        onProduct={() => scrollTo(featuresRef)}
        onHow={() => scrollTo(howRef)}
        onPricing={() => go('pricing')}
        onChangelog={() => onComingSoon('Changelog')}
        onDocs={() => onComingSoon('Docs')}
        authed={authed}
      />
      <Hero onCta={ctaPrimary} onSample={() => go('report')} authed={authed} />
      <KeyFigures />
      <ProblemStatement />
      <div ref={howRef}><HowItWorks /></div>
      <ReportPreview onOpen={() => go('report')} />
      <div ref={featuresRef} data-section="features"><FeaturesGrid /></div>
      <div ref={pricingRef}><PricingStrip onCta={() => go('pricing')} /></div>
      <TestimonialStrip />
      <FAQSection />
      <Footer />
    </div>
  );
}

function TopNav({ onCta, onLogin, onProduct, onHow, onPricing, onChangelog, onDocs, authed }) {
  const { go } = useNav();
  return (
    <div style={{
      position: 'sticky', top: 0, zIndex: 20,
      background: 'rgba(11,12,13,0.85)',
      backdropFilter: 'blur(10px)',
      borderBottom: '1px solid var(--line)',
    }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '14px 32px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <a onClick={() => go('landing')} style={{ cursor: 'pointer' }}><Logo size={22}/></a>
        <nav style={{ display: 'flex', gap: 28, fontSize: 13 }}>
          <a className="ink-dim" style={{ cursor: 'pointer' }} onClick={onProduct}>Product</a>
          <a className="ink-dim" style={{ cursor: 'pointer' }} onClick={onHow}>How it works</a>
          <a className="ink-dim" style={{ cursor: 'pointer' }} onClick={onPricing}>Pricing</a>
          <a className="ink-dim" style={{ cursor: 'pointer' }} onClick={onChangelog}>Changelog</a>
          <a className="ink-dim" style={{ cursor: 'pointer' }} onClick={onDocs}>Docs</a>
        </nav>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          {authed
            ? <button className="btn btn-primary btn-sm" onClick={() => go('upload')}>Open app →</button>
            : <>
                <button className="btn btn-ghost btn-sm" onClick={onLogin}>Sign in</button>
                <button className="btn btn-primary btn-sm" onClick={onCta}>Get Fossyl</button>
              </>}
        </div>
      </div>
    </div>
  );
}

function Hero({ onCta, onSample, authed }) {
  return (
    <section style={{ position: 'relative', borderBottom: '1px solid var(--line)' }}>
      {/* faint grid */}
      <div style={{
        position: 'absolute', inset: 0,
        backgroundImage: 'linear-gradient(to right, rgba(255,255,255,0.025) 1px, transparent 1px), linear-gradient(to bottom, rgba(255,255,255,0.025) 1px, transparent 1px)',
        backgroundSize: '56px 56px',
        maskImage: 'radial-gradient(ellipse at 50% 40%, black 0%, transparent 75%)',
      }}/>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '72px 32px 56px', position: 'relative' }}>
        <div className="row ai-c g-8" style={{ marginBottom: 28 }}>
          <span className="caps">Fossyl — Field report v1.2</span>
          <span className="dim">·</span>
          <span className="mono" style={{ fontSize: 11, color: 'var(--muted)' }}>Stratum 2005—2015 / Zope · Plone · ZODB</span>
        </div>
        <h1 className="display" style={{ margin: 0, fontSize: 88, lineHeight: 0.98, maxWidth: 1100, fontWeight: 400, letterSpacing: '-0.025em' }}>
          Turn the legacy codebase<br/>
          you <em style={{ fontStyle: 'italic', color: 'var(--bone)' }}>inherited</em> into a map<br/>
          you can actually read.
        </h1>
        <div className="row g-48" style={{ marginTop: 56, alignItems: 'flex-start' }}>
          <p style={{ fontSize: 17, lineHeight: 1.55, maxWidth: 540, color: 'var(--ink-dim)', margin: 0 }}>
            Fossyl ingests a Zope/Plone codebase — filesystem, live ZODB export, optional MySQL schema — and produces a structured archaeological report of what runs in production, what was never version-controlled, what breaks if you touch it, and what is safe to remove.
          </p>
          <div className="col g-16" style={{ maxWidth: 420 }}>
            <div className="row g-12 ai-c">
              <button className="btn btn-primary btn-lg" onClick={onCta}>{authed ? 'Run an excavation →' : 'Run your first excavation →'}</button>
              <button className="btn btn-lg" onClick={onSample}>View sample report</button>
            </div>
            <div className="mono" style={{ fontSize: 11.5, color: 'var(--muted)' }}>
              Upload ZIP + ZODB export. Full report in ≤ 60s. No data retained after download.
            </div>
          </div>
        </div>

        {/* Stratum ribbon */}
        <div style={{ marginTop: 72, border: '1px solid var(--line)', borderRadius: 3, background: 'var(--bg-1)' }}>
          <div className="row" style={{ padding: '10px 16px', borderBottom: '1px solid var(--line)', justifyContent: 'space-between', alignItems: 'center' }}>
            <span className="caps">Specimen 01 — Charité Berlin / Patient Portal (ca. 2008)</span>
            <span className="mono" style={{ fontSize: 11, color: 'var(--dim)' }}>scan_id F-8a3f · 2026-04-12 09:14</span>
          </div>
          <Ticks count={72} height={8}/>
          <div className="row" style={{ padding: '0 0 0 0' }}>
            <HeroStratum label="FILESYSTEM" count="1,204" sub="files, version-controlled" tone="slate" bar={[['slate', 100]]}/>
            <HeroStratum label="ZODB RECORDS" count="862" sub="persisted objects in live db" tone="bone" bar={[['bone', 100]]}/>
            <HeroStratum label="TTW-ONLY" count="693" sub="through-the-web, no fs copy" tone="rust" bar={[['rust', 100]]}/>
            <HeroStratum label="DIVERGENT" count="41%" sub="of live code exists nowhere in git" tone="rust" bar={[['rust', 41], ['line', 59]]}/>
          </div>
        </div>
      </div>
    </section>
  );
}

function HeroStratum({ label, count, sub, tone, bar }) {
  const colorMap = { slate: 'var(--slate)', bone: 'var(--bone)', rust: 'var(--rust)', lichen: 'var(--lichen)', line: 'var(--line-2)' };
  return (
    <div style={{ flex: 1, padding: '20px 24px', borderRight: '1px solid var(--line)' }}>
      <div className="caps" style={{ marginBottom: 10 }}>{label}</div>
      <div className="num" style={{ fontFamily: 'var(--serif)', fontSize: 44, fontWeight: 400, letterSpacing: '-0.02em', lineHeight: 1, color: colorMap[tone] }}>{count}</div>
      <div className="mono" style={{ fontSize: 11, color: 'var(--muted)', marginTop: 8 }}>{sub}</div>
      <div style={{ display: 'flex', marginTop: 14, height: 3, borderRadius: 1, overflow: 'hidden' }}>
        {bar.map(([c, pct], i) => (
          <div key={i} style={{ width: pct + '%', background: colorMap[c] }}/>
        ))}
      </div>
    </div>
  );
}

function KeyFigures() {
  return (
    <section style={{ borderBottom: '1px solid var(--line)' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px' }}>
        <div className="row" style={{ borderLeft: '1px solid var(--line)', borderRight: '1px solid var(--line)' }}>
          <Stat label="ZODB records parsed" value="862" unit="objects"/>
          <Stat label="Dependency edges" value="412" unit="directed"/>
          <Stat label="TTW scripts surfaced" value="693" unit="no fs copy" tone="rust"/>
          <Stat label="Dead code candidates" value="117" unit="unreferenced"/>
          <Stat label="Report size" value="4.2" unit="MB · self-contained"/>
        </div>
      </div>
    </section>
  );
}

function ProblemStatement() {
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '96px 0' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px', display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 80 }}>
        <div>
          <span className="caps">§ 01 — The problem</span>
          <h2 className="display" style={{ fontSize: 52, fontWeight: 400, letterSpacing: '-0.02em', lineHeight: 1.05, margin: '20px 0 0' }}>
            Half of what's running<br/>isn't in the repo.
          </h2>
        </div>
        <div className="col g-32">
          <p style={{ fontSize: 18, lineHeight: 1.55, color: 'var(--ink)', margin: 0, fontFamily: 'var(--serif)', fontWeight: 300 }}>
            Zope/Plone systems allow code to live in two places simultaneously — the filesystem (visible, version-controlled) and the live ZODB object database (invisible, untracked, often the only copy).
          </p>
          <p style={{ fontSize: 16, lineHeight: 1.6, color: 'var(--ink-dim)', margin: 0, maxWidth: 640 }}>
            A script edited through the browser five years ago by a contractor who has since left the organisation exists nowhere except the running server. If that server dies, the code is gone. If you're planning a migration, you cannot plan around what you cannot see.
          </p>
          <p style={{ fontSize: 16, lineHeight: 1.6, color: 'var(--ink-dim)', margin: 0, maxWidth: 640 }}>
            <span className="bone">Fossyl makes the invisible layer visible.</span>{' '}
            It reconciles the filesystem against the live database, surfaces every script that has no version-controlled copy, and ranks each artifact by how much downstream code depends on it.
          </p>

          <div className="col g-8" style={{ marginTop: 16 }}>
            <FieldNote index={1}>
              A Patient-Admission workflow in Specimen 01 contained 14 TTW scripts. None were in git. Three of them wrote directly to the billing ledger.
            </FieldNote>
            <FieldNote index={2}>
              Of 862 ZODB records examined, 693 (80.4%) had no counterpart on the filesystem — the definition of the object existed only in the running process.
            </FieldNote>
            <FieldNote index={3}>
              The oldest divergence we have measured: a Python Script named <code className="mono" style={{ color: 'var(--bone)' }}>sendReferralFax</code> last modified 2011-03-08. Still in the critical path in 2026.
            </FieldNote>
          </div>
        </div>
      </div>
    </section>
  );
}

function HowItWorks() {
  const steps = [
    { n: '01', t: 'Ingest', d: 'Upload your repository ZIP and a ZODB export. Optionally add a phpMyAdmin SQL dump for schema mapping.', meta: 'zip · fs.data · schema.sql' },
    { n: '02', t: 'Excavate', d: 'Fossyl parses every ZODB record, walks the filesystem, resolves Zope traversal, and reconciles the two layers. 40–60 seconds on a mid-sized codebase.', meta: '~52s median · 862 records' },
    { n: '03', t: 'Map', d: 'The dependency graph, divergence matrix, coupling analysis, and version-group detection run on the reconciled tree.', meta: '8 sections · 412 edges' },
    { n: '04', t: 'Read', d: 'A self-contained HTML report is generated — readable in a browser, printable as PDF, no server required after download.', meta: 'single file · ≤ 4.2 MB' },
  ];
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '96px 0', background: 'var(--bg-1)' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px' }}>
        <div className="row jc-b ai-s" style={{ marginBottom: 56 }}>
          <div>
            <span className="caps">§ 02 — Method</span>
            <h2 className="display" style={{ fontSize: 52, fontWeight: 400, letterSpacing: '-0.02em', margin: '20px 0 0' }}>Four layers. One report.</h2>
          </div>
          <div className="mono" style={{ fontSize: 11, color: 'var(--muted)', maxWidth: 280, textAlign: 'right' }}>
            Fig. 02 — Ingestion pipeline. Each layer can be audited independently.
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, border: '1px solid var(--line)', background: 'var(--bg)' }}>
          {steps.map((s, i) => (
            <div key={s.n} style={{ padding: '28px 24px 32px', borderRight: i < 3 ? '1px solid var(--line)' : 'none', position: 'relative' }}>
              <div className="row jc-b ai-c" style={{ marginBottom: 32 }}>
                <span className="mono" style={{ fontSize: 11, color: 'var(--dim)' }}>{s.n}</span>
                <span className="mono" style={{ fontSize: 10.5, color: 'var(--muted)', letterSpacing: '0.08em' }}>{s.meta}</span>
              </div>
              <h3 className="serif" style={{ fontSize: 26, fontWeight: 400, letterSpacing: '-0.01em', margin: '0 0 14px' }}>{s.t}</h3>
              <p style={{ fontSize: 13.5, lineHeight: 1.55, color: 'var(--ink-dim)', margin: 0 }}>{s.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function ReportPreview({ onOpen }) {
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '96px 0' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px' }}>
        <div className="row jc-b ai-s" style={{ marginBottom: 40 }}>
          <div>
            <span className="caps">§ 03 — The report</span>
            <h2 className="display" style={{ fontSize: 52, fontWeight: 400, letterSpacing: '-0.02em', margin: '20px 0 0' }}>Eight sections.<br/>One HTML file.</h2>
          </div>
          <button className="btn" onClick={onOpen}>Open sample report →</button>
        </div>
        <div style={{ border: '1px solid var(--line)', background: 'var(--bg-1)', borderRadius: 3, padding: 24 }}>
          <div className="row jc-b ai-c" style={{ marginBottom: 20 }}>
            <span className="caps">Fig. 03 — §2 Risk stratigraphy (excerpt from a real report)</span>
            <div className="row g-12" style={{ fontSize: 11, fontFamily: 'var(--mono)', color: 'var(--muted)' }}>
              <span><span className="dot safe"></span> synchronized</span>
              <span><span className="dot warn"></span> diverged</span>
              <span><span className="dot risk"></span> TTW-only</span>
            </div>
          </div>
          <RiskStratigraphy/>
          <div style={{ marginTop: 24, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', columnGap: 24, rowGap: 0 }}>
            <ReportListItem num="§1" title="Filesystem ↔ ZODB divergence" meta="41% divergent"/>
            <ReportListItem num="§2" title="Dependency graph" meta="412 edges / 145 nodes"/>
            <ReportListItem num="§3" title="High-coupling risk analysis" meta="18 critical files"/>
            <ReportListItem num="§4" title="Version-group detection" meta="33 duplicate clusters"/>
            <ReportListItem num="§5" title="Dead-code candidates" meta="117 unreferenced"/>
            <ReportListItem num="§6" title="AI field explanations" meta="per critical artifact"/>
            <ReportListItem num="§7" title="Source browser" meta="full, filterable"/>
            <ReportListItem num="§8" title="DB schema mapping" meta="optional · MySQL"/>
          </div>
        </div>
      </div>
    </section>
  );
}

function ReportListItem({ num, title, meta }) {
  return (
    <div className="row jc-b ai-c" style={{ padding: '10px 0', borderBottom: '1px solid var(--line)' }}>
      <div className="row g-12 ai-c">
        <span className="mono" style={{ color: 'var(--dim)', fontSize: 11, minWidth: 24 }}>{num}</span>
        <span style={{ fontSize: 13.5 }}>{title}</span>
      </div>
      <span className="mono" style={{ fontSize: 10.5, color: 'var(--muted)', letterSpacing: '0.04em' }}>{meta}</span>
    </div>
  );
}

function FeaturesGrid() {
  const items = [
    { e: '§ Divergence', t: 'Filesystem vs live database', d: 'Every script running in production, mapped against what exists in version control. The delta is the danger.' },
    { e: '§ Graph', t: '400+ edge dependency map', d: 'Directed graph of which scripts call which, with adjustable layout (force, radial, adjacency matrix).' },
    { e: '§ Coupling', t: 'Risk ranking', d: 'Identifies the files with the most downstream dependents — the ones that break everything if you touch them.' },
    { e: '§ Version', t: 'Version-group detection', d: 'Finds duplicate or near-duplicate logic across the codebase. Three copies of the same function is three bugs waiting.' },
    { e: '§ Dead', t: 'Unreferenced artifacts', d: 'Candidates for deletion. Scripts, templates and objects with zero callers, still taking up space in the ZODB.' },
    { e: '§ AI', t: 'Plain-English field notes', d: 'For each critical artifact, a dry, factual explanation of what it does and why changing it is dangerous.' },
    { e: '§ Source', t: 'Full source browser', d: 'Every file, filterable and searchable, inside the same self-contained HTML report.' },
    { e: '§ Schema', t: 'Database schema map', d: 'Optional. Ingest a phpMyAdmin SQL export and get the relational layer cross-referenced to Zope types.' },
  ];
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '96px 0', background: 'var(--bg-1)' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px' }}>
        <div style={{ marginBottom: 48 }}>
          <span className="caps">§ 04 — What you get</span>
          <h2 className="display" style={{ fontSize: 52, fontWeight: 400, letterSpacing: '-0.02em', margin: '20px 0 0' }}>Every section earns its place.</h2>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, border: '1px solid var(--line)', background: 'var(--bg)' }}>
          {items.map((it, i) => (
            <div key={i} style={{
              padding: '28px 24px',
              borderRight: (i + 1) % 4 !== 0 ? '1px solid var(--line)' : 'none',
              borderBottom: i < 4 ? '1px solid var(--line)' : 'none',
              minHeight: 200,
            }}>
              <div className="caps" style={{ marginBottom: 20 }}>{it.e}</div>
              <h3 className="serif" style={{ fontSize: 20, fontWeight: 400, letterSpacing: '-0.01em', margin: '0 0 12px' }}>{it.t}</h3>
              <p style={{ fontSize: 13, lineHeight: 1.55, color: 'var(--ink-dim)', margin: 0 }}>{it.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function PricingStrip({ onCta }) {
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '72px 0' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 80, alignItems: 'center' }}>
        <div>
          <span className="caps">§ 05 — Pricing</span>
          <h2 className="display" style={{ fontSize: 44, fontWeight: 400, letterSpacing: '-0.02em', margin: '20px 0 24px' }}>
            One scan. One report.<br/>One flat fee.
          </h2>
          <p style={{ fontSize: 15, lineHeight: 1.55, color: 'var(--ink-dim)', maxWidth: 480, margin: 0 }}>
            Most customers buy a single scan to prepare a migration. Teams running multiple sites subscribe. Consulting firms use the Agency plan.
          </p>
        </div>
        <div className="col g-12">
          <PricingMini name="One-off scan" price="€ 2,400" sub="single codebase · single report"/>
          <PricingMini name="Team" price="€ 490" sub="/ month · unlimited scans, 5 seats" featured/>
          <PricingMini name="Agency" price="custom" sub="white-label reports · 10+ clients"/>
          <button className="btn btn-primary btn-lg" style={{ marginTop: 12, width: '100%', justifyContent: 'center' }} onClick={onCta}>See full pricing →</button>
        </div>
      </div>
    </section>
  );
}

function PricingMini({ name, price, sub, featured }) {
  return (
    <div className="row jc-b ai-c" style={{
      padding: '16px 20px',
      border: '1px solid ' + (featured ? 'var(--bone-dim)' : 'var(--line)'),
      background: featured ? 'var(--bg-2)' : 'var(--bg-1)',
      borderRadius: 3,
    }}>
      <div className="col">
        <span style={{ fontSize: 15, fontWeight: 500 }}>{name}</span>
        <span className="mono" style={{ fontSize: 11, color: 'var(--muted)' }}>{sub}</span>
      </div>
      <div className="serif" style={{ fontSize: 26, fontWeight: 400, letterSpacing: '-0.02em' }}>{price}</div>
    </div>
  );
}

function TestimonialStrip() {
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '96px 0' }}>
      <div style={{ maxWidth: 1080, margin: '0 auto', padding: '0 32px' }}>
        <span className="caps">§ 06 — Specimen reports</span>
        <div className="row" style={{ marginTop: 32, gap: 48, alignItems: 'flex-start' }}>
          <blockquote style={{ margin: 0, flex: 1 }}>
            <p className="serif" style={{ fontSize: 24, fontWeight: 300, lineHeight: 1.35, margin: 0, letterSpacing: '-0.01em' }}>
              "We had spent four months arguing about what the old patient portal actually did. Fossyl answered the argument in 52 seconds. 693 scripts that weren't in git. We had estimated 40."
            </p>
            <footer style={{ marginTop: 20, fontSize: 12, color: 'var(--muted)', fontFamily: 'var(--mono)' }}>
              — Engineering lead, University hospital (name withheld). Specimen 01.
            </footer>
          </blockquote>
          <div style={{ width: 200, flexShrink: 0 }}>
            <FossilPlaceholder w={200} h={140} label="PORTRAIT" sub="Dr. M. —"/>
          </div>
        </div>
      </div>
    </section>
  );
}

function FAQSection() {
  const faqs = [
    { q: 'Where does my code go?', a: 'Uploads are processed in an ephemeral container and deleted immediately after the report is generated. Fossyl retains no copy of your source, your ZODB, or your schema.' },
    { q: 'What about the AI explanations — is my code sent to a third party?', a: 'Only the signatures and call sites of critical artifacts are sent to the model, never the full source. You can disable AI explanations entirely; the rest of the report is generated locally.' },
    { q: 'Can I run Fossyl on-premise?', a: 'Yes. Enterprise plans include a Docker image that runs inside your network. Nothing leaves your infrastructure.' },
    { q: 'What frameworks does it support?', a: 'Today: Zope 2, Zope 4, Plone 4/5/6. The ingestion layer is modular. Django, Rails and legacy Java EE are on the roadmap.' },
    { q: 'What about very large codebases?', a: 'Tested up to 50k files / 12k ZODB records. The report stays under 12 MB and remains a single HTML file.' },
  ];
  return (
    <section style={{ borderBottom: '1px solid var(--line)', padding: '96px 0', background: 'var(--bg-1)' }}>
      <div style={{ maxWidth: 1080, margin: '0 auto', padding: '0 32px' }}>
        <span className="caps">§ 07 — Questions from the field</span>
        <h2 className="display" style={{ fontSize: 44, fontWeight: 400, letterSpacing: '-0.02em', margin: '20px 0 40px' }}>Frequently asked.</h2>
        <div>
          {faqs.map((f, i) => (
            <div key={i} style={{ borderTop: '1px solid var(--line)', padding: '24px 0', display: 'grid', gridTemplateColumns: '40px 1fr 1fr', gap: 32, alignItems: 'start' }}>
              <span className="mono" style={{ color: 'var(--dim)', fontSize: 11, paddingTop: 4 }}>Q.0{i+1}</span>
              <h3 className="serif" style={{ fontSize: 20, fontWeight: 400, margin: 0, letterSpacing: '-0.01em' }}>{f.q}</h3>
              <p style={{ margin: 0, fontSize: 14, lineHeight: 1.6, color: 'var(--ink-dim)' }}>{f.a}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Footer() {
  const { go } = useNav();
  const { toast } = useToast();
  const cs = (label) => () => toast(`${label} \u2014 coming soon`);
  const scrollToTop = () => window.scrollTo({ top: 0, behavior: 'smooth' });
  const product = [
    ['Features', () => { document.querySelector('[data-section="features"]')?.scrollIntoView({ behavior: 'smooth' }); }],
    ['Pricing', () => go('pricing')],
    ['Changelog', cs('Changelog')],
    ['Sample report', () => go('report')],
    ['Roadmap', cs('Roadmap')],
  ];
  const resources = [
    ['Docs', cs('Docs')],
    ['ZODB primer', cs('ZODB primer')],
    ['Plone 6 migration', cs('Migration guide')],
    ['Support', () => { window.location.href = 'mailto:support@getfossyl.dev'; }],
    ['Status', cs('Status page')],
  ];
  const company = [
    ['About', scrollToTop],
    ['Contact', () => { window.location.href = 'mailto:eri@getfossyl.dev'; }],
    ['Privacy', cs('Privacy policy')],
    ['Terms', cs('Terms of service')],
    ['Security', cs('Security')],
  ];
  return (
    <footer style={{ padding: '48px 0 32px', background: 'var(--bg)' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px' }}>
        <div className="row jc-b ai-s" style={{ paddingBottom: 40, borderBottom: '1px solid var(--line)' }}>
          <div>
            <Logo size={22}/>
            <p style={{ fontSize: 13, color: 'var(--muted)', marginTop: 16, maxWidth: 320 }}>
              Codebase archaeology for teams inheriting systems they didn't build.
            </p>
          </div>
          <div className="row g-48">
            <FooterCol title="Product" items={product}/>
            <FooterCol title="Resources" items={resources}/>
            <FooterCol title="Company" items={company}/>
          </div>
        </div>
        <div className="row jc-b ai-c" style={{ paddingTop: 24 }}>
          <span className="mono" style={{ fontSize: 11, color: 'var(--dim)' }}>© 2026 Fossyl · Berlin · getfossyl.dev</span>
          <span className="mono" style={{ fontSize: 11, color: 'var(--dim)' }}>Built by Erich Kirsten · F-0001 · last field update 2026-04-18</span>
        </div>
      </div>
    </footer>
  );
}

function FooterCol({ title, items }) {
  return (
    <div className="col g-12">
      <span className="caps">{title}</span>
      <div className="col g-8">
        {items.map(([label, onClick]) => (
          <a
            key={label}
            className="ink-dim footer-link"
            style={{ fontSize: 13, cursor: 'pointer' }}
            onClick={onClick}
          >{label}</a>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { Landing });
