const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "Sand",
  "type": "Archivo + Spectral"
}/*EDITMODE-END*/;

const PALETTES = {
  "Sand":       { bg: "#e9e0d2", panel: "#f3ece0", ink: "#1c1813", soft: "#766d5d", line: "rgba(28,24,19,.13)" },
  "Cool paper": { bg: "#eceef0", panel: "#f6f7f8", ink: "#15181c", soft: "#697079", line: "rgba(21,24,28,.12)" },
  "Ivory":      { bg: "#f4efe3", panel: "#fbf8f0", ink: "#211d15", soft: "#7a7363", line: "rgba(33,29,21,.12)" },
  "Slate":      { bg: "#17181a", panel: "#202225", ink: "#ededea", soft: "#9a9a95", line: "rgba(237,237,234,.14)" },
};
const TYPESETS = {
  "Archivo + Spectral": { display: "'Archivo','Helvetica Neue',Arial,sans-serif", body: "'Spectral',Georgia,serif" },
  "All Archivo":        { display: "'Archivo','Helvetica Neue',Arial,sans-serif", body: "'Archivo','Helvetica Neue',Arial,sans-serif" },
  "Archivo + Newsreader": { display: "'Archivo','Helvetica Neue',Arial,sans-serif", body: "'Newsreader',Georgia,serif" },
};

function applyTheme(t) {
  const p = PALETTES[t.palette] || PALETTES["Sand"];
  const ty = TYPESETS[t.type] || TYPESETS["Archivo + Spectral"];
  const r = document.documentElement.style;
  r.setProperty("--cv-bg", p.bg);
  r.setProperty("--cv-panel", p.panel);
  r.setProperty("--cv-ink", p.ink);
  r.setProperty("--cv-soft", p.soft);
  r.setProperty("--cv-line", p.line);
  r.setProperty("--font-display", ty.display);
  r.setProperty("--font-body", ty.body);
  document.documentElement.dataset.palette = t.palette === "Slate" ? "dark" : "light";
}

/* Curated marquee sets for the home carousels */
const ICONIC_FUNDS = ["usv-2004", "bench-7", "seq-8", "thrive-2", "rb-1", "mk-1"];
const ICONIC_PEOPLE = [
  "seq-valentine", "seq-moritz", "bench-gurley", "kp-doerr", "ff-thiel", "ff-rabois",
  "ff-stephens", "usv-wilson", "thrive-kushner", "mk-hsu", "mk-rannala", "fr-kopelman", "rb-malka",
];

/* One-line teasers leading with the notable investments / returns that made each fund iconic */
const ICONIC_FUND_TEASERS = {
  "usv-2004": "Twitter, Zynga, Etsy & Tumblr — ~13.9x on a $125M fund, Twitter alone ~8x.",
  "bench-7": "Led Uber's 2011 Series A — one of the greatest venture returns ever recorded.",
  "seq-8": "Sequoia's 1998 vintage — the Google bet (~$12M → billions), plus PayPal.",
  "thrive-2": "Instagram in 2011 — ~2x in 72 hours — as the concentration thesis took shape.",
  "rb-1": "Ribbit's debut — Coinbase, Credit Karma & the seed of a fintech dynasty.",
  "mk-1": "Honey returned ~$280M (23x the fund); ServiceTitan IPO'd at ~$9B — 43–53x net.",
};

/* One-sentence teasers for what made each iconic person iconic */
const ICONIC_PEOPLE_TEASERS = {
  "seq-valentine": "The father of Silicon Valley venture — backed Atari, Apple, Oracle & Cisco.",
  "seq-moritz": "Wrote the early checks into Google, Yahoo & PayPal.",
  "bench-gurley": "Led Benchmark's Uber bet and defined the internet-marketplace playbook.",
  "kp-doerr": "Backed Google and Amazon; brought OKRs to the Valley.",
  "ff-thiel": "First outside investor in Facebook; co-founded PayPal and Palantir.",
  "ff-rabois": "The operator-investor behind Square, Affirm, Ramp & Faire.",
  "ff-stephens": "Co-founded Anduril and turned American Dynamism into a thesis.",
  "usv-wilson": "Built USV on a daily blog; early in Twitter, Etsy & Coinbase.",
  "thrive-kushner": "Turned a $5M first fund into Thrive; led OpenAI's record round.",
  "mk-hsu": "Ex-eBay & AT&T operator who built Mucker's LA-first micro-VC.",
  "mk-rannala": "Coined the 'Blue Collar VC' and rode Honey to a 23x fund.",
  "fr-kopelman": "Invented institutional seed; wrote First Round's first check into Uber.",
  "rb-malka": "Fintech operator-investor behind Coinbase, Nubank & Robinhood.",
};

/* A firm-swatch used in group headers and the home collage */
function FirmSwatch({ firm }) {
  return (
    <span className="dirgroup__swatch" style={{ background: firm.bg, color: firm.ink }}>
      {firm.logoSrc ? <img src={firm.logoSrc} alt="" /> : firm.name.split(" ").map((w) => w[0]).slice(0, 2).join("")}
    </span>
  );
}

/* Directory view — every fund, grouped by firm */
function FundsDirectory({ nav, search, setSearch }) {
  return (
    <main className="home">
      <TopBar search={search} setSearch={setSearch} onMenu={nav.menu} onHome={nav.home} nav={nav} />
      <div className="pagenav" style={{ padding: "0 44px" }}>
        <Pill variant="ghost" onClick={nav.back}><span style={{ marginRight: 8 }}>←</span> Back</Pill>
      </div>
      <div className="dirhead">
        <h1 className="dirhead__title">Every fund</h1>
        <p className="dirhead__sub">All {window.FUNDS.length} funds across the directory, grouped by firm and ordered by vintage.</p>
      </div>
      {window.FIRMS.map((firm) => {
        const funds = window.fundsForFirm(firm.id).sort((a, b) => (a.vintage || 0) - (b.vintage || 0));
        if (!funds.length) return null;
        return (
          <section className="dirgroup" key={firm.id}>
            <div className="dirgroup__head">
              <FirmSwatch firm={firm} />
              <button className="dirgroup__name" style={{ background: "none", border: "none", cursor: "pointer", padding: 0 }} onClick={() => nav.firm(firm.id)}>{firm.name}</button>
              <span className="dirgroup__count">{funds.length} funds</span>
            </div>
            <DirectoryGrid>
              {funds.map((fd) => (
                <Tile key={fd.id} title={fd.name} tag={String(fd.vintage)}
                  teaser={fd.strategy ? (fd.strategy.length > 116 ? fd.strategy.slice(0, 113).replace(/\s+\S*$/, "") + "…" : fd.strategy) : ""}
                  bg={firm.bg} ink={firm.ink} accent={firm.accent} onClick={() => nav.fund(fd.id)} />
              ))}
            </DirectoryGrid>
          </section>
        );
      })}
      <SiteFooter />
    </main>
  );
}

/* Directory view — every person, grouped by firm */
function PeopleDirectory({ nav, search, setSearch }) {
  return (
    <main className="home">
      <TopBar search={search} setSearch={setSearch} onMenu={nav.menu} onHome={nav.home} nav={nav} />
      <div className="pagenav" style={{ padding: "0 44px" }}>
        <Pill variant="ghost" onClick={nav.back}><span style={{ marginRight: 8 }}>←</span> Back</Pill>
      </div>
      <div className="dirhead">
        <h1 className="dirhead__title">Every person</h1>
        <p className="dirhead__sub">All {window.PEOPLE.length} investors profiled across the directory, grouped by firm.</p>
      </div>
      {window.FIRMS.map((firm) => {
        const people = window.peopleForFirm(firm.id);
        if (!people.length) return null;
        return (
          <section className="dirgroup" key={firm.id}>
            <div className="dirgroup__head">
              <FirmSwatch firm={firm} />
              <button className="dirgroup__name" style={{ background: "none", border: "none", cursor: "pointer", padding: 0 }} onClick={() => nav.firm(firm.id)}>{firm.name}</button>
              <span className="dirgroup__count">{people.length} people</span>
            </div>
            <DirectoryGrid>
              {people.map((p) => (
                <Tile key={p.id} variant="person" initials={initialsOf(p.name)} fullName={p.noPhoto ? p.name : null} title={p.name} tag={p.name}
                  teaser={<React.Fragment><span className="tile__teaserrole">{p.role}</span><br />{p.tenure}</React.Fragment>}
                  bg={p.noPhoto ? "#111111" : firm.bg} ink={p.noPhoto ? "#ffffff" : firm.ink} accent={firm.accent}
                  logoId={p.noPhoto ? undefined : "dir-headshot-" + p.id} src={p.noPhoto ? undefined : p.headshotSrc} onClick={() => nav.person(p.id)} />
              ))}
            </DirectoryGrid>
          </section>
        );
      })}
      <SiteFooter />
    </main>
  );
}

/* ===== URL routing (real paths, e.g. /firm/sequoia) =====
   Paths are shareable and SEO-indexable. The host must rewrite all routes to
   index.html (vercel.json / serve.json included in this folder). */
function viewToPath(v) {
  if (v.kind === "home") return "/";
  if (v.kind === "funds") return "/funds";
  if (v.kind === "people") return "/people";
  return "/" + v.kind + "/" + v.id;
}
function pathToView(path) {
  const p = (path || "/").replace(/\/+$/, "") || "/";
  if (p === "/" || p.endsWith("index.html") || p.endsWith(".html")) return { kind: "home" };
  if (p === "/funds") return { kind: "funds" };
  if (p === "/people") return { kind: "people" };
  const m = p.match(/^\/(firm|fund|person)\/([\w-]+)$/);
  if (m) {
    const lookup = { firm: window.getFirm, fund: window.getFund, person: window.getPerson }[m[1]];
    if (lookup(m[2])) return { kind: m[1], id: m[2] };
  }
  return { kind: "home" };
}
/* Build the logical ancestry for a deep-linked view so the in-app Back works. */
function stackForView(v) {
  const home = { kind: "home" };
  if (v.kind === "home") return [home];
  if (v.kind === "funds" || v.kind === "people") return [home, v];
  if (v.kind === "firm") return [home, v];
  const rec = v.kind === "fund" ? window.getFund(v.id) : window.getPerson(v.id);
  return [home, { kind: "firm", id: rec.firmId }, v];
}
function viewTitle(v) {
  const base = "The Vintage Project";
  if (v.kind === "firm") return window.getFirm(v.id).name + " · " + base;
  if (v.kind === "fund") { const f = window.getFund(v.id); return f.name + " · " + window.getFirm(f.firmId).name + " · " + base; }
  if (v.kind === "person") { const p = window.getPerson(v.id); return p.name + " · " + window.getFirm(p.firmId).name + " · " + base; }
  if (v.kind === "funds") return "Every fund · " + base;
  if (v.kind === "people") return "Every person · " + base;
  return base + " | Every investment firm has a story.";
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [stack, setStack] = React.useState(() => stackForView(pathToView(window.location.pathname)));
  const [search, setSearch] = React.useState("");
  const [menuOpen, setMenuOpen] = React.useState(false);

  React.useEffect(() => { applyTheme(t); }, [t.palette, t.type]);

  const view = stack[stack.length - 1];

  /* Keep the address bar + tab title in sync with the current view. */
  React.useEffect(() => {
    const path = viewToPath(view);
    if (window.location.pathname !== path && window.location.protocol !== "file:") {
      window.history.pushState({}, "", path);
    }
    document.title = viewTitle(view);
  }, [view]);

  /* Browser back/forward → rebuild the view from the URL. */
  React.useEffect(() => {
    const onPop = () => { setStack(stackForView(pathToView(window.location.pathname))); window.scrollTo(0, 0); };
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  const go = (v) => { setStack((s) => [...s, v]); window.scrollTo(0, 0); };
  const nav = {
    home: () => { setStack([{ kind: "home" }]); window.scrollTo(0, 0); },
    back: () => setStack((s) => (s.length > 1 ? s.slice(0, -1) : s)),
    firm: (id) => go({ kind: "firm", id }),
    fund: (id) => go({ kind: "fund", id }),
    person: (id) => go({ kind: "person", id }),
    funds: () => go({ kind: "funds" }),
    people: () => go({ kind: "people" }),
    menu: () => setMenuOpen(true),
  };

  const filtered = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return window.FIRMS;
    return window.FIRMS.filter((f) => (f.name + " " + f.teaser + " " + f.blurb).toLowerCase().includes(q));
  }, [search]);

  return (
    <div className="app">
      {view.kind === "home" && (
        <main className="home">
          <TopBar search={search} setSearch={setSearch} onMenu={nav.menu} onHome={nav.home} nav={nav} />

          {search.trim() ? (
            filtered.length === 0 ? (
              <div className="empty">No firms match “{search}”.</div>
            ) : (
              <DirectoryGrid>
                {filtered.map((f) => (
                  <Tile key={f.id} title={f.name} tag={f.name} teaser={f.teaser} logoId={"logo-" + f.id}
                    src={f.logoSrc} bg={f.bg} ink={f.ink} accent={f.accent} onClick={() => nav.firm(f.id)} />
                ))}
              </DirectoryGrid>
            )
          ) : (
            <React.Fragment>
              {/* 1 — Firm directory, above the fold, no header */}
              <DirectoryGrid>
                {window.FIRMS.map((f) => (
                  <Tile key={f.id} title={f.name} tag={f.name} teaser={f.teaser} logoId={"logo-" + f.id}
                    src={f.logoSrc} bg={f.bg} ink={f.ink} accent={f.accent} onClick={() => nav.firm(f.id)} />
                ))}
              </DirectoryGrid>

              {/* 2 — Every firm has a story */}
              <section className="storyband">
                <h1 className="storyband__title">Every investment firm has a story.</h1>
                <p className="storyband__sub">We research the funds, people, and decisions that have created the most iconic firms in the world.</p>
                <div className="storyband__cta">
                  <ArrowPill onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}>Explore The Vintage Project</ArrowPill>
                </div>
              </section>

              {/* 3 — Iconic funds */}
              <Carousel title="Iconic funds" sub="The vintages that rewrote what a single fund could return." onMore={nav.funds}>
                {ICONIC_FUNDS.map((id) => {
                  const fd = window.getFund(id); if (!fd) return null;
                  return <FundCard key={id} fund={fd} firm={window.getFirm(fd.firmId)} teaser={ICONIC_FUND_TEASERS[id]} onClick={() => nav.fund(id)} />;
                })}
              </Carousel>

              {/* 4 — Iconic people */}
              <Carousel title="Iconic people" sub="The investors who defined their firms and eras." onMore={nav.people}>
                {ICONIC_PEOPLE.map((id) => {
                  const p = window.getPerson(id); if (!p) return null;
                  return <PersonCard key={id} person={p} firm={window.getFirm(p.firmId)} teaser={ICONIC_PEOPLE_TEASERS[id]} onClick={() => nav.person(id)} />;
                })}
              </Carousel>
            </React.Fragment>
          )}

          <SiteFooter />
        </main>
      )}

      {view.kind === "funds" && <FundsDirectory nav={nav} search={search} setSearch={setSearch} />}
      {view.kind === "people" && <PeopleDirectory nav={nav} search={search} setSearch={setSearch} />}

      {view.kind === "firm" && (
        <FirmView firm={window.getFirm(view.id)} nav={nav} search={search} setSearch={setSearch} />
      )}
      {view.kind === "fund" && (
        <FundView fund={window.getFund(view.id)} nav={nav} search={search} setSearch={setSearch} />
      )}
      {view.kind === "person" && (
        <PersonView person={window.getPerson(view.id)} nav={nav} search={search} setSearch={setSearch} />
      )}

      <MenuOverlay open={menuOpen} onClose={() => setMenuOpen(false)} onHome={nav.home} />

      <NewsletterPopup key={view.kind + (view.id || "")} />

      {view.kind === "home" && <WelcomePopup />}

      <TweaksPanel>
        <TweakSection label="Palette" />
        <TweakRadio label="Canvas" value={t.palette}
          options={["Sand", "Cool paper", "Ivory", "Slate"]}
          onChange={(v) => setTweak("palette", v)} />
        <TweakSection label="Typography" />
        <TweakRadio label="Type set" value={t.type}
          options={["Archivo + Spectral", "All Archivo", "Archivo + Newsreader"]}
          onChange={(v) => setTweak("type", v)} />
      </TweaksPanel>
    </div>
  );
}

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