/**
 * Stretched Links — front-end mechanics.
 *
 * Expands one link inside a container block so its clickable area covers the
 * whole container (the Bootstrap "stretched link" pattern).
 *
 * Every rule is scoped to .yoko-link-container on purpose: an unscoped overlay
 * would escape to whatever ancestor happened to be positioned — up to the page
 * itself — so a link marked as stretched with no container ancestor stays an
 * ordinary link instead of hijacking the page.
 *
 * Nothing in this file makes a visual decision. Themes own the affordance and
 * style .yoko-link-container:hover themselves.
 *
 * DEBUG: view source and search for "yoko-link-container" and
 * "yoko-stretched-link". Both classes present but the container is not
 * clickable usually means the theme has overridden position on the container,
 * or a closer descendant became the containing block. The positioned case is
 * handled below; a descendant carrying a transform or a filter is not, and
 * shows up in DevTools as the overlay's box matching that element rather than
 * the container.
 */

.yoko-link-container {
	position: relative;
}

.yoko-link-container .yoko-stretched-link::after {
	content: "";
	inset: 0;
	position: absolute;
	z-index: 1;
}

/*
 * WHY: an absolutely positioned overlay stretches to its nearest *positioned*
 * ancestor, and core positions more elements than it looks like. This one rule
 * ships with every theme —
 *
 *   :where( .wp-block-group.wp-block-group-is-layout-constrained ) {
 *     position: relative;
 *   }
 *
 * — and constrained is the default group layout. So the ordinary way to build a
 * card, an outer group marked as the container holding an inner group for the
 * padded content, put a positioned element between the link and the container:
 * the click area stopped at the inner group and the container's own padding was
 * dead. Measured on that shape, one of five points across the card activated
 * the link, and the four in the padding did nothing.
 *
 * So the elements between the link and its container are taken out of the
 * running. `:has()` selects exactly that chain — a descendant of the container
 * that contains the link — and nothing else, so a sibling group that is
 * positioned for its own reasons keeps its positioning.
 *
 * Two things this cannot do anything about, both documented:
 *
 * - A `transform`, `filter`, `backdrop-filter`, `perspective`, `contain` or
 *   `will-change` on an intermediate element also makes it the containing
 *   block, and unsetting any of those would change what the page looks like.
 *   Put hover transforms on the container itself, not on a wrapper inside it.
 * - An intermediate wrapper that needs its own positioning — an absolutely
 *   placed badge, a sticky header — can opt out with `yoko-link-keep-position`,
 *   and the click area then stops at that wrapper by choice rather than by
 *   accident.
 *
 * Browsers without `:has()` drop the rule and get the old behavior, which is
 * the right way to fail: no worse than before, never broken differently.
 */
.yoko-link-container :has( .yoko-stretched-link ):not( .yoko-link-container, .yoko-link-keep-position ) {
	position: static;
}

/*
 * WHY: the overlay covers the whole container, which makes every other
 * interactive element inside it unclickable. Lifting them back above it is
 * load-bearing, not defensive — cards routinely hold linked taxonomy terms,
 * icon buttons and form controls.
 */
.yoko-link-container :is( a, button, details, input, label, select, summary, textarea, [tabindex] ):not( .yoko-stretched-link ) {
	position: relative;
	z-index: 2;
}

/*
 * WHY: embeds get stacking order only, never position. Core's responsive embed
 * wrapper absolutely positions the iframe inside a padding-ratio box, so
 * setting position here would collapse that layout. z-index alone is ignored
 * on anything still static, which makes this safe either way.
 */
.yoko-link-container :is( iframe, video, audio ) {
	z-index: 2;
}

/*
 * WHY: focus lands on an invisible overlay, so a browser draws its ring around
 * the link text while the real hit area is the whole container. The default
 * ring is replaced — never simply removed — with one traced around the overlay
 * itself. Inset so an ancestor with overflow: hidden cannot clip it, and
 * currentcolor so it inherits the theme's own colors rather than inventing any.
 */
.yoko-link-container .yoko-stretched-link:focus-visible {
	outline: none;
}

.yoko-link-container .yoko-stretched-link:focus-visible::after {
	outline: 2px solid currentcolor;
	outline-offset: -2px;
}
