/*
 * Section: Team members — Figma 4006:5440 (small) / 2296:7179 (large),
 * with the large card's second face at 2296:7212.
 *
 * The frame draws the seam twice: a 5 inset on each card's photo, and a 6 gap
 * in the row itself, so 11 of ground shows between two photos.
 *
 * Sizes are shares of the 1676 frame so the row scales as one piece.
 */

.section-team__grid {
	display: grid;
	grid-template-columns: repeat(var(--columns, 3), minmax(0, 1fr));
	margin: 0;
	padding: 0;
	list-style: none;
}

.section-team--small .section-team__grid {
	gap: 0.358vw; /* 6 */
}

/* The large grid's three 559 cards sit 1.667 apart and its rows 10 apart
   (Figma 2246:2234 lays them at x 0/560.667/1121.333, y 0/773). With the 5
   photo inset that reads as 6.667 of ground down a column and 10 across a row.
   Three 559s plus the gaps overrun the 1676 frame by 4.33 — the columns are
   1fr here so they take that back rather than bleed. */
.section-team--large .section-team__grid {
	column-gap: 0.099vw; /* 1.667 */
	row-gap: 0.597vw; /* 10 */
}

.team-card {
	position: relative;
	display: flex;
	align-items: flex-end;
	overflow: hidden;
	isolation: isolate;
	padding-right: 0.298vw; /* 5 */
	color: #fff;
}

/* Two faces ---------------------------------------------------------------
 *
 * The card turns on its vertical axis between the photo (2296:7179) and the
 * Harbor panel (2296:7212). Both faces are absolute so the card keeps the
 * frame's height whichever one is showing, and both are inset by the same 5 as
 * the photo so the seam survives the turn.
 */

.team-card--turns {
	perspective: 71.6vw; /* 1200 — far enough that the turn reads as a turn
	                        rather than as a card thrown at the reader */
}

/* The seam is carried here rather than on the faces. This is the element that
   turns, and it turns about its own centre, so its box stays exactly where it
   was; a seam written on a face inside it is mirrored by the turn instead, and
   the back panel ends up painting over the 5 it was supposed to leave. */
.team-card__faces {
	position: absolute;
	inset: 0 0.298vw 0 0; /* 5 */
	z-index: 2;
	transform-style: preserve-3d;
	transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);

	/* Transparent to the pointer so a click lands on the button painted under
	   them. The LinkedIn link takes its own clicks back below. */
	pointer-events: none;
}

.team-card__face {
	position: absolute;
	inset: 0;
	display: flex;
	backface-visibility: hidden;
}

.team-card__face--front {
	align-items: flex-end;
}

/* Turned on hover where there is a pointer to hover with, and on tap where
   there is not — the button below handles that, and the keyboard. */
@media (hover: hover) and (pointer: fine) {
	.team-card--turns:hover .team-card__faces,
	.team-card--turns:focus-within .team-card__faces {
		transform: rotateY(180deg);
	}
}

.team-card--turns.is-turned .team-card__faces {
	transform: rotateY(180deg);
}

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

/* Covers the card so a tap anywhere turns it. Painted under the faces rather
   than over them: the faces ignore the pointer, so a click falls through to
   this, while the LinkedIn link on the back — which does take clicks — is
   painted above it and wins where the two overlap. Not the card itself: a link
   inside a button is not markup a browser can make sense of. */
.team-card__toggle {
	position: absolute;
	inset: 0;
	z-index: 1;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
	appearance: none;
}

/* Back face -------------------------------------------------------------- */

.team-card__face--back {
	z-index: 1;
	flex-direction: column;
	align-items: flex-start;

	overflow-y: auto;

	/* Deliberately not overscroll-behavior: contain. The panel is one item in a
	   grid the reader is scrolling past, not a modal — once the bio is at its
	   end the wheel has to carry on down the page, or a card the pointer
	   happens to be over stops the page dead. */
	overscroll-behavior: auto;
	/* The 51 below is carried by the copy, not by this box: a sticky element
	   cannot leave its own container, so with the padding here the fade stuck
	   51 up the panel and the last lines carried on underneath it. */
	padding: 2.625vw 2.387vw 0; /* 44 / 40 */
	background: var(--harbor);
	transform: rotateY(180deg);
}

/* The faces ignore the pointer so a click reaches the button under them, but a
   bio longer than the card has to be scrollable, and a panel that ignores the
   pointer never sees the wheel. So the back takes the pointer back — but only
   once the card has been opened on purpose, by click, tap or keyboard.
   Deliberately not on hover: the reader scrolling the page past a row of cards
   has a pointer resting on one of them the whole way down, and a panel that
   grabbed the wheel there would stop the page every time it passed a long bio.
   The click that used to fall through to the button is handled in
   team-flip.js instead. */
.team-card--turns:focus-within .team-card__face--back,
.team-card--turns.is-turned .team-card__face--back {
	pointer-events: auto;
}

/* Hovering shows the bio but does not hand over the wheel, so a bio too long
   for the card would just be cut off with nothing to say so. This is the say
   so: a wash over the last of the copy, on while there is more below it.
   It sticks to the foot of the panel from inside the copy rather than being
   painted over the card, so it turns with the panel and cannot show through
   the photo mid-turn. */
.team-card--turns.is-scrollable:not(.is-at-end) .team-card__back::after {
	content: "";
	position: sticky;
	bottom: 0;
	width: 100%;
	height: 4.773vw; /* 80 */
	margin-top: -4.773vw;
	background: linear-gradient(rgba(41 73 117 / 0) 0%, var(--harbor) 85%);
	pointer-events: none;
}

/* No scrollbar at all. The platform one is a 15 grey trough with arrows down
   the edge of a Harbor panel, which reads as part of the card rather than as
   chrome — and worse, it takes its 15 out of the copy, so a card with a long
   bio wrapped its lines narrower than the card beside it. The fade at the foot
   of the panel is what says there is more to read. */
.team-card__face--back {
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.team-card__face--back::-webkit-scrollbar {
	display: none;
}

/* 445 in the frame, with its own 20 of left padding inside the 40 — the same
   double indent the front's copy block carries. */
.team-card__back {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	width: 26.551vw; /* 445 */
	max-width: 100%;
	padding-bottom: 3.043vw; /* 51 — the panel's, moved in. See above. */
}

.team-card__heading {
	padding: 0 0 0.955vw 1.193vw; /* 16 below, 20 in */
}

.team-card__detail {
	padding-left: 1.193vw; /* 20 */
}

/* 437 against the 425 its own container leaves it: the frame lets the copy
   overhang, which is what decides where it wraps. */
.team-card__bio-full {
	width: 26.074vw; /* 437 */
	max-width: none;
	color: rgba(255 255 255 / 0.8);
	font-size: 0.835vw; /* 14 */
	font-weight: 400;
	line-height: 1.625; /* 22.75 */
}

.team-card__bio-full p {
	margin: 0 0 1.358vw; /* the frame's blank line, 22.75 */
}

.team-card__bio-full p:last-child {
	margin-bottom: 0;
}

/* 2296:7318 gives the link a 109 block: 37 above it and 51 below, around a 27
   icon — which comes to 115, so the frame clips 6 off the bottom. */
.team-card__social {
	margin: 0;
	padding: 2.208vw 0 3.043vw; /* 37 / 51 */
}

.team-card__social-link {
	position: relative;
	display: block;
	pointer-events: auto;
	width: 1.611vw; /* 27 */
	height: 1.611vw;
	color: #fff;
}

.team-card__social-link svg {
	display: block;
	width: 100%;
	height: 100%;
}

.team-card__social-link:hover,
.team-card__social-link:focus-visible {
	color: var(--ivory);
}

/* The 45x109 wedge at the top-right of the photo. The frame paints it as a
   white triangle (the "Mark" layer) over the picture rather than cutting the
   card, and it sits inside the 5 seam, not across it. Painting also keeps the
   clipped edge off a fractional device pixel, which is what put a seam down the
   process row at 125% display scaling. */
/* Drawn on each face rather than once over the card. The card sets a
   perspective, which puts its children in a 3D rendering context where they
   are sorted by depth and not by z-index — so through the turn, the half of the
   panel swinging towards the reader came out in front of a wedge painted over
   the card, and the corner filled in blue mid-flip. On the faces it is part of
   the plane it belongs to and cannot be passed. */
.team-card__face::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0; /* the seam is on the faces wrapper; the face is flush inside it */
	width: 2.685vw; /* 45 */
	height: 6.504vw; /* 109 */
	background: #fff;
	clip-path: polygon(0 0, 100% 0, 100% 100%);
}

/* Held as a shape rather than a height so the row can carry four, five or
   three-and-wrapping without the card's proportions changing with the count:
   at the frame's four-up the column is 416 and this is the frame's 335. */
.section-team--small .team-card {
	/* The frame's 335 against a 416 column made a short, letterboxed card and
	   the headshots read small in it. Run taller on the client's note of
	   2026-10-28 - same width, more height, so the faces have somewhere to
	   sit above the name. */
	aspect-ratio: 416 / 440;
}

.section-team--large .team-card {
	min-height: 45.525vw; /* 763 */
}

/* No seam of its own: the photo sits inside the faces wrapper, which is
   already the 5 short. Insetting here as well was taking it twice, so 16 of
   ground showed between two small cards where the frame shows 11. */
.team-card__image {
	position: absolute;
	inset: 0;
	z-index: -2;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The portraits are cut to one standard (1200 x 1400, face a quarter of the
   width, eyes at 34% of the height), so the crop is the same instruction for
   everybody rather than a focal point per person. The large card is taller
   than that cut and fills by height — every pixel of it, top to bottom, with
   the sides trimmed — so it needs nothing here. The small card is wider than
   it is tall and fills by width, leaving a third of the portrait to fall
   outside: 22% down the overflow puts the eye line a little above the card's
   middle, where the frame has it, rather than in the centre. */
.section-team--small .team-card__image {
	object-position: var(--img-focus, 50% 22%);
}

.team-card__scrim {
	position: absolute;
	inset: 0;
	z-index: -1;
}

/* Small: an even bottom-up wash. Large: the same stops pushed further down,
   so the top half of a portrait stays clear (2296:7181). */
.section-team--small .team-card__scrim {
	background: linear-gradient(
		0deg,
		rgba(11 22 40 / 0.95) 0%,
		rgba(11 22 40 / 0.6) 50%,
		rgba(11 22 40 / 0.1) 100%
	);
}

.section-team--large .team-card__scrim {
	background: linear-gradient(
		0deg,
		rgba(11 22 40 / 0.95) 2.205%,
		rgba(11 22 40 / 0.6) 27.648%,
		rgba(11 22 40 / 0.1) 57.502%
	);
}

/* 40 of side padding with another 20 on the text itself, as on the Return
   cards; 51 below on the large card.

   The small card's copy block is not measured from the card's own bottom: the
   frame centres a 313 container in the 335 card and hangs a 16 padded heading
   inside it, which puts the last line's baseline 59 up rather than 33. */
.team-card__body {
	width: 100%;
	padding: 0 2.387vw 33px 3.580vw; /* 40 / 60 */
}

/* The frame's 59 put the last baseline well up the card, which sat the name
   and the role across the lower half of the face. Dropped to the same 33 the
   base card uses, which carries the copy clear of the chin and still leaves a
   proper gutter under it. */
.section-team--small .team-card__body {
	padding-bottom: 1.969vw; /* 33 */
}

/* No right gutter of its own: the copy block below is a fixed 459 starting 60
   in, which leaves the frame's 40 to the card edge on its own. Declaring the
   40 as padding as well would fight the card's own 5 seam and shave the
   measure. */
.section-team--large .team-card__body {
	padding-right: 0;
	padding-bottom: 3.043vw; /* 51 */
}

/* Figma 2296:7184 fixes the copy block at 136 and bottom-aligns inside it, so
   a two-line bio hangs off the same baseline as a three-line one and every
   card in the row keeps its name at the same height. */
.team-card__text {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	width: 100%;
}

/* Measured against the frame, not against the card: three 559s overrun 1676 by
   4.33, so a 1fr column is 1.45 narrower than the frame's card and the bio
   loses "phases" off the end of its second line. 459 is the text node's own
   width in 2296:7189. */
.section-team--large .team-card__text {
	width: 27.387vw; /* 459 */
	max-width: 100%;
	min-height: 8.115vw; /* 136 */
}

.team-card__name {
	margin: 0;
	color: #fff;
	font-size: var(--wp--preset--font-size--heading-md); /* 24 */
	font-weight: 800;
	line-height: 1.333; /* 32 */
	letter-spacing: -0.025em; /* -0.6 */
}

/* Pure vw on both cards: the boxes scale with the frame, so the type has to as
   well or the two drift apart below the design width. */
.section-team--small .team-card__name,
.section-team--large .team-card__name {
	font-size: 1.432vw; /* 24 */
}

.section-team--small .team-card__role,
.section-team--large .team-card__role {
	font-size: 0.716vw; /* 12 */
}

.team-card__role {
	margin: 0;
	color: var(--ivory);
	font-size: var(--wp--preset--font-size--eyebrow); /* 12 */
	font-weight: 700;
	line-height: 1.333; /* 16 */
	letter-spacing: 0.1em; /* 1.2 */
	text-transform: uppercase;
}

/* The 16 before the bio is the heading block's own bottom padding (2296:7185). */
.team-card__bio {
	margin: 0.955vw 0 0; /* 16 */
	color: rgba(255 255 255 / 0.8);
	font-size: 0.835vw; /* 14 */
	font-weight: 400;
	line-height: 1.625; /* 22.75 */
}

@media (max-width: 1024px) {
	.section-team__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.section-team--small .section-team__grid {
		gap: 6px;
	}

	.section-team--large .section-team__grid {
		column-gap: 2px;
		row-gap: 10px;
	}

	/* Stacked, the frame's shares stop meaning anything. */
	.section-team--small .team-card__name,
	.section-team--large .team-card__name {
		font-size: var(--wp--preset--font-size--heading-md);
	}

	.section-team--small .team-card__role,
	.section-team--large .team-card__role {
		font-size: var(--wp--preset--font-size--eyebrow);
	}

	.team-card__bio {
		margin-top: 16px;
		font-size: var(--wp--preset--font-size--caption);
	}

	.section-team--large .team-card__text {
		width: 100%;
		min-height: 0;
	}

	.team-card {
		padding-right: 0;
	}

	.team-card__image,
	.team-card__scrim,
	.team-card__faces,
	.team-card__face {
		inset: 0;
		width: 100%;
	}

	.team-card__face::after {
		width: 45px;
		height: 109px;
	}

	/* Stacked, the frame's shares stop meaning anything. */
	.team-card__face--back {
		padding: 32px 24px 0 32px;
	}

	.team-card--turns.is-scrollable:not(.is-at-end) .team-card__back::after {
		height: 80px;
		margin-top: -80px;
	}

	.team-card__back {
		width: 100%;
		padding-bottom: 32px;
	}

	.team-card__heading {
		padding: 0 0 16px;
	}

	.team-card__detail {
		padding-left: 0;
	}

	.team-card__bio-full {
		width: 100%;
		font-size: var(--wp--preset--font-size--caption);
	}

	.team-card__bio-full p {
		margin-bottom: 16px;
	}

	.team-card__social {
		padding: 24px 0 0;
	}

	.team-card__social-link {
		width: 27px;
		height: 27px;
	}

	.section-team--large .team-card {
		min-height: 560px;
	}

	/* Two-up below the handover, at a height rather than the frame's shape. */
	.section-team--small .team-card {
		aspect-ratio: auto;
		min-height: 260px;
	}

	.team-card__body,
	.section-team--small .team-card__body {
		padding: 0 24px 32px 32px;
	}
}

@media (max-width: 782px) {
	.section-team__grid {
		grid-template-columns: 1fr;
	}

	.team-card__face::after {
		display: none;
	}

	.section-team--large .team-card {
		min-height: 420px;
	}

	/* Name and role only — at full width the frame's 335 is mostly empty. */
	.section-team--small .team-card {
		min-height: 220px;
	}

	.team-card__body,
	.section-team--small .team-card__body {
		padding: 0 20px 24px 24px;
	}
}
