/**
 * core/media-text — the media column always reaches the edge of the screen.
 *
 * The block keeps whatever alignment the editor picked: the text column stays
 * inside the content width, and only the media is pulled out to the viewport
 * edge on the side it happens to sit on. So a full-bleed image no longer costs
 * a full-width block plus a hand-constrained group around the text.
 *
 * Loaded by includes/styles/blocks/core-media-text.php as the block's default
 * style, so every instance gets it — the selectors below target the block
 * itself, never an `.is-style-*` class.
 *
 * ## One breakpoint, and it is not core's
 *
 * **The block stacks at `72rem`, not at core's `600px`.** Every `@media` below
 * is that threshold, which is `settings.viewport.tablet` in theme.json — the
 * same number the `@tablet` style state compiles to, so a pattern's per-viewport
 * spacing and the block's own reflow switch on the same line. Core's `600px`
 * is 19rem earlier, and a 50/50 split that early leaves a display heading two
 * or three words to a line: at 768px the text column is ~294px against a
 * heading core is still ramping towards 48px. Nothing in a pattern asks for
 * this; every Media & Text on the site gets it.
 */

.wp-block-media-text {
	/*
	 * The width the layout gave this block, and half of what the viewport has
	 * left over — the distance the media has to travel to reach the edge. Read
	 * from the layout tokens rather than hardcoded, so it follows
	 * contentSize/wideSize in theme.json: the `min(… - 2rem, …)` form those are
	 * written in is what collapses the bleed to the 1rem gutter on small screens
	 * without a breakpoint here.
	 *
	 * Written once, with each alignment below saying only which width it uses.
	 */
	--kg-media-text-layout-width: var(--wp--style--global--content-size);
	--kg-media-text-bleed: max(
		0px,
		(var(--screen-size, 100vw) - var(--kg-media-text-layout-width)) / 2
	);

	/* One side, until the block stacks and the media bleeds both ways. */
	--kg-media-text-bleed-total: var(--kg-media-text-bleed);
}

.wp-block-media-text.alignwide {
	--kg-media-text-layout-width: var(--wp--style--global--wide-size);
}

/* Already as wide as the screen, so the bleed works out to zero by itself. */
.wp-block-media-text.alignfull {
	--kg-media-text-layout-width: var(--screen-size, 100vw);
}

/*
 * Pull the figure out of its grid area instead of resizing the area, so the
 * column tracks — and with them the text — stay exactly where the layout put
 * them.
 *
 * That is also what makes this indifferent to the media/text ratio. Core sizes
 * the media track as a percentage of the block: 50% from its own stylesheet, or
 * an inline `grid-template-columns: 30% auto` the moment the Media width
 * control is touched. A percentage track resolves against the container and
 * never against its item, so a negative margin on the figure cannot feed back
 * into the track — every ratio bleeds by the same amount and keeps the split it
 * was given.
 *
 * Logical properties even though the block never flips: core forces
 * `direction: ltr` on the wrapper and hardcodes the media to `grid-column: 1`,
 * so inline-start stays the left edge in RTL too — which is the side the media
 * is actually on.
 *
 * The `figure` in the selector is load-bearing. Core zeroes the same margins
 * from `.wp-block-media-text > .wp-block-media-text__media`, an equal
 * specificity that would leave this at the mercy of which sheet the browser
 * reads last. Naming the element — the media is always a figure, for video as
 * much as for an image — settles it without an !important or a doubled class.
 */
.wp-block-media-text > figure.wp-block-media-text__media {
	margin-inline-start: calc(-1 * var(--kg-media-text-bleed));
}

.wp-block-media-text.has-media-on-the-right
	> figure.wp-block-media-text__media {
	margin-inline-start: 0;
	margin-inline-end: calc(-1 * var(--kg-media-text-bleed));
}

/*
 * Stacked: one full-width column, so the media bleeds both ways and the text
 * underneath keeps the content width.
 *
 * The three declarations that collapse the grid are core's own, restated at this
 * theme's threshold rather than core's — between `600px` and `72rem` core still
 * draws two columns, and nothing in its stylesheet can be reached to move that.
 * `!important` on the columns for core's reason, which is worth repeating
 * because it looks gratuitous: touching the Media width control writes
 * `grid-template-columns` as an *inline* style, and nothing but `!important`
 * beats one.
 *
 * **Core's `padding: 0 8%` on the text comes off.** It is the gutter between the
 * copy and the media beside it, and stacked there is no media beside it — but it
 * is a percentage of the *block*, so it keeps charging for a gutter that is not
 * there: 8% of a 375px window is 26px a side, which turns a 327px rail into a
 * 275px measure and re-wraps every heading written against the phone frame. The
 * rail's own gutter is already in `contentSize`/`wideSize`; this was a second
 * one on top of it.
 */
@media (width <= 72rem) {
	.wp-block-media-text.is-stacked-on-mobile {
		--kg-media-text-bleed-total: calc(2 * var(--kg-media-text-bleed));

		grid-template-columns: 100% !important;
	}

	.wp-block-media-text.is-stacked-on-mobile
		> figure.wp-block-media-text__media,
	.wp-block-media-text.is-stacked-on-mobile.has-media-on-the-right
		> figure.wp-block-media-text__media {
		grid-column: 1;
		grid-row: 1;
		margin-inline: calc(-1 * var(--kg-media-text-bleed));
	}

	.wp-block-media-text.is-stacked-on-mobile > .wp-block-media-text__content {
		grid-column: 1;
		grid-row: 2;
		padding-inline: 0;
	}
}

/*
 * Border radius, moved onto the media.
 *
 * Core's border support writes the radius as an inline style on the block
 * wrapper, where there is nothing to round: the wrapper is a bare grid, so the
 * control appears to do nothing at all. `inherit` hands the computed value down
 * to the figure and from there to the image, which is the box anyone rounding a
 * Media & Text block means. The wrapper keeps its own radius rather than having
 * it zeroed, so a block that does carry a background or a border still rounds
 * with it — and that is also what the two rules below have to inherit from.
 *
 * On the media element rather than by clipping the figure: the editor puts the
 * resize handles inside that figure, half of each one hanging over the edge, and
 * an `overflow: clip` would slice them off.
 */
.wp-block-media-text > figure.wp-block-media-text__media,
.wp-block-media-text > figure.wp-block-media-text__media :is(img, video) {
	border-radius: inherit;
}

/*
 * Media aspect ratio — the "Media aspect ratio" control in the Dimensions panel,
 * added by src/editor/filters/media-text-aspect-ratio.js. That file stores the
 * ratio and hands it over as a custom property on the wrapper; where it lands is
 * decided here, and it depends on whether the media is cropped.
 *
 * Uncropped, the media is whatever shape the file is, at every width. The ratio
 * goes on the media element itself, with `object-fit` so a ratio that disagrees
 * with the file crops instead of stretching it.
 */
.wp-block-media-text.kg-has-media-aspect-ratio:not(.is-image-fill-element)
	> figure.wp-block-media-text__media
	:is(img, video) {
	aspect-ratio: var(--kg-media-text-aspect-ratio);
	object-fit: cover;
}

/*
 * Cropped, and still in two columns: the media is matched to the height of the
 * text beside it, which is the whole point of "Crop image to fill". A ratio
 * would only fight it, so it stays out.
 *
 * Cropped and stacked: there is no text beside it any more, and core falls back
 * to a hardcoded `min-height: 250px` — which is on `is-image-fill-element` at
 * every width, and was only ever hidden by the text being taller. That is the
 * number the ratio replaces, and the floor has to go with it, or a wide ratio on
 * a narrow screen is silently held at 250px. The `kg-has-media-aspect-ratio`
 * class is what keeps that `min-height: 0` away from every block that has no
 * ratio set: CSS cannot ask whether a custom property exists.
 */
@media (width <= 72rem) {
	.wp-block-media-text.kg-has-media-aspect-ratio.is-image-fill-element.is-stacked-on-mobile
		> figure.wp-block-media-text__media {
		aspect-ratio: var(--kg-media-text-aspect-ratio);
		min-height: 0;
	}
}

/*
 * Editor only.
 *
 * On the front end the figure is a stretched grid item, so the negative margin
 * widens it: used width is the grid area minus the margins. In the editor it is
 * not — MediaContainer wraps the media in a ResizableBox, which writes
 * `width: 50%; max-width: 100%` as an *inline* style. The margin then only slides
 * the figure towards the edge at its original width, leaving a gap between the
 * media and the text that the front end does not have. Nothing but !important
 * beats an inline style, so: !important, on a class only the editor has.
 *
 * The Media width handle keeps working, for two reasons worth writing down
 * before anyone is tempted to make this rule conditional. The handle sits on the
 * media's *inner* edge and the bleed only ever grows the outer one, so it stays
 * exactly where it would otherwise be. And dragging it calls onWidthChange on
 * every tick, which re-renders the block's `grid-template-columns` from the
 * in-progress width — so the grid area, and with it the `100%` below, follows
 * the cursor live.
 */
.block-editor-block-list__block.wp-block-media-text
	> figure.wp-block-media-text__media {
	inline-size: calc(100% + var(--kg-media-text-bleed-total)) !important;
	max-inline-size: none !important;
}
