/* ==========================================================================
   Testimonials screen
   Contents: hero quote · video stories · reviews · patient gallery
   ========================================================================== */

/*
 * The photograph is not mirrored. The stock one this screen started with was,
 * so that its patient faced the headline and the quote sat over the blurred
 * gym. The one chosen on 6 October 2026 was composed the right way round, with
 * the quote's blank wall on the right; mirrored, the quote lands on her face.
 * The mirror had been reaching only visitors who ask for reduced motion: for
 * everyone else the hero's settle animation replaced it (quantum-hero-settle
 * in main.css, which now animates `scale` so it cannot do that again). Blog
 * still mirrors its photograph, on purpose: that one is composed reversed.
 */

/*
 * The note's own size, the same as every other screen's (main.css): it was
 * about a fifth larger here — 39px against 32 on a wide screen — although the
 * design draws it no larger than About's, and it is the longest note on the
 * site, so the Spanish one reached the patient's hair. Only its swoosh and its
 * attribution line are its own.
 */
.route-testimonials .page-hero__script {
	--swoosh-width: 2.9em;
	--swoosh-offset: 1.55em;
	--swoosh-gap: 0.1em;
	--cite-offset: 34%;
	top: 5rem;
}

/* Video stories
   ========================================================================== */

.video-grid {
	display: grid;
	gap: var(--space-5);
}

.video-card {
	/*
	 * Laid out the way a video site lists its videos (Robert, 20 October
	 * 2026): the photograph with the play button in its centre, and the quote
	 * and its topic underneath on the page, in the reviews' name-and-place
	 * style. Over the photograph, white on a gradient, the quote ran into the
	 * button from its second line, went out of the top of the tile when it
	 * was long, and its first line read at 1.6:1 over the placeholder image.
	 *
	 * The whole card is the target, photograph and text, the way a video
	 * site's is: the play button's link is stretched over it (further down),
	 * so it is still one link and one tab stop, named for whose story it is.
	 * The card is that stretch's containing block, which is why nothing
	 * between it and the link may be positioned or transformed.
	 */
	position: relative;
	min-width: 0;
}

/*
 * The photograph's box. It keeps the 16:9 shape even before a photograph is
 * chosen (the ink shows), so the button and the duration always have their
 * place. The hover zoom is the shared .hover-zoom utility in main.css, on
 * this box in page-testimonials.php: it clips the zoomed image here, and on
 * the whole card it would also have clipped this box's shadow.
 *
 * The photograph, the button and the duration share one grid cell instead
 * of being positioned over the photograph: a positioned box here would
 * become the containing block of the stretched link and keep it to the
 * photograph.
 */
.video-card__media {
	display: grid;
	/*
	 * One track the size of the box. Left to auto, the row took the
	 * photograph's own height (400x300 for the placeholder), taller than the
	 * 16:9 box: the button sat at 67% and the duration fell out of the bottom.
	 */
	grid-template: minmax(0, 1fr) / minmax(0, 1fr);
	aspect-ratio: 16 / 9;
	color: var(--color-white);
	background: var(--color-ink);
	border-radius: var(--radius);
	box-shadow: var(--shadow-sm);
}

.video-card__media > * {
	grid-area: 1 / 1;
}

/*
 * Over the photograph. The shared .hover-zoom gives the image will-change:
 * transform, which paints it like a positioned box, above the siblings that
 * are not. The button cannot be positioned — it would become the containing
 * block of its own stretch — but a grid item takes a z-index without being
 * positioned, so that lifts it, and the duration with it. Without this the
 * photograph hid both while the link still answered clicks (20 October 2026).
 */
.video-card__play,
.video-card__duration {
	z-index: 1;
}

/*
 * The ink is painted under the photograph by the photograph itself, not by
 * the box, whenever there is one. Painted by the box, it showed round the
 * picture: a dark fringe on the rounded corners, where both edges are
 * anti-aliased, and a 1px dark line down the right edge of a card whose width
 * ends in a fraction (the middle one at 1200, 782.66px), because the image
 * sits on its own layer (.hover-zoom's will-change) and is snapped to whole
 * pixels apart from the box (20 October 2026). The box keeps the ink only for
 * a testimonial with no photograph.
 */
.video-card__media:has(.video-card__image) {
	background: none;
}

.video-card__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 22%;
	background: var(--color-ink);
}

/*
 * One line, ending in an ellipsis when the quote is longer (Robert, 20
 * October 2026). Two lines left the cards of a row with their topics at
 * different heights whenever one quote wrapped and the next did not. How many
 * characters a line holds depends on the words and on the width of the card:
 * see the plugin's help for the quote field.
 */
.video-card__quote {
	overflow: hidden;
	margin-top: var(--space-3);
	font-family: var(--font-heading);
	font-weight: 600;
	line-height: 1.4;
	color: var(--color-ink);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.video-card__topic {
	margin-top: var(--space-1);
	font-size: var(--fs-sm);
}

.video-card__play {
	display: grid;
	place-items: center;
	place-self: center;
	width: 64px;
	height: 64px;
	padding: 0 0 0 4px;
	color: var(--color-ink);
	background: var(--color-white);
	border: 0;
	border-radius: 50%;
	box-shadow: var(--shadow);
	transition: width var(--transition), height var(--transition);
}

/* The stretch: the link's own box is the circle, this covers the card. */
.video-card__play::after {
	position: absolute;
	inset: 0;
	content: "";
}

/*
 * The colour is repeated here on purpose. This button is an anchor, so the
 * global `a:hover` rule repaints the triangle with the link colour — a
 * decision nobody made for this control. Its hover is the lift, nothing else.
 */
.video-card__play:hover,
.video-card__play:focus-visible {
	color: var(--color-ink);
}

/*
 * The lift, 64 to 69px, the 8% the scale() used to give. Grown by its size
 * rather than scaled, because a transform on the link would make it the
 * containing block of its own stretch: the hover would shrink the target to
 * the circle, lose the hover, and flicker.
 */
.video-card:hover .video-card__play,
.video-card__play:focus-visible {
	width: 69px;
	height: 69px;
}

.video-card__duration {
	place-self: end;
	margin: var(--space-4);
	padding: 0.15rem 0.65rem;
	font-family: var(--font-heading);
	font-size: var(--fs-xs);
	font-weight: 600;
	/*
	 * 0.8, not 0.55: the gradient that used to darken the bottom of the
	 * photograph went with the quote, and the pill now sits on the photograph
	 * as it is. Its label is 13px, so the bar is 4.5:1, and 0.55 gave 4.1 over
	 * the placeholder image and 3.8 over white (20 October 2026); 0.8 gives
	 * 9.1 and 8.8, as dark as a video site's duration badge.
	 */
	background: rgb(15 31 51 / 0.8);
	border: 1.5px solid rgb(255 255 255 / 0.9);
	border-radius: var(--radius-pill);
}

/*
 * Three a row from 992, not 768 (20 October 2026): one a row below that, the
 * way the reviews further down already go, at Robert's choice.
 */
@media (min-width: 992px) {
	.video-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* Reviews
   ========================================================================== */

.reviews__heading {
	align-items: center;
}

.reviews__heading .section-heading__text {
	flex: 1 1 280px;
}

.rating-summary__score {
	display: flex;
	gap: var(--space-3);
	align-items: center;
	font-family: var(--font-heading);
	font-size: 1.6rem;
	color: var(--color-ink);
}

.rating-summary__score .icon {
	width: 22px;
	height: 22px;
}

.rating-summary__note {
	font-size: var(--fs-sm);
}

.review-grid {
	display: grid;
	gap: var(--space-5);
}

.review-card {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	/*
	 * Only the first row is sized: 1fr, so it swallows whatever height the card
	 * has left over and everything under it — the stars and the author — is
	 * pushed to the bottom edge. That is what keeps the three cards in a row
	 * aligned when one review is two lines and the next is eight. Naming just
	 * one row rather than all three matters: a review with no rating recorded
	 * has no stars row, and an explicit three-row template would leave an empty
	 * row under its author instead.
	 */
	grid-template-rows: 1fr;
	gap: var(--space-2) var(--space-4);
	height: 100%;
	padding: var(--space-6);
	background: var(--color-white);
	border: 1px solid #e8eef5;
	border-radius: var(--radius);
	box-shadow: var(--shadow-sm);
}

.review-card__mark {
	/* Both start-aligned: the row is taller than they are now, and a stretched
	   quote mark would be drawn out of shape. */
	align-self: start;
	color: #cddff5;
}

.review-card__text {
	align-self: start;
	font-size: 0.9375rem;
	line-height: 1.65;
}

.review-card .stars {
	grid-column: 2;
	margin-top: var(--space-2);
}

.review-card__author {
	display: flex;
	grid-column: 1 / -1;
	gap: var(--space-4);
	align-items: center;
	margin-top: var(--space-2);
}

.avatar {
	flex-shrink: 0;
	width: 56px;
	height: 56px;
	object-fit: cover;
	object-position: center 20%;
	border-radius: 50%;
}

/* The initials stand-in (quantum_initials(); the look is in main.css). */
.avatar--initials {
	font-size: 1.25rem;
	line-height: 1;
}

.review-card__name {
	display: block;
	font-family: var(--font-heading);
	font-weight: 600;
	color: var(--color-ink);
}

.review-card__location {
	font-size: var(--fs-sm);
}

@media (min-width: 992px) {
	.review-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* Patient gallery
   ========================================================================== */

.photo-gallery {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
	padding-bottom: var(--section-space);
}

.photo-gallery__image {
	width: 100%;
	aspect-ratio: 10 / 9;
	object-fit: cover;
	object-position: center 25%;
	border-radius: var(--radius-tile);
}

@media (min-width: 768px) {
	.photo-gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1200px) {
	.photo-gallery { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
