/*
 * Client Testimonials — video / quote slider.
 *
 * Figma: heading 1752:4061 (399x217 at x163 y5775) beside the slider
 * 1752:4070 (1084x456 at x618 y5678), on the wash 1752:3947
 * (1440x875, y5578..6453). Component set 1615:10967 supplies the two card
 * templates; see template-parts/home/testimonials.php for the variant map
 * and the reasoning behind the arrow and progress-bar behaviour.
 *
 * Frame geometry, all literal Figma values:
 *   1084x456 slider = 658x410 card + 24px gap + 402x332 translucent card
 *   (which starts at x=682 and so bleeds 262px past the 1440 viewport),
 *   with a 658x26 control bar at y=430.
 */

/* Soft blue wash behind the whole testimonial band.
   Figma 1752:3947 — a 1440x875 rect, linear-gradient(#f4f7ff 0%, #f4f7ff00 100%),
   spanning y=5578..6453. That covers the testimonial block *and* the client-logo
   strip below it, so the ramp is painted once at a fixed 875px height and the two
   sections each show their slice of it (see section-client-logos.css for the tail).
   Anchoring to a fixed height rather than 100% keeps the fade rate identical in
   both sections, so no seam appears at the boundary. */
:root {
	/* Single source of truth for the two slices of the wash. --tp-wash-height is
	   the Figma rect height; --tp-testimonials-height must equal the rendered
	   height of .tp2026-testimonials so the tail lines up. Here that is the
	   100px top inset (5578→5678) plus the 456px slider = 556. */
	--tp-wash-height: 875px;
	--tp-testimonials-height: 556px;
}

.tp2026-testimonials {
	/* Clips the 402px card that deliberately overhangs the viewport. */
	overflow: hidden;
	/* Figma: band top y=5578, slider top y=5678; the slider's own 456px box
	   carries the rest, and the client-logo strip supplies the 52px below. */
	padding: 100px 0 0;
	background-image: linear-gradient(180deg, var(--tp-soft-blue) 0%, rgba(244, 247, 255, 0) 100%);
	background-repeat: no-repeat;
	background-size: 100% var(--tp-wash-height);
	background-position: left top;
}

/* 1112 row: 399 heading + 55 gap + 658 slider (x163 / x618 on the page). */
.tp2026-testimonials__layout {
	display: grid;
	grid-template-columns: 399px 1fr;
	gap: 55px;
	align-items: start;
}

/* The heading sits 97px lower than the slider (y5775 vs y5678). */
.tp2026-testimonials__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 42px;
	margin-top: 97px;
}

/* Figma 1752:4062 — SemiBold 40/normal #021b42, 399px measure, textCase TITLE.
   The node uses normal leading, not --tp-h2's solid 40/1. */
.tp2026-testimonials__title {
	font: var(--tp-h2);
	line-height: normal;
	color: var(--tp-heading);
	text-transform: capitalize;
	max-width: 399px;
}

/* 1752:4063 — avatar cluster + proof copy, 12px apart. */
.tp2026-testimonials__proof {
	display: flex;
	align-items: center;
	gap: 12px;
}

/* 1752:4064 — four 75px portraits, each pulled 32px under the next.
   flex: 0 0 auto is load-bearing: the portraits inside are themselves
   unshrinkable, so if this box is allowed to shrink it just narrows around
   them and the last portrait spills out over the proof copy. */
.tp2026-testimonials__avatars {
	display: flex;
	align-items: center;
	flex: 0 0 auto;
}

.tp2026-testimonials__avatar {
	display: block;
	width: 75px;
	height: 75px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 auto;
}

.tp2026-testimonials__avatar:not(:last-child) {
	margin-right: -32px;
}

/* 1752:4069 — "1000+," Bold 16/24 #1977f3 over "satisfied customers"
   Regular 16/24 #3b3b3b, both textCase TITLE. */
.tp2026-testimonials__proof-text {
	display: flex;
	flex-direction: column;
	font: var(--tp-body);
	text-transform: capitalize;
	white-space: nowrap;
	min-width: 0;
}

.tp2026-testimonials__proof-text strong {
	font-weight: 700;
	color: var(--tp-blue);
}

.tp2026-testimonials__proof-text span {
	color: #3b3b3b;
}

/* ---------------------------------------------------------------------------
   Slider frame — 658 wide visible column, 456 tall
   --------------------------------------------------------------------------- */
.tp2026-testimonials__showcase {
	position: relative;
	width: 658px;
	height: 456px;
}

/* 1615:10924 — 402x332 at x=682 of the 1084 frame, i.e. 24px clear of the
   card's right edge. Runs off the viewport; the section clips it. */
.tp2026-testimonials__deco {
	position: absolute;
	left: 682px;
	top: 40px;
	width: 402px;
	height: 332px;
	background: rgba(255, 255, 255, 0.37);
	border: 1px solid rgba(210, 229, 255, 0.64);
	border-radius: 24px;
	pointer-events: none;
}

/* Both card templates share this 658x410 box and cross-fade inside it. */
.tp2026-testimonials__stage {
	position: relative;
	display: grid;
	width: 658px;
	height: 410px;
}

.tp2026-testimonials__slide {
	grid-area: 1 / 1;
	position: relative;
	margin: 0;
	border: 1px solid #d2e5ff;
	border-radius: 24px;
	overflow: hidden;
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--tp-speed) var(--tp-ease);
}

.tp2026-testimonials__slide.is-active {
	opacity: 1;
	pointer-events: auto;
}

/* --- Video template (1615:10966) ------------------------------------------ */
.tp2026-testimonials__slide--video {
	background: var(--tp-white);
}

.tp2026-testimonials__poster {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 1820:4623 — 112px mark, dead centre. */
.tp2026-testimonials__play {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	display: block;
	width: 112px;
	height: 112px;
	transition: transform var(--tp-speed-fast) var(--tp-ease);
}

.tp2026-testimonials__play img {
	display: block;
	width: 112px;
	height: 112px;
}

a.tp2026-testimonials__play:hover,
a.tp2026-testimonials__play:focus-visible {
	transform: translate(-50%, -50%) scale(1.06);
}

/* 1634:11406 — 249x69 band at y=318 of the 410 card, i.e. floating 23px clear
   of its bottom edge rather than flush to it. Anchored from the bottom so it
   keeps that relationship when the card stops being exactly 410 tall. */
.tp2026-testimonials__scrim {
	position: absolute;
	left: 0;
	bottom: 23px;
	width: 249px;
	height: 69px;
	background: linear-gradient(90deg, #084a9f 0%, rgba(8, 74, 159, 0) 100%);
	pointer-events: none;
}

/* --- In-widget playback (FR-046) ------------------------------------------
   The player is mounted into the card, so it fills the same 658x410 box the
   poster occupied and inherits the slide's 24px rounded clip. */
.tp2026-testimonials__video-mount {
	position: absolute;
	inset: 0;
	display: block;
	background: #000;
	/* Empty until the play control is used — the poster must stay visible and
	   clickable up to that point. */
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--tp-speed) var(--tp-ease);
}

.tp2026-testimonials__slide.is-playing .tp2026-testimonials__video-mount {
	opacity: 1;
	pointer-events: auto;
}

.tp2026-testimonials__video {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

/* Once the video is running the poster furniture would only sit on top of it. */
.tp2026-testimonials__slide.is-playing .tp2026-testimonials__play,
.tp2026-testimonials__slide.is-playing .tp2026-testimonials__scrim,
.tp2026-testimonials__slide.is-playing .tp2026-testimonials__namecard--on-video {
	opacity: 0;
	pointer-events: none;
}

/* The play control is a <button>; strip the UA chrome so it stays the 112px
   Figma mark. */
button.tp2026-testimonials__play {
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
	appearance: none;
}

button.tp2026-testimonials__play:hover,
button.tp2026-testimonials__play:focus-visible {
	transform: translate(-50%, -50%) scale(1.06);
}

/* 1615:11402 — 116x49 name block at x=59 y=330, i.e. 31px off the bottom,
   reversed out of the band. */
.tp2026-testimonials__namecard--on-video {
	position: absolute;
	left: 59px;
	bottom: 31px;
	width: 116px;
	height: 49px;
}

.tp2026-testimonials__namecard {
	display: flex;
	flex-direction: column;
	text-transform: capitalize;
}

/* 1615:11403 — Bold 20/normal; 1615:11404 — Medium 16/24 at 39% opacity. */
.tp2026-testimonials__name {
	font: 700 20px/normal var(--tp-font-heading);
}

.tp2026-testimonials__role {
	font: 500 16px/24px var(--tp-font-body);
}

.tp2026-testimonials__namecard--on-video .tp2026-testimonials__name {
	color: var(--tp-white);
}

.tp2026-testimonials__namecard--on-video .tp2026-testimonials__role {
	color: rgba(255, 255, 255, 0.39);
}

/* --- Quote template (1615:10968) ------------------------------------------ */
.tp2026-testimonials__slide--quote {
	display: flex;
	flex-direction: column;
	gap: 24px;
	background: var(--tp-white);
	/* 1615:10981 — content inset 40 left / 50 top, 578 wide, 314 tall. */
	padding: 50px 40px;
}

.tp2026-testimonials__quote-body {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.tp2026-testimonials__stars {
	display: block;
	width: 132px;
	height: 22.429px;
}

/* 1615:10992 — Regular 16/24 #595959, textCase TITLE, 578px measure. */
.tp2026-testimonials__quote {
	margin: 0;
}

/* Figma 1615:10992 sets textCase TITLE, which this rule used to mirror with
   text-transform: capitalize. Requirement 008 replaced the one line of filler
   with seven verbatim, attributed quotes from named executives — Title Casing
   Every Word Of Those misquotes them, so the copy now renders as written. */
.tp2026-testimonials__quote p {
	font: var(--tp-body);
	color: var(--tp-gray-700);
	margin: 0;
}

/* 1615:10993 — 578x1 hairline. */
.tp2026-testimonials__rule {
	display: block;
	height: 1px;
	background: #c5d3f9;
	margin-top: auto;
}

.tp2026-testimonials__byline {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
}

/* 1615:10995 — 76px avatar, 12px from the name block. */
.tp2026-testimonials__author {
	display: flex;
	align-items: center;
	gap: 12px;
}

.tp2026-testimonials__author-avatar {
	display: block;
	width: 76px;
	height: 76px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 auto;
}

/* Fallback for the slides with no exported portrait — same initials-badge
   convention as life-at-thinkpalm.php. */
.tp2026-testimonials__author-avatar--initials {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--tp-blue-gradient);
	color: var(--tp-white);
	font: 700 22px/1 var(--tp-font-heading);
	letter-spacing: 0.02em;
}

/* 1615:10998/10999 — same sizes as the video card, in black. */
.tp2026-testimonials__slide--quote .tp2026-testimonials__name {
	color: var(--tp-black);
}

.tp2026-testimonials__slide--quote .tp2026-testimonials__role {
	color: rgba(0, 0, 0, 0.39);
}

/* Was Figma's 1615:11000 lockup — a fixed 149x26 built from a 34.5px mark plus
   a wordmark at a hardcoded offset, which only held because the artwork was one
   placeholder. Requirement 008's seven real logos run from wide (PERDIX, 6.3:1)
   to near-square (RAD, 1.6:1), so the slot is a fixed-height box and each logo
   is contained inside it: heights line up across slides, widths vary as the
   artwork does. Taller than Figma's 26px so the squarer marks are still
   legible; the byline row is 76px tall, so nothing grows.

   At the original flat 40px / 160px cap the two widest (Cevitr 5.7:1, Rambus
   4.8:1) hit the WIDTH cap before the height one and rendered 28px and 33px
   tall against everyone else's 40px — that mismatch is what read as "the logos
   are different sizes".

   Two ways to fix it, and the obvious one is wrong. Giving every logo an
   identical height is mechanically equal but not optically equal: at a shared
   33px, Cevitr is 189px wide and RAD's compact badge is 53px, so RAD still
   reads as the small one — and it comes out SMALLER than it was before the
   "fix". So the height is matched per logo instead, on aspect ratio:

       height = 51.4 / ratio^0.25

   which is the midpoint between equal-height and equal-area. Square-ish marks
   get taller, wide wordmarks get shorter, and every logo ends up covering
   roughly the same amount of the row. 51.4 is not arbitrary: it is the largest
   constant that keeps the widest logo (Cevitr) inside 190px, which is in turn
   the most width the byline can give up before the longest role line is
   squeezed. Per-slide values are precomputed in testimonials.php — they change
   only when the artwork does, so there is nothing to recalculate at render.

   Resulting box, widest to narrowest: Cevitr 189x33, Rambus 167x35, Ribbon
   137x37, PERDIX 131x37, Momentum 124x38, InterPlay 108x40, RAD 74x46. The
   46px tallest still clears the 76px byline row, so nothing grows. */
.tp2026-testimonials__client-logo {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	/* Deliberately NOT --tp-logo-h: client-logos.php already sets that on every
	   tile of the partners strip below this section. */
	height: var(--tp-testimonial-logo-h, 36px);
	max-width: 190px;
	flex: 0 0 auto;
}

.tp2026-testimonials__client-logo img {
	display: block;
	max-height: 100%;
	max-width: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
}

/* ---------------------------------------------------------------------------
   Control bar 1615:10926 — 658x26 at y=430, i.e. 20px under the card.
   --------------------------------------------------------------------------- */
.tp2026-testimonials__bar {
	position: absolute;
	left: 0;
	top: 430px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 658px;
	height: 26px;
}

/* 1615:10927 — Figma sets this in Inter, which the theme does not self-host;
   Plus Jakarta Sans stands in at the same sizes. */
.tp2026-testimonials__counter {
	margin: 0;
	color: #454545;
	white-space: nowrap;
}

.tp2026-testimonials__counter-current {
	font: 700 16px/26px var(--tp-font-body);
}

.tp2026-testimonials__counter-total {
	font: 400 14px/26px var(--tp-font-body);
	color: rgba(69, 69, 69, 0.5);
}

/* 1615:10929/10930 — 530x3 track, radius 14, with a #454545 fill over it. */
.tp2026-testimonials__progress {
	position: relative;
	display: block;
	width: 530px;
	height: 3px;
	border-radius: 14px;
	background: rgba(69, 69, 69, 0.3);
	overflow: hidden;
	flex: 0 0 auto;
}

/* The slider is manual, so the fill marks position, not time: JS sets the
   width to (index + 1) / total. The two Figma variants' 113px and 209px fills
   are read as samples of that same track. */
.tp2026-testimonials__progress-fill {
	position: absolute;
	left: 0;
	top: 0;
	width: 25%;
	height: 3px;
	border-radius: 14px;
	background: #454545;
	transition: width 400ms ease;
}

/* 1615:10931 — two 24px glyphs, 12px apart, hard right. */
.tp2026-testimonials__nav {
	display: flex;
	align-items: center;
	gap: 12px;
}

.tp2026-testimonials__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	padding: 0;
	border: 0;
	background: none;
	color: #454545;
	cursor: pointer;
	transition: opacity var(--tp-speed-fast) var(--tp-ease);
}

/* The next glyph is the prev glyph rotated, exactly as Figma builds it. */
.tp2026-testimonials__arrow--next svg {
	transform: rotate(180deg);
}

/* 1615:10932 vs 1615:10977 — the inactive end is the same mark at 50%. */
.tp2026-testimonials__arrow:disabled {
	opacity: 0.5;
	cursor: default;
}

/* Responsive breakpoints reference (Figma frame = 1440):
   1440 desktop / 1024 small-desktop / 768 tablet / 425,375,320 mobile */
@media (max-width: 1160px) {
	/* Below the 1112 column the fixed 399+55+658 row no longer fits, so the
	   slider takes the full width and the deco card is dropped rather than
	   left hanging over the content beside it. */
	.tp2026-testimonials__layout {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	.tp2026-testimonials__head {
		margin-top: 0;
	}

	.tp2026-testimonials__showcase,
	.tp2026-testimonials__stage,
	.tp2026-testimonials__bar {
		width: 100%;
	}

	.tp2026-testimonials__showcase,
	.tp2026-testimonials__stage {
		height: auto;
	}

	/* Keep the card on the Figma 658:410 proportion at whatever width it lands
	   on; the quote slide can still push the shared grid row taller. */
	.tp2026-testimonials__slide--video {
		aspect-ratio: 658 / 410;
	}

	.tp2026-testimonials__deco {
		display: none;
	}

	.tp2026-testimonials__bar {
		position: static;
		margin-top: 20px;
	}

	.tp2026-testimonials__progress {
		flex: 1 1 auto;
		width: auto;
		margin: 0 24px;
	}
}

@media (max-width: 1024px) {
	.tp2026-testimonials {
		padding-top: 64px;
	}
}

/* ---------------------------------------------------------------------------
   Mobile — Figma 2283:4658 + 2300:2446 on the 360 frame:

     wash       0,5144  360x814  #f4f7ff ramp, 40px into the section
     title     20,5194  267x68   28/34 SemiBold #021b42
     proof     20,5278  304x50.7 four 50.735 portraits, -21.647 overlap
     card      20,5352  320x347  radius 20, 0.486px #d2e5ff
       play          centred     54.47 mark
       plate   20,5631 163x48    90deg #084a9f -> transparent, 20 off the base
     bar       20,5711  320x26   "01/04" + 185x3 track + two 24px arrows

   The card turns portrait here (320:347 against the desktop 658:410) and the
   name plate goes flush to the card's left edge instead of sitting 59px in.
   --------------------------------------------------------------------------- */

@media (max-width: 768px) {
	/* The band is 814 tall and starts 40px below the section's own top edge
	   (products ends y5080, the section at y5104, the wash at y5144). The
	   client-logo strip continues the same ramp from
	   -(section height - 40) — see section-client-logos.css. */
	.tp2026-testimonials {
		--tp-wash-height: 814px;
		--tp-testimonials-height: 593.73px;
		/* 2283:4688's own three stops — it holds the tint most of the way down
		   rather than ramping straight off, which a plain 0->100% fade does
		   not reproduce (it is ~0.19 too transparent by the halfway mark). */
		padding: 90px 0 0;
		background-image: linear-gradient(180deg, rgba(244, 247, 255, 1) 1.483%, rgba(244, 247, 255, 0.717) 46.472%, rgba(244, 247, 255, 0) 102.832%);
		background-position: left 40px;
	}

	.tp2026-testimonials__layout {
		gap: 24px;
	}

	.tp2026-testimonials__head {
		gap: 16px;
	}

	.tp2026-testimonials__title {
		max-width: none;
		font-size: 28px;
		line-height: 34px;
	}

	/* Figma 2283:4661 — 50.735px portraits at a 21.647px overlap, each ringed
	   in 1.353px of white. */
	.tp2026-testimonials__avatar {
		width: 50.735px;
		height: 50.735px;
		border: 1.353px solid var(--tp-white);
	}

	.tp2026-testimonials__avatar:not(:last-child) {
		margin-right: -21.647px;
	}

	.tp2026-testimonials__slide {
		border-width: 0.486px;
		border-radius: 20px;
	}

	/* Figma 2300:2339 — the card is taller than it is wide here (320:347
	   against the desktop 658:410).

	   The ratio used to sit on the stage as well, which capped the shared grid
	   row and meant the quote copy had to be clamped to fit inside the video
	   card's box. Requirement 008 removed the video slide and replaced the
	   filler quotes with seven real testimonials, and four lines of a 14/22
	   card cuts every one of them mid-sentence — these are attributed
	   statements, so showing 40% of one is worse than a taller card.

	   The ratio therefore sits on the video slide alone, exactly as the
	   ≥769 block above already has it: the video card keeps its Figma box if
	   it is ever restored, and the quote slides push the shared row to
	   whichever of them is tallest. All slides are grid-area 1/1, so the row
	   is sized by the longest quote and the card height does not jump as the
	   carousel advances. */
	.tp2026-testimonials__stage {
		height: auto;
	}

	.tp2026-testimonials__slide--video {
		height: auto;
		aspect-ratio: 320 / 347;
	}

	.tp2026-testimonials__slide--quote {
		gap: 16px;
		padding: 24px;
	}

	.tp2026-testimonials__quote-body {
		gap: 16px;
	}

	/* The 4-line clamp that used to be here went with the fixed stage height
	   above — see that comment. Real testimonials run to seven lines at 320px
	   and are shown in full. */
	.tp2026-testimonials__quote p {
		font-size: 14px;
		line-height: 22px;
	}

	.tp2026-testimonials__byline {
		flex-wrap: wrap;
		gap: 16px;
	}

	.tp2026-testimonials__author-avatar {
		width: 48px;
		height: 48px;
	}

	.tp2026-testimonials__author-avatar--initials {
		font-size: 16px;
	}

	.tp2026-testimonials__slide--quote .tp2026-testimonials__name {
		font-size: 16px;
	}

	.tp2026-testimonials__slide--quote .tp2026-testimonials__role {
		font-size: 13px;
		line-height: 20px;
	}

	/* 2300:2339;1820:4623 — the same 112px mark at 54.47. */
	.tp2026-testimonials__play,
	.tp2026-testimonials__play img {
		width: 54.47px;
		height: 54.47px;
	}

	/* 2300:2341 — 163x48 and flush to the card's left edge, 20px up from its
	   base; the copy sits 20px in and 25.55px off the bottom. */
	.tp2026-testimonials__scrim {
		width: 163px;
		height: 48px;
		bottom: 20px;
	}

	.tp2026-testimonials__namecard--on-video {
		left: 20px;
		bottom: 25.55px;
		width: auto;
		height: auto;
		gap: 3px;
	}

	.tp2026-testimonials__namecard--on-video .tp2026-testimonials__name {
		font: 700 12px/15.12px var(--tp-font-heading);
	}

	/* Figma reports a 16.386 line height on the role but draws the box at
	   15.23, the same as the name above it — the pair has to measure 33.45
	   for the block to sit where 2300:2342 puts it. */
	.tp2026-testimonials__namecard--on-video .tp2026-testimonials__role {
		font: 500 10px/15.23px var(--tp-font-body);
	}

	/* 2300:2345 — 12px under the card, and the 12px gaps make the track land
	   on its Figma 185 (43 counter + 12 + 185 + 12 + 68 arrows = 320). */
	.tp2026-testimonials__bar {
		margin-top: 12px;
	}

	.tp2026-testimonials__progress {
		margin: 0 12px;
	}

	.tp2026-testimonials__nav {
		gap: 20px;
	}
}

/* At 320 the container gives 280px of content. The cluster wants
   138 (avatars) + 12 (gap) + 154 (proof copy) = 304, so it has to come down
   24px: smaller portraits at the same ~43% overlap, and 14/20 proof copy.
   `white-space: normal` is the safety valve — below this the copy wraps to a
   third line instead of running off the edge. */
@media (max-width: 340px) {
	.tp2026-testimonials__avatar {
		width: 44px;
		height: 44px;
	}

	.tp2026-testimonials__avatar:not(:last-child) {
		margin-right: -18px;
	}

	.tp2026-testimonials__proof-text {
		font-size: 14px;
		line-height: 20px;
		white-space: normal;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tp2026-testimonials__slide,
	.tp2026-testimonials__play,
	.tp2026-testimonials__arrow,
	.tp2026-testimonials__progress-fill {
		transition: none;
	}
}
