/* ---- Team introduction — sticky intro copy + scrolling team card grid ----
   Standard CSS sticky-sidebar recipe: both columns are flex items in a
   row, so the flex container (.team-intro) is already as tall as its
   tallest child — the card grid — regardless of align-items. Deliberately
   align-items: flex-start (NOT stretch) — the sticky column keeps its own
   short, natural content height rather than being stretched to match the
   card grid; only the *container* needs to be tall for sticky's travel
   range, and leaving the sticky item itself unstretched is the more
   reliably-supported variant of this technique (a stretched sticky item
   can make some engines miscalculate the release point almost
   immediately). position: sticky on the intro column holds it at `top`
   until its containing block's bottom edge is reached — no JS, no
   ScrollTrigger, no separate scroll container. Desktop-only (min-width:
   1024px); below that both columns stack in normal document flow with no
   sticky behaviour. */

.team-intro {
  display: grid;
  gap: var(--space-8);
}

.team-intro__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
}

@media (min-width: 1024px) {
  .team-intro {
    display: flex;
    align-items: flex-start;
    gap: var(--space-16);
  }

  .team-intro__intro,
  .team-intro__list {
    flex: 1 1 50%;
    min-width: 0;
  }

  .team-intro__intro {
    position: sticky;
    top: calc(var(--header-height) + var(--space-10));
    flex-basis: 35%;
  }

  /* Real CSS Grid, 3 columns, on desktop only. align-items: start keeps
     grid from stretching shorter cards to match the tallest in their row
     (grid's default), which would otherwise pad — not crop — the space
     below a card's meta text but still read as inconsistent. */
  .team-intro__list {
    flex-basis: 65%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: var(--space-8);
    row-gap: var(--space-16);
    align-items: start;
  }
}

.team-card {
  display: flex;
  flex-direction: column;
}

/* All source photos are 720x1080 (2:3) — card ratio matches exactly so
   every image fits without cropping. The mask — fixed size, clips its
   content, never itself carries a transform; hover zoom lives one level
   deeper, on .team-card__media-zoom (same reasoning as
   .project-card__media / .project-card__media-zoom in card.css — scaling
   this outer wrapper would grow the box itself and bleed into
   neighbouring cards instead of staying masked within a fixed frame). */
.team-card__media {
  aspect-ratio: 2 / 3;
  overflow: hidden;
  background-color: var(--color-bg-alt);
}

.team-card__media-zoom {
  width: 100%;
  height: 100%;
  transition: transform var(--duration-slow) var(--ease-standard);
}

.team-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.team-card:hover .team-card__media-zoom,
.team-card:focus-visible .team-card__media-zoom {
  transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .team-card__media-zoom {
    transition: none;
  }
}

/* Spacing + type match .project-card__meta / .project-card__category
   (card.css) exactly — name uses .heading-h3, role uses .caption in the
   markup (same classes project-card__title/__category build on), this
   file only carries the size/spacing/colour overrides that differ from
   .caption's own defaults. Sized up a step from .caption's 11px default —
   at that size the sand accent colour reads too faint to be legible. */
.team-card__meta {
  margin-top: var(--space-8);
}

.team-card__role {
  margin-top: var(--space-3);
  font-size: var(--font-size-4);
  color: var(--color-accent);
}

/* Per-row fade-in stagger, desktop 3-col grid only. The site-wide
   nth-child(2)/(3) stagger (project-detail.css, tuned for 2-3-item
   editorial modules) only staggers the flat list's 2nd/3rd item overall —
   with 20 cards that meant only row 1 visibly staggered. Repeating the
   same two-step delay every 3 items (this rule's higher specificity wins
   over the global one) makes every row fade in left-to-right as it
   crosses into view, not just the first. */
@media (min-width: 1024px) {
  .team-intro__list [data-reveal]:nth-child(3n+1) {
    transition-delay: 0s;
  }

  .team-intro__list [data-reveal]:nth-child(3n+2) {
    transition-delay: var(--duration-fast);
  }

  .team-intro__list [data-reveal]:nth-child(3n) {
    transition-delay: calc(var(--duration-fast) * 2);
  }
}
