/* About.jsx -- Mission + Meet the team. Editorial aesthetic matches the
   rest of the site: warm cream, ink borders, display fonts, accent
   tints per card.

   Team list lives in a const at the top of this file so it's a one-edit
   update to add or change a team member. The first 5 fields (name,
   role, bio, accent, initials) are required; photo is optional -- if
   omitted the card renders the initials block instead. */

const TEAM = [
  {
    name: "J.J. Pospiech",
    role: "Performing Arts Coordinator",
    bio: "J.J. coordinates PPR's Performing Arts Office. Fifteen years managing recreation centers across Philadelphia; he books the rooms, hires the teaching artists, and shows up to every opening night.",
    accent: "var(--c-primary)",
    initials: "JJ",
  },
];

// Performing Arts Committee -- volunteer representatives from rec centers
// across Philadelphia. Accent colors rotate through the palette for visual
// variety; bios are placeholder pending individual write-ups (CR #210).
const COMMITTEE_ACCENTS = [
  "var(--c-tertiary)", "var(--c-accent)", "#7A8B5C",
  "var(--c-plum)", "var(--c-primary-deep)",
];
const COMMITTEE_ROSTER = [
  ["George Kilcullen",        "Pelbano"],
  ["Bill Arthur",             "Holmesburg"],
  ["Allison Darcy",           "O'Connor"],
  ["Kathy Migliarese",        "O'Connor"],
  ["Veronica Lawson",         "Palmer"],
  ["Kelly Orenshaw",          "Venice Island"],
  ["Shinelle Graves-Brinson", "Stenton Park"],
  ["Tawanda Starkes",         "Happy Hollow"],
  ["Shav'on Smith",           "Zeihler"],
  ["Angelique Haynseworth",   "Schmidt"],
  ["Kevin Sommerville",       "Cione"],
  ["Da'Lia Starkey",          "Conestoga"],
  ["Dwan Hunt",               "Amos"],
  ["Jose (Ralphie) Rodriguez","Waterloo"],
  ["Jessica (Jessie) Sherlock","MLK Older Adult Center"],
  ["Alice Dignam",            "Northern Liberties"],
  ["Jamila Abdur-Rahman",     "Francis J. Myers"],
  ["Lisa Summers",            "James Finnegan"],
  ["Steve Hnosko",            "Eastwick"],
  ["Folami Islam",            "Hawthorne"],
];
function getInitials(fullName) {
  // Strip parenthetical nicknames before extracting initials.
  const clean = fullName.replace(/\([^)]*\)/g, "").trim();
  const parts = clean.split(/\s+/).filter(Boolean);
  if (parts.length === 0) return "—";
  if (parts.length === 1) return parts[0][0].toUpperCase();
  // Use first and last word so hyphenated surnames give a clean 2-letter mark.
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
}
// CR #230: COMMITTEE (TeamCard-shaped) array removed -- the per-member
// tiles are gone; CommitteeMap is now the only way to browse the
// roster. getInitials is kept for the JJ TeamCard above (TEAM array)
// and is no longer used by the committee path.

// CR #229 / #230: committee map. Coordinates seeded one-shot via
// OpenStreetMap Nominatim against `<center name> Recreation Center,
// Philadelphia, PA` (with playground/rec-center fallbacks). Phone
// numbers per CR #230 are the direct lines for each rec center,
// pulled from publicly listed Philadelphia Parks & Recreation contact
// info -- not the central PPR office line.
const COMMITTEE_SITES = {
  "Pelbano":                { coords: [40.06219, -75.05094], neighborhood: "Northeast", phone: "215-685-1975" },
  "Holmesburg":             { coords: [40.03641, -75.02639], neighborhood: "Northeast", phone: "215-685-8714" },
  "Palmer":                 { coords: [40.09517, -74.98954], neighborhood: "Northeast", phone: "215-685-0371" },
  "Venice Island":          { coords: [40.023636, -75.221887], neighborhood: "Manayunk",  phone: "215-685-3583" },
  "Happy Hollow":           { coords: [40.02390, -75.16640], neighborhood: "Northwest", phone: "215-685-2195" },
  "Stenton Park":           { coords: [40.02408, -75.15283], neighborhood: "North",     phone: "215-685-9147" },
  "Zeihler":                { coords: [40.03400, -75.11887], neighborhood: "North",     phone: "215-685-9145" },
  "Schmidt":                { coords: [40.00200, -75.12930], neighborhood: "North",     phone: "215-685-9895" },
  "Amos":                   { coords: [39.98170, -75.16030], neighborhood: "North",     phone: "215-685-2708" },
  "Waterloo":               { coords: [39.98870, -75.13290], neighborhood: "North",     phone: "215-685-9891" },
  "MLK Older Adult Center": { coords: [39.98060, -75.17040], neighborhood: "North",     phone: "215-685-2715" },
  "Cione":                  { coords: [39.98020, -75.11870], neighborhood: "Kensington", phone: "215-685-9880" },
  "Northern Liberties":     { coords: [39.96270, -75.14350], neighborhood: "Kensington", phone: "215-686-1785" },
  // CR #231: "O'Connor" is the renamed Chalfont Playground in
  // Northeast Philly (Millbrook), 4330 Deerpath Lane -- not the
  // unrelated O'Connor pool in Center City that the first geocode
  // matched. Corrected coords + neighborhood.
  "O'Connor":               { coords: [40.07945, -74.97434], neighborhood: "Northeast", phone: "215-685-9398" },
  "Hawthorne":              { coords: [39.93590, -75.16710], neighborhood: "South",     phone: "215-685-1848" },
  "Francis J. Myers":       { coords: [39.93450, -75.22890], neighborhood: "Southwest", phone: "215-685-2698" },
  "James Finnegan":         { coords: [39.91530, -75.23230], neighborhood: "Southwest", phone: "215-685-4191" },
  "Eastwick":               { coords: [39.90480, -75.25110], neighborhood: "Southwest", phone: "215-685-4194" },
  "Conestoga":              { coords: [39.97530, -75.22730], neighborhood: "West Philadelphia", phone: "215-685-0146" },
};

// CR #256: per-member bios. Keyed by the exact name string in
// COMMITTEE_ROSTER so the rendering side can do an O(1) lookup and fall back
// to the "Bio coming soon." placeholder when a member isn't here yet.
const COMMITTEE_BIOS = {
  "Jessica (Jessie) Sherlock": "Jessica grew up as a camper at Young Performers Theater Camp, and as a performer in multiple musical theater shows and dance shows with Parks and Recreation before working with the Performing Arts office. Within the Performing Arts office, Jessica has directed and choreographed children's musical theater, and is now bringing the Performing Arts into Older Adult Centers.",
  "Bill Arthur": "Bill has worked for the Philadelphia Department of Parks & Recreation since 1995, spending his first ten years in the Performing Arts Office before moving into recreation center leadership. He founded the Star Players Theater Group in 2013 -- now in its 14th season -- and today runs Holmesburg Recreation Center, where he leads performing arts programs for all ages and emcees every show. Bill studied theater at the University of the Arts, majoring in acting and directing, and has performed in over 200 shows, professional and amateur. His credits include commercials, voice-over work, Murder Mystery theater, and national tours across the United States and Canada. He's also a 25-year member of the Vogue Players of Parks and Recreation.",
  "Shav'on Smith": "Shav'on Smith, a native of North Philadelphia and a graduate of Morgan State University with a BA in Theater, is the artistic director of Vivid Movement Dance Collective and Grounded Theatre Company, and a Recreation Leader 2 for Philadelphia Parks and Recreation.",
};

// CR #272: optional per-member portrait. Keyed by the exact name string
// in COMMITTEE_ROSTER. Rendered to the right of the bio text when the
// member is selected on the map; absent members fall back to the
// text-only layout.
const COMMITTEE_PHOTOS = {
  "Bill Arthur": "/img/committee-bill-arthur.jpg",
  "Shav'on Smith": "/img/committee-shavon-smith.jpg",
};

// CR #273: optional per-member "see also" links. Renders as a small
// ghost button under the bio. Hash-routed links jump to a known anchor
// after switching to the target page (Gallery scrolls to #star-players
// via the section's id + scrollMarginTop).
const COMMITTEE_LINKS = {
  "Bill Arthur": { label: "See the Star Players gallery →", hash: "#gallery", anchor: "star-players" },
};

function jumpToHashAnchor(hash, anchor) {
  // Navigate the SPA hash router, then scroll to the in-page anchor on
  // the new page. Two animation frames give the route a chance to mount
  // before the scroll fires.
  window.location.hash = hash;
  requestAnimationFrame(() => requestAnimationFrame(() => {
    const el = document.getElementById(anchor);
    if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  }));
}

const COMMITTEE_MEMBERS_MAPPED = COMMITTEE_ROSTER
  .map(([name, center], i) => {
    const site = COMMITTEE_SITES[center];
    if (!site) return null;
    return {
      name, center,
      coords: site.coords,
      neighborhood: site.neighborhood,
      phone: site.phone,
      accent: COMMITTEE_ACCENTS[i % COMMITTEE_ACCENTS.length],
    };
  })
  .filter(Boolean);

function CommitteeMap() {
  const [neighborhoodFilter, setNeighborhoodFilter] = React.useState("all");
  const [selected, setSelected] = React.useState(null);
  const containerRef = React.useRef(null);
  const mapRef = React.useRef(null);

  const allNeighborhoods = React.useMemo(() => {
    const set = new Set(COMMITTEE_MEMBERS_MAPPED.map(m => m.neighborhood));
    return Array.from(set).sort();
  }, []);

  const filtered = React.useMemo(() => (
    neighborhoodFilter === "all"
      ? COMMITTEE_MEMBERS_MAPPED
      : COMMITTEE_MEMBERS_MAPPED.filter(m => m.neighborhood === neighborhoodFilter)
  ), [neighborhoodFilter]);

  // Init Leaflet once. Leaflet's CSS + JS load in index.html so it's
  // available across pages without bundling here.
  React.useEffect(() => {
    let cancelled = false;
    function init() {
      if (cancelled || !window.L || !containerRef.current || mapRef.current) return;
      const L = window.L;
      const map = L.map(containerRef.current, {
        center: [39.99, -75.16],
        zoom: 11,
        zoomControl: true,
        attributionControl: false,
        scrollWheelZoom: false,
      });
      L.tileLayer("https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png", {
        subdomains: "abcd",
        maxZoom: 18,
      }).addTo(map);
      mapRef.current = { map, layer: L.layerGroup().addTo(map) };
    }
    if (window.L) init();
    else {
      const interval = setInterval(() => { if (window.L) { clearInterval(interval); init(); } }, 50);
      return () => {
        cancelled = true;
        clearInterval(interval);
        if (mapRef.current) { mapRef.current.map.remove(); mapRef.current = null; }
      };
    }
    return () => {
      cancelled = true;
      if (mapRef.current) { mapRef.current.map.remove(); mapRef.current = null; }
    };
  }, []);

  // Redraw pins whenever the filter changes. clearLayers preserves the
  // tile layer (added directly to map) and only wipes the markers layer.
  React.useEffect(() => {
    if (!mapRef.current || !window.L) return;
    const { layer } = mapRef.current;
    layer.clearLayers();
    const L = window.L;
    filtered.forEach((m) => {
      const icon = L.divIcon({
        className: "cmtt-pin",
        html: `<div class="cmtt-pin-body" style="background:${m.accent}"><div class="cmtt-pin-dot"></div></div>`,
        iconSize: [22, 22],
        iconAnchor: [11, 11],
      });
      L.marker(m.coords, { icon }).addTo(layer).on("click", () => setSelected(m));
    });
  }, [filtered]);

  return (
    <div style={{ marginTop: 32 }}>
      {/* CR #230: filter chips above the 2-col map/info layout. The
          previous "Find your neighborhood." SectionHeader was removed
          per the CR. */}
      <div className="pgm-filter-row" style={{ marginTop: 4, display: "grid", gridTemplateColumns: "120px 1fr", alignItems: "center", gap: 12 }}>
        <div className="pgm-filter-label" style={{ fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--c-ink-soft)" }}>Neighborhood</div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
          <CmttFilterChip active={neighborhoodFilter === "all"} onClick={() => setNeighborhoodFilter("all")} label="All" count={COMMITTEE_MEMBERS_MAPPED.length} />
          {allNeighborhoods.map(n => (
            <CmttFilterChip
              key={n}
              active={neighborhoodFilter === n}
              onClick={() => setNeighborhoodFilter(n)}
              label={n}
              count={COMMITTEE_MEMBERS_MAPPED.filter(m => m.neighborhood === n).length}
            />
          ))}
        </div>
      </div>

      {/* Two-column layout: smaller map on the left, member info on
          the right. Stacks vertically below 900px so the info card
          always lands directly under the map on mobile. */}
      <div className="cmtt-map-grid" style={{ marginTop: 18 }}>
        <div
          ref={containerRef}
          className="cmtt-map-canvas"
          style={{
            height: 380,
            borderRadius: 18, overflow: "hidden",
            border: "2px solid var(--c-ink)",
            boxShadow: "var(--shadow-lift)",
            background: "var(--c-cream-deep)",
            // CR #237: isolate Leaflet's z-index stack so its zoom controls
            // (z-index ~1000) and popups don't paint over the sticky header.
            position: "relative",
            isolation: "isolate",
          }}
        />
        <div className="cmtt-info">
          {selected ? (
            <div
              className="card"
              style={{
                background: "var(--c-paper)",
                border: "2px solid var(--c-ink)",
                borderRadius: 18,
                padding: 24,
                boxShadow: "var(--shadow-lift)",
                height: "100%",
              }}
            >
              <div className="eyebrow" style={{ color: selected.accent }}>Committee member</div>
              <div className="display" style={{ fontSize: 26, marginTop: 6, lineHeight: 1.1 }}>{selected.name}</div>
              <div style={{ fontSize: 13.5, color: "var(--c-ink-soft)", marginTop: 6 }}>
                {selected.center} &middot; {selected.neighborhood}
              </div>
              <div style={{ marginTop: 16, fontSize: 14.5 }}>
                <a
                  href={`tel:${selected.phone.replace(/[^0-9+]/g, "")}`}
                  style={{ color: "var(--c-primary-deep)", fontWeight: 600 }}
                >
                  {selected.phone}
                </a>
                <div style={{ fontSize: 11.5, color: "var(--c-ink-soft)", marginTop: 4, fontFamily: "var(--f-mono)", letterSpacing: "0.05em" }}>
                  {selected.center} direct line
                </div>
              </div>
              {(() => {
                const bio = COMMITTEE_BIOS[selected.name] || "Bio coming soon.";
                const photo = COMMITTEE_PHOTOS[selected.name];
                if (!photo) {
                  return <p style={{ fontSize: 13.5, color: "var(--c-ink-soft)", marginTop: 16, lineHeight: 1.55 }}>{bio}</p>;
                }
                return (
                  <div className="cmtt-bio-row" style={{ marginTop: 16 }}>
                    <p style={{ fontSize: 13.5, color: "var(--c-ink-soft)", lineHeight: 1.55, margin: 0 }}>{bio}</p>
                    <div className="cmtt-bio-photo">
                      <img
                        src={photo}
                        alt={`Portrait of ${selected.name}`}
                        loading="lazy"
                        style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
                      />
                    </div>
                  </div>
                );
              })()}
              {COMMITTEE_LINKS[selected.name] && (
                <div style={{ marginTop: 16 }}>
                  <button
                    type="button"
                    className="btn small"
                    onClick={() => {
                      const link = COMMITTEE_LINKS[selected.name];
                      jumpToHashAnchor(link.hash, link.anchor);
                    }}
                  >
                    {COMMITTEE_LINKS[selected.name].label}
                  </button>
                </div>
              )}
              <div style={{ marginTop: 18 }}>
                <button type="button" className="btn small ghost" onClick={() => setSelected(null)}>Clear</button>
              </div>
            </div>
          ) : (
            <div
              style={{
                background: "var(--c-cream-deep)",
                border: "2px dashed var(--c-ink-soft)",
                borderRadius: 18,
                padding: 24,
                height: "100%",
                display: "flex",
                flexDirection: "column",
                justifyContent: "center",
              }}
            >
              <div className="eyebrow">Tap a pin</div>
              <p style={{ fontSize: 14, color: "var(--c-ink-soft)", marginTop: 8, lineHeight: 1.55 }}>
                Click any committee pin on the map to see the member, their
                home rec center, and a direct phone line.
              </p>
            </div>
          )}
        </div>
      </div>

      <style>{`
        .cmtt-map-grid {
          display: grid;
          grid-template-columns: 1.15fr 1fr;
          gap: 22px;
          align-items: stretch;
        }
        .cmtt-info { display: flex; }
        .cmtt-info > * { width: 100%; }
        .cmtt-bio-row {
          display: grid;
          grid-template-columns: 1fr 140px;
          gap: 16px;
          align-items: start;
        }
        .cmtt-bio-photo {
          width: 140px;
          aspect-ratio: 1 / 1;
          border-radius: 14px;
          overflow: hidden;
          border: 2px solid var(--c-ink);
          box-shadow: var(--shadow-lift);
          background: var(--c-cream-deep);
        }
        @media (max-width: 900px) {
          .cmtt-map-grid { grid-template-columns: 1fr; }
          .cmtt-map-canvas { height: 320px !important; }
          .cmtt-bio-row { grid-template-columns: 1fr; }
          .cmtt-bio-photo { width: 160px; }
        }
        .cmtt-pin-body {
          width: 22px; height: 22px;
          border: 2px solid var(--c-ink);
          border-radius: 50%;
          display: flex; align-items: center; justify-content: center;
          box-shadow: 0 1px 2px rgba(42,24,32,0.4);
          cursor: pointer;
        }
        .cmtt-pin-dot {
          width: 6px; height: 6px;
          border-radius: 50%;
          background: var(--c-paper);
        }
        .cmtt-chip {
          appearance: none;
          background: var(--c-paper);
          border: 1.5px solid var(--c-ink);
          border-radius: 999px;
          padding: 6px 12px;
          font-family: var(--f-mono);
          font-size: 11.5px;
          letter-spacing: 0.05em;
          color: var(--c-ink);
          cursor: pointer;
          display: inline-flex;
          align-items: center;
          gap: 6px;
        }
        .cmtt-chip:hover { background: var(--c-cream-deep); }
        .cmtt-chip.is-active {
          background: var(--c-ink);
          color: var(--c-paper);
          border-color: var(--c-ink);
        }
        .cmtt-chip-count {
          font-size: 10.5px;
          opacity: 0.7;
        }
      `}</style>
    </div>
  );
}

function CmttFilterChip({ active, onClick, label, count }) {
  return (
    <button type="button" onClick={onClick} className={`cmtt-chip ${active ? "is-active" : ""}`}>
      {label} <span className="cmtt-chip-count">{count}</span>
    </button>
  );
}

function AboutPage() {
  return (
    <div>
      {/* Hero -- mission statement front and center */}
      <section style={{ background: "var(--c-cream)", borderBottom: "2px solid var(--c-ink)" }}>
        <div className="container" style={{ padding: "80px 0 56px" }}>
          <div className="eyebrow">About Performing Arts</div>
          <div style={{ display: "grid", gridTemplateColumns: "1.05fr 0.95fr", gap: 48, alignItems: "center", marginTop: 12 }} className="about-hero">
            <div>
              <h1 className="display" style={{ fontSize: "clamp(48px, 9vw, 124px)", margin: "0 0 24px", lineHeight: 0.95 }}>
                Every kid<br />gets a <span style={{ fontStyle: "italic", color: "var(--c-primary)" }}>stage.</span>
              </h1>
              <p style={{ fontSize: 20, lineHeight: 1.55, color: "var(--c-ink)", maxWidth: 560 }}>
                PPR's Performing Arts Office gives every Philadelphia kid a place to make
                something live. We run free and low-cost dance, theater, and music programs
                at recreation centers across the city, alongside our flagship summer camps
                and the Venice Island Performing Arts Center.
              </p>
              <p style={{ fontSize: 17, lineHeight: 1.6, color: "var(--c-ink-soft)", maxWidth: 540, marginTop: 16 }}>
                Whether you're auditioning for college, trying tap shoes for the first time,
                or just need a room full of other kids who care about the same thing &mdash;
                the magic happens here.
              </p>
            </div>
            <div style={{
              borderRadius: 22, overflow: "hidden",
              border: "2px solid var(--c-ink)", boxShadow: "var(--shadow-lift)",
              aspectRatio: "4/3",
            }}>
              <img
                src="/img/cr-170-jj-photo.jpg"
                alt="PPR Performing Arts kids at a community showcase"
                style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
              />
            </div>
          </div>
        </div>
        <style>{`
          @media (max-width: 900px) { .about-hero { grid-template-columns: 1fr !important; gap: 28px !important; } }
        `}</style>
      </section>

      {/* The three pillars -- access, craft, community */}
      <section className="section" style={{ background: "var(--c-paper)", borderBottom: "2px solid var(--c-ink)" }}>
        <div className="container">
          <SectionHeader
            eyebrow="What we stand for"
            title="Three things, no compromise."
            subtitle="If a program doesn't fit at least two of these, we don't run it."
          />
          <div className="about-pillars">
            <Pillar
              num="01"
              tint="#F5C6B0"
              title="Access"
              body="Programs at every recreation center we can staff. We meet kids where they live. Philadelphia kids always have a place to perform."
            />
            <Pillar
              num="02"
              tint="#F2D88F"
              title="Craft"
              body="Working artists teach the technique. Real stages, real lighting, real audiences. The point isn't a participation trophy &mdash; it's coming back next year better than you were last year."
            />
            <Pillar
              num="03"
              tint="#C9D9B0"
              title="Community"
              body="The kid in your camp this summer might be the kid who casts you in a show ten years from now. We're building a network, not just a cast list."
            />
          </div>
        </div>
      </section>

      {/* Meet the team */}
      <section className="section">
        <div className="container">
          <SectionHeader
            eyebrow="The people"
            title="Meet the team."
            subtitle="Small team, generous calendar. Reach us at the office line: 215-685-3585."
          />
          <div className="about-team">
            {TEAM.map((p, i) => (
              <TeamCard key={p.name} person={p} index={i} />
            ))}
          </div>

          {/* Performing Arts Committee -- volunteer reps from rec
              centers citywide. CR #230: individual TeamCard tiles
              removed; the map below is the canonical way to browse
              the committee. */}
          <div style={{ marginTop: 56 }}>
            <SectionHeader
              eyebrow="Performing Arts Committee"
              title="With deep appreciation."
              subtitle="Thank you to the volunteers across the city who serve on the Performing Arts Committee. They support JJ on programming, partnerships, and recruitment from their home recreation centers. Find a member on the map below."
            />
            <CommitteeMap />
          </div>

          <div className="card" style={{
            marginTop: 48,
            padding: "28px 32px",
            background: "var(--c-cream-deep)",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            gap: 20,
            flexWrap: "wrap",
          }}>
            <div>
              <div className="eyebrow">Want to teach with us?</div>
              <div className="display" style={{ fontSize: 26, marginTop: 6 }}>
                We're always hiring teaching artists.
              </div>
              <p style={{ fontSize: 14.5, color: "var(--c-ink-soft)", marginTop: 8, maxWidth: 540 }}>
                Dance, theater, music, voice, audition prep, technical theatre &mdash;
                if you've got a craft and a community in mind, send us a note.
              </p>
            </div>
            <a href="mailto:Joseph.J.Pospiech@phila.gov" className="btn">
              Email JJ &rarr;
            </a>
          </div>
        </div>
      </section>

      <style>{`
        .about-pillars {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 22px;
        }
        .about-team {
          display: grid;
          grid-template-columns: repeat(2, 1fr);
          gap: 22px;
        }
        @media (max-width: 900px) {
          .about-pillars { grid-template-columns: 1fr; }
          .about-team    { grid-template-columns: 1fr; }
        }
      `}</style>
    </div>
  );
}

function Pillar({ num, tint, title, body }) {
  return (
    <div className="card" style={{
      padding: 28,
      background: "var(--c-paper)",
      border: "2px solid var(--c-ink)",
      borderRadius: 22,
      boxShadow: "var(--shadow-lift)",
      position: "relative",
      overflow: "hidden",
    }}>
      <div style={{
        position: "absolute", top: 0, left: 0, right: 0, height: 8, background: tint,
      }} />
      <div style={{
        fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.18em",
        textTransform: "uppercase", color: "var(--c-ink-soft)", marginTop: 8,
      }}>{num}</div>
      <div className="display" style={{ fontSize: 30, marginTop: 6, lineHeight: 1 }}>
        {title}
      </div>
      <p style={{ fontSize: 14.5, lineHeight: 1.6, color: "var(--c-ink)", marginTop: 14 }}>
        {body}
      </p>
    </div>
  );
}

function TeamCard({ person, index }) {
  // Tilt every other card a hair so the grid reads handmade rather than
  // SaaS-template. Subtle: 0.6 / -0.6 deg, no bigger.
  const tilt = index % 2 === 0 ? "rotate(-0.6deg)" : "rotate(0.6deg)";
  return (
    <div className="card" style={{
      padding: 0,
      overflow: "hidden",
      background: "var(--c-paper)",
      border: "2px solid var(--c-ink)",
      borderRadius: 22,
      boxShadow: "var(--shadow-lift)",
      transform: tilt,
      display: "grid",
      gridTemplateColumns: "auto 1fr",
    }}>
      <div style={{
        background: person.accent,
        color: "var(--c-paper)",
        padding: "28px 22px",
        fontFamily: "var(--f-display)",
        fontWeight: 800,
        fontSize: 32,
        letterSpacing: "-0.01em",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        minWidth: 110,
        borderRight: "2px solid var(--c-ink)",
      }} aria-hidden="true">
        {person.initials}
      </div>
      <div style={{ padding: "22px 24px" }}>
        <div className="eyebrow">{person.role}</div>
        <div className="display" style={{ fontSize: 24, marginTop: 4, lineHeight: 1.05 }}>
          {person.name}
        </div>
        <p style={{ fontSize: 14.5, lineHeight: 1.6, color: "var(--c-ink-soft)", marginTop: 12 }}>
          {person.bio}
        </p>
      </div>
    </div>
  );
}

Object.assign(window, { AboutPage });
