/* =============================================================================
   Design tokens
   Same values as the `about` repo's :root (see about/README.md) — pull from
   there rather than introducing new ones if this page grows. `--pad-x` gets
   a responsive override below per about/README.md's own guidance ("if you
   add anything wider than a headline/paragraph, backport the responsive
   `--pad-x` media queries from `home`").
   ============================================================================= */
:root {
  --space-025:   2px;
  --space-050:   4px;
  --space-075:   6px;
  --space-100:   8px;
  --space-150:  12px;
  --space-200:  16px;
  --space-250:  20px;
  --space-300:  24px;
  --space-400:  32px;
  --space-500:  40px;
  --space-600:  48px;
  --space-800:  64px;
  --space-1000: 80px;

  --c-bg:       #ffffff;
  --c-dark:     #0d0d0c;
  --c-light-bg: #f8f7f4;
  --c-accent:   #5533ee;
  --c-red:      #f03d1f;
  /* Deeper red-orange — the gradient's closing stop, promoted to a token
     of its own. Link text on a white/light ground uses this: --c-red
     only reaches ~3.9:1 against white, this clears 4.5:1. --c-red stays
     the brand accent for fills, borders, icons, tags and labels. */
  --c-red-dark:   #df3611;
  --c-gray:     #888680;
  --c-white:    #ffffff;
  --c-gradient: linear-gradient(150deg, #5533ee 0%, var(--c-red-dark) 81%);

  /* Two families, no third — and the split is by what the text IS, not by
     heading level. --f-serif: page titles, and titles of works or names of
     people (a post title, a paper title, a person's name), plus pull-quote
     copy. --f-sans: section headings, card and UI labels, running prose,
     metadata, controls and uppercase micro-labels.
     The one that trips people up: a SECTION HEADING IS NOT SERIF. Serif
     marks a thing that has its own name; sans marks the furniture around
     it. See README -> Typography. */
  --f-serif: 'EB Garamond', Georgia, 'Times New Roman', serif;
  --f-sans:  'DM Sans', system-ui, -apple-system, sans-serif;
  /* -- Type scale (sitewide -- see README) --------------------------------
     Fluid: each clamp() interpolates between the mobile floor and the
     desktop ceiling, so tablet needs no separate breakpoint override.
     12px is the hard floor; nothing on the site ships smaller.         */
  --fs-display:     clamp(36px, 22.7px + 3.70vw, 76px);
  --fs-h1:          clamp(36px, 29.3px + 1.85vw, 56px);
  --fs-h2:          clamp(26px, 21.3px + 1.30vw, 40px);
  --fs-h3:          clamp(20px, 18.7px + 0.37vw, 24px);
  --fs-lede:        clamp(18px, 17.3px + 0.19vw, 20px);
  --fs-body:        16px;
  --fs-small:       14px;
  --fs-small-serif: 15px;   /* EB Garamond runs ~1px small beside DM Sans */
  --fs-micro:       12px;   /* uppercase labels, tags, meta -- the floor */

  --lh-display: 1.05;
  --lh-heading: 1.15;
  --lh-lede:    1.26;
  --lh-title:   1.3;
  --lh-body:    1.55;

  --max-w: 1440px;
  --pad-x: var(--space-1000);
}
@media (max-width: 900px) {
  :root { --pad-x: var(--space-400); }
}
@media (max-width: 480px) {
  :root { --pad-x: var(--space-250); }
}

/* =============================================================================
   External Link Arrow Badge — copied verbatim from about/styles.css.
   Black circle + white arrow signaling "opens an external site," on every
   card that links out. Sliding purple-to-orange gradient on hover. Host
   element needs position: relative. If you touch one repo's copy, touch
   the other's.
   ============================================================================= */
.card-arrow {
  position: absolute;
  top: var(--space-100);
  right: var(--space-100);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--c-dark);
  color: var(--c-white);
  font-size: var(--fs-micro);
  line-height: 1;
  transition: transform 0.2s ease;
  pointer-events: none;
}
@keyframes card-arrow-slide {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}
a:hover .card-arrow {
  transform: scale(1.15) translate(2px, -2px);
  background: linear-gradient(100deg, var(--c-accent), var(--c-red), var(--c-accent));
  background-size: 220% 100%;
  animation: card-arrow-slide 1.2s linear infinite;
}

/* =============================================================================
   Reset
   ============================================================================= */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* overflow-anchor: none avoids a browser "scroll anchoring" bug where the
   page silently scrolls itself down a bit after load — the hero title
   sits right at the very top with only 20px of padding above it, and when
   the web fonts swap in a beat after first paint, the hero title's height
   shifts slightly; the browser's default scroll-anchoring then nudges the
   viewport to compensate, which crops the title. Scrolling up manually
   reveals it fine — this just stops the auto-scroll from happening in the
   first place. */
html { scroll-behavior: smooth; overflow-anchor: none; }
body {
  font-family: var(--f-sans);
  color: var(--c-dark);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overflow-anchor: none;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; height: auto; display: block; }
a:focus-visible {
  outline: 2px solid var(--c-red);
  outline-offset: 2px;
}

/* =============================================================================
   Shared inner container — same rule/selector convention as about/styles.css.
   ============================================================================= */
.team-hero__inner,
.team-section__inner {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

/* =============================================================================
   Scroll-triggered reveal — same progressive-enhancement pattern as
   about/styles.css: the opacity/transform rule only applies once the page's
   own script confirms it can run (js-reveal-ready on <html>), so a page with
   JS disabled or blocked never gets stuck with invisible content.

   Uses the standalone `translate` property (not `transform`) for the
   entrance slide, on purpose: .person-card's hover lift uses `transform:
   translateY(-4px)` with its own fast 0.15s transition (see the .person-card
   rule below), and `transform` was also being used here for the entrance —
   since a `transition` shorthand replaces the whole list per property, the
   more specific reveal rule was silently overriding transform's transition
   to this reveal's slower duration even after the reveal had long finished,
   making hover lifts feel sluggish instead of crisp. `translate` and
   `transform` are independent, separately-transitionable properties, so
   splitting them here removes that conflict entirely. Also switched off the
   generic `ease` curve to a smoother ease-out (cubic-bezier), and dropped
   the added `scale()` and reduced the travel distance — the combination of
   a long 56px slide, a scale change, and a slow linear-ish ease was reading
   as heavy/sluggish rather than smooth.
   ============================================================================= */
.js-reveal-ready .reveal {
  opacity: 0;
  translate: 0 24px;
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), translate 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.js-reveal-ready .reveal.is-visible {
  opacity: 1;
  translate: none;
}

/* Person-card tiles get their own staggered reveal, cued off their parent
   section's .is-visible class — same technique as about's school-block /
   center-block / partner-card stagger. */
.js-reveal-ready .person-card {
  opacity: 0;
  translate: 0 20px;
  transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1), translate 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.is-visible .person-card {
  opacity: 1;
  translate: none;
}
.person-card:nth-child(1) { transition-delay: 0.05s; }
.person-card:nth-child(2) { transition-delay: 0.11s; }
.person-card:nth-child(3) { transition-delay: 0.17s; }
.person-card:nth-child(4) { transition-delay: 0.23s; }
.person-card:nth-child(5) { transition-delay: 0.29s; }
.person-card:nth-child(6) { transition-delay: 0.35s; }
.person-card:nth-child(7) { transition-delay: 0.41s; }
.person-card:nth-child(8) { transition-delay: 0.47s; }

/* =============================================================================
   HERO  ("Our Team")
   Same shape as about's Mission Statement block: serif accent-purple H1,
   sans lede paragraph filling the full padded width. No eyebrow/kicker
   above the title.
   ============================================================================= */
.team-hero {
  /* Top of page: 80px from the site menu to the page title, the same on
     every page (--space-1000, the documented page-level rhythm). */
  padding-top: var(--space-1000);
  padding-bottom: var(--space-600);
}

.team-hero__title {
  font-family: var(--f-serif);
  font-size: var(--fs-h1);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: 0;
  color: var(--c-accent);
  margin-bottom: var(--space-250);
}

.team-hero__lede {
  font-family: var(--f-sans);
  font-size: var(--fs-lede);
  font-weight: 300;
  line-height: var(--lh-lede);
  color: var(--c-dark);
}

/* =============================================================================
   TEAM SECTIONS  (Leadership & Staff / Knight Fellows / Faculty Advisors /
   Part-Time Staff)
   Section-header pattern per about/README.md: 24px / weight 600 / --c-dark,
   with a bottom border — the documented convention for repeated section
   headings on a plain (non-gradient) page.
   ============================================================================= */
.team-section {
  padding-top: var(--space-1000);
  padding-bottom: var(--space-1000);
}
.team-section:last-child {
  padding-bottom: var(--space-800);
}

/* Matches about's repeated colored-block chapter titles (.partners__title /
   .related-centers__title) exactly — 40px / weight 600 / -0.02em / 1.15 —
   rather than home's smaller 24px "What's New" list-header size. No
   border-bottom, since about's own version of this heading doesn't have
   one; the heading-to-grid gap below is still the documented 48px. */
/* Weight 700 on the white sections; the two colored variants below pull
   it back to 600, per the sitewide white-vs-colored heading split. */
.team-section__title {
  font-family: var(--f-sans);
  font-size: var(--fs-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: var(--lh-heading);
  color: var(--c-red);
  margin-bottom: var(--space-300);
}

/* Lede paragraph under each section heading — about's actual heading+lede
   pattern (.partners__title -> .partners__lede, .related-centers__title ->
   .related-centers__lede), both at the documented flat 24px gap, rather
   than jumping straight from heading to grid. Full padded width, no
   max-width of its own, per about/README.md's body-copy rule. */
.team-section__lede {
  font-family: var(--f-sans);
  font-size: var(--fs-lede);
  font-weight: 300;
  line-height: var(--lh-lede);
  color: var(--c-dark);
  margin-bottom: var(--space-300);
}

/* Core Team gets a full-bleed brand-gradient backdrop (the
   same purple-to-red gradient used across the shared system) so it reads
   as the page's lead section — cards stay plain white tiles floating on
   top, same figure/ground logic as home's Research/Faculty CTA blocks. */
.team-section--gradient {
  background: var(--c-gradient);
}
.team-section--gradient .team-section__title,
.team-section--gradient .team-section__lede {
  color: var(--c-white);
}

.team-section--gradient .team-section__title { font-weight: 600; }

/* Faculty Advisors gets a solid brand-purple backdrop — same treatment as
   about's Partners section (background: var(--c-accent)), distinct from
   the two-tone --c-gradient used on Core Team so the two
   colored sections read as siblings, not duplicates. Cards stay white. */
.team-section--purple {
  background: var(--c-accent);
}
.team-section--purple .team-section__title,
.team-section--purple .team-section__lede {
  color: var(--c-white);
}

.team-section--purple .team-section__title { font-weight: 600; }

/* Grid never just shrinks its columns as the viewport narrows — auto-fill +
   minmax reflows to fewer columns at natural breakpoints instead, same
   reasoning as about's fixed-column grids with explicit breakpoints. */
.team-section__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--space-250);
}

/* Card shape: plain white tile, lifting with depth on hover — same hover
   treatment as about's logo tiles (box-shadow + translateY), no accent
   top-border or border-color swap. */
.person-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-075);
  background: var(--c-white);
  border: 1px solid rgba(13, 13, 12, 0.08);
  padding: var(--space-300) var(--space-200);
  transition: box-shadow 0.15s, transform 0.15s;
}
.person-card:hover {
  box-shadow: 0 12px 24px rgba(13, 13, 12, 0.16);
  transform: translateY(-4px);
}

/* Knight Fellows and Part Time Staff sit on plain white backgrounds, so
   their cards get a red-orange border instead of the section-heading's
   solid fill — a visible accent without inverting the card to a filled
   color block. Text stays the standard dark/gray, since the tile itself
   is still white. */
.team-section:not(.team-section--gradient):not(.team-section--purple) .person-card {
  background: var(--c-white);
  border: 2px solid var(--c-red);
}

/* Alumni status always reads as a white tile with the style guide's
   --c-gray border, regardless of section — overrides both the plain
   white tile and the red-bordered tile above, same "border, not fill"
   treatment. */
.person-card--alumni,
.team-section:not(.team-section--gradient):not(.team-section--purple) .person-card--alumni {
  background: var(--c-white);
  border: 2px solid var(--c-gray);
}

.person-card__photo {
  width: 208px;
  height: 208px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: var(--space-150);
  background: var(--c-light-bg);
  filter: grayscale(100%);
  transition: filter 0.3s ease;
}
.person-card:hover .person-card__photo {
  filter: grayscale(0%);
}

.person-card__name {
  font-family: var(--f-serif);
  font-weight: 600;
  font-size: var(--fs-lede);
  line-height: var(--lh-title);
  color: var(--c-dark);
}

.person-card__role {
  font-family: var(--f-sans);
  font-size: var(--fs-small);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--c-gray);
  margin-top: var(--space-050);
}

.person-card__tag {
  position: absolute;
  top: var(--space-150);
  left: var(--space-150);
  padding: var(--space-025) var(--space-150);
  font-family: var(--f-sans);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-gray);
  background: var(--c-light-bg);
}

@media (max-width: 640px) {
  .team-hero { padding-bottom: var(--space-600); }
  .team-section { padding-bottom: var(--space-800); }
}

/* ── Trailing-margin guard ─────────────────────────────────────────────────
   These pages are embedded in an iframe that is resized to the height this
   page reports, and that height is measured from document.body.

   A bottom margin on the last element COLLAPSES THROUGH body and out to
   <html>. It never appears in body.scrollHeight, but it does extend
   documentElement.scrollHeight — so the frame gets sized short of the real
   document, the embedded page is left with a few px it can scroll, and it
   swallows the visitor's wheel events: the outer page then only scrolls when
   the cursor is over its scrollbar. It has bitten twice (home, 64px;
   grants-overview, 80px) and it is invisible in the builder.

   display: flow-root makes body a block formatting context, so descendant
   margins can no longer escape it and the measured height is always the whole
   document. Cheap, and it removes a whole class of bug rather than one
   instance. If a page grows here, something was relying on a margin escaping
   — convert that margin to padding rather than removing this.
   ====================================================================== */
body { display: flow-root; }

/* ── Page end ──────────────────────────────────────────────────────────
   Sitewide (Sept 2026): the last section sits flush on the global footer,
   which opens with its own 132px white signal band. That band is the gap
   before the footer on every page. The old 80px trailing space on top of it
   left 200px+ of white at the end of some pages. */
.team-section:last-of-type { padding-bottom: 0; }
