/*
 * Testimonial section — the carousel viewport, track, cards, arrows and
 * dots. docs/step-17-testimonial-section.md, measured live at 1440px against
 * https://stodio.webflow.io/.
 *
 * The card surface (.is-surface-card, dark bg, 24px radius, 16px inset) is
 * entirely handled by style.css's existing utility — nothing here duplicates
 * it. The eyebrow badge reuses the same chassis as the hero, gallery, service
 * and pricing badges (.idia-hero-card__badge.is-style-badge-icon-plus-square).
 *
 * Carousel motion (the translateX transform on the track) is applied by
 * assets/js/testimonial-carousel.js, not here — this file only sizes the
 * slides/mask/track and styles the arrows/dots. The `transform` property
 * itself has no CSS `transition` rule below: the script tweens the
 * translateX value across animation frames with its own easing curve rather
 * than delegating to a CSS transition, so no duration/easing needs
 * duplicating in both places. See the JS file for the reduced-motion branch.
 *
 * New theme.json token: custom.gap.28 (28px) — the star icon's measured
 * size. Every other fixed dimension here (12/44/48/64/120) already existed.
 */

/* ---- Content clipping ----
   .testimonial-section > .container > .testimonial-content-block in the
   reference — CONTENT here is the equivalent wrapper. overflow: hidden is
   what clips off-screen slides in both the JS-on sliding state and the
   JS-off static-row fallback (no JS class needed either way). */
.idia-testimonial__content {
	overflow: hidden;
}

/* ---- Intro column ----
   The reference's right-hand paragraph uses line-height 28.8px on an 18px
   ("small"/intro) size — a 1.6 ratio, distinct from the theme's own default
   paragraph line-height. Kept as an explicit rule since AGENTS.md §9.3
   reserves line-height overrides for cases the element default doesn't
   already supply, and no element default targets a lone measure-scoped
   paragraph like this one. */
.idia-testimonial__title-block p.is-measure-aside-narrow {
	line-height: 1.6;
}

/* ---- Slider / mask / track ---- */

.idia-testimonial__mask {
	position: relative;
	overflow: hidden;
}

/* Step 17b, defect 5: the track is draggable (swipe support in
   testimonial-carousel.js), so without this a drag gesture highlights the
   quote text and ghost-drags the author image instead of moving the
   carousel. Scoped to the track only, not the section (AGENTS.md's "don't
   disable selection on the whole section" — a visitor can still select and
   copy a quote when not actively dragging). touch-action:pan-y keeps
   vertical page scroll working for touch input inside the mask; the
   pointer handlers in JS already avoid preventDefault on vertical moves. */
.idia-testimonial__track {
	display: flex;
	flex-wrap: nowrap;
	gap: var(--wp--preset--spacing--24);
	will-change: transform;
	user-select: none;
	touch-action: pan-y;
}

.idia-testimonial__track img {
	-webkit-user-drag: none;
	user-drag: none;
}

/* JS off: no transform is ever applied, so the track renders as a plain
   static row — already clipped by .idia-testimonial__content's overflow:
   hidden above. Arrows and dots are added to the DOM by the script itself
   (see the pattern's static <div> shells), so with JS disabled the
   #idia-testimonial-dots container stays empty and the arrow buttons, while
   present in markup for progressive enhancement, are hidden here until JS
   confirms the carousel initialised. */
.idia-testimonial__nav {
	display: none;
}

.js-idia-testimonial-ready .idia-testimonial__nav {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--12);
	padding-top: var(--wp--preset--spacing--12);
}

/* ---- Slide / card ----
   442px matches the reference's measured slide width at 1440 exactly; the
   24px gap comes from .idia-testimonial__track's blockGap above, never a
   per-slide margin, so assets/js/testimonial-carousel.js can read
   `slide.getBoundingClientRect().width + trackGap` at runtime for the step
   distance instead of a hardcoded constant. */
.idia-testimonial__slide {
	flex: 0 0 442px;
	width: 442px;
}

.idia-testimonial__card-body {
	position: relative;
}

/* Reference note: the star sits in a height:0 wrapper, positioned
   absolutely inside it. Reproduced here as a fixed-height box in normal
   flow instead (see the pattern file, point 7) — visually identical, no
   off-flow hack.

   The glyph itself was a hardcoded-red PNG (attachment 249, #de322d) with
   no theme.json equivalent — a raster asset the site owner could not
   recolour from the Editor (AGENTS.md §7, §12 item 12). Replaced with a
   CSS mask-image, same mechanism as the eyebrow badge icons
   (footer-cta.css) — a Phosphor "quotes-fill" glyph painted with an
   explicit colour token rather than currentColor, since this element sits
   in normal text flow with no icon-colour ancestor to inherit from.
   `primary` matches this section's own existing accent use (the arrow
   buttons' hover state, below) — `[[NEEDS DECISION: accent colour]]` is
   still open per AGENTS.md §7, so this reuses an existing preset rather
   than inventing a new one. */
.idia-testimonial__star {
	width: var(--wp--custom--gap--28);
	height: var(--wp--custom--gap--28);
	margin: 0;
	display: block;
	background-color: var(--wp--preset--color--primary);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20256%20256%22%20fill%3D%22%23000%22%3E%3Cpath%20d%3D%22M104%2C58a6%2C6%2C0%2C0%2C1-6%2C6H86a6%2C6%2C0%2C0%2C0%2C0%2C12h6a6%2C6%2C0%2C0%2C1%2C6%2C6v40a14%2C14%2C0%2C0%2C1-14%2C14H60a14%2C14%2C0%2C0%2C1-14-14V90A44.05%2C44.05%2C0%2C0%2C1%2C90%2C46%2C6%2C6%2C0%2C0%2C1%2C104%2C58Zm88%2C0a6%2C6%2C0%2C0%2C1-6%2C6H174a6%2C6%2C0%2C0%2C0%2C0%2C12h6a6%2C6%2C0%2C0%2C1%2C6%2C6v40a14%2C14%2C0%2C0%2C1-14%2C14H148a14%2C14%2C0%2C0%2C1-14-14V90a44.05%2C44.05%2C0%2C0%2C1%2C44-44A6%2C6%2C0%2C0%2C1%2C192%2C58Z%22%2F%3E%3C%2Fsvg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20256%20256%22%20fill%3D%22%23000%22%3E%3Cpath%20d%3D%22M104%2C58a6%2C6%2C0%2C0%2C1-6%2C6H86a6%2C6%2C0%2C0%2C0%2C0%2C12h6a6%2C6%2C0%2C0%2C1%2C6%2C6v40a14%2C14%2C0%2C0%2C1-14%2C14H60a14%2C14%2C0%2C0%2C1-14-14V90A44.05%2C44.05%2C0%2C0%2C1%2C90%2C46%2C6%2C6%2C0%2C0%2C1%2C104%2C58Zm88%2C0a6%2C6%2C0%2C0%2C1-6%2C6H174a6%2C6%2C0%2C0%2C0%2C0%2C12h6a6%2C6%2C0%2C0%2C1%2C6%2C6v40a14%2C14%2C0%2C0%2C1-14%2C14H148a14%2C14%2C0%2C0%2C1-14-14V90a44.05%2C44.05%2C0%2C0%2C1%2C44-44A6%2C6%2C0%2C0%2C1%2C192%2C58Z%22%2F%3E%3C%2Fsvg%3E");
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.idia-testimonial__quote {
	margin-top: var(--wp--preset--spacing--44);
	margin-bottom: 0;
}

.idia-testimonial__author-block {
	margin-top: var(--wp--preset--spacing--24);
}

.idia-testimonial__author-info {
	padding-top: var(--wp--preset--spacing--120);
	gap: var(--wp--preset--spacing--4);
}

.idia-testimonial__author-info p {
	margin: 0;
}

.idia-testimonial__author-image {
	margin: 0 0 var(--wp--preset--spacing--4);
}

/* Literal px, not --wp--custom--gap--64: that custom property is the
   marquee's own track-gap token (style.css) and steps to 16px at <=767px for
   that unrelated purpose — reusing it here silently collapsed the avatar to
   16x26px (object-fit stretching the rest) at the same breakpoint
   (docs/step-homepage-responsiveness-audit.md). The reference's own
   .testimonial-author-image only steps once, to 60px, at <=479px — see the
   breakpoint block below. */
.idia-testimonial__author-image img {
	width: 64px;
	height: 64px;
	border-radius: var(--wp--preset--border-radius--md);
	object-fit: cover;
}

.idia-testimonial__logo img {
	width: 140px;
	height: auto;
	object-fit: contain;
}

/* ---- Arrows ----
   Real <button> elements (pattern file) — no core/button reuse, since these
   carry only an SVG-mask glyph and an aria-label, no visible text. Same
   48px circular chassis as the reference's .left-arrow/.right-arrow (step
   17b, defect 3: --wp--custom--gap--48 did not exist before this fix — the
   theme's spacing scale jumped 44 -> 50 with no 48 token, so this rule's
   width/height fell back to `auto` and the browser's UA button padding took
   over. Added to theme.json's settings.custom.gap alongside the other
   fixed-dimension tokens (12/28/44/64) this section already uses).

   DOM order stays prev-arrow, dots, next-arrow (pattern file) so Tab order
   is untouched; `order` here only changes the visual position so the two
   arrows sit adjacent on the right with the dots filling the space to
   their left, matching the reference's row without reordering focus. */
.idia-testimonial__arrow {
	appearance: none;
	border: none;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--custom--gap--48);
	height: var(--wp--custom--gap--48);
	border-radius: var(--wp--preset--border-radius--full);
	background-color: var(--wp--preset--color--primary-alt-accent);
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--base);
	flex-shrink: 0;
	user-select: none;
	transition: background-color var(--wp--custom--transition) ease, border-radius var(--wp--custom--transition) cubic-bezier(0.32, 0.72, 0, 1);
}

.idia-testimonial__arrow--prev {
	order: 2;
}

.idia-testimonial__arrow--next {
	order: 3;
}

.idia-testimonial__arrow:hover,
.idia-testimonial__arrow:focus-visible {
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--main);
	border-radius: var(--wp--preset--border-radius--lg);
}

.idia-testimonial__arrow:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 3px;
}

.idia-testimonial__arrow:disabled {
	opacity: 0.4;
	cursor: default;
}

@media (prefers-reduced-motion: reduce) {
	.idia-testimonial__arrow {
		transition: none;
	}
}

/* Fills the space to the left of the two (now-adjacent) arrows — order:1
   keeps it visually first despite sitting between the arrows in the DOM. */
.idia-testimonial__dots {
	display: flex;
	align-items: center;
	flex: 1;
	order: 1;
	gap: var(--wp--preset--spacing--8);
	user-select: none;
}

/* Inactive colour (step 17b, defect 4): the reference measures 40% white,
   not the solid primary-alt-accent dark this used before — on the section's
   #0a0a0a background the solid dark read as nearly invisible. Expressed as
   color-mix against the theme's own `base` token (white) rather than a raw
   rgba(), matching the alpha pattern style.css already uses elsewhere
   (color-mix(in srgb, var(--wp--preset--color--...) N%, ...)) — no preset
   on the colour scale is itself partially transparent, so a literal
   percentage against the token is the closest fit to "use a token." */
.idia-testimonial__dot {
	appearance: none;
	border: none;
	cursor: pointer;
	width: var(--wp--custom--gap--12);
	height: var(--wp--custom--gap--12);
	border-radius: var(--wp--preset--border-radius--full);
	background-color: color-mix(in srgb, var(--wp--preset--color--base) 40%, transparent);
	padding: 0;
	transition: background-color var(--wp--custom--transition) cubic-bezier(0.32, 0.72, 0, 1);
}

.idia-testimonial__dot[aria-current="true"] {
	background-color: var(--wp--preset--color--base);
}

.idia-testimonial__dot:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.idia-testimonial__dot {
		transition: none;
	}
}

/* ---- Breakpoints ----
   Visible-slide counts step down with the reference: 3 at 1440, 2 at 991
   and 767, 1 at 479. The slide width itself is left to the browser/JS to
   measure — only the CSS width changes here; the JS reads it back via
   getBoundingClientRect(), never a hardcoded value at any breakpoint. */
@media (max-width: 991px) {

	.idia-testimonial__slide {
		flex-basis: 380px;
		width: 380px;
	}
}

@media (max-width: 767px) {

	.idia-testimonial__slide {
		flex-basis: 320px;
		width: 320px;
	}

	.idia-testimonial__author-info {
		padding-top: var(--wp--preset--spacing--80);
	}
}

@media (max-width: 479px) {

	.idia-testimonial__slide {
		flex-basis: 280px;
		width: 280px;
	}

	.idia-testimonial__author-image img {
		width: 60px;
		height: 60px;
	}
}

/* ---- Column entrance — starting state ----
   Standard "Fade In" family (blur + rise + fade — same mechanism as the hero
   and CTA), applied to the left column (badge + heading, 200ms) and the
   right column (intro line, 300ms) only. The slider itself and its slides
   get NO entrance of their own — confirmed no data-w-id/IX2 binding exists
   on either in the reference; it simply appears once the two heading
   columns above it have revealed, its only motion being the native slide
   transition already in testimonial-carousel.js. See
   animation-map-remaining-sections.json, testimonial section. Opt-in only:
   scoped to prefers-reduced-motion: no-preference, so a reduced-motion
   visitor's section renders complete and settled immediately —
   testimonial-carousel.js independently checks the same media query before
   running these tweens. */
@media (prefers-reduced-motion: no-preference) {

	.idia-testimonial__title-block > .is-measure-testimonial,
	.idia-testimonial__title-block > .is-measure-aside-narrow {
		opacity: 0;
		transform: translateY(50px);
		filter: blur(5px);
	}
}
