/* Folclore Latin Fund I — Partners & track record.
   Named people, firms, and career histories appear only when they
   are actually on file. Further appointments stay "Not yet on file"
   until they are. */

const TEAM_HELLO = "hello@folclore.capital";
const TEAM_NICK = "nick.walker@folclore.capital";
const TEAM_HENRIQUE = "henrique.lamim@folclore.capital";
const TEAM_DOLLY = "dolly.moorheard@folclore.capital";
const TEAM_DEALS = "deals@folclore.capital";
const TEAM_DEALROOM = "dealroom@folclore.capital";

/* In-page jumps only. Same rail as the return model: fixed to the right edge. */
const TEAM_NAV = [
  ["top", "↑", "Partners"],
  ["01", "01", "The team"],
  ["02", "02", "Advisors"],
  ["03", "03", "Service providers"],
  ["04", "04", "Documents"],
];

function teamPersonName(person) {
  return person.first + " " + person.last + (person.credential ? ", " + person.credential : "");
}

function teamRecordBio(person) {
  if (person && person.bio && person.bio.length) return person.bio;
  return ["Biography coming soon."];
}

const TEAM_PARTNERS = [
  {
    id: "nw",
    first: "Nick",
    last: "Walker",
    role: "Co-founder · Managing partner",
    place: "New York & Rio de Janeiro",
    keyPerson: true,
    photo: "assets/team/nick-walker.jpg",
    bioDownload: "https://drive.google.com/file/d/1MWQqumeiNkuecSx9-_dB-lBYPBWNEIll/view?usp=sharing",
    linkedin: "https://www.linkedin.com/in/nicolaswalker/",
    blurb: "Co-Founder and Managing Partner. He invests in established Latin American luxury brands and builds their presence in the United States and Europe.",
    leads: "Investments",
    languages: "English, Portuguese, Spanish, French",
    bio: [
      "Nick Walker is Co-Founder and Managing Partner of Folclore Capital Partners, a growth equity fund that invests in established Latin American luxury consumer brands and builds their presence in international markets, principally the United States & Europe. He previously co-founded The Folclore Company (TFC) in 2018, served as its Chief Executive Officer until 2025, and became Chairman in 2026. Under his leadership, TFC grew from inception to seven-figure annual revenue, with distribution across 12 U.S. states, Canada and the Caribbean. Folclore owns Cãna, an ultra-premium cachaça, and Dom Maria, a premium Brazilian sparkling wine. In 2020 TFC acquired the North American rights to Amázzoni Gin, a Brazilian craft gin. It continued to build the brand in those markets after Pernod Ricard acquired Amázzoni in 2021/2022, and in 2025 Pernod Ricard acquired TFC’s rights. Mr. Walker also co-founded & was an investor in Sphere Global, a direct-to-consumer logistics platform. He successfully exited the business in 2024.",
      "Earlier in his career, he was a Management Associate at Bridgewater Associates. Through the firm’s rotational management program, he worked with department heads and senior leadership on planning and executing organizational change. From 2017 to 2019 he was at Animal Ventures, a venture-building firm. There he led a four-person research team, working with the Blockchain Research Institute, on supply-chain and asset-tracking applications of distributed-ledger technology, and later served as Entrepreneur in Residence.",
      "Mr. Walker developed Fact Tag, a traceability and anti-counterfeiting system for luxury goods, and is the named inventor on U.S. Patent No. 11,516,014. He holds a B.S. in International Affairs from Georgetown University and a Postgraduate Diploma in Strategy and Innovation from Saïd Business School, University of Oxford. Brazilian-American and fluent in English, Portuguese, Spanish, and French, he serves on the board of the Impact Public Service Fund, a non-partisan non-profit.",
    ],
    career: [
      { role: "Co-Founder & Managing Partner", org: "Folclore Capital Partners", when: "Present" },
      { role: "Chairman", org: "The Folclore Company", when: "2026–present" },
      { role: "Co-Founder & CEO", org: "The Folclore Company", when: "2018–2025" },
      { role: "Co-Founder & Investor", org: "Sphere Global", when: "Exited 2024" },
      { role: "Entrepreneur in Residence", org: "Animal Ventures", when: "2017–2019" },
      { role: "Management Associate", org: "Bridgewater Associates", when: "" },
    ],
    email: TEAM_NICK,
  },
  {
    id: "dm",
    first: "Dolly",
    last: "Moorhead",
    role: "Co-founder · Partner · Head of investor relations",
    place: "New York",
    keyPerson: true,
    photo: "assets/team/dolly-moorhead.jpeg",
    bioDownload: "https://drive.google.com/file/d/1VztiQE47AQOKUn-ugqUmZowUqutN14YC/view?usp=sharing",
    linkedin: "https://www.linkedin.com/in/dolly-moorhead-a12689b3/",
    blurb: "Co-Founder and Partner, Head of Investor Relations. She leads relationships with limited partners and the firm’s investor communications.",
    leads: "Investor relations",
    bio: [
      "Dolly Kilroy Moorhead is Co-Founder and Partner, Head of Investor Relations, of Folclore Capital Partners, where she leads the firm’s relationships with limited partners and its investor communications.",
      "Ms. Moorhead served in the U.S. federal government from 2017 to 2021. She joined the Office of the U.S. Surgeon General in January 2017 as Special Advisor. In July 2019 she moved to the White House Office of Science and Technology Policy (OSTP) as a Policy Advisor covering biotechnology, the bioeconomy and healthcare and represented OSTP on the Committee on Foreign Investment in the United States (CFIUS). At the onset of the COVID-19 pandemic she coordinated federal policy on telehealth adoption, including as the project lead on the interagency launch of telehealth.hhs.gov. She returned to the Office of the Surgeon General as Senior Advisor from September 2020 to January 2021. In that role she worked on COVID-19 vaccine public outreach, developed public-health partnerships including with the National Football League. She received the Surgeon General’s Award for Outstanding Service on her departure.",
      "In March 2021 she founded Limenitis LLC, an advisory firm serving healthcare, health-technology, pharmaceutical and medical-device clients on regulatory strategy, product development and crisis management. Alongside it she has held product and business-development roles at early-stage health-technology companies, including as Chief Product Officer of Mediportal Technologies. In 2023 she was Director of Operations and Programs at VALID AI, a generative-AI collaborative of health systems and technology partners, ahead of its launch at HLTH 2023.",
      "Ms. Moorhead holds a B.S. in Biology from Georgetown University, where she was a research fellow at the Georgetown Lombardi Comprehensive Cancer Center. She is a named inventor on U.S. and European patent applications. She is American and is based in New York City.",
    ],
    career: [
      { role: "Co-Founder & Partner, Head of Investor Relations", org: "Folclore Capital Partners", when: "Present" },
      { role: "Director of Operations and Programs", org: "VALID AI", when: "2023" },
      { role: "Founder", org: "Limenitis LLC", when: "2021–present" },
      { role: "Chief Product Officer", org: "Mediportal Technologies", when: "" },
      { role: "Senior Advisor", org: "Office of the U.S. Surgeon General", when: "2020–2021" },
      { role: "Policy Advisor", org: "White House OSTP", when: "2019–2020" },
      { role: "Special Advisor", org: "Office of the U.S. Surgeon General", when: "2017–2019" },
    ],
    email: TEAM_DOLLY,
  },
  {
    id: "hl",
    first: "Henrique",
    last: "Lamim",
    credential: "CFA",
    role: "Partner",
    place: "Rio de Janeiro",
    photo: "assets/team/henrique-lamim.jpg",
    bioDownload: "https://drive.google.com/file/d/1uiUPE2PZ8ZZ1S5ya0nYcUVrRs3BDJnbl/view?usp=sharing",
    linkedin: "https://www.linkedin.com/in/henrique-lamim-cfa-95240040/",
    blurb: "Partner responsible for valuation, financial due diligence, and portfolio monitoring. He holds the role alongside YorkLion and devotes about half his time to the Fund.",
    leads: "Valuation, diligence and monitoring",
    languages: "Portuguese, English",
    bio: [
      "Henrique Lamim, CFA, is a Partner of Folclore Capital Partners, where he is responsible for valuation, financial due diligence and portfolio monitoring. He holds this role alongside his position as Senior Research Analyst at YorkLion, an investment manager that invests on contrarian value principles where a catalyst for change can be identified, with an absolute-return objective. Mr. Lamim devotes approximately 50% of his professional time to the Fund.",
      "Mr. Lamim joined YorkLion in April 2012 as an equity research intern, building and maintaining research models and monitoring risk-arbitrage positions. He became a full-time analyst in January 2013. Since then he has conducted bottom-up fundamental analysis and valuation of listed companies on a generalist, global mandate covering the United States, Canada, Europe, Asia and Brazil. He reports directly to the firm’s Founding Partner, Nick Walker Sr.",
      "Mr. Lamim is a CFA charterholder and holds the ANBIMA CGA and CGE certifications. The CGE is the credential ANBIMA requires of professionals with investment decision-making authority over Brazilian structured funds, including private equity vehicles (FIPs). He holds a degree in Production Engineering from the Pontifícia Universidade Católica do Rio de Janeiro (PUC-Rio). Brazilian and fluent in Portuguese and English, he is based in Rio de Janeiro.",
    ],
    career: [
      { role: "Partner", org: "Folclore Capital Partners", when: "Present · ~50% time" },
      { role: "Senior Research Analyst", org: "YorkLion", when: "2013–present" },
      { role: "Equity Research Intern", org: "YorkLion", when: "2012–2013" },
    ],
    email: TEAM_HENRIQUE,
  },
];

/* Named only once a role and a biography are on file.
   A portrait or a biography file is omitted until it is on file. */
const TEAM_ADVISORS = [
  {
    id: "cp",
    first: "Camila",
    last: "Pierotti",
    role: "Advisor",
    place: "New York",
    photo: "assets/team/camila-pierotti.jpg",
    bioDownload: "https://drive.google.com/file/d/1jjsm1JJlxCo2uMOrLbfLu9tZyNEcATEb/view?usp=sharing",
    linkedin: "https://www.linkedin.com/in/camila-pierotti-6396711/",
    blurb: "Advisor to the Fund and its portfolio companies on brand positioning, product strategy, and U.S. market entry. A non-voting member of the Investment Committee.",
    languages: "English, Portuguese",
    bio: [
      "Camila Pierotti is an Advisor to Folclore Capital Partners, where she advises the Fund and its portfolio companies on brand positioning, product strategy and U.S. market entry. She is a non-voting member and advisor to the Investment Committee.",
      "Ms. Pierotti is a co-founder of Sol de Janeiro, the Brazilian-inspired body-care and fragrance brand. She served as its Chief Marketing Officer from 2014, ahead of the brand’s 2015 U.S. launch, until 2021. During her tenure the brand rolled out nationally with Sephora, and in 2021 L’Occitane Group acquired a majority stake at a valuation of US$450 million. Since 2022, she has stepped back from the role.",
      "Before Sol de Janeiro, she spent a decade in prestige beauty marketing in New York. She was Marketing Manager at Clinique (The Estée Lauder Companies) from 2003 to 2010 and at NARS Cosmetics (Shiseido) from 2010 to 2014, working across skin care, color cosmetics and gifting.",
      "Ms. Pierotti holds a degree from Georgetown University. Born in Rio de Janeiro, she is Brazilian and American, fluent in English and Portuguese. She is based in New York.",
    ],
    career: [
      { role: "Advisor", org: "Folclore Capital Partners", when: "Present" },
      { role: "Co-Founder & Chief Marketing Officer", org: "Sol de Janeiro", when: "2014–2021" },
      { role: "Marketing Manager", org: "NARS Cosmetics (Shiseido)", when: "2010–2014" },
      { role: "Marketing Manager", org: "Clinique (The Estée Lauder Companies)", when: "2003–2010" },
    ],
  },
  {
    id: "df",
    first: "Denis",
    last: "O’Flynn O’Brien",
    role: "Advisor",
    place: "Philadelphia",
    linkedin: "https://www.linkedin.com/in/denisoflynnobrien/",
    blurb: "Advisor on operations, logistics, and U.S. distribution. Managing Partner of Sudu Partners.",
    bio: [
      "Denis O’Flynn O’Brien is an Advisor to Folclore Capital Partners, advising on operations, logistics and U.S. distribution. He is Managing Partner of Sudu Partners, a holding company that acquires and operates founder-led businesses in the Philadelphia area with $500,000 to $3 million of EBITDA, with the intent to hold them for the long term. Mr. O’Brien has led the firm since 2019.",
      "From 2021 to 2022 Mr. O’Brien was Vice President of Operations at Base64.ai, a document-processing automation company. Before that he spent nearly five years at Uber, from 2014 to 2019. He was one of the earliest members of its operations and logistics team and held responsibility across more than a dozen cities. He progressed from Lead Operations & Logistics Manager in Philadelphia to Senior Operations & Logistics Manager in New York. He began his career in 2011 at Axia Ltd., a Boston-based strategy consulting firm later acquired by Accenture Strategy, where he advised corporate clients on growth strategy.",
      "Mr. O’Brien was a mentor in First Round Capital’s Fast Track program from 2019 to 2021 and has served on the board of Penn Student Agencies since 2020. He holds a B.A. in Economics and East Asian Languages and Civilizations from the University of Pennsylvania. He is American and is based in Philadelphia.",
    ],
    career: [
      { role: "Advisor", org: "Folclore Capital Partners", when: "Present" },
      { role: "Managing Partner", org: "Sudu Partners", when: "2019–present" },
      { role: "Vice President of Operations", org: "Base64.ai", when: "2021–2022" },
      { role: "Senior Operations & Logistics Manager", org: "Uber, New York", when: "2014–2019" },
      { role: "Lead Operations & Logistics Manager", org: "Uber, Philadelphia", when: "2014–2019" },
      { role: "Growth strategy", org: "Axia Ltd.", when: "From 2011" },
      { role: "Mentor, Fast Track", org: "First Round Capital", when: "2019–2021" },
      { role: "Board member", org: "Penn Student Agencies", when: "2020–present" },
    ],
  },
  {
    id: "ml",
    first: "Michele",
    last: "Levy",
    role: "Advisor",
    place: "New York",
    linkedin: "https://www.linkedin.com/in/michele-levy/",
    blurb: "Advisor to Folclore Capital Partners and a voting member of its Investment Committee. Co-Founder, President and Chief Operating Officer of HeadOffice.ai.",
    languages: "Portuguese, English, Spanish; professional French",
    bio: [
      "Michele Levy is an Advisor to Folclore Capital Partners and a voting member of its Investment Committee. She is Co-Founder, President and Chief Operating Officer of HeadOffice.ai, a company that builds artificial-intelligence agents for customer support, sales and operations at franchise and multi-unit businesses.",
      "In 2009 Ms. Levy founded Ilhabela Holdings and obtained the exclusive U.S. license for Melissa, the Brazilian footwear brand of Grendene, which sells millions of pairs a year worldwide. As Chief Executive Officer until 2021, she introduced a brand with no U.S. presence to the market. Without outside capital, the company was profitable by its second year, and revenue grew at a compound annual rate of approximately 45% over ten years. The company grew to more than 100 employees and 12 retail stores, alongside wholesale and direct-to-consumer channels.",
      "In 2017 Ms. Levy co-founded Costa Brazil, a luxury clean-beauty brand built on ingredients sourced from the Amazon, with Francisco Costa, former Creative Director of Calvin Klein. As Chief Executive Officer she led fundraising, commercial strategy, finance and the team, and secured distribution at Bergdorf Goodman, Harrods, Comme des Garçons and Bluemercury. In 2021 the company was acquired by Amyris, Inc., and Ms. Levy sold her entire interest in the transaction.",
      "Earlier in her career, Ms. Levy spent twelve years in private equity and venture capital at J.P. Morgan and its predecessor firms, including Chase Capital Partners and JPMorgan Partners, in Brazil and New York, from 1992 to 2004. From 2004 to 2008 she was Senior Director at the Americas Society/Council of the Americas.",
      "Ms. Levy has served on the advisory boards of consumer companies including Agua Bendita, Løci, Children Chic and The List. She has been a member of YPO since 2015, of Women Corporate Directors since 2022, and of Extraordinary Women on Boards since 2023. She holds an MBA from Harvard Business School and a B.A. in Economics from the Universidade de São Paulo. Brazilian and fluent in Portuguese, English and Spanish, with professional working French, she is based in New York.",
    ],
    career: [
      { role: "Advisor", org: "Folclore Capital Partners", when: "Present" },
      { role: "Co-Founder, President & Chief Operating Officer", org: "HeadOffice.ai", when: "Present" },
      { role: "Founder & Chief Executive Officer", org: "Ilhabela Holdings", when: "2009–2021" },
      { role: "Co-Founder & Chief Executive Officer", org: "Costa Brazil", when: "2017–2021" },
      { role: "Senior Director", org: "Americas Society/Council of the Americas", when: "2004–2008" },
      { role: "Private equity and venture capital", org: "J.P. Morgan", when: "1992–2004" },
      { role: "Advisory boards", org: "Agua Bendita, Løci, Children Chic, The List", when: "" },
    ],
  },
];

const TEAM_PEOPLE = TEAM_PARTNERS.concat(TEAM_ADVISORS);

const TEAM_OFFICES = [
  { city: "New York", focus: "465 Park Ave, New York, 10022" },
  { city: "Rio de Janeiro", focus: "R. Miranda Valverde, 64 - Botafogo, Rio de Janeiro - RJ, 22281-000" },
];

const TEAM_PROVIDERS = [
  {
    id: "admin",
    section: "Fund administration",
    role: "Fund administrator",
    status: "In process",
    expected: "Before or with first closing",
    shortlist: ["Citco", "SS&C", "Apex Group", "Alter Domus"],
    profile: "Institutional fund administrator with private equity expertise.",
    scope: "Capital call processing, distribution management, NAV calculations, LP reporting, K-1 preparation, and investor portal management.",
    docs: [
      "dataroom/08-team-operations/fund-administrator-report.pdf",
      "dataroom/08-team-operations/service-provider-directory.pdf",
    ],
  },
  {
    id: "audit",
    section: "Audit and tax",
    role: "Auditor",
    status: "In process",
    expected: "Before or with first closing",
    shortlist: ["Deloitte", "PwC", "EY", "KPMG"],
    profile: "Big Four accounting firm.",
    scope: "Annual GAAP-compliant financial statement audits, quarterly review procedures, portfolio company valuation review, and compliance attestation.",
    docs: ["dataroom/08-team-operations/auditor-comfort-letter.pdf"],
  },
  {
    id: "tax",
    section: "Audit and tax",
    role: "Tax advisor",
    status: "In process",
    expected: "Before or with first closing",
    shortlist: ["Deloitte Tax", "PwC Tax", "EY Tax", "Specialized boutique"],
    profile: "Specialized private equity tax advisory firm.",
    scope: "Fund structure optimization, K-1 preparation and distribution, UBTI and ECI analysis for tax-exempt investors, state and international tax compliance, and portfolio company tax structuring.",
    docs: ["dataroom/04-fund-financials/tax-schedules-k1.pdf"],
  },
  {
    id: "counsel",
    section: "Legal services",
    role: "Fund counsel",
    firm: "Seward & Kissel LLP",
    contact: "David Mulle",
    title: "Partner",
    status: "Appointed",
    expected: "Engaged",
    logo: "assets/team/seward-kissel.png",
    phone: "(212) 574-1452",
    fax: "(212) 480-8421",
    email: "mulle@sewkis.com",
    web: "www.sewkis.com",
    address: "One Battery Park Plaza, New York, NY 10004",
    scope: "Fund formation, the limited partnership agreement, subscription documents, and side letters.",
    docs: [
      "dataroom/08-team-operations/legal-counsel-opinion.pdf",
      "dataroom/02-legal-documents/limited-partnership-agreement.pdf",
    ],
  },
  {
    id: "latam",
    section: "Legal services",
    role: "Transaction counsel",
    status: "Deal by deal",
    expected: "Engaged per investment",
    approach: "Counsel is selected for each transaction based on the jurisdiction, counterparty, and deal structure. Preference is for top-tier M&A and corporate firms with Latin American and luxury and consumer experience.",
    profile: "M&A and corporate counsel with Latin American and luxury and consumer expertise.",
    scope: "Investment transaction documentation (SPAs and shareholders’ agreements), due diligence support, cross-border structuring, and regulatory approvals.",
    docs: ["dataroom/08-team-operations/service-provider-directory.pdf"],
  },
  {
    id: "bank",
    section: "Banking and custody",
    role: "Custodian bank",
    status: "In process",
    expected: "Before or with first closing",
    shortlist: ["U.S. Bank", "BNY Mellon", "Northern Trust", "JPMorgan"],
    profile: "Institutional custodian with private fund capabilities.",
    scope: "Fund cash management, subscription receipt and processing, distribution execution, banking services, and foreign exchange.",
    docs: ["dataroom/02-legal-documents/custody-agreement.pdf"],
  },
  {
    id: "line",
    section: "Banking and custody",
    role: "Capital call line",
    status: "After first closing",
    expected: "Once the custodian is in place",
    approach: "The subscription line is typically matched to the custodian bank. Selection begins after first closing, once the fund’s banking relationship is set.",
    profile: "Subscription line of credit to pace capital deployment and limited partner IRRs.",
    scope: "Target facility of 15–20% of commitments, with competitive SOFR plus spread pricing.",
    docs: ["dataroom/02-legal-documents/custody-agreement.pdf"],
  },
  {
    id: "compliance",
    section: "Compliance and regulatory",
    role: "Compliance consultant",
    status: "In process",
    expected: "Before or with first closing",
    shortlist: ["ACA Compliance Group", "Duff & Phelps Compliance", "Specialized boutique"],
    profile: "Specialized private equity compliance advisory firm.",
    scope: "Compliance manual, SEC filing support (Form D, and Form ADV if applicable), annual compliance reviews, policy documentation, and regulatory monitoring.",
    docs: [
      "dataroom/03-compliance-regulatory/compliance-manual.pdf",
      "dataroom/03-compliance-regulatory/form-adv-part-2a.pdf",
    ],
  },
  {
    id: "cyber",
    section: "Compliance and regulatory",
    role: "Cybersecurity",
    status: "In process",
    expected: "Before or with first closing",
    shortlist: ["Deloitte Cyber", "PwC Cyber", "Specialized boutique"],
    profile: "Cybersecurity consultant for annual audits and penetration testing.",
    scope: "Annual security assessments, penetration testing, incident response planning, and cybersecurity due diligence support on portfolio companies.",
    docs: ["dataroom/03-compliance-regulatory/compliance-manual.pdf"],
  },
  {
    id: "do",
    section: "Insurance",
    role: "D&O insurance",
    status: "To be placed",
    expected: "Before first closing",
    approach: "Coverage will be placed with a carrier experienced in private fund directors and officers liability before first closing.",
    profile: "Directors and officers liability insurance covering GP and fund-level fiduciary duties.",
    scope: "Target coverage of $5–10 million.",
    docs: ["dataroom/08-team-operations/insurance-certificates.pdf"],
  },
  {
    id: "eo",
    section: "Insurance",
    role: "E&O insurance",
    status: "To be placed",
    expected: "Before first closing",
    approach: "Errors and omissions coverage for investment adviser activities will be placed before first closing.",
    profile: "Errors and omissions insurance for investment adviser activities.",
    scope: "Target coverage of $2–5 million.",
    docs: ["dataroom/08-team-operations/insurance-certificates.pdf"],
  },
  {
    id: "cyberins",
    section: "Insurance",
    role: "Cyber insurance",
    status: "To be placed",
    expected: "Before first closing",
    approach: "Cyber liability and data-breach coverage will be placed before first closing, alongside the other fund insurance lines.",
    profile: "Cybersecurity liability and data breach coverage.",
    scope: "Target coverage of $2–3 million.",
    docs: ["dataroom/08-team-operations/insurance-certificates.pdf"],
  },
];

function teamProviderPhase(v) {
  if (v.firm) return "appointed";
  if (v.status === "In process") return "process";
  if (v.status === "Deal by deal") return "deal";
  if (v.status === "After first closing") return "later";
  return "pending";
}

function teamProviderMark(v) {
  const phase = teamProviderPhase(v);
  if (phase === "appointed") return "ready";
  if (phase === "process") return "prep";
  return "pending";
}

const TEAM_BIOS_DOC = "dataroom/08-team-operations/team-biographies.pdf";
const TEAM_ORG_DOC = "dataroom/08-team-operations/organizational-chart.pdf";

const TEAM_DOC_PATHS = [
  TEAM_BIOS_DOC,
  TEAM_ORG_DOC,
  "dataroom/01-offering-materials/track-record-case-studies.pdf",
  "dataroom/08-team-operations/service-provider-directory.pdf",
  "dataroom/08-team-operations/fund-administrator-report.pdf",
  "dataroom/08-team-operations/auditor-comfort-letter.pdf",
  "dataroom/08-team-operations/legal-counsel-opinion.pdf",
  "dataroom/08-team-operations/insurance-certificates.pdf",
];

function teamMail(email, name) {
  return "mailto:" + email + "?subject=" + encodeURIComponent("Folclore Latin Fund I — " + name);
}

function teamAdvisorCallMail(advisorName, viewer) {
  const name = viewer && viewer.name ? String(viewer.name).trim() : "";
  const email = viewer && viewer.email ? String(viewer.email).trim() : "";
  const who = advisorName || "an advisor";
  const subject = "Folclore Latin Fund I — arrange a call with " + who;
  const body = [
    "Name: " + name,
    "Email: " + email,
    "Advisor: " + who,
  ].join("\r\n");
  return "mailto:" + TEAM_DEALROOM
    + "?subject=" + encodeURIComponent(subject)
    + "&body=" + encodeURIComponent(body);
}

function teamCanAccess(userLevel, required) {
  return Number(userLevel || 1) >= Number(required || 1);
}

function teamFile(path) {
  const tree = (typeof DATAROOM_TREE !== "undefined" && DATAROOM_TREE) || [];
  for (let i = 0; i < tree.length; i++) {
    const folder = tree[i];
    const file = folder.files.find((f) => f.path === path);
    if (file) return Object.assign({}, file, { folderName: folder.name });
  }
  return null;
}

function teamDocState(file, level) {
  if (!file) return { kind: "missing", label: "Not in the room" };
  if (!teamCanAccess(level, file.level)) return { kind: "locked", label: "Level " + file.level };
  if (file.status === "ready") return { kind: "ready", label: "Available" };
  return { kind: "prep", label: "In preparation" };
}

function TpRule() {
  return <span className="tp-num-rule" aria-hidden="true" />;
}

function TpArrow() {
  return (
    <svg className="tp-ico" width="14" height="14" viewBox="0 0 24 24" aria-hidden="true">
      <path d="M5 12h14" />
      <path d="m12 5 7 7-7 7" />
    </svg>
  );
}

function TpChevron() {
  return (
    <svg className="tp-ico" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true">
      <path d="m9 18 6-6-6-6" />
    </svg>
  );
}

function TpLock() {
  return (
    <svg className="tp-ico" width="14" height="14" viewBox="0 0 24 24" aria-hidden="true">
      <rect width="18" height="11" x="3" y="11" rx="2" />
      <path d="M7 11V7a5 5 0 0 1 10 0v4" />
    </svg>
  );
}

function TpClose() {
  return (
    <svg className="tp-ico" width="15" height="15" viewBox="0 0 24 24" aria-hidden="true">
      <path d="M18 6 6 18" />
      <path d="m6 6 12 12" />
    </svg>
  );
}

function TeamMark({ status }) {
  if (status === "ready") return <span className="tp-dot tp-dot-on" aria-hidden="true" />;
  if (status === "locked") return <TpLock />;
  if (status === "pending") return <span className="tp-dot tp-dot-muted" aria-hidden="true" />;
  return <span className="tp-dot" aria-hidden="true" />;
}

function TeamMonogram({ first, last, photo }) {
  const [failed, setFailed] = React.useState(false);
  React.useEffect(() => { setFailed(false); }, [photo]);
  if (photo && !failed) {
    return (
      <div className="tp-mono tp-mono-photo" aria-hidden="true">
        <img src={photo} alt="" onError={() => setFailed(true)} />
      </div>
    );
  }
  return (
    <div className="tp-mono" aria-hidden="true">
      <img src="assets/logo-mark-gold.png" alt="" />
      <div className="tp-mono-name">
        <span className="tp-mono-line" />
        <span>{first}</span>
        <span>{last}</span>
      </div>
    </div>
  );
}

function teamPersonFacts(person) {
  const rows = [];
  if (person.place) rows.push(["Based in", person.place]);
  if (person.languages) rows.push(["Languages", person.languages]);
  if (person.leads) rows.push(["Leads", person.leads]);
  return rows;
}

function TeamMeta({ rows }) {
  if (!rows || !rows.length) return null;
  return (
    <dl className="tp-meta">
      {rows.map(([k, v]) => {
        const mail = String(v).indexOf("@") >= 0;
        return (
          <div key={k}>
            <dt>{k}</dt>
            <dd>{mail ? <a href={"mailto:" + v}>{v}</a> : v}</dd>
          </div>
        );
      })}
    </dl>
  );
}

function TeamPersonLinks({ person }) {
  return (
    <div className="tp-actions" onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>
      {person.email && (
        <a className="tp-btn" href={teamMail(person.email, person.first)}>Get in touch</a>
      )}
      {person.linkedin && (
        <a href={person.linkedin} target="_blank" rel="noopener noreferrer">LinkedIn <TpArrow /></a>
      )}
      {person.bioDownload ? (
        <a href={person.bioDownload} target="_blank" rel="noopener noreferrer">Download biography <TpArrow /></a>
      ) : null}
    </div>
  );
}

function TeamPersonCard({ person, onOpen }) {
  const open = () => onOpen(person.id);
  return (
    <article
      className="tp-partner tp-partner-hit"
      role="button"
      tabIndex={0}
      aria-label={"Open biography for " + teamPersonName(person)}
      onClick={open}
      onKeyDown={(e) => {
        if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          open();
        }
      }}
    >
      <TeamMonogram first={person.first} last={person.last} photo={person.photo} />
      <div className="tp-partner-copy">
        <p className="tp-kicker">{person.role}</p>
        <h3>{teamPersonName(person)}</h3>
        <div className="tp-blurb">
          <p className="tp-prose">{person.blurb}</p>
          <span className="tp-bio-link">
            Full biography <TpArrow />
          </span>
        </div>
        <TeamMeta rows={[
          ["Based in", person.place],
          ["Leads", person.leads],
        ].filter((row) => row[1])} />
        <TeamPersonLinks person={person} />
      </div>
    </article>
  );
}

function TeamCareer({ items }) {
  const [open, setOpen] = React.useState(false);
  if (!items || !items.length) return null;
  const limit = 4;
  const truncated = !open && items.length > limit;
  const shown = truncated ? items.slice(0, limit) : items;
  return (
    <div className="tp-career">
      <p className="tp-kicker tp-kicker-quiet">Career</p>
      <ul>
        {shown.map((item, i) => (
          <li key={i}>
            <span className="tp-career-role">{item.role}</span>
            <span className="tp-career-org">{item.org}</span>
            {item.when ? <span className="tp-career-when">{item.when}</span> : null}
          </li>
        ))}
      </ul>
      {items.length > limit && (
        <button type="button" className="tp-bio-toggle" onClick={() => setOpen((v) => !v)} aria-expanded={open}>
          {open ? "Show less" : "Show full career"}
        </button>
      )}
    </div>
  );
}

function TeamBioCollapse({ paras }) {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="tp-bio">
      <p className="tp-kicker tp-kicker-quiet">Biography</p>
      <div className={"tp-bio-clamp" + (open ? " is-open" : "")}>
        {paras.map((para, i) => (
          <p key={i} className="tp-prose tp-prose-light">{para}</p>
        ))}
      </div>
      <button type="button" className="tp-bio-toggle" onClick={() => setOpen((v) => !v)} aria-expanded={open}>
        {open ? "Show less" : "Read full biography"}
      </button>
    </div>
  );
}

function TeamDrawer({ item, level, viewer, onClose, onOpenDoc }) {
  const closeRef = React.useRef(null);
  const titleId = "tp-drawer-title";
  React.useEffect(() => {
    if (closeRef.current) closeRef.current.focus();
  }, [item.kind, item.id]);

  const files = item.kind === "provider" ? (item.docs || []).map(teamFile).filter(Boolean) : [];

  return (
    <div className="tp-drawer-root">
      <button type="button" className="tp-backdrop" aria-label="Close" onClick={onClose} />
      <aside className="tp-drawer" role="dialog" aria-modal="true" aria-labelledby={titleId}>
        <div className="tp-drawer-top">
          <div>
            {item.kind === "provider" && <p className="tp-kicker">{item.eyebrow}</p>}
            {item.logo && (
              <div className="tp-drawer-logo" aria-hidden="true">
                <img src={item.logo} alt="" />
              </div>
            )}
            <h2 id={titleId}>{item.title}</h2>
            <p className="tp-drawer-sub">{item.sub}</p>
          </div>
          <button type="button" className="tp-icon-btn" aria-label="Close" ref={closeRef} onClick={onClose}>
            <TpClose />
          </button>
        </div>

        {item.kind === "person" && (
          <div className="tp-drawer-body">
            <TeamBioCollapse key={item.id} paras={Array.isArray(item.bio) ? item.bio : [item.bio]} />
            <TeamMeta rows={item.meta} />
            {item.email && (
              <dl className="tp-meta tp-meta-contact">
                <div>
                  <dt>Email</dt>
                  <dd><a href={teamMail(item.email, item.first)}>{item.email}</a></dd>
                </div>
                {item.phone && (
                  <div>
                    <dt>Phone</dt>
                    <dd><a href={"tel:" + String(item.phone).replace(/[^\d+]/g, "")}>{item.phone}</a></dd>
                  </div>
                )}
              </dl>
            )}
            <TeamCareer items={item.career} />
            {item.advisor ? (
              <a className="tp-btn" href={teamAdvisorCallMail(item.title, viewer)}>Arrange a call</a>
            ) : window.APPOINTMENT_URL ? (
              <a className="tp-btn" href={window.APPOINTMENT_URL} target="_blank" rel="noopener noreferrer">Arrange a call</a>
            ) : null}
          </div>
        )}

        {item.kind === "provider" && (
          <div className="tp-drawer-body">
            {item.profile && (
              <p className="tp-prose tp-prose-light">{item.profile}</p>
            )}
            <TeamMeta rows={item.meta} />
            {item.shortlist && item.shortlist.length > 0 && (
              <div className="tp-shortlist">
                <p className="tp-kicker tp-kicker-quiet">Shortlist</p>
                <ul>
                  {item.shortlist.map((name) => (
                    <li key={name}>{name}</li>
                  ))}
                </ul>
                {item.shortlistNote && (
                  <p className="tp-shortlist-note">{item.shortlistNote}</p>
                )}
              </div>
            )}
            {item.approach && (
              <div className="tp-note">
                <p className="tp-kicker">{item.noteTitle || "Approach"}</p>
                <p className="tp-prose tp-prose-light">{item.approach}</p>
              </div>
            )}
            {item.scope && (
              <div className="tp-bio">
                <p className="tp-kicker tp-kicker-quiet">Scope</p>
                <p className="tp-prose tp-prose-light">{item.scope}</p>
              </div>
            )}
          </div>
        )}

        {files.length > 0 && (
          <div className="tp-drawer-docs">
            <p className="tp-kicker tp-kicker-quiet">In the data room</p>
            {files.map((file) => {
              const state = teamDocState(file, level);
              return (
                <button key={file.path} type="button" className="tp-doc tp-doc-tight" onClick={() => onOpenDoc(file)}>
                  <TeamMark status={state.kind} />
                  <span className={"tp-doc-name" + (state.kind === "ready" ? "" : " is-dim")}>{file.name}</span>
                  <span className={"tp-status" + (state.kind === "ready" ? " is-on" : "")}>{state.label}</span>
                </button>
              );
            })}
          </div>
        )}

        <p className="tp-drawer-hint">↑ ↓ to move · Esc to close</p>
      </aside>
    </div>
  );
}

function TeamPage({ navigate, accessLevel, userEmail }) {
  const level = Number(accessLevel || 1);
  const [sel, setSel] = React.useState(null);
  const [viewerName, setViewerName] = React.useState("");
  const [active, setActive] = React.useState("top");
  const [navHover, setNavHover] = React.useState(null);
  const [vw, setVw] = React.useState(typeof window !== "undefined" ? window.innerWidth : 1440);
  const secEls = React.useRef({});
  const lockSpy = React.useRef(0);
  const mainEl = React.useRef(null);
  const docs = TEAM_DOC_PATHS.map(teamFile).filter(Boolean);

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const session = typeof getDataRoomSession === "function" ? await getDataRoomSession() : null;
        const meta = session && session.user && session.user.user_metadata;
        let name = meta ? String(meta.full_name || meta.name || "").trim() : "";
        if (window.folcloreSupabase) {
          const { data, error } = await window.folcloreSupabase
            .from("lp_access")
            .select("name")
            .limit(1)
            .maybeSingle();
          if (!error && data && data.name) name = String(data.name).trim();
        }
        if (!cancelled && name) setViewerName(name);
      } catch (_) {}
    })();
    return () => { cancelled = true; };
  }, []);

  React.useEffect(() => {
    const root = document.querySelector(".dr-main");
    mainEl.current = root;
    const onResize = () => setVw(window.innerWidth);
    window.addEventListener("resize", onResize);
    const scroller = root || window;
    let raf = null;
    const offset = 24;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = null;
        if (Date.now() < lockSpy.current) return;
        let cur = "top";
        const box = mainEl.current;
        const scrollBottom = box
          ? box.scrollTop + box.clientHeight >= box.scrollHeight - 4
          : window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 4;
        if (scrollBottom) cur = TEAM_NAV[TEAM_NAV.length - 1][0];
        else {
          for (let i = 0; i < TEAM_NAV.length; i++) {
            const k = TEAM_NAV[i][0];
            const el = secEls.current[k];
            if (k === "top" || !el) continue;
            const top = el.getBoundingClientRect().top;
            const base = box ? box.getBoundingClientRect().top : 0;
            if (top - base - offset <= 8) cur = k;
          }
        }
        setActive((prev) => (prev === cur ? prev : cur));
      });
    };
    scroller.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => {
      window.removeEventListener("resize", onResize);
      scroller.removeEventListener("scroll", onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  const goTo = React.useCallback((k) => {
    setActive(k);
    lockSpy.current = Date.now() + 900;
    const el = secEls.current[k];
    const root = mainEl.current;
    const offset = 24;
    if (k === "top" || !el) {
      if (root) root.scrollTo({ top: 0, behavior: "smooth" });
      else window.scrollTo({ top: 0, behavior: "smooth" });
      return;
    }
    if (root) {
      const top = el.getBoundingClientRect().top - root.getBoundingClientRect().top + root.scrollTop - offset + 8;
      root.scrollTo({ top: Math.max(0, top), behavior: "smooth" });
    } else {
      const top = el.getBoundingClientRect().top + window.scrollY - offset + 8;
      window.scrollTo({ top: Math.max(0, top), behavior: "smooth" });
    }
  }, []);

  const setSecRef = (k) => (el) => { secEls.current[k] = el; };
  const showRail = vw >= 900;
  const showNames = vw >= 1280;

  React.useEffect(() => {
    if (!sel) return undefined;
    const onKey = (e) => {
      const tag = (e.target && e.target.tagName) || "";
      if (/INPUT|TEXTAREA|SELECT/.test(tag)) return;
      if (e.key === "Escape") {
        setSel(null);
        return;
      }
      if (e.key !== "ArrowDown" && e.key !== "ArrowUp") return;
      const ids = sel.kind === "person" ? TEAM_PEOPLE.map((p) => p.id) : TEAM_PROVIDERS.map((p) => p.id);
      const i = ids.indexOf(sel.id);
      if (i < 0) return;
      e.preventDefault();
      const n = e.key === "ArrowDown" ? Math.min(ids.length - 1, i + 1) : Math.max(0, i - 1);
      if (n !== i) setSel({ kind: sel.kind, id: ids[n] });
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [sel]);

  const openDoc = (file) => {
    if (!file) return;
    if (file.status === "ready" && teamCanAccess(level, file.level) && typeof logRoomEvent === "function") {
      logRoomEvent("documents", file.path);
    }
    if (navigate) navigate("documents", { file: file.path });
  };

  const person = sel && sel.kind === "person" ? TEAM_PEOPLE.find((p) => p.id === sel.id) : null;
  const provider = sel && sel.kind === "provider" ? TEAM_PROVIDERS.find((p) => p.id === sel.id) : null;
  let drawer = null;
  if (person) {
    drawer = {
      kind: "person",
      id: person.id,
      title: teamPersonName(person),
      sub: person.role,
      bio: teamRecordBio(person),
      meta: teamPersonFacts(person),
      email: person.email,
      phone: person.phone || "",
      first: person.first,
      career: person.career || [],
      advisor: TEAM_ADVISORS.some((advisor) => advisor.id === person.id),
    };
  } else if (provider) {
    const phase = teamProviderPhase(provider);
    const appointed = phase === "appointed";
    const shortlist = Array.isArray(provider.shortlist) ? provider.shortlist : [];
    let approach = provider.approach || "";
    let noteTitle = "Approach";
    if (phase === "process") {
      noteTitle = "Selection";
      approach = approach || "An RFP is under way. Final selection is expected before or with first closing. References from firms on the shortlist are available on request at level 4.";
    } else if (phase === "deal") {
      noteTitle = "Deal by deal";
    } else if (phase === "later") {
      noteTitle = "Timing";
    } else if (phase === "pending") {
      noteTitle = "To be started";
    }
    const shortlistNote = shortlist.length
      ? (provider.shortlistNote || "Names are provisional and may change at any time before first close.")
      : "";
    drawer = {
      kind: "provider",
      id: provider.id,
      appointed: appointed,
      eyebrow: "Service provider · " + provider.section,
      title: appointed ? provider.firm : provider.role,
      sub: appointed
        ? [provider.contact, provider.title].filter(Boolean).join(", ")
        : provider.status + (provider.expected ? " · " + provider.expected : ""),
      profile: provider.profile || "",
      scope: provider.scope || "",
      logo: provider.logo || "",
      shortlist: shortlist,
      shortlistNote: shortlistNote,
      approach: approach,
      noteTitle: noteTitle,
      meta: appointed
        ? [
            ["Status", "Appointed"],
            ["Role", provider.role],
            ["Contact", provider.contact],
            ["Title", provider.title],
            ["Telephone", provider.phone],
            ["Email", provider.email],
            ["Address", provider.address],
            ["Fax", provider.fax],
            ["Web", provider.web],
          ].filter((row) => row[1])
        : [
            ["Status", provider.status],
            ["Timing", provider.expected],
            ["Category", provider.section],
          ].filter((row) => row[1]),
      docs: provider.docs,
    };
  }

  return (
    <React.Fragment>
    <article className="tp" inert={drawer ? true : undefined}>
      <header className="tp-hero" ref={setSecRef("top")}>
        <p className="tp-kicker"><TpRule />Fund I · People</p>
        <div>
          <h1>The Fund I Partners</h1>
          <p className="tp-italic">— a patient hand for enduring houses.</p>
        </div>
      </header>

      <section className="tp-section" aria-labelledby="tp-partners" ref={setSecRef("01")}>
        <header className="tp-section-head">
          <p className="tp-kicker"><span className="tp-idx">01</span>The Team</p>
          <h2 id="tp-partners">The people who run Fund I</h2>
        </header>
        <div className="tp-partners">
          {TEAM_PARTNERS.map((p) => (
            <TeamPersonCard
              key={p.id}
              person={p}
              onOpen={(id) => setSel({ kind: "person", id })}
            />
          ))}
        </div>
        <div className="tp-group">
          <div className="tp-group-head">
            <span>Offices</span>
          </div>
          {TEAM_OFFICES.map((o) => (
            <div key={o.city} className="tp-city">
              <div>
                <span className="tp-city-name">{o.city}</span>
                <span className="tp-city-role">{o.role}</span>
              </div>
              <span className="tp-city-focus">{o.focus}</span>
            </div>
          ))}
        </div>
      </section>

      <section className="tp-section" aria-labelledby="tp-advisors" ref={setSecRef("02")}>
        <header className="tp-section-head">
          <p className="tp-kicker"><span className="tp-idx">02</span>Advisors</p>
          <h2 id="tp-advisors">Advisors to the partnership</h2>
        </header>
        {TEAM_ADVISORS.length ? (
          <div className="tp-partners">
            {TEAM_ADVISORS.map((p) => (
              <TeamPersonCard
                key={p.id}
                person={p}
                onOpen={(id) => setSel({ kind: "person", id })}
              />
            ))}
          </div>
        ) : (
          <p className="tp-prose tp-section-lead">Advisors are coming onto this page. A name appears here with the role and the biography, once both are on file.</p>
        )}
      </section>

      <section className="tp-section" aria-labelledby="tp-providers" ref={setSecRef("03")}>
        <header className="tp-section-head">
          <p className="tp-kicker"><span className="tp-idx">03</span>Service providers</p>
          <h2 id="tp-providers">Independent hands on the fund.</h2>
        </header>
        <div className="tp-prov-intro">
          <p className="tp-prose">Fund counsel is Seward &amp; Kissel LLP. The remaining appointments are open: RFPs where selection is in process, deal-by-deal counsel as investments require, and insurance and the capital call line timed to first closing. Open a row for the shortlist or the approach. Limited partner views are welcome.</p>
          <p className="tp-legend">
            <span className="tp-dot tp-dot-on" aria-hidden="true" />{TEAM_PROVIDERS.filter((v) => teamProviderPhase(v) === "appointed").length} appointed
            <span className="tp-dot" aria-hidden="true" />{TEAM_PROVIDERS.filter((v) => teamProviderPhase(v) === "process").length} in process
            <span className="tp-dot tp-dot-muted" aria-hidden="true" />{TEAM_PROVIDERS.filter((v) => !["appointed", "process"].includes(teamProviderPhase(v))).length} timed later
          </p>
        </div>
        <div className="tp-group">
          <div className="tp-prov-head" aria-hidden="true">
            <span />
            <span>Role</span>
            <span>Status</span>
            <span />
          </div>
          {TEAM_PROVIDERS.map((v) => {
            const on = provider && provider.id === v.id;
            const phase = teamProviderPhase(v);
            return (
              <button
                key={v.id}
                type="button"
                className={"tp-prov" + (on ? " is-on" : "")}
                onClick={() => setSel({ kind: "provider", id: v.id })}
              >
                <TeamMark status={teamProviderMark(v)} />
                <span className="tp-prov-id">
                  <span className="tp-prov-role">{v.role}</span>
                  {phase === "appointed" && v.firm && (
                    <span className="tp-prov-firm is-named">{v.firm}</span>
                  )}
                  {phase !== "appointed" && (
                    <span className="tp-prov-firm">{v.section}</span>
                  )}
                </span>
                <span className="tp-prov-status">
                  <span>{v.status}</span>
                  <span>{v.expected}</span>
                </span>
                <TpChevron />
              </button>
            );
          })}
        </div>
      </section>

      <section className="tp-section" aria-labelledby="tp-docs" ref={setSecRef("04")}>
        <header className="tp-section-head">
          <p className="tp-kicker"><span className="tp-idx">04</span>Documents</p>
          <h2 id="tp-docs">Biographies, references and the record.</h2>
        </header>
        <div className="tp-docs">
          {docs.map((file) => {
            const isBios = file.path === TEAM_BIOS_DOC;
            const isOrg = file.path === TEAM_ORG_DOC;
            const state = isOrg ? { kind: "ready", label: "Available" } : teamDocState(file, level);
            const readyLabel = isBios || isOrg ? "Done" : "View";
            const sub = isBios
              ? "Fund Documents Directory · partner and advisor biographies"
              : isOrg
                ? "See above · the three Fund I partners"
                : state.kind === "ready"
                  ? file.folderName
                  : state.kind === "locked"
                    ? "Opens with Level " + file.level + " access, or may await first close"
                    : "In preparation · added when the file is in the room";
            return (
              <button
                key={file.path}
                type="button"
                className="tp-doc"
                onClick={() => {
                  if (isOrg) {
                    goTo("01");
                    return;
                  }
                  if (isBios && navigate) {
                    navigate("documents", { folder: "operations", file: TEAM_BIOS_DOC });
                    return;
                  }
                  openDoc(file);
                }}
              >
                <TeamMark status={state.kind} />
                <span className="tp-doc-copy">
                  <span className={"tp-doc-name" + (state.kind === "ready" ? "" : " is-dim")}>{file.name}</span>
                  <span className="tp-doc-sub">{sub}</span>
                </span>
                <span className={"tp-status" + (state.kind === "ready" ? " is-on" : "")}>
                  {state.kind === "ready" ? readyLabel : state.label}
                  {state.kind === "ready" && <TpArrow />}
                </span>
              </button>
            );
          })}
        </div>
        <p className="tp-caption">Team Biographies open in the Fund Documents Directory. A locked file opens once your access includes that level or could be awaiting 1st close.</p>
      </section>

      <footer className="tp-foot">
        <div className="tp-foot-meta">
          <div><span>Maintained by</span><strong>Investor relations, Fund I</strong></div>
          <div><span>Review</span><strong>When a person or an appointment changes</strong></div>
          <div><span>Questions</span><a href={teamMail(TEAM_DOLLY, "Dolly Moorhead")}>Write to Dolly Moorhead</a></div>
          <div><span>Origination</span><a href={teamMail(TEAM_DEALS, "Origination")}>{TEAM_DEALS}</a></div>
        </div>
        <div className="tp-jumps">
          <button type="button" className="tp-jump" onClick={() => navigate("documents")}>
            <span>← Previous</span>
            <strong>Fund documents</strong>
          </button>
          <button type="button" className="tp-jump tp-jump-next" onClick={() => navigate("strategy")}>
            <span>Next →</span>
            <strong>Strategy & structure</strong>
          </button>
        </div>
      </footer>

      {drawer && ReactDOM.createPortal(
        <TeamDrawer
          item={drawer}
          level={level}
          viewer={{ name: viewerName, email: userEmail || "" }}
          onClose={() => setSel(null)}
          onOpenDoc={openDoc}
        />,
        document.body
      )}
    </article>
    {showRail && !drawer && ReactDOM.createPortal(
      <nav className="rm-rail" aria-label="Sections">
        {TEAM_NAV.map(([k, cd, label]) => {
          const on = active === k;
          const hov = navHover === k;
          return (
            <button
              key={k}
              type="button"
              className={"rm-rail-btn" + (on ? " active" : "")}
              aria-label={label}
              aria-current={on ? "true" : undefined}
              onClick={() => goTo(k)}
              onMouseEnter={() => setNavHover(k)}
              onMouseLeave={() => setNavHover(null)}
            >
              {showNames && (
                <span
                  className="rm-rail-name"
                  style={{
                    color: on
                      ? "var(--gold-200)"
                      : hov
                        ? "var(--alabaster)"
                        : "var(--sapphire-200)",
                  }}
                >
                  {label}
                </span>
              )}
              {!showNames && hov && (
                <span className="rm-rail-tip">{label}</span>
              )}
              <span
                className="rm-rail-code"
                style={{
                  color: on
                    ? "var(--gold-400)"
                    : hov
                      ? "var(--alabaster)"
                      : "var(--sapphire-400)",
                }}
              >
                {cd}
              </span>
              <span className="rm-rail-tick-wrap">
                <span
                  className="rm-rail-tick"
                  style={{
                    width: on ? 20 : hov ? 16 : 10,
                    background: on
                      ? "var(--gold-500)"
                      : hov
                        ? "var(--alabaster)"
                        : "var(--sapphire-400)",
                  }}
                />
              </span>
            </button>
          );
        })}
      </nav>,
      document.body
    )}
    </React.Fragment>
  );
}
