/**
 * JS Story Testimonials
 *
 * Ported from cci-core's cci-story-testimonials.css in cci-website: a centred
 * quote rotator with a row of circular photos (the active one ringed), a
 * title, a divider, the story and the person's name. Panels are stacked in
 * one grid cell so the section never jumps when the story changes.
 *
 * What differs from CCI's: the gold is the site's highlight token rather than
 * CCI's gradient, the text colours are variables so the widget reads on a
 * light section as well as a dark one, and the quote marks are CSS rather
 * than injected icons.
 */

.js-story-testimonials {
	--js-st-avatar-size: 60px;
	--js-st-edge-size: 20px;
	--js-st-avatar-gap: 20px;
	/* Gold ring around the active photo: a gap then the ring,
	 * drawn outside the photo (a ::after overlay) so the active photo stays the
	 * same size as the others — no separate active size. */
	--js-st-ring-gap: 7px;
	--js-st-ring-width: 1.5px;
	/*
	 * Photos Per View — read by the JS as how many photos (centred on the
	 * active one) stay full size before the rest shrink toward the edges. The
	 * widget control overrides this per device (4 / 3 / 2 by default).
	 */
	--js-st-nav-per-view: 5;
	/* Site highlight gold, shared by the title, divider and active ring. */
	--js-st-accent: var(--js-color-highlight, #b28b2c);
	--js-st-ring: var(--js-st-accent);
	position: relative;
	width: 100%;
	box-sizing: border-box;
	text-align: center;
}

.js-story-testimonials *,
.js-story-testimonials *::before,
.js-story-testimonials *::after {
	box-sizing: border-box;
}

/* =========================================
   Photo strip (the nav carousel)
========================================= */
.js-story-testimonials__avatars {
	margin-bottom: 40px;
}

/*
 * The viewport spans the container and clips the wide strip HORIZONTALLY only
 * — never vertically, so the photos/ring can't be cut off (e.g. on mobile,
 * where the strip was clipping to a sliver). overflow:hidden is the fallback
 * for browsers without overflow:clip.
 */
.js-story-testimonials__avatars-viewport {
	width: 100%;
	overflow: hidden;
}

@supports (overflow: clip) {
	.js-story-testimonials__avatars-viewport {
		overflow-x: clip;
		overflow-y: visible;
	}
}

/*
 * The track is the positioning context for the photos. Before the JS runs it
 * is a simple centred flex row showing just the first (active) photo, so that
 * photo appears immediately instead of waiting for the script (important on
 * mobile, where the footer script runs late). Once ready, the JS positions
 * every photo absolutely and sets the exact height inline.
 */
.js-story-testimonials__avatars-track {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: calc(
		var(--js-st-avatar-size, 60px) + 2 *
			(var(--js-st-ring-gap, 7px) + var(--js-st-ring-width, 1.5px))
	);
}

/* Pre-JS: only the first (active) photo shows, centred. */
.js-story-testimonials:not(.js-story-testimonials--ready)
	.js-story-testimonials__avatar-slot:not(:first-child) {
	display: none;
}

.js-story-testimonials--ready .js-story-testimonials__avatars-track {
	display: block;
}

/*
 * Each photo is positioned (transform) and sized (width/height) per-frame by
 * the JS; these transitions make moves and resizes smooth. The wrap-around
 * photo has its transition momentarily cleared by the JS so it snaps instead
 * of sliding across the strip.
 */
.js-story-testimonials__avatar-slot {
	flex: 0 0 auto;
	width: var(--js-st-avatar-size);
	height: var(--js-st-avatar-size);
	will-change: transform;
	transition:
		transform 0.5s ease,
		width 0.5s ease,
		height 0.5s ease,
		opacity 0.5s ease;
}

.js-story-testimonials--ready .js-story-testimonials__avatar-slot {
	position: absolute;
	top: 0;
	left: 0;
}

.js-story-testimonials__avatar-slot.is-active {
	z-index: 2;
}

/* Instant (no-animation) jumps — initial layout and resize re-positioning. */
.js-story-testimonials--no-anim .js-story-testimonials__avatar-slot {
	transition: none !important;
}

/*
 * The photo button. Reset aggressively so it's exactly the slot square (theme
 * button styles can otherwise add height/min-height and a focus outline, which
 * pushed the photo off-centre inside its box — clipping it and shifting the
 * ring). overflow:hidden clips the image to the circle.
 */
.js-story-testimonials__avatar {
	display: block;
	position: relative;
	width: 100%;
	height: 100%;
	/* !important to beat the Elementor kit button rule (.elementor-kit-N button)
	 * which adds 18px vertical padding + min-height and breaks the small edge
	 * photos. */
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	min-width: 0 !important;
	min-height: 0 !important;
	border-radius: 50%;
	overflow: hidden;
	background: none !important;
	box-shadow: none;
	outline: none;
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
}

/* Keyboard focus stays visible; mouse clicks rely on the gold active ring. */
.js-story-testimonials__avatar:focus-visible {
	outline: 2px solid var(--js-st-accent);
	outline-offset: 3px;
}

/*
 * Active photo: circled by the gold ring. The ring is a ::after
 * overlay on the active SLOT — a cleanly JS-sized square box — so it always
 * centres on the photo. It's a transparent gap (showing the section behind)
 * then the ring colour masked to just its border, so the photo never resizes
 * and the gap needs no colour match.
 */
.js-story-testimonials__avatar-slot.is-active::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: calc(100% + 2 * (var(--js-st-ring-gap) + var(--js-st-ring-width)));
	height: calc(100% + 2 * (var(--js-st-ring-gap) + var(--js-st-ring-width)));
	transform: translate(-50%, -50%);
	border-radius: 50%;
	padding: var(--js-st-ring-width);
	background: var(--js-st-ring);
	-webkit-mask:
		linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask-composite: exclude;
	pointer-events: none;
}

/*
 * Fill the photo button exactly. Absolute inset:0 pins all four edges so the
 * image spans the button regardless of theme `img { height: auto }` rules
 * (which otherwise let the photo collapse to its source aspect — a clipped
 * band or dome). object-fit then crops it to a clean circle.
 */
.js-story-testimonials__avatar-img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100% !important;
	height: 100% !important;
	max-width: none;
	object-fit: cover;
	border-radius: 50%;
	/* Don't ghost-drag the photo when swiping the carousel. */
	-webkit-user-drag: none;
	user-select: none;
	transition:
		filter 0.3s ease,
		opacity 0.3s ease;
}

/* Placeholder for testimonials without a featured image: initial in a circle. */
.js-story-testimonials__avatar-fallback {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	background: var(--js-color-primary, #111827);
	color: #ffffff;
	font-family: var(--js-font-family, "Inter", sans-serif);
	font-size: 1.2em;
	font-weight: 600;
	text-transform: uppercase;
	transition: opacity 0.3s ease;
}

/*
 * Dim Inactive Photos (the js-st-grayscale-* prefix class from the widget):
 * desaturate the non-active photos. Their opacity is dimmed per-tier by the
 * JS (smaller edge photos fade out), so this only handles the colour.
 */
.js-st-grayscale-yes .js-story-testimonials__avatar:not(.is-active) .js-story-testimonials__avatar-img {
	filter: grayscale(1);
}

@media (hover: hover) {
	.js-st-grayscale-yes .js-story-testimonials__avatar:not(.is-active):hover .js-story-testimonials__avatar-img {
		filter: none;
	}
}

/* =========================================
   Story panels
========================================= */
/*
 * All panels share the same grid cell, so the container is as tall as the
 * tallest story and switching never makes the page jump. Only the active
 * panel is visible (and interactive).
 */
.js-story-testimonials__panels {
	display: grid;
	/* Draggable/swipeable: grab at rest, grabbing while dragging (set by JS). */
	cursor: grab;
}

.js-story-testimonials--dragging .js-story-testimonials__panels {
	cursor: grabbing;
	-webkit-user-select: none;
	user-select: none;
}

.js-story-testimonials__panel {
	grid-area: 1 / 1;
	opacity: 0;
	visibility: hidden;
	transition:
		opacity 0.45s ease,
		visibility 0.45s;
}

.js-story-testimonials__panel.is-active {
	opacity: 1;
	visibility: visible;
}

/*
 * Title: the site gold by default; the Title Colour control overrides it.
 * Scoped under the wrapper (0,2,0) so it outranks the theme and Elementor-kit
 * heading styles on a bare h2/h3/h4.
 */
.js-story-testimonials .js-story-testimonials__title {
	margin: 0 0 32px;
	color: var(--js-st-title, var(--js-st-accent));
	font-family: var(--js-font-family, "Inter", sans-serif);
	font-size: 32px;
	font-weight: 700;
	line-height: 40px;
}

.js-story-testimonials__divider {
	display: block;
	width: 100%;
	height: 1px;
	margin: 0 auto 40px;
	background: var(--js-st-accent);
}

.js-story-testimonials__story {
	max-width: 900px;
	margin: 0 auto 40px;
	/* A blockquote: clear the theme's quote indent, rule and italics. */
	padding: 0;
	border: 0;
	font-style: normal;
	color: var(--js-st-text, var(--js-color-primary, #111827));
	font-family: var(--js-font-family, "Inter", sans-serif);
	font-size: 24px;
	font-weight: 400;
	line-height: 36px;
}

.js-story-testimonials__story p {
	margin: 0 0 1em;
}

.js-story-testimonials__story p:last-child {
	margin-bottom: 0;
}

/*
 * Quote marks hanging outside the story, as on the CCI widget: zero layout
 * width, so they never push a word onto a line of its own.
 */
.js-story-testimonials__story p:first-child::before,
.js-story-testimonials__story p:last-child::after {
	display: inline-block;
	width: 0;
	line-height: 0;
	opacity: 0.35;
}

.js-story-testimonials__story p:first-child::before {
	content: "\201C";
	transform: translateX(-0.6em);
}

.js-story-testimonials__story p:last-child::after {
	content: "\201D";
	transform: translateX(0.15em);
}

.js-story-testimonials__name {
	display: block;
	color: var(--js-st-name, var(--js-color-primary, #111827));
	font-family: var(--js-font-family, "Inter", sans-serif);
	font-size: 18px;
	font-weight: 600;
	line-height: 28px;
}

/* =========================================
   Responsive
========================================= */
@media (max-width: 1024px) {
	.js-story-testimonials .js-story-testimonials__title {
		font-size: 24px;
		line-height: 32px;
	}

	.js-story-testimonials__divider {
		margin-bottom: 32px;
	}

	.js-story-testimonials__story {
		margin-bottom: 32px;
		font-size: 18px;
		line-height: 28px;
	}
}

@media (max-width: 767px) {
	.js-story-testimonials__avatars {
		margin-bottom: 28px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.js-story-testimonials__avatars-track,
	.js-story-testimonials__avatar-slot,
	.js-story-testimonials__avatar,
	.js-story-testimonials__avatar-img,
	.js-story-testimonials__avatar-fallback,
	.js-story-testimonials__panel {
		transition: none;
	}
}
