/*
 * 2026 design system — the About Us page.
 *
 * Loads after pages.css and only on page-about-ds.php. Two compositions, and that is the
 * whole file: the travelling photo strip on ink, and the executive team's list-turned-
 * carousel. Everything else the page is made of already existed — the ruled column, the
 * split, .fc-display-slide, .fc-copy, .fc-stack, and the entire offices section, which is
 * the contact page's block called rather than copied.
 *
 * WHAT WENT TO layout.css: .fc-split-13, the 1fr 2fr split, and .fc-display-slide, the
 * 80px display role Build-16 moved the global section's h2 up to. The split was already in
 * the tree as .fc-kb-split in knowledge.css, and that file's own header says a fourth
 * non-Hub caller is the day it moves up; this page is that caller. Nothing else here is
 * shared yet — the strip is one page's header and the team carousel is one page's component
 * — and both are named as though they were, so the move is a cut and paste if a second page
 * asks.
 *
 * ── THE STRIP IS A SCROLL CONTAINER, NOT A TRANSFORM ────────────────────────
 *
 * The export travels the strip by translating a wrapper: a computed offset in a coordinate
 * space that grows forever, with nine cells drawn around the active index. That is a clean
 * way to write it in React and it is the wrong way to ship it, because it means nothing
 * moves at all until a script runs.
 *
 * So the strip here is `overflow-x: auto` over a flex row of forty-six fixed cells, and the
 * position the design calls a transform is a scrollLeft. Everything follows from that:
 *
 *   · With no script the header is a real gallery. Swipe, two-finger scroll, drag the
 *     scrollbar that is hidden but still there, or focus it and press an arrow key — all of
 *     it is the browser's, and none of it is our code.
 *   · assets/ds/strip.js animates the SAME scrollLeft, so its travel and the visitor's are
 *     one position rather than two that have to be reconciled. Mid-drag interruption is
 *     free; there is nothing to interrupt.
 *   · Infinite travel is rotation-with-compensation, in the script: append the first cell,
 *     subtract its width plus the gap from scrollLeft, and the picture is unchanged while
 *     the DOM stays at forty-six elements.
 *
 * The cost is that the cells cannot be sized in percentages — a scroll container has no
 * width to be a percentage of — so they are fixed pixels scaled by --strip-scale, and the
 * `sizes` attribute in inc/ds-about.php restates that same ladder for the srcset. Those two
 * have to move together; there is no way for one to read the other.
 *
 * The dimming and the arrow cursor are JS-only ON PURPOSE. A cell at 0.45 opacity is only
 * meaningful next to one at 1, and nothing sets that until the script picks an active cell,
 * so the resting state shows forty-six photographs at full strength instead of forty-five that
 * look broken.
 *
 * ── THE TEAM CAROUSEL IS A LIST FIRST ───────────────────────────────────────
 *
 * post_content holds all thirteen executives — photograph, name, role, bio — as an ordered
 * list, and this file styles that list as a readable column. assets/ds/team.js then sets
 * data-fc-team="on" and everything under THE CAROUSEL, below, takes over: twelve of the
 * thirteen are hidden, the face row and the controls the script built become visible, and
 * the list becomes the drag surface.
 *
 * That ordering is the point, and it is the same bargain partners.js and pulse.js make: the
 * resting state is the complete working state. A visitor whose script failed gets thirteen
 * executives in a column instead of one executive and no way to reach the other twelve.
 *
 * The face row's sizes and opacities are the design's, and they arrive as custom properties
 * rather than as inline width/height — --face-size and --face-dim, set by the script per
 * face from its distance to the current leader. That is what lets :hover put the opacity
 * back to 1 in CSS: an inline `opacity` would beat any rule in this file, and the design
 * asks for exactly that hover.
 *
 * @package Fluent_Commerce
 */

/* ─────────────────────────────────────────────────────────────────────────────
 * THE HEADER
 * A band of ink the height of the design's 640px, holding the strip and the
 * headline. `isolation: isolate` keeps the header's own stacking to itself, so the
 * headline's z-index is measured against the strip beneath it rather than against
 * anything else on the page.
 *
 * No .fc-section class and no --pad-section: the photographs run to all four
 * edges, which is the whole composition.
 * ────────────────────────────────────────────────────────────────────────── */
body.fc-ds .fc-about-hero {
	--strip-scale: 1;
	--strip-gap: 120px;
	--strip-height: 640px;
	--strip-title-top: var(--sp-54);
	--strip-title-x: 40px;

	position: relative;
	height: var(--strip-height);
	overflow: hidden;
	isolation: isolate;
	background: var(--fc-ink-10);
}

/*
 * The scroller. See THE STRIP IS A SCROLL CONTAINER in the header: this is the position the
 * design expresses as a transform, and everything the visitor can do to it for free.
 *
 * The scrollbar is hidden and the scrolling is not — hiding it is a composition decision (a
 * grey bar across the bottom of a full-bleed photograph) and it costs nothing, because every
 * other route to the same position is still open.
 *
 * scroll-behavior is pinned to auto because strip.js runs its own easing on scrollLeft; a
 * `smooth` inherited from an anchor-scrolling rule elsewhere would have the browser animating
 * every frame of an animation we are already drawing.
 */
body.fc-ds .fc-strip {
	position: absolute;
	inset: 0;
	overflow-x: auto;
	overflow-y: hidden;
	overscroll-behavior-x: contain;
	scroll-behavior: auto;
	scrollbar-width: none;
	-ms-overflow-style: none;
	user-select: none;
}

body.fc-ds .fc-strip::-webkit-scrollbar {
	display: none;
}

body.fc-ds .fc-strip__rail {
	margin: 0;
	padding: 0;
	list-style: none;
	height: 100%;
	/*
	 * max-content, not 100%: a flex row inside a scroll container has to be as wide as its
	 * cells or the cells shrink to fit the box and the strip has nothing to scroll.
	 */
	width: max-content;
	display: flex;
	align-items: center;
	gap: var(--strip-gap);
}

/*
 * Cells are FIXED PIXELS, scaled. A percentage would resolve against the scroll container's
 * width, which is the viewport, so every cell would be the same fraction of the screen and
 * the design's rhythm of tall and short cells would collapse into forty-six identical
 * rectangles.
 *
 * --cell-w and --cell-h ARRIVE INLINE, one pair per `<li>`, written by
 * fluent_commerce_ds_about_gallery_markup(). They used to come from seven shape classes right
 * here — the export's galleryDefs() — and that is where the cropping came from: a shape is a
 * fixed aspect ratio, and a photograph that does not share it loses a slice. Now the width is
 * derived from each photograph's own ratio at one of the design's seven heights, so it is a
 * per-cell number and a class per value would mean forty-six of them.
 *
 * The fallbacks are for a cell that somehow arrives without the pair: 520x420 is the design's
 * first shape, and a wrong-shaped cell is a great deal better than calc() failing and the cell
 * drawing at auto width inside a max-content row.
 */
body.fc-ds .fc-strip__cell {
	flex: none;
	width: calc(var(--cell-w, 520px) * var(--strip-scale));
	height: calc(var(--cell-h, 420px) * var(--strip-scale));
	overflow: hidden;
	background: var(--fc-bone-a08);
}

/*
 * contain, not cover. The cell is already this photograph's aspect ratio, so the two agree to
 * within a rounded pixel — but where they disagree, contain shows the whole frame and cover
 * cuts it, and not cutting it is the point. Any bar this leaves is a sub-pixel one.
 */
body.fc-ds .fc-strip__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/*
 * THE HEADLINE
 * The one heading on the site set in the grotesk at display size. Its four numbers are the
 * export's literals and none of them is a token on purpose — see DEVIATIONS in
 * inc/ds-about.php.
 *
 * SOLID WHITE, NOT BLENDED. The export sets mix-blend-mode: difference here, and difference
 * against a photograph is a per-pixel inversion: over ink the letters are white, over a bright
 * wall they go dark, and over a mid-grey they land close enough to the photograph to disappear.
 * The effect reads as a half-transparent headline rather than as a headline. So the letters sit
 * ON the photographs at full opacity instead, and the shadow — invisible over the ink, which is
 * most of the band — is what holds them against the brightest cells as those travel past.
 *
 * pointer-events: none matters here. The headline covers most of the strip, and every click
 * and every pointer move on it has to reach the scroller underneath.
 */
body.fc-ds .fc-about-hero__title {
	position: absolute;
	top: var(--strip-title-top);
	left: calc(var(--gutter-page) + var(--strip-title-x));
	z-index: 2;
	max-width: calc(100% - var(--gutter-page) * 2 - var(--strip-title-x));
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: clamp(53px, 7.15cqw, 132px);
	line-height: 0.86;
	letter-spacing: -0.03em;
	color: var(--fc-white);
	text-shadow: 0 2px 28px rgba(10, 10, 10, 0.45);
	pointer-events: none;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE STRIP, ONCE THE SCRIPT IS RUNNING
 * Two things the resting state cannot have: a dimmed cell, which is only legible
 * beside an undimmed one, and a cursor that has to be drawn at a position no
 * stylesheet knows. Both gated on the attribute strip.js sets.
 * ────────────────────────────────────────────────────────────────────────── */
body.fc-ds .fc-about-hero[data-fc-strip="on"] .fc-strip__cell {
	opacity: 0.45;
	/* The travel's own duration — GLIDE in strip.js. The two are one movement. */
	transition: opacity 520ms ease-out;
}

body.fc-ds .fc-about-hero[data-fc-strip="on"] .fc-strip__cell.is-active {
	opacity: 1;
}

/*
 * The arrow that replaces the pointer, and the `cursor: none` that makes room for it. Both
 * only on a device that has a pointer to hide — the attribute is set from a hover/fine media
 * query, not from the script running.
 */
body.fc-ds .fc-about-hero[data-fc-cursor="on"] .fc-strip {
	cursor: none;
}

body.fc-ds .fc-strip__cursor {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 4;
	width: 64px;
	height: 64px;
	margin: -32px 0 0 -32px;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--fc-white);
	opacity: 0;
	transition: opacity 200ms ease-out;
	pointer-events: none;
}

body.fc-ds .fc-strip__cursor.is-shown {
	opacity: 1;
}

/* The arrow points the way the click will travel, flipped by the script. */
body.fc-ds .fc-strip__cursor--left svg {
	transform: scaleX(-1);
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE HEADER, NARROWED
 * Six-hundred-pixel cells at full size on a phone are one photograph and no
 * strip, so the band steps down in three tiers: the cells shrink, the gap
 * shrinks with them so the rhythm holds, and the band's own height follows.
 *
 * These four scales are also written out as the `sizes` attribute in
 * fluent_commerce_ds_about_gallery_markup(), because a browser choosing between
 * the 1× and 2× encode cannot read a custom property. Change one, change both.
 * ────────────────────────────────────────────────────────────────────────── */
@container page (max-width: 1100px) {
	body.fc-ds .fc-about-hero {
		--strip-scale: 0.8;
		--strip-gap: 96px;
		--strip-height: 560px;
	}
}

@container page (max-width: 820px) {
	body.fc-ds .fc-about-hero {
		--strip-scale: 0.62;
		--strip-gap: 72px;
		--strip-height: 460px;
		/* The design's 40px indent is a luxury of a 120px gutter. */
		--strip-title-x: 0px;
	}
}

@container page (max-width: 440px) {
	body.fc-ds .fc-about-hero {
		--strip-scale: 0.46;
		--strip-gap: 48px;
		--strip-height: 380px;
		--strip-title-top: var(--sp-32);
	}
}

/*
 * ── ON A PHONE THE HEADLINE COMES OFF THE PHOTOGRAPHS ──────────────────────
 *
 * Same change, same reason and the same breakpoint as ON A PHONE THE TYPE COMES OFF THE
 * PHOTOGRAPHS in layout.css, which does this for the Partners and Customers galleries. Two
 * sheets because these are two components — that one slides a track, this one is a scroll
 * container — but the fault is one fault and a visitor moving between the three pages should
 * not find it fixed on two of them.
 *
 * It is worst here. "Hey. We're Fluent Commerce." is three lines at a phone width against a
 * strip that has room for one photograph, and the headline is WHITE: the design leans on the
 * ink band behind it, so wherever a bright cell passes under the type it is the text-shadow
 * holding the letters up on its own. Below 640 there is nothing under them but the band.
 *
 * The strip is the second child and the h1 the third, so order swaps them — see the note in
 * layout.css for why that rather than a margin. `max-width` goes because it was measured
 * against the absolute box's own left offset; in flow the padding sets the measure.
 * position: absolute on .fc-strip__cursor keeps it out of the flex flow, so the drawn arrow is
 * untouched — and it is only ever shown where there is a mouse anyway.
 */
@container page (max-width: 640px) {
	body.fc-ds .fc-about-hero {
		display: flex;
		flex-direction: column;
		height: auto;
	}

	body.fc-ds .fc-about-hero .fc-strip {
		order: 2;
		position: relative;
		inset: auto;
		height: var(--strip-height);
	}

	body.fc-ds .fc-about-hero__title {
		order: 1;
		position: static;
		max-width: none;
		/* Margin rather than padding, for the reason the layout.css block spells out. */
		margin: var(--sp-32) var(--gutter-page) var(--sp-24);
	}
}

/* ─────────────────────────────────────────────────────────────────────────────
 * WE'RE GLOBAL. WE'RE LOCAL.
 * Two page-scoped measures and one weight. The split itself is .fc-split-13 in
 * layout.css and the type is .fc-display-slide and .fc-copy, so this is all
 * that is left of the section.
 * ────────────────────────────────────────────────────────────────────────── */
body.fc-ds .fc-about-global__lede {
	max-width: 460px;
}

/*
 * The page's thesis, and the design sets it apart by weight and by going to full ink while
 * the five paragraphs above it sit at --text-on-light. Its own class rather than a <strong>
 * around a whole paragraph, which would be marking up emphasis that is really a role.
 */
body.fc-ds .fc-about-global__close {
	font-weight: var(--fw-semibold);
	color: var(--fc-ink-12);
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE EXECUTIVE TEAM, AS A LIST
 * The resting state, and the whole section for anyone whose script did not run.
 * Thirteen leaders in a column, each one a face, a name, a role and a bio.
 * ────────────────────────────────────────────────────────────────────────── */
body.fc-ds .fc-team__title {
	text-align: center;
}

body.fc-ds .fc-team__stage {
	max-width: 760px;
	margin: var(--sp-54) auto 0;
}

body.fc-ds .fc-team__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--sp-72);
}

body.fc-ds .fc-team__member {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-32);
	text-align: center;
}

/*
 * 124px is the design's centre face and the file is 248px, so the largest this is ever
 * drawn is still a downscale. object-fit because the sources are square but a replacement
 * portrait dropped in later may not be.
 */
body.fc-ds .fc-team__photo {
	display: block;
	width: 124px;
	height: 124px;
	flex: none;
	border-radius: 200px;
	object-fit: cover;
	background: var(--fc-bone);
}

body.fc-ds .fc-team__caption {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-8);
}

body.fc-ds .fc-team__name {
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: var(--type-h5-24);
	line-height: var(--lh-snug);
	color: var(--fc-ink-12);
}

/*
 * The design's role line is 500 weight and NOT letterspaced, so it is not .fc-eyebrow —
 * that role is 700 and tracked out. Same size token, different voice: this is a job title
 * under a name, not a label over a section.
 */
body.fc-ds .fc-team__role {
	font-family: var(--font-core);
	font-weight: var(--fw-medium);
	font-size: var(--type-eyebrow-16);
	line-height: var(--lh-snug);
	color: var(--fc-violet);
}

body.fc-ds .fc-team__bio {
	max-width: 640px;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE CAROUSEL
 * Everything below here is inert until assets/ds/team.js sets data-fc-team="on".
 * Nothing in this block styles a state the page can reach on its own, which is
 * why it is one attribute and not thirteen classes.
 * ────────────────────────────────────────────────────────────────────────── */

/*
 * The stage holds one leader at a time and the bios differ by three lines end to end, so
 * its height is reserved rather than measured — 320px is the design's own min-height, and
 * without it every advance would move the controls, the seam and the offices below.
 *
 * touch-action: pan-y is what keeps the page scrolling vertically under a swipe that
 * starts on a leader. Same contract as the story carousel's stage.
 */
body.fc-ds .fc-team[data-fc-team="on"] .fc-team__list {
	display: block;
	min-height: 320px;
	touch-action: pan-y;
}

body.fc-ds .fc-team[data-fc-team="on"] .fc-team__member {
	display: none;
}

body.fc-ds .fc-team[data-fc-team="on"] .fc-team__member.is-current {
	display: flex;
}

/*
 * The current leader's own photograph is hidden, because the face row above the stage is
 * already showing it at 124px in the middle of its six neighbours. It stays in the markup
 * — it is what the face row copies its src from, and it is the whole picture in the
 * resting state.
 */
body.fc-ds .fc-team[data-fc-team="on"] .fc-team__photo {
	display: none;
}

body.fc-ds .fc-team__faces {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: var(--sp-32);
}

/*
 * One flanking face. --face-size and --face-dim are set per face by the script from its
 * distance to the current leader: 96px at 0.55, 76 at 0.4, 58 at 0.28. They are custom
 * properties and not inline width/opacity so that the hover below can win — see the
 * header.
 */
body.fc-ds .fc-team__face {
	width: var(--face-size, 58px);
	height: var(--face-size, 58px);
	flex: none;
	padding: 0;
	border: 0;
	border-radius: 200px;
	overflow: hidden;
	background: transparent;
	cursor: pointer;
	opacity: var(--face-dim, 1);
	transition: opacity var(--dur-fast) var(--ease-out);
}

body.fc-ds .fc-team__face:hover,
body.fc-ds .fc-team__face:focus-visible {
	opacity: 1;
}

/* The middle of the row: the leader on the stage, at full size and not a control. */
body.fc-ds .fc-team__face--current {
	width: 124px;
	height: 124px;
	opacity: 1;
	cursor: default;
}

body.fc-ds .fc-team__face-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	background: var(--fc-bone);
}

body.fc-ds .fc-team__controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-32);
	margin-top: var(--sp-54);
}

/*
 * The two 44px arrows. 44 is also the pointer target the design happens to land on, so
 * nothing here has to make it bigger than it looks.
 */
body.fc-ds .fc-team__arrow {
	width: 44px;
	height: 44px;
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	background: transparent;
	border: var(--stroke-1) solid var(--border-on-light);
	border-radius: 200px;
	color: var(--fc-ink-12);
	cursor: pointer;
	transition:
		background var(--dur-fast) var(--ease-out),
		border-color var(--dur-fast) var(--ease-out),
		color var(--dur-fast) var(--ease-out);
}

body.fc-ds .fc-team__arrow:hover,
body.fc-ds .fc-team__arrow:focus-visible {
	background: var(--fc-violet);
	border-color: var(--fc-violet);
	color: var(--fc-white);
}

body.fc-ds .fc-team__arrow svg {
	display: block;
}

body.fc-ds .fc-team__dots {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 12px;
}

/*
 * Thirteen dots, and the current one grows sideways rather than filling in place — the
 * design's own transition, on the design's own curve, which --ease-out already is.
 */
body.fc-ds .fc-team__dot {
	width: 8px;
	height: 8px;
	flex: none;
	padding: 0;
	border: 0;
	border-radius: 200px;
	background: var(--fc-ink-a20);
	cursor: pointer;
	transition:
		width var(--dur-base) var(--ease-out),
		background var(--dur-base) var(--ease-out);
}

body.fc-ds .fc-team__dot[aria-current="true"] {
	width: 32px;
	background: var(--fc-violet);
}

/* The drag. Both cursors are added by the script, never by the markup. */
body.fc-ds .fc-team__list.is-grab {
	cursor: grab;
}

body.fc-ds .fc-team__list.is-dragging {
	cursor: grabbing;
	user-select: none;
}

/*
 * A leader on their way out follows the pointer at half speed and fades — the resistance
 * the story carousel has, for the same reason: there is no neighbour waiting off to the
 * side to be pulled in, so the movement is acknowledgement rather than travel. The
 * transition is what springs it back, and .is-dragging suspends it so the pull itself is
 * not damped.
 */
body.fc-ds .fc-team[data-fc-team="on"] .fc-team__member.is-current {
	transition:
		transform var(--dur-base) var(--ease-out),
		opacity var(--dur-base) var(--ease-out);
}

body.fc-ds .fc-team__list.is-dragging .fc-team__member.is-current {
	transition: none;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * THE FACE ROW, NARROWED
 * Seven faces at the design's sizes are 584px of photograph plus 60px of gap:
 * 644px, which fits the 760px stage and nothing much below it. Wrapping is the
 * wrong answer — the row means "the leaders either side of this one", and a
 * second line puts the 124px face off the centre of the first, which is exactly
 * what it read as on a phone. So the row is thinned from the outside in: the
 * faces are removed in pairs, the current one stays in the middle, and the dots
 * below still reach all thirteen.
 *
 * The distances come from data-fc-face, set by team.js. These set width and
 * height rather than --face-size because the script writes that property inline,
 * and inline wins; the attribute selector is a class more specific than the base
 * rule, which is what lets a plain width through.
 * ────────────────────────────────────────────────────────────────────────── */
@container page (max-width: 820px) {
	body.fc-ds .fc-team__face[data-fc-face="3"] {
		display: none;
	}
}

@container page (max-width: 560px) {
	body.fc-ds .fc-team__face[data-fc-face="2"] {
		display: none;
	}
}

/*
 * A phone. Three faces at the design's sizes are 336px against 310px of column, so the last
 * step is a proportional shrink rather than another pair removed — one face on its own has
 * no row left to be the middle of.
 *
 * The controls row is the other thing that needs saying here: three items with 32px between
 * them is wider than a 350px phone once the dots wrap, so both gaps come in.
 */
@container page (max-width: 440px) {
	body.fc-ds .fc-team__face[data-fc-face="1"] {
		width: 56px;
		height: 56px;
	}

	body.fc-ds .fc-team__face[data-fc-face="0"] {
		width: 88px;
		height: 88px;
	}

	body.fc-ds .fc-team__controls {
		gap: var(--sp-16);
	}

	body.fc-ds .fc-team__dots {
		gap: 8px;
	}
}
