/**
 * miraigo/text-image
 *
 * Shares the paired-media convention with numbered-steps (see that block's
 * style.css for the full statement): DOM order is always media, then title,
 * then body — never reordered in markup. Below 1024px stacked; at >=1024px a
 * two-column grid with side controlled by `mediaPosition` via CSS, never by
 * touching the DOM.
 *
 * One deviation from numbered-steps: on mobile the stacked order is
 * heading -> image -> paragraph -> CTA, not image-first. The visual stacked
 * order below is title, then media, then body — achieved with `order` on
 * the title only, DOM stays media-first. numbered-steps has no such
 * override.
 *
 * Grid tracks are asymmetric (871:541), not the 1fr/1fr numbered-steps uses:
 * the design uses a 871px media / 541px text split inside the 1470px content
 * area. An even split would shrink the media 19% and widen the text column
 * past a comfortable measure at body-md.
 *
 * Title is 36px/H3, set in the block's own stylesheet rather than per
 * pattern. font-weight stays 600: H3's own default already matches.
 */

.wp-block-miraigo-text-image {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
	max-width: var(--wp--custom--width--measure);
	margin-inline: auto;
}

.text-image__title {
	order: -1;
	margin: 0;
	font-size: var(--wp--preset--font-size--heading-3);
	font-weight: 600;
	line-height: 1.1;
	color: var(--wp--preset--color--text-primary);
	text-align: center;
}

/**
 * Overline — the small brand-red kicker above the title ("CHANNEL MANAGERS",
 * "PASARELAS DE PAGO").
 *
 * `order: -2` keeps it above the title's own `order: -1` while the block is
 * a stacked column, so DOM order stays media-first exactly as the header of
 * this file states — the overline is emitted after the figure, never before.
 *
 * No `letter-spacing`: the `overline` font-size token is shared with h6,
 * whose theme.json element style adds 3px of tracking, but the overline
 * needs 0 here. Declared explicitly rather than inherited by accident.
 */
.text-image__overline {
	order: -2;
	margin: 0;
	font-size: var(--wp--preset--font-size--overline);
	font-weight: 600;
	line-height: 1.37;
	letter-spacing: 0;
	color: var(--wp--preset--color--text-brand);
	text-transform: uppercase;
	text-align: center;
}

/*
 * 45px/H2 title, against the 36px/H3 the other instances share. A modifier
 * the pattern opts into, not a new default.
 */
.wp-block-miraigo-text-image.is-title-lg .text-image__title {
	font-size: var(--wp--preset--font-size--heading-2);
}

/*
 * The same larger title on mobile only. Desktop keeps the 36px title.
 */
@media (max-width: 767.98px) {

	.wp-block-miraigo-text-image.is-title-lg-mobile .text-image__title {
		font-size: var(--wp--preset--font-size--heading-2);
	}
}

.text-image__media :is(img, video) {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--wp--custom--radius--image);
}

.text-image__media {
	margin: 0;
}

/* Opt-in frame for the FEATURES and INTEGRACIONES demo videos, same stroke as the cards. */
.wp-block-miraigo-text-image.is-media-bordered .text-image__media :is(img, video) {
	border: var(--wp--custom--border--button) solid var(--wp--preset--color--border-strong);
}

.text-image__body {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--35);
}

.text-image__description {
	margin: 0;
	font-size: var(--wp--preset--font-size--body-md);
	color: var(--wp--preset--color--text-secondary);
	text-align: center;
}

/*
 * text-primary/text-secondary read as dark-grey-on-dark-grey inside a dark
 * section-panel. Same .is-surface-dark contract core-button.css and
 * core-list.css already key off — title and body both
 * collapse to text-inverse, matching every other block's flat single-ink
 * treatment on this surface (hero, stat-card, plan-card, icon-row).
 */
/* stylelint-disable-next-line no-descending-specificity -- No conflict: `is-title-lg` above sets font-size, this sets colour on dark panels. */
.is-surface-dark .text-image__title,
.is-surface-dark .text-image__description {
	color: var(--wp--preset--color--text-inverse);
}

.text-image__body :where(ol, ul) {
	text-align: left;
}

@media (min-width: 1024px) {

	/*
	 * Row 1 and row 4 are anonymous 1fr spacers (the "." cells) with no
	 * element in them. They absorb the slack above and below the title+body
	 * pair in equal shares, which is what actually centers that pair against
	 * the media column — `align-items: center` on a 2-row split does not:
	 * a grid item spanning two `auto` rows forces both to inflate to make up
	 * its height, which centers title and body INSIDE their own inflated
	 * rows instead of centering the pair as a unit.
	 */
	.wp-block-miraigo-text-image {
		display: grid;
		grid-template-columns: minmax(0, 871fr) minmax(0, 541fr);
		grid-template-rows: 1fr auto auto 1fr;
		grid-template-areas: "media ." "media title" "media body" "media .";
		gap: var(--wp--preset--spacing--55);
		max-width: none;
	}

	.text-image__media {
		grid-area: media;

		/*
		 * Without this, a grid item defaults to align-self: stretch: the
		 * figure stretches to fill all four spanned rows, but the <img>
		 * inside it keeps its own aspect ratio (height: auto) and just sits
		 * at the top of that stretched box — leaving the photo top-aligned
		 * and off-centre whenever the text column is taller than the photo
		 * (long copy, or a wide/short crop). Centring the figure itself
		 * keeps it sized to its own content and centred in the same box the
		 * title+body spacer rows already centre their pair in.
		 */
		align-self: center;
	}

	.text-image__title {
		grid-area: title;
		order: initial;
		text-align: start;
	}

	.text-image__body {
		grid-area: body;
	}

	.text-image__description {
		text-align: start;
	}

	.text-image--media-right {
		grid-template-columns: minmax(0, 541fr) minmax(0, 871fr);
		grid-template-areas: ". media" "title media" "body media" ". media";
	}

	/*
	 * Five rows instead of four, scoped to the modifier so the five
	 * overline-less instances keep the exact template they were reviewed
	 * with. The two 1fr spacers still bracket the stack, so the
	 * overline+title+body group centres against the media column as one
	 * unit — same mechanism the base rule's docblock above describes.
	 */
	.text-image--has-overline {
		grid-template-rows: 1fr auto auto auto 1fr;
		grid-template-areas: "media ." "media overline" "media title" "media body" "media .";
	}

	.text-image--has-overline.text-image--media-right {
		grid-template-areas: ". media" "overline media" "title media" "body media" ". media";
	}

	.text-image__overline {
		grid-area: overline;
		text-align: start;
	}

	/*
	 * The overline labels the title, so the 60px row gap that separates the
	 * real blocks of content is wrong between those two. The wanted gap is
	 * 26px; pulling the title up by the difference lands on spacing--35 (24px) without a second
	 * `row-gap` that would also retune the title/body distance.
	 */
	.text-image--has-overline .text-image__title {
		margin-block-start: calc(var(--wp--preset--spacing--35) - var(--wp--preset--spacing--55));
	}

	.text-image--no-media {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto auto;
		grid-template-areas: "title" "body";
	}
}

/**
 * `is-reveal-split` — opt-in scroll reveal, set from the pattern's
 * `className` rather than from render.php.
 *
 * That placement is the whole point: text-image also builds sections where
 * motion is not wanted. A class the composition applies keeps this to the
 * sections that opt in, and turning it on elsewhere is a pattern edit, not a
 * change here.
 *
 * `.miraigo-reveal-ready` (assets/js/reveal.js, front end only) gates the
 * hidden state, so this stylesheet staying mirrored into the block editor
 * costs nothing — the class never exists there. See the header of
 * assets/css/utilities/reveal.css for why the reduced-motion query wraps the
 * start state instead of the transition.
 */

/* Below the two-column breakpoint the block is a single stacked column, so
   there are no opposite sides to come in from: the whole block rises. */
@media (prefers-reduced-motion: no-preference) and (max-width: 1023.98px) {

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split {
		opacity: 0;
		transform: translateY(var(--wp--custom--reveal--distance));
		transition:
			opacity var(--wp--custom--transition--reveal),
			transform var(--wp--custom--transition--reveal);
	}

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split.is-revealed {
		opacity: 1;
		transform: none;
	}
}

/* From 1024px the halves travel towards each other, following whichever side
   `mediaPosition` actually put the image on. The inbound travel can overhang
   the viewport for a frame; `overflow-x: clip` on body (style.css)
   is what keeps that from becoming a horizontal scrollbar. */
@media (prefers-reduced-motion: no-preference) and (min-width: 1024px) {

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split :is(.text-image__media, .text-image__overline, .text-image__title, .text-image__body) {
		opacity: 0;
		transition:
			opacity var(--wp--custom--transition--reveal),
			transform var(--wp--custom--transition--reveal);
	}

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split .text-image__media {
		transform: translateX(calc(var(--wp--custom--reveal--distance-inline) * -1));
	}

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split :is(.text-image__overline, .text-image__title, .text-image__body) {
		transform: translateX(var(--wp--custom--reveal--distance-inline));
	}

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split.text-image--media-right .text-image__media {
		transform: translateX(var(--wp--custom--reveal--distance-inline));
	}

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split.text-image--media-right :is(.text-image__overline, .text-image__title, .text-image__body) {
		transform: translateX(calc(var(--wp--custom--reveal--distance-inline) * -1));
	}

	.miraigo-reveal-ready .wp-block-miraigo-text-image.is-reveal-split.is-revealed :is(.text-image__media, .text-image__overline, .text-image__title, .text-image__body) {
		opacity: 1;
		transform: none;
	}
}
