/* stylelint-disable selector-class-pattern, selector-max-specificity --
 * The selectors below are WooCommerce's and selectWoo's own markup, quoted
 * verbatim (snake_case and BEM modifiers included). Renaming them to our
 * conventions would simply stop matching.
 */

/*
 * Native form fields in a WooCommerce context.
 *
 * Astra Pro ships `.woocommerce select:focus, .woocommerce-page select:focus
 * { outline: 0 }` (specificity 0-2-1) in woocommerce-grid.css, and
 * astra-addon-css is enqueued *after* this plugin - so the generic
 * `select:focus-visible` (0-1-1) in astra-focus-visible.css loses twice over
 * and the variation dropdowns end up with no focus ring at all. Verified in
 * Chromium against Astra Pro 4.13.
 *
 * Anchoring on `body` lifts these to 0-2-2, which wins on specificity alone
 * and therefore does not depend on enqueue order. Still no !important, so a
 * project can override it.
 */
body.woocommerce select:focus-visible,
body.woocommerce input:focus-visible,
body.woocommerce textarea:focus-visible,
body.woocommerce-page select:focus-visible,
body.woocommerce-page input:focus-visible,
body.woocommerce-page textarea:focus-visible,
body .woocommerce select:focus-visible,
body .woocommerce input:focus-visible,
body .woocommerce textarea:focus-visible {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentcolor);
	outline-offset: var(--ls-focus-width, 3px);
	box-shadow: 0 0 0 var(--ls-focus-width, 3px) var(--ls-focus-backdrop, transparent);
}

/*
 * Focus visibility on WooCommerce controls that need more than the generic
 * rule (WCAG 2.4.7).
 *
 * Select2/selectWoo replaces the country and state selects with a div plus a
 * separate search input. Neither carries a focus style of its own, and
 * projects tend to style only [aria-expanded="true"], which is a different
 * state than "focused".
 */

.select2-container--default .select2-selection--single:focus,
.select2-container--default .select2-selection--single:focus-visible,
.select2-container--default.select2-container--open .select2-selection--single,
.select2-container--default .select2-search__field:focus,
.select2-container--default .select2-search__field:focus-visible {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentColor);
	outline-offset: var(--ls-focus-width, 3px);
	box-shadow: 0 0 0 var(--ls-focus-width, 3px) var(--ls-focus-backdrop, transparent);
}

/*
 * The highlighted result is the keyboard equivalent of hover. Without a
 * visible marker there is no way to tell what Enter would select - and it is
 * also the state our Tab guard keys off.
 */
.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted[data-selected] {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentColor);
	outline-offset: calc(var(--ls-focus-width, 3px) * -1);
}

/*
 * Payment methods and shipping options are native radios, but the label is
 * the visible target - so the label has to show the focus too.
 */
ul.payment_methods input[type="radio"]:focus-visible + label,
ul.woocommerce-shipping-methods input[type="radio"]:focus-visible + label,
.woocommerce-checkout input[type="checkbox"]:focus-visible + label,
.woocommerce-checkout input[type="checkbox"]:focus-visible + span {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentColor);
	outline-offset: var(--ls-focus-width, 3px);
	box-shadow: 0 0 0 var(--ls-focus-width, 3px) var(--ls-focus-backdrop, transparent);
}

/*
 * Cart icon links have font-size: 0 and a background image, so there is no
 * text box for a ring to hug. The ring is drawn on the element box instead,
 * with no offset so it stays inside the surrounding layout.
 */
.woocommerce-cart table.shop_table td.product-remove a:focus-visible,
.vrn_variation_toggle:focus-visible {
	outline-offset: 0;
}

/*
 * Two third-party rules zero the outline out from under the base rule above,
 * and neither of them is a :focus rule, so raising specificity is the only way
 * back. Both were measured to leave the element with outline-style: none while
 * :focus-visible matched.
 *
 * - Astra Addon prints `.woocommerce-js .quantity .minus, … .plus { outline: 0 }`
 *   inline (0-3-0), beating `a:focus-visible` (0-1-1).
 * - WooCommerce's own woocommerce-grid.min.css has
 *   `.woocommerce-js form .form-row textarea { outline: 0 }` (0-2-2), which ties
 *   with `body.woocommerce textarea:focus-visible` and wins on load order.
 */
.woocommerce-js .quantity .minus:focus-visible,
.woocommerce-js .quantity .plus:focus-visible,
.woocommerce .quantity .minus:focus-visible,
.woocommerce .quantity .plus:focus-visible,
.woocommerce-js form .form-row textarea:focus-visible,
.woocommerce-js form .form-row input.input-text:focus-visible {
	/*
	 * Ring only, no outline-offset. This selector is 0-3-3 and would otherwise
	 * outrank a project's own placement rule - it did, and pushed the checkout
	 * fields to an outside ring the project had not asked for.
	 */
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentcolor);
}

/*
 * The quantity number input: WooCommerce's own grid stylesheet has
 * `.woocommerce-js .quantity input[type="number"]:focus { outline: 0 }` at
 * 0-4-1, which outranks every element- and class-level rule here and left the
 * field with Astra's 1px dotted *border* as its only focus cue. The `body`
 * prefix buys the one point needed to win.
 */
/*
 * The country dropdown is replaced by selectWoo, so the element that actually
 * takes focus is `span.select2-selection[tabindex=0]` - and WooCommerce's grid
 * stylesheet zeroes its outline with
 * `.woocommerce .select2-container .select2-selection--single:focus` (0-4-0),
 * which outranks the Select2 block further up (0-3-0). The `body` prefix is
 * what tips it.
 */
body .woocommerce .select2-container .select2-selection--single:focus,
body .woocommerce .select2-container .select2-selection--single:focus-visible,
body .woocommerce .select2-container--open .select2-selection--single {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentcolor);
	outline-offset: 0;
}

body.woocommerce-js .quantity input[type="number"]:focus-visible,
body.woocommerce .quantity input[type="number"]:focus-visible,
body .woocommerce-js .quantity input[type="number"]:focus-visible,
body .woocommerce .quantity input[type="number"]:focus-visible {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentcolor);
	outline-offset: 0;
}

/*
 * The quantity controls sit flush against each other and against the input, so
 * an offset ring would be drawn underneath its neighbour. Keep it on the border
 * box and lift it above the neighbour.
 *
 * Do NOT set `position` here. Astra positions these two anchors absolutely, and
 * overriding that on :focus re-runs their layout - measured: the control became
 * 7.7px taller and shifted its neighbour the moment it took focus. z-index
 * applies to the absolutely positioned element as it is.
 */
.woocommerce-js .quantity .minus:focus-visible,
.woocommerce-js .quantity .plus:focus-visible,
.woocommerce .quantity .minus:focus-visible,
.woocommerce .quantity .plus:focus-visible {
	outline-offset: 0;
	z-index: 4;
}

/*
 * The "clear selection" link is reset with `all: initial` at 0-4-2:
 * `.woocommerce-js div.product form.cart .reset_variations { all: initial; … }`
 * (Astra's woocommerce-grid). `all` drops the outline along with everything
 * else, and no element- or class-level rule can outrank that selector - the
 * link had no ring at all once a variation made it visible.
 */
.woocommerce-js div.product form.cart .reset_variations:focus-visible,
.woocommerce div.product form.cart .reset_variations:focus-visible {
	outline: var(--ls-focus-width, 3px) var(--ls-focus-style, solid) var(--ls-focus-ring, currentcolor);
	outline-offset: 0;
}
