/*
	Testimonials block. Splide (components: carousel.css) owns the mechanics
	and the per-view sizing for the Carousel Display option; this file only
	styles a testimonial's own content — the .testimonial component below is
	shared as-is by the Grid option too (a plain .grid-2 of these, no Splide
	involved), so nothing here should assume a .splide__slide parent.
*/

/* Equal-height slides: the Splide list is a flex row, so a full-height slide
   lets short and long quotes line up. */
.flex-section--testimonial-slider .splide__slide {
	height: auto;
}

/*
	The bordered "card" look lives on this wrap, one level inside .container
	— not on .container itself. .container is the same plain, standard
	wrapper every other block on the site uses (width, max-width: 1200px,
	gutter, centering via margin-inline: auto); giving IT a border/padding
	of its own meant fighting that box model just to get an outer gutter
	that still centred correctly at every width, and it lost a fixed
	48px (2 gutters) off .container's usual width in the process — this
	wrap needs none of that: it's a plain block filling .container's own
	already-correct content box, so it's never wider or narrower than any
	other block's content measure.

	.testimonial-slider__wrap only ever renders in Carousel mode (see
	testimonial-slider.php) — Grid mode's .section-header sits directly in
	.container instead, unwrapped, so no :has() is needed here to tell the
	two apart the way the old .container-based rule needed.
*/
.testimonial-slider__wrap {
	position: relative;
	display: grid;
	/* Mobile-first, matching .grid-2's own convention (layout.css): a single
	   stacked column below 61.75em, the real 1fr/2fr split only once there's
	   room for it side by side (see the media query below). */
	grid-template-columns: 1fr;
	gap: var(--space-8);
	align-items: start;
	border: 1px solid var(--color-accent-bg);
	padding: var(--space-6);
	padding-top: var(--space-8);
	background-color: var(--color-default-bg);
	/*
		Offset accent panel, peeking out from behind the wrap's own
		bottom-right edge. box-shadow rather than a ::before: a child
		pseudo-element can never paint behind its own parent's background —
		that's the bottom layer for anything inside the parent's box, no
		matter what z-index says — so the tint just sat on TOP of the
		background instead of hiding behind it. A shadow doesn't have that
		problem; it's defined to render behind the box's own background by
		default. 0 blur, 0 spread keeps it a crisp same-sized copy of the box
		rather than a soft/diffuse shadow.
	*/
	box-shadow: 10px 15px 0 0 color-mix(in srgb, var(--color-accent-bg) 30%, transparent);

	& .section-header {
		margin-block-end: 0;
	}

	.section-header__cta {
		margin-top: var(--space-6);
	}
}

@media (min-width: 61.75em) {
	.testimonial-slider__wrap:has(.section-header) {
		grid-template-columns: 1fr 2fr;
		column-gap: var(--space-10);
	}
}

/*
	No more reserved side columns for arrows — carousel.js moves them (and
	the dots) out into .testimonial-slider__controls once Splide mounts, so
	.splide itself only ever holds the track now.
*/
.flex-section--testimonial-slider .splide {
	grid-template-columns: minmax(0, 1fr);
}

.flex-section--testimonial-slider .splide__track {
	/* carousel.css's base rule puts the track in column 2, for the 3-column
	   arrows-beside-track layout. This block's .splide is down to a single
	   column above, so column 2 doesn't exist here — left at 2, the track
	   would land in an implicit column of its own, past the real (-1) edge
	   of the explicit grid, and leave column 1 sitting empty beside it for
	   .splide__toggle to wrongly auto-place into. */
	grid-column: 1;
	min-width: 0;
}

/*
	Previous arrow, dots, next arrow, together, centred under the WHOLE
	block — not just the carousel column .splide itself is confined to.
	carousel.js builds this element and moves the three real controls into
	it (in this exact order) right after Splide mounts; grid-column: 1 / -1
	only takes effect when the parent (.container) is a grid at all (the
	carousel + header case above) — it's a harmless no-op in normal block
	flow otherwise, so this one rule covers both shapes.
*/
.testimonial-slider__controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--carousel-arrow-gap);
	margin-block-start: var(--space-5);
	grid-column: 1 / -1;

	/* carousel.css's own default assumes .splide__pagination sits stacked
	   BELOW the arrows as its own row, hence its margin-block-start — here
	   it's an inline sibling of the arrows instead, so that would just push
	   it out of vertical alignment with them. */
	& .splide__pagination {
		margin-block-start: 0;
	}

	/*
		.splide__pagination__page is a <button> (inline-block) inside an <li>
		— align-items: center on the <ul> (carousel.css) correctly centres
		each <li>, but the button itself is an inline-level box that then
		sits at its line box's baseline within that <li>, not centred in it.
		Invisible at rest, since every dot is normally the same height — but
		the active one is 2x taller (transform: scaleY(2)), and a scaleY
		transform grows from whatever position the button already occupies,
		so the whole row read as sitting a few px low. display: flex on the
		<li> makes it centre its own single child directly, sidestepping the
		inline baseline math entirely.
	*/
	& .splide__pagination li {
		display: flex;
		align-items: center;
	}
}

.testimonial {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--space-5);
	height: 100%;
	padding: var(--space-6);
	padding-top: var(--space-8);
	border-top: 1px solid var(--color-accent-bg);
	border-left: 1px solid var(--color-accent-bg);

	/*
		No inset for the arrows any more. They used to be overlaid on the track and
		every text block had to reserve room at the sides; carousel.css now gives
		them their own grid columns beside the track, so the card can use the full
		width it is given.
	*/
	margin: 0;

	&.testimonial--carousel {
		/* Top-aligned: quote and attribution sit together as one block at the
		   top of the slide, rather than stretching them to the full slide
		   height — see .testimonial--carousel .testimonial__cite below,
		   which is what actually keeps them together (justify-content alone
		   isn't enough while .testimonial__cite's own auto margin, used to
		   pin it to the bottom in Grid, is still in play). */
		justify-content: flex-start;
		border: 0;
		padding: 0
	}
}

/*
	Decorative quote mark (assets/images/quote.svg) — a finished, pre-coloured
	brand asset, not a currentColor icon, so it's an <img> rather than inline
	markup. Hangs over the card's own top-left corner: -space-5 (-24px) pulls
	it up above the top border by exactly its own top offset, rather than
	sitting inset within the padding the way a purely-decorative mark usually
	would.
*/
.testimonial__mark {
	position: absolute;
	top: calc(-1 * var(--space-5));
	left: var(--space-5);
	width: var(--space-7);
	height: auto;
}

.testimonial__quote {
	margin: 0;
	font-size: var(--font-size-3);
	line-height: var(--line-height-body);
	text-wrap: pretty;
}

.testimonial__cite {
	display: flex;
	align-items: center;
	gap: var(--space-4);
	margin-block-start: auto; /* Grid: pin attribution to the bottom of the card */
	font-style: normal;
	font-size: var(--font-size-3);
}

/* Carousel: sit right after the quote, using .testimonial's own gap, instead
   of Grid's bottom-pin — a short slide would otherwise leave a gap floating
   above the attribution. */
.testimonial--carousel .testimonial__cite {
	margin-block-start: 0;
}

/*
	Hold the avatar's width against the attribution text beside it.

	.testimonial__cite is a flex row, so this span is a flex item and shrinks by
	default. `min-width: auto` would normally stop a flex item collapsing below
	its content, but the reset's `max-width: 100%` on images makes the <img>
	arbitrarily shrinkable, so the automatic minimum resolves to nothing and the
	span gives way to the text. The height is fixed, so the circle flattened into
	a vertical ellipse — measured at 41.2 x 56 on a 375px viewport.

	object-fit: cover means the photo itself was never distorted, only cropped;
	it's the box (and so the border-radius circle) that was squashed.
*/
.testimonial__photo {
	flex-shrink: 0;
}

.testimonial__photo img {
	display: block;
	width: 3.5rem;
	height: 3.5rem;
	border-radius: 50%;
	object-fit: cover;
}

.testimonial__attribution {
	display: flex;
	flex-direction: column;
}

.testimonial__name {
	font-weight: var(--font-weight-bold);
}

.testimonial__role {
	font-size: var(--font-size-2);
	color: var(--color-text-muted);
}

/*
	Grid only — a long quote assigned this class (see AS_TESTIMONIAL_WIDE_
	THRESHOLD in testimonial-slider.php) spans both columns instead of
	wrapping tall in one and throwing off the row next to its neighbour.
	No effect in Carousel: grid-column does nothing outside a grid container.
	Scoped to the 61.75em-up breakpoint because .grid-2 is a single column below
	it anyway, so there's nothing to span yet.
*/
@media (min-width: 61.75em) {
	.grid-2 > .testimonial--wide {
		grid-column: 1 / -1;
	}
}
