/**
 * MCN Animations — Hover
 *
 * Rebuilt from:
 *   Jhey, "Glide To Reveal with CSS :has()" (codepen.io/jh3y/pen/JjxPKXz, MIT)
 *   Jhey, "CSS OS Dock"                     (codepen.io/jh3y/pen/mdxggmO, MIT)
 *
 * Both originals use the same trick: the hovered item claims the largest
 * scale, and each sibling further away claims a smaller one, selected via
 * chained `+` combinators in both directions with :has(). It is pure CSS
 * proximity falloff with no JS, and it is genuinely the right tool.
 *
 * Browser support note: :has() is available in all current evergreen browsers.
 * The fallback is graceful — without :has(), only the directly hovered item
 * scales and neighbours stay put. Still usable, just less fluid.
 *
 * @package MCN_Animations
 */

/* --------------------------------------------------------------------------
 * Dock — proximity magnification
 *
 * Markup: a flex row of .anim-dock__item inside .anim-dock.
 * Items must be real links or buttons so keyboard users get the same effect
 * via :focus-visible — the original does this and it is the reason this
 * pattern passes 2.1.1 where most dock clones fail it.
 * ----------------------------------------------------------------------- */

.anim-dock {
	--dock-lerp-0: 1.6;   /* hovered */
	--dock-lerp-1: 1.32;  /* immediate neighbours */
	--dock-lerp-2: 1.16;
	--dock-lerp-3: 1.06;
	--dock-lerp-4: 1;
	--dock-size: 56px;

	display: flex;
	align-items: flex-end;
	gap: 0.5rem;
	padding: 0.5rem;
}

.anim-dock__item {
	--lerp: 1;
	flex: none;
	width: var(--dock-size);
	height: var(--dock-size);
	display: grid;
	place-items: center;
	transform: scale(var(--lerp));
	transform-origin: bottom center;
	transition: transform var(--anim-duration) var(--anim-ease-overshoot);
	/* 2.5.8 (AA): the resting box is the target, so it must clear 24px even
	   before magnification. --dock-size is the guard. */
	min-width: 24px;
	min-height: 24px;
}

/* Distance 0 — the item under the pointer or keyboard focus. */
.anim-dock__item:is(:hover, :focus-visible) {
	--lerp: var(--dock-lerp-0);
	z-index: 5;
}

/* Distance 1 — the sibling after, and (via :has) the sibling before. */
.anim-dock__item:is(:hover, :focus-visible) + .anim-dock__item,
.anim-dock__item:has(+ .anim-dock__item:is(:hover, :focus-visible)) {
	--lerp: var(--dock-lerp-1);
	z-index: 4;
}

/* Distance 2 */
.anim-dock__item:is(:hover, :focus-visible) + .anim-dock__item + .anim-dock__item,
.anim-dock__item:has(+ .anim-dock__item + .anim-dock__item:is(:hover, :focus-visible)) {
	--lerp: var(--dock-lerp-2);
	z-index: 3;
}

/* Distance 3 */
.anim-dock__item:is(:hover, :focus-visible) + .anim-dock__item + .anim-dock__item + .anim-dock__item,
.anim-dock__item:has(+ .anim-dock__item + .anim-dock__item + .anim-dock__item:is(:hover, :focus-visible)) {
	--lerp: var(--dock-lerp-3);
	z-index: 2;
}

/* --------------------------------------------------------------------------
 * Glide to reveal — proximity de-blur
 *
 * Same falloff maths, applied to filter:blur instead of scale. Useful for
 * "hover to read" price tables and spoiler content.
 *
 * IMPORTANT: blurred text is not hidden text. Anything behind this is still
 * in the accessibility tree and still selectable — do not use it for anything
 * that actually needs to stay secret.
 * ----------------------------------------------------------------------- */

.anim-glide {
	--glide-blur-0: 0px;
	--glide-blur-1: 2px;
	--glide-blur-2: 5px;
	--glide-blur-3: 8px;
	--glide-blur-rest: 10px;

	display: flex;
	gap: 0.35rem;
}

.anim-glide__item {
	--blur: var(--glide-blur-rest);
	--scale: 1;
	filter: blur(var(--blur));
	transform: scale(var(--scale));
	transition:
		filter var(--anim-duration) var(--anim-ease),
		transform var(--anim-duration) var(--anim-ease);
}

.anim-glide__item:is(:hover, :focus-visible) {
	--blur: var(--glide-blur-0);
	--scale: 1.25;
}

.anim-glide__item:is(:hover, :focus-visible) + .anim-glide__item,
.anim-glide__item:has(+ .anim-glide__item:is(:hover, :focus-visible)) {
	--blur: var(--glide-blur-1);
	--scale: 1.12;
}

.anim-glide__item:is(:hover, :focus-visible) + .anim-glide__item + .anim-glide__item,
.anim-glide__item:has(+ .anim-glide__item + .anim-glide__item:is(:hover, :focus-visible)) {
	--blur: var(--glide-blur-2);
	--scale: 1.04;
}

.anim-glide__item:is(:hover, :focus-visible) + .anim-glide__item + .anim-glide__item + .anim-glide__item,
.anim-glide__item:has(+ .anim-glide__item + .anim-glide__item + .anim-glide__item:is(:hover, :focus-visible)) {
	--blur: var(--glide-blur-3);
}

/* --------------------------------------------------------------------------
 * Image / tile hover kit
 * Small, composable hovers that get reached for on nearly every build.
 * ----------------------------------------------------------------------- */

.anim-hover-zoom {
	overflow: hidden;
}

.anim-hover-zoom > img,
.anim-hover-zoom > picture > img {
	display: block;
	width: 100%;
	transition: transform var(--anim-duration-slow) var(--anim-ease);
}

.anim-hover-zoom:hover > img,
.anim-hover-zoom:focus-within > img,
.anim-hover-zoom:hover > picture > img,
.anim-hover-zoom:focus-within > picture > img {
	transform: scale(1.07);
}

.anim-hover-tilt {
	transition: transform var(--anim-duration) var(--anim-ease-overshoot);
	transform-style: preserve-3d;
}

.anim-hover-tilt:hover,
.anim-hover-tilt:focus-within {
	transform: perspective(700px) rotateX(4deg) rotateY(-4deg) translateZ(8px);
}

.anim-hover-lift {
	transition:
		transform var(--anim-duration) var(--anim-ease),
		box-shadow var(--anim-duration) var(--anim-ease);
}

.anim-hover-lift:hover,
.anim-hover-lift:focus-within {
	transform: translateY(-4px);
	box-shadow: 0 14px 30px -18px rgb(0 0 0 / 0.5);
}

@media (prefers-reduced-motion: reduce) {

	.anim-dock__item,
	.anim-glide__item,
	.anim-hover-zoom > img,
	.anim-hover-tilt,
	.anim-hover-lift {
		transition: none !important;
		transform: none !important;
	}

	/* Blur is the whole point of glide, so keep the reveal — just make it
	   instant rather than animated. */
	.anim-glide__item:is(:hover, :focus-visible) {
		filter: none;
	}
}
