/**
 * Block Hover — Effects + Hover Colors.
 *
 * 59 button effects target .wp-block-button.has-hover-{slug} .wp-block-button__link;
 * container effects target .wp-block-{group|column}.has-hover-{slug} directly.
 * Structural setup folded into each effect so effect-less buttons pay zero cost.
 * Per-style defaults + sentinel gate documented at PER-STYLE DEFAULTS below.
 * Hover-bg reads var(--le-hover-bg, var(--hover-bg, preset)); rainbow (Group N) hardcodes.
 */

/* ============================================================
   Shared transition baseline — buttons with a has-hover-* class, plus the 10
   named styles with no such class (so per-style default hovers animate smoothly).
   ============================================================ */
.wp-block-button[class*="has-hover-"] > .wp-block-button__link,
.wp-block-button:is(
	.is-style-solid,
	.is-style-ghost,
	.is-style-pill,
	.is-style-brutal,
	.is-style-slanted,
	.is-style-3d-press,
	.is-style-soft,
	.is-style-dashed,
	.is-style-asymmetric,
	.is-style-editorial
):not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link {
	position: relative;
	transition:
		transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
		background-color 0.45s ease,
		color 0.35s ease,
		box-shadow 0.45s ease,
		border-radius 0.45s ease,
		letter-spacing 0.35s ease,
		top 0.15s ease,
		opacity 0.35s ease,
		padding 0.35s ease,
		filter 0.35s ease;
}

/* ============================================================
   GROUP A — Translation
   ============================================================ */
.wp-block-button.has-hover-fx-lift > .wp-block-button__link:hover {
	transform: translateY(-6px);
	box-shadow: 0 14px 28px -10px rgba(0, 0, 0, 0.45);
}

/* Subtle 1–2px lift, distinct from the larger fx-lift. Used as Solid's default. */
.wp-block-button.has-hover-fx-lift-soft > .wp-block-button__link:hover {
	transform: translateY(-2px);
	filter: brightness(0.92);
}

.wp-block-button.has-hover-fx-push > .wp-block-button__link:hover {
	transform: translateY(6px);
	box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}

.wp-block-button.has-hover-fx-slide-l > .wp-block-button__link:hover {
	transform: translateX(-6px);
	box-shadow: 8px 0 18px -8px rgba(0, 0, 0, 0.35);
}

.wp-block-button.has-hover-fx-slide-r > .wp-block-button__link:hover {
	transform: translateX(6px);
	box-shadow: -8px 0 18px -8px rgba(0, 0, 0, 0.35);
}

/* Padding-based shift (no transform), for text-link buttons (Editorial). On
   buttons with non-zero padding-right at rest it reads as a shrink, not a shift. */
.wp-block-button.has-hover-fx-shift-r > .wp-block-button__link:hover {
	padding-right: 0.5em;
}

/* ============================================================
   GROUP B — Scale & Zoom
   ============================================================ */
.wp-block-button.has-hover-fx-zoom-in > .wp-block-button__link:hover {
	transform: scale(1.08);
}

.wp-block-button.has-hover-fx-zoom-out > .wp-block-button__link:hover {
	transform: scale(0.92);
}

.wp-block-button.has-hover-fx-stretch-x > .wp-block-button__link:hover {
	transform: scaleX(1.12);
}

.wp-block-button.has-hover-fx-stretch-y > .wp-block-button__link:hover {
	transform: scaleY(1.18);
}

/* ============================================================
   GROUP C — Rotate & Skew
   ============================================================ */
.wp-block-button.has-hover-fx-rot-cw > .wp-block-button__link:hover {
	transform: rotate(2.5deg);
}

.wp-block-button.has-hover-fx-rot-ccw > .wp-block-button__link:hover {
	transform: rotate(-2.5deg);
}

.wp-block-button.has-hover-fx-skew-r > .wp-block-button__link:hover {
	transform: skewX(-8deg);
}

.wp-block-button.has-hover-fx-skew-l > .wp-block-button__link:hover {
	transform: skewX(8deg);
}

/* ============================================================
   GROUP D — 3D Perspective (perspective added to the .wp-block-button wrapper)
   ============================================================ */
.wp-block-button[class*="has-hover-fx-3d-"] {
	perspective: 700px;
}

.wp-block-button.has-hover-fx-3d-r > .wp-block-button__link:hover {
	transform: rotateY(18deg);
}

.wp-block-button.has-hover-fx-3d-l > .wp-block-button__link:hover {
	transform: rotateY(-18deg);
}

.wp-block-button.has-hover-fx-3d-up > .wp-block-button__link:hover {
	transform: rotateX(18deg);
}

.wp-block-button.has-hover-fx-3d-down > .wp-block-button__link:hover {
	transform: rotateX(-18deg);
}

/* ============================================================
   GROUP E — Press & Depth
   ============================================================ */
.wp-block-button.has-hover-fx-press > .wp-block-button__link {
	box-shadow:
		0 4px 0 0 var(--wp--preset--color--ink),
		0 6px 14px -4px rgba(0, 0, 0, 0.4);
	top: 0;
}

.wp-block-button.has-hover-fx-press > .wp-block-button__link:hover {
	top: 4px;
	box-shadow:
		0 0 0 0 var(--wp--preset--color--ink),
		0 1px 3px rgba(0, 0, 0, 0.25);
}

.wp-block-button.has-hover-fx-lift-shadow > .wp-block-button__link:hover {
	transform: translateY(-3px);
	box-shadow:
		0 24px 40px -16px rgba(0, 0, 0, 0.55),
		0 6px 12px -6px rgba(0, 0, 0, 0.3);
}

/* Lift + colored halo (shadow from primary via color-mix). Used as Pill's default. */
.wp-block-button.has-hover-fx-lift-glow > .wp-block-button__link:hover {
	transform: translateY(-3px);
	box-shadow:
		0 12px 24px -8px color-mix(in srgb, var(--wp--preset--color--primary) 60%, transparent),
		0 6px 14px -10px color-mix(in srgb, var(--wp--preset--color--primary) 35%, transparent);
}

/* ============================================================
   GROUP F — Background Directional Swipe
   8 directions use a ::before overlay revealing --hover-bg (default accent).
   isolation:isolate makes a stacking context so the ::before's z-index:-1 sits
   behind the text yet inside the button — no extra markup.
   ============================================================ */
.wp-block-button[class*="has-hover-fx-bg-"] > .wp-block-button__link {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.wp-block-button[class*="has-hover-fx-bg-"]:not(.has-hover-fx-bg-split):not(.has-hover-fx-bg-clamp) > .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: -1;
	transition: transform 0.55s cubic-bezier(0.7, 0, 0.2, 1);
}

/* From left */
.wp-block-button.has-hover-fx-bg-l > .wp-block-button__link::before {
	transform: translateX(-101%);
}
.wp-block-button.has-hover-fx-bg-l > .wp-block-button__link:hover::before {
	transform: translateX(0);
}

/* From right */
.wp-block-button.has-hover-fx-bg-r > .wp-block-button__link::before {
	transform: translateX(101%);
}
.wp-block-button.has-hover-fx-bg-r > .wp-block-button__link:hover::before {
	transform: translateX(0);
}

/* From top */
.wp-block-button.has-hover-fx-bg-t > .wp-block-button__link::before {
	transform: translateY(-101%);
}
.wp-block-button.has-hover-fx-bg-t > .wp-block-button__link:hover::before {
	transform: translateY(0);
}

/* From bottom */
.wp-block-button.has-hover-fx-bg-b > .wp-block-button__link::before {
	transform: translateY(101%);
}
.wp-block-button.has-hover-fx-bg-b > .wp-block-button__link:hover::before {
	transform: translateY(0);
}

/* From top-left */
.wp-block-button.has-hover-fx-bg-tl > .wp-block-button__link::before {
	transform: translate(-101%, -101%);
}
.wp-block-button.has-hover-fx-bg-tl > .wp-block-button__link:hover::before {
	transform: translate(0, 0);
}

/* From top-right */
.wp-block-button.has-hover-fx-bg-tr > .wp-block-button__link::before {
	transform: translate(101%, -101%);
}
.wp-block-button.has-hover-fx-bg-tr > .wp-block-button__link:hover::before {
	transform: translate(0, 0);
}

/* From bottom-left */
.wp-block-button.has-hover-fx-bg-bl > .wp-block-button__link::before {
	transform: translate(-101%, 101%);
}
.wp-block-button.has-hover-fx-bg-bl > .wp-block-button__link:hover::before {
	transform: translate(0, 0);
}

/* From bottom-right */
.wp-block-button.has-hover-fx-bg-br > .wp-block-button__link::before {
	transform: translate(101%, 101%);
}
.wp-block-button.has-hover-fx-bg-br > .wp-block-button__link:hover::before {
	transform: translate(0, 0);
}

/* ============================================================
   GROUP G — Background Radial & Reveal
   Iris reuses Group F's ::before; curtain uses its own ::before + ::after pair.
   ============================================================ */

/* Iris open — hover-bg circle scales up from center, corners square out as it grows */
.wp-block-button.has-hover-fx-bg-iris-out > .wp-block-button__link::before {
	border-radius: 50%;
	transform: scale(0);
	transform-origin: center;
	transition:
		transform 0.6s cubic-bezier(0.7, 0, 0.2, 1),
		border-radius 0.4s ease 0.2s;
}
.wp-block-button.has-hover-fx-bg-iris-out > .wp-block-button__link:hover::before {
	transform: scale(2.6);
	border-radius: 0;
}

/* Iris close — hover-bg covers all, recedes to a center circle on hover
   (button's own background shows through). Inverse of iris-out. */
.wp-block-button.has-hover-fx-bg-iris-in > .wp-block-button__link::before {
	transform: scale(1);
	transform-origin: center;
	border-radius: 0;
	transition:
		transform 0.55s cubic-bezier(0.7, 0, 0.2, 1),
		border-radius 0.4s ease;
}
.wp-block-button.has-hover-fx-bg-iris-in > .wp-block-button__link:hover::before {
	transform: scale(0);
	border-radius: 50%;
}

/* Curtain part — two hover-bg halves slide in from top and bottom, meeting on hover. */
.wp-block-button.has-hover-fx-bg-split > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bg-split > .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 50%;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: -1;
	transition: transform 0.55s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-bg-split > .wp-block-button__link::before {
	top: 0;
	transform: translateY(-101%);
}
.wp-block-button.has-hover-fx-bg-split > .wp-block-button__link::after {
	bottom: 0;
	transform: translateY(101%);
}
.wp-block-button.has-hover-fx-bg-split > .wp-block-button__link:hover::before,
.wp-block-button.has-hover-fx-bg-split > .wp-block-button__link:hover::after {
	transform: translateY(0);
}

/* Curtain close — two hover-bg halves slide in from left and right, meeting on hover. */
.wp-block-button.has-hover-fx-bg-clamp > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bg-clamp > .wp-block-button__link::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: 50%;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: -1;
	transition: transform 0.55s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-bg-clamp > .wp-block-button__link::before {
	left: 0;
	transform: translateX(-101%);
}
.wp-block-button.has-hover-fx-bg-clamp > .wp-block-button__link::after {
	right: 0;
	transform: translateX(101%);
}
.wp-block-button.has-hover-fx-bg-clamp > .wp-block-button__link:hover::before,
.wp-block-button.has-hover-fx-bg-clamp > .wp-block-button__link:hover::after {
	transform: translateX(0);
}

/* ============================================================
   GROUP — Background Fill (cross-fade)
   background-color cross-fades to --hover-bg (default text color), text flips to
   background for contrast. Used as Ghost's and Dashed's default.
   ============================================================ */
.wp-block-button.has-hover-fx-fill > .wp-block-button__link:hover {
	background-color: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--ink)));
	color: var(--wp--preset--color--background);
}

/* ============================================================
   GROUP H — Border Edges
   Horizontal and vertical edge lines that grow from one side.
   ============================================================ */
.wp-block-button[class*="has-hover-fx-bd-"] > .wp-block-button__link {
	overflow: hidden;
	isolation: isolate;
}

/* Edges from left — top + bottom edge lines grow rightward */
.wp-block-button.has-hover-fx-bd-l > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bd-l > .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 2px;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: 2;
	transform-origin: left;
	transform: scaleX(0);
	transition: transform 0.5s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-bd-l > .wp-block-button__link::before { top: 0; }
.wp-block-button.has-hover-fx-bd-l > .wp-block-button__link::after { bottom: 0; }
.wp-block-button.has-hover-fx-bd-l > .wp-block-button__link:hover::before,
.wp-block-button.has-hover-fx-bd-l > .wp-block-button__link:hover::after {
	transform: scaleX(1);
}

/* Edges from right */
.wp-block-button.has-hover-fx-bd-r > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bd-r > .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 2px;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: 2;
	transform-origin: right;
	transform: scaleX(0);
	transition: transform 0.5s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-bd-r > .wp-block-button__link::before { top: 0; }
.wp-block-button.has-hover-fx-bd-r > .wp-block-button__link::after { bottom: 0; }
.wp-block-button.has-hover-fx-bd-r > .wp-block-button__link:hover::before,
.wp-block-button.has-hover-fx-bd-r > .wp-block-button__link:hover::after {
	transform: scaleX(1);
}

/* Edges from top — left + right edge lines grow downward */
.wp-block-button.has-hover-fx-bd-t > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bd-t > .wp-block-button__link::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: 2px;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: 2;
	transform-origin: top;
	transform: scaleY(0);
	transition: transform 0.5s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-bd-t > .wp-block-button__link::before { left: 0; }
.wp-block-button.has-hover-fx-bd-t > .wp-block-button__link::after { right: 0; }
.wp-block-button.has-hover-fx-bd-t > .wp-block-button__link:hover::before,
.wp-block-button.has-hover-fx-bd-t > .wp-block-button__link:hover::after {
	transform: scaleY(1);
}

/* Edges from bottom */
.wp-block-button.has-hover-fx-bd-b > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bd-b > .wp-block-button__link::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: 2px;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: 2;
	transform-origin: bottom;
	transform: scaleY(0);
	transition: transform 0.5s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-bd-b > .wp-block-button__link::before { left: 0; }
.wp-block-button.has-hover-fx-bd-b > .wp-block-button__link::after { right: 0; }
.wp-block-button.has-hover-fx-bd-b > .wp-block-button__link:hover::before,
.wp-block-button.has-hover-fx-bd-b > .wp-block-button__link:hover::after {
	transform: scaleY(1);
}

/* Border draw — two L-shaped pseudo elements grow to form a full border */
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link {
	overflow: visible;
	background: transparent;
	color: var(--wp--preset--color--ink);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--ink) 12%, transparent);
}
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link::before,
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link::after {
	content: "";
	position: absolute;
	pointer-events: none;
	border: 1.5px solid var(--wp--preset--color--ink);
	width: 0;
	height: 0;
	transition:
		width 0.25s ease,
		height 0.25s ease 0.25s;
}
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link::before {
	top: -1px;
	left: -1px;
	border-right: 0;
	border-bottom: 0;
}
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link::after {
	bottom: -1px;
	right: -1px;
	border-left: 0;
	border-top: 0;
}
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link:hover::before {
	width: calc(100% + 2px);
	height: calc(100% + 2px);
}
.wp-block-button.has-hover-fx-bd-draw > .wp-block-button__link:hover::after {
	width: calc(100% + 2px);
	height: calc(100% + 2px);
	transition:
		width 0.25s ease 0.5s,
		height 0.25s ease 0.75s;
}

/* Outline grow — soft outline expands outward */
.wp-block-button.has-hover-fx-bd-thick > .wp-block-button__link {
	box-shadow: 0 0 0 0 var(--wp--preset--color--ink);
	transition: box-shadow 0.35s ease;
}
.wp-block-button.has-hover-fx-bd-thick > .wp-block-button__link:hover {
	box-shadow: 0 0 0 4px var(--wp--preset--color--ink);
}

/* ============================================================
   GROUP — Shape (radius flip) — diagonal radius flip + bg swap to --hover-bg.
   Asymmetric's default. On uniform-corner buttons the flip is invisible; only the bg swap shows.
   ============================================================ */
.wp-block-button.has-hover-fx-radius-flip > .wp-block-button__link:hover {
	border-radius: 4px 22px 4px 22px;
	background-color: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
}

/* ============================================================
   GROUP I — Shine Sweep
   Diagonal/linear gradient sweeps across button on hover.
   ============================================================ */
.wp-block-button[class*="has-hover-fx-shine-"] > .wp-block-button__link {
	overflow: hidden;
	isolation: isolate;
}

.wp-block-button.has-hover-fx-shine-r > .wp-block-button__link::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: -120%;
	width: 120%;
	background: linear-gradient(
		120deg,
		transparent 30%,
		rgba(255, 255, 255, 0.55) 50%,
		transparent 70%
	);
	z-index: 1;
	pointer-events: none;
	transition: transform 0.9s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.wp-block-button.has-hover-fx-shine-r > .wp-block-button__link:hover::before {
	transform: translateX(200%);
}

.wp-block-button.has-hover-fx-shine-l > .wp-block-button__link::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	right: -120%;
	width: 120%;
	background: linear-gradient(
		-120deg,
		transparent 30%,
		rgba(255, 255, 255, 0.55) 50%,
		transparent 70%
	);
	z-index: 1;
	pointer-events: none;
	transition: transform 0.9s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.wp-block-button.has-hover-fx-shine-l > .wp-block-button__link:hover::before {
	transform: translateX(-200%);
}

.wp-block-button.has-hover-fx-shine-d > .wp-block-button__link::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -120%;
	height: 120%;
	background: linear-gradient(
		180deg,
		transparent 30%,
		rgba(255, 255, 255, 0.55) 50%,
		transparent 70%
	);
	z-index: 1;
	pointer-events: none;
	transition: transform 0.9s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.wp-block-button.has-hover-fx-shine-d > .wp-block-button__link:hover::before {
	transform: translateY(200%);
}

.wp-block-button.has-hover-fx-shine-u > .wp-block-button__link::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -120%;
	height: 120%;
	background: linear-gradient(
		0deg,
		transparent 30%,
		rgba(255, 255, 255, 0.55) 50%,
		transparent 70%
	);
	z-index: 1;
	pointer-events: none;
	transition: transform 0.9s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.wp-block-button.has-hover-fx-shine-u > .wp-block-button__link:hover::before {
	transform: translateY(-200%);
}

/* ============================================================
   GROUP J — Glow
   ============================================================ */
.wp-block-button.has-hover-fx-glow-out > .wp-block-button__link {
	box-shadow: 0 0 0 0 transparent;
	transition: box-shadow 0.45s ease;
}
.wp-block-button.has-hover-fx-glow-out > .wp-block-button__link:hover {
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--wp--preset--color--primary) 40%, transparent),
		0 0 28px 4px color-mix(in srgb, var(--wp--preset--color--primary) 55%, transparent),
		0 0 60px 10px color-mix(in srgb, var(--wp--preset--color--primary) 25%, transparent);
}

.wp-block-button.has-hover-fx-glow-in > .wp-block-button__link {
	overflow: hidden;
	isolation: isolate;
}
.wp-block-button.has-hover-fx-glow-in > .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: radial-gradient(
		120% 80% at 50% 50%,
		rgba(255, 255, 255, 0.55) 0%,
		rgba(255, 255, 255, 0) 60%
	);
	opacity: 0;
	transition: opacity 0.4s ease;
	z-index: 1;
}
.wp-block-button.has-hover-fx-glow-in > .wp-block-button__link:hover::before {
	opacity: 1;
}

/* Ambient shadow via filter:drop-shadow so it's additive — composes with the
   host style's resting box-shadow instead of replacing it. Soft's default. */
.wp-block-button.has-hover-fx-shadow-grow > .wp-block-button__link:hover {
	filter: drop-shadow(0 14px 18px rgba(0, 0, 0, 0.18));
}

/* ============================================================
   GROUP K — Text Swap
   A ::before pseudo-element holds the hover text (--hover-text-content) — no markup
   injection, so it works identically in editor and front end. Empty text = slide out/back.
   ============================================================ */
.wp-block-button[class*="has-hover-fx-tx-"] > .wp-block-button__link {
	overflow: hidden;
	isolation: isolate;
}

.wp-block-button[class*="has-hover-fx-tx-"] > .wp-block-button__link::before {
	content: var(--hover-text-content, "");
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: inherit;
	pointer-events: none;
	transition: transform 0.45s cubic-bezier(0.7, 0, 0.2, 1),
		opacity 0.25s ease 0.15s;
}

/* Swap up — original text fades, hover text rises from below */
.wp-block-button.has-hover-fx-tx-up > .wp-block-button__link::before {
	transform: translateY(100%);
}
.wp-block-button.has-hover-fx-tx-up > .wp-block-button__link:hover::before {
	transform: translateY(0);
}
.wp-block-button.has-hover-fx-tx-up > .wp-block-button__link:hover {
	color: transparent;
}

/* Swap down — original text fades, hover text descends from above */
.wp-block-button.has-hover-fx-tx-down > .wp-block-button__link::before {
	transform: translateY(-100%);
}
.wp-block-button.has-hover-fx-tx-down > .wp-block-button__link:hover::before {
	transform: translateY(0);
}
.wp-block-button.has-hover-fx-tx-down > .wp-block-button__link:hover {
	color: transparent;
}

/* Swap left — original text fades, hover text comes from the right */
.wp-block-button.has-hover-fx-tx-left > .wp-block-button__link::before {
	transform: translateX(120%);
}
.wp-block-button.has-hover-fx-tx-left > .wp-block-button__link:hover::before {
	transform: translateX(0);
}
.wp-block-button.has-hover-fx-tx-left > .wp-block-button__link:hover {
	color: transparent;
}

/* Swap right — original text fades, hover text comes from the left */
.wp-block-button.has-hover-fx-tx-right > .wp-block-button__link::before {
	transform: translateX(-120%);
}
.wp-block-button.has-hover-fx-tx-right > .wp-block-button__link:hover::before {
	transform: translateX(0);
}
.wp-block-button.has-hover-fx-tx-right > .wp-block-button__link:hover {
	color: transparent;
}

/* ============================================================
   GROUP L — Letter Spacing
   ============================================================ */
.wp-block-button.has-hover-fx-track-out > .wp-block-button__link:hover {
	letter-spacing: 0.22em;
}

.wp-block-button.has-hover-fx-track-in > .wp-block-button__link {
	letter-spacing: 0.22em;
}
.wp-block-button.has-hover-fx-track-in > .wp-block-button__link:hover {
	letter-spacing: 0.01em;
}

/* ============================================================
   GROUP M — Underline
   Animated underline that grows from a side or center.
   ============================================================ */
.wp-block-button.has-hover-fx-und-l > .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--ink);
	border-radius: 0;
	overflow: visible;
}
.wp-block-button.has-hover-fx-und-l > .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 4px;
	height: 2px;
	background: var(--wp--preset--color--ink);
	transform-origin: left;
	transform: scaleX(0);
	transition: transform 0.45s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-und-l > .wp-block-button__link:hover::after {
	transform: scaleX(1);
}

.wp-block-button.has-hover-fx-und-c > .wp-block-button__link {
	overflow: visible;
}
.wp-block-button.has-hover-fx-und-c > .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 4px;
	height: 2px;
	background: var(--wp--preset--color--ink);
	transform-origin: center;
	transform: scaleX(0);
	transition: transform 0.45s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.has-hover-fx-und-c > .wp-block-button__link:hover::after {
	transform: scaleX(1);
}

/* ============================================================
   GROUP N — Animated Rainbow Border
   ⚠️ DESIGN EXCEPTION (owner-approved): hardcoded gradient hex — "rainbow" has no
   semantic token equivalent. The ONLY non-token colors in the hover system.
   ============================================================ */
@keyframes theme-fx-rainbow-pan {
	to {
		background-position: -200% 0;
	}
}

@keyframes theme-fx-rainbow-pulse {
	0%, 100% { box-shadow: 0 0 14px 1px rgba(255, 91, 46, 0.55); }
	25%      { box-shadow: 0 0 14px 1px rgba(255, 225, 74, 0.55); }
	50%      { box-shadow: 0 0 14px 1px rgba(31, 138, 91, 0.55); }
	75%      { box-shadow: 0 0 14px 1px rgba(74, 108, 255, 0.55); }
}

.wp-block-button[class*="has-hover-fx-rb-"] > .wp-block-button__link {
	overflow: visible;
	isolation: auto;
}
.wp-block-button[class*="has-hover-fx-rb-"] > .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: -2px;
	border-radius: inherit;
	padding: 2px;
	background: linear-gradient(
		90deg,
		#ff5b2e, #ffe14a, #1f8a5b, #4a6cff, #c084fc, #ff5b2e
	);
	background-size: 200% 100%;
	-webkit-mask:
		linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask-composite: exclude;
	opacity: 0;
	pointer-events: none;
	z-index: 1;
	transition: opacity 0.3s ease;
}

/* Bottom rainbow — clip-path keeps only the bottom half */
.wp-block-button.has-hover-fx-rb-bot > .wp-block-button__link::before {
	clip-path: inset(50% -4px -4px -4px);
}
.wp-block-button.has-hover-fx-rb-bot > .wp-block-button__link:hover::before {
	opacity: 1;
	animation: theme-fx-rainbow-pan 2.4s linear infinite;
}

/* Top rainbow */
.wp-block-button.has-hover-fx-rb-top > .wp-block-button__link::before {
	clip-path: inset(-4px -4px 50% -4px);
}
.wp-block-button.has-hover-fx-rb-top > .wp-block-button__link:hover::before {
	opacity: 1;
	animation: theme-fx-rainbow-pan 2.4s linear infinite;
}

/* All-sides rainbow (with pulse) */
.wp-block-button.has-hover-fx-rb-all > .wp-block-button__link:hover::before {
	opacity: 1;
	animation: theme-fx-rainbow-pan 2.4s linear infinite;
}
.wp-block-button.has-hover-fx-rb-all > .wp-block-button__link:hover {
	animation: theme-fx-rainbow-pulse 3.2s linear infinite;
}

/* ============================================================
   PER-STYLE DEFAULTS
   Fire when a button uses one of the 10 named styles AND has no has-hover-* class.
   The :not([class*="has-hover-fx-"]):not(.has-hover-none) gate:
     - has-hover-{slug} → preset wins, default suppressed
     - has-hover-none   → default suppressed
     - empty hoverEffect → default applies
   Each mirrors its preset's :hover — update both together.
   ============================================================ */

/* Solid → fx-lift-soft */
.wp-block-button.is-style-solid:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	transform: translateY(-2px);
	filter: brightness(0.92);
}

/* Ghost → fx-fill (default --hover-bg = text color) */
.wp-block-button.is-style-ghost:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	background-color: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--ink)));
	color: var(--wp--preset--color--background);
}

/* Pill → fx-lift-glow */
.wp-block-button.is-style-pill:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	transform: translateY(-3px);
	box-shadow:
		0 12px 24px -8px color-mix(in srgb, var(--wp--preset--color--primary) 60%, transparent),
		0 6px 14px -10px color-mix(in srgb, var(--wp--preset--color--primary) 35%, transparent);
}

/* Brutal → fx-press (hover-only; Brutal keeps its resting shadow, animating shadow → flat) */
.wp-block-button.is-style-brutal:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	top: 4px;
	box-shadow:
		0 0 0 0 var(--wp--preset--color--ink),
		0 1px 3px rgba(0, 0, 0, 0.25);
}

/* Slanted → fx-bg-b (curtain from bottom). Self-contained ::before setup; Slanted's own
   CSS gives position/overflow, we add isolation:isolate so ::before z-index:-1 stays in context. */
.wp-block-button.is-style-slanted:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link {
	isolation: isolate;
}
.wp-block-button.is-style-slanted:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
	z-index: -1;
	transform: translateY(101%);
	transition: transform 0.55s cubic-bezier(0.7, 0, 0.2, 1);
}
.wp-block-button.is-style-slanted:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover::before {
	transform: translateY(0);
}

/* 3D Press → fx-press (hover-only, same shape as Brutal default) */
.wp-block-button.is-style-3d-press:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	top: 4px;
	box-shadow:
		0 0 0 0 var(--wp--preset--color--ink),
		0 1px 3px rgba(0, 0, 0, 0.25);
}

/* Soft → fx-shadow-grow (drop-shadow so Soft's layered box-shadow stays intact) */
.wp-block-button.is-style-soft:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	filter: drop-shadow(0 14px 18px rgba(0, 0, 0, 0.18));
}

/* Dashed → fx-fill (default --hover-bg = text color) */
.wp-block-button.is-style-dashed:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	background-color: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--ink)));
	color: var(--wp--preset--color--background);
}

/* Asymmetric → fx-radius-flip */
.wp-block-button.is-style-asymmetric:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	border-radius: 4px 22px 4px 22px;
	background-color: var(--le-hover-bg, var(--hover-bg, var(--wp--preset--color--accent)));
}

/* Editorial → fx-shift-r */
.wp-block-button.is-style-editorial:not([class*="has-hover-fx-"]):not(.has-hover-none) > .wp-block-button__link:hover {
	padding-right: 0.5em;
}

/* ============================================================
   CONTAINER EFFECTS — core/group & core/column
   Curated subset applied directly to the container. Same has-hover-{slug} class,
   scoped by block class (no collision). Scale/rotate gentler than buttons to avoid
   overflow on large blocks. Keep the slug list in sync with CONTAINER_EFFECTS in editor.js.
   ============================================================ */

/* Shared transition baseline — only on containers carrying an effect. */
.wp-block-group[class*="has-hover-fx-"],
.wp-block-column[class*="has-hover-fx-"] {
	transition:
		transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
		box-shadow 0.45s ease,
		filter 0.35s ease;
}

/* Translation */
.wp-block-group.has-hover-fx-lift:hover,
.wp-block-column.has-hover-fx-lift:hover {
	transform: translateY(-6px);
	box-shadow: 0 14px 28px -10px rgba(0, 0, 0, 0.45);
}
.wp-block-group.has-hover-fx-lift-soft:hover,
.wp-block-column.has-hover-fx-lift-soft:hover {
	transform: translateY(-2px);
	filter: brightness(0.96);
}
.wp-block-group.has-hover-fx-push:hover,
.wp-block-column.has-hover-fx-push:hover {
	transform: translateY(6px);
}
.wp-block-group.has-hover-fx-slide-l:hover,
.wp-block-column.has-hover-fx-slide-l:hover {
	transform: translateX(-6px);
}
.wp-block-group.has-hover-fx-slide-r:hover,
.wp-block-column.has-hover-fx-slide-r:hover {
	transform: translateX(6px);
}

/* Scale & zoom (gentler than the button equivalents) */
.wp-block-group.has-hover-fx-zoom-in:hover,
.wp-block-column.has-hover-fx-zoom-in:hover {
	transform: scale(1.03);
}
.wp-block-group.has-hover-fx-zoom-out:hover,
.wp-block-column.has-hover-fx-zoom-out:hover {
	transform: scale(0.97);
}
.wp-block-group.has-hover-fx-stretch-x:hover,
.wp-block-column.has-hover-fx-stretch-x:hover {
	transform: scaleX(1.04);
}
.wp-block-group.has-hover-fx-stretch-y:hover,
.wp-block-column.has-hover-fx-stretch-y:hover {
	transform: scaleY(1.05);
}

/* Rotate & skew */
.wp-block-group.has-hover-fx-rot-cw:hover,
.wp-block-column.has-hover-fx-rot-cw:hover {
	transform: rotate(2deg);
}
.wp-block-group.has-hover-fx-rot-ccw:hover,
.wp-block-column.has-hover-fx-rot-ccw:hover {
	transform: rotate(-2deg);
}
.wp-block-group.has-hover-fx-skew-r:hover,
.wp-block-column.has-hover-fx-skew-r:hover {
	transform: skewX(-6deg);
}
.wp-block-group.has-hover-fx-skew-l:hover,
.wp-block-column.has-hover-fx-skew-l:hover {
	transform: skewX(6deg);
}

/* 3D perspective — perspective folded into the transform so no parent setup is
   required (self-contained). */
.wp-block-group.has-hover-fx-3d-r:hover,
.wp-block-column.has-hover-fx-3d-r:hover {
	transform: perspective(900px) rotateY(10deg);
}
.wp-block-group.has-hover-fx-3d-l:hover,
.wp-block-column.has-hover-fx-3d-l:hover {
	transform: perspective(900px) rotateY(-10deg);
}
.wp-block-group.has-hover-fx-3d-up:hover,
.wp-block-column.has-hover-fx-3d-up:hover {
	transform: perspective(900px) rotateX(10deg);
}
.wp-block-group.has-hover-fx-3d-down:hover,
.wp-block-column.has-hover-fx-3d-down:hover {
	transform: perspective(900px) rotateX(-10deg);
}

/* Depth */
.wp-block-group.has-hover-fx-lift-shadow:hover,
.wp-block-column.has-hover-fx-lift-shadow:hover {
	transform: translateY(-3px);
	box-shadow:
		0 24px 40px -16px rgba(0, 0, 0, 0.55),
		0 6px 12px -6px rgba(0, 0, 0, 0.3);
}
.wp-block-group.has-hover-fx-lift-glow:hover,
.wp-block-column.has-hover-fx-lift-glow:hover {
	transform: translateY(-3px);
	box-shadow:
		0 12px 24px -8px color-mix(in srgb, var(--wp--preset--color--primary) 60%, transparent),
		0 6px 14px -10px color-mix(in srgb, var(--wp--preset--color--primary) 35%, transparent);
}

/* Glow */
.wp-block-group.has-hover-fx-glow-out:hover,
.wp-block-column.has-hover-fx-glow-out:hover {
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--wp--preset--color--primary) 40%, transparent),
		0 0 28px 4px color-mix(in srgb, var(--wp--preset--color--primary) 55%, transparent),
		0 0 60px 10px color-mix(in srgb, var(--wp--preset--color--primary) 25%, transparent);
}
.wp-block-group.has-hover-fx-shadow-grow:hover,
.wp-block-column.has-hover-fx-shadow-grow:hover {
	filter: drop-shadow(0 14px 18px rgba(0, 0, 0, 0.18));
}

/* Outline grow */
.wp-block-group.has-hover-fx-bd-thick:hover,
.wp-block-column.has-hover-fx-bd-thick:hover {
	box-shadow: 0 0 0 4px var(--wp--preset--color--ink);
}

/* ============================================================
   HOVER COLORS (Text + Background)
   Effect-independent. le-has-hover-* classes + --le-hover-text/bg custom properties
   on the wrapper (editor: BlockListBlock; front end: render_block).
   !important needed: a custom Text/Background color is an inline style that would
   otherwise beat these :hover rules. Button: colored element is the inner link.
   ============================================================ */

/* Transition baseline for group/column hover colors. Buttons excluded — the top-of-file
   baseline already covers any .wp-block-button with a has-hover-* class. */
.wp-block-group.le-has-hover-text,
.wp-block-group.le-has-hover-bg,
.wp-block-column.le-has-hover-text,
.wp-block-column.le-has-hover-bg {
	transition: color 0.25s ease, background-color 0.25s ease;
}

/* Group / Column — the element itself. */
.wp-block-group.le-has-hover-text:hover,
.wp-block-column.le-has-hover-text:hover {
	color: var(--le-hover-text) !important;
}

.wp-block-group.le-has-hover-bg:hover,
.wp-block-column.le-has-hover-bg:hover {
	background-color: var(--le-hover-bg) !important;
}

/* Button — inner link is the colored surface. */
.wp-block-button.le-has-hover-text > .wp-block-button__link:hover {
	color: var(--le-hover-text) !important;
}

/* Generic always-on hover background. Excludes bg-animating effects so the overlay
   doesn't swipe against a matching color (invisible): (1) has-hover-fx-bg-*, and
   (2) Slanted with no explicit effect (its default fx-bg-b is a ::before swipe). */
.wp-block-button.le-has-hover-bg:not([class*="has-hover-fx-bg-"]):not(.is-style-slanted) > .wp-block-button__link:hover,
.wp-block-button.le-has-hover-bg.is-style-slanted[class*="has-hover-fx-"]:not([class*="has-hover-fx-bg-"]) > .wp-block-button__link:hover {
	background-color: var(--le-hover-bg) !important;
}
