/* ---------------------------------------------------------------------------
 * Motion and interaction detail.
 *
 * Curves and durations come from theme.json (--wp--custom--ease--*,
 * --wp--custom--duration--*) so motion is part of the design system rather
 * than a pile of magic numbers in a stylesheet.
 *
 * Rules this file follows:
 *   - Only transform, opacity, filter, box-shadow and colour are animated.
 *     Those skip layout and paint; animating height or padding does not.
 *   - Never `transition: all` - it animates properties you did not intend.
 *   - Never `ease-in` on UI. It delays the first frame, the exact moment the
 *     user is watching, so it reads as sluggish at any duration.
 *   - Never enter from scale(0). Nothing in the real world appears from
 *     nothing; entrances start at 0.96-0.98.
 *   - Hover effects are gated behind (hover: hover) and (pointer: fine).
 *     Without that gate, tapping on a touch screen latches hover on.
 *   - Frequent actions are NOT animated. Filtering the trips grid fires many
 *     times a minute, so it stays instant on purpose.
 * ------------------------------------------------------------------------- */

:root {
	--pb-ease-out: var(--wp--custom--ease--out, cubic-bezier(0.23, 1, 0.32, 1));
	--pb-ease-in-out: var(--wp--custom--ease--in-out, cubic-bezier(0.77, 0, 0.175, 1));
	--pb-ease-drawer: var(--wp--custom--ease--drawer, cubic-bezier(0.32, 0.72, 0, 1));
	--pb-press: var(--wp--custom--duration--press, 160ms);
	--pb-fast: var(--wp--custom--duration--fast, 200ms);
	--pb-base: var(--wp--custom--duration--base, 240ms);
}

/* --- Press feedback -------------------------------------------------------
 * Every pressable surface confirms it heard the press. Highest-value motion
 * on the site: fires on every interaction, costs 160ms. Scale stays subtle. */

.wp-block-button__link,
.pickleball-chip,
.pickleball-trips-sort,
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	transition:
		transform var(--pb-press) var(--pb-ease-out),
		background-color var(--pb-fast) ease,
		border-color var(--pb-fast) ease,
		color var(--pb-fast) ease;
}

.wp-block-button__link:active,
.pickleball-chip:active,
.wp-block-navigation__responsive-container-open:active,
.wp-block-navigation__responsive-container-close:active {
	transform: scale(0.97);
}

.pickleball-booking .single_add_to_cart_button:active,
.pickleball-booking-bar a:active {
	transform: scale(0.96);
}

/* --- Focus -----------------------------------------------------------------
 * :focus-visible only, so a mouse press never paints a ring but keyboard
 * users always get one. */

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--success);
	outline-offset: 3px;
	border-radius: var(--wp--custom--radius--chip, 12px);
}

/* --- Trip cards ------------------------------------------------------------
 * Hover lift is gated: on a touch device the lift would stick after a tap. */

.pickleball-trip-card {
	transition:
		transform var(--pb-fast) var(--pb-ease-out),
		box-shadow var(--pb-fast) ease;
}

.pickleball-card__media {
	overflow: hidden;
}

@media (hover: hover) and (pointer: fine) {
	.pickleball-trip-card:hover {
		transform: translateY(-3px);
		box-shadow: var(--wp--custom--shadow--lift);
	}

	.pickleball-trip-card .pickleball-card__image {
		transition: transform 320ms var(--pb-ease-out);
	}

	.pickleball-trip-card:hover .pickleball-card__image {
		transform: scale(1.03);
	}
}

.pickleball-trip-card:focus-within {
	transform: translateY(-3px);
	box-shadow: var(--wp--custom--shadow--lift);
}

.pickleball-trip-card:active {
	transform: translateY(-1px) scale(0.995);
	transition-duration: var(--pb-press);
}

/* --- Nav links -------------------------------------------------------------
 * The canvas underlines the active item. Animating an underline from the
 * centre out costs nothing: scaleX on a pseudo-element touches no layout. */

@media (hover: hover) and (pointer: fine) {
	.wp-block-navigation .wp-block-navigation-item__content {
		position: relative;
	}

	.wp-block-navigation .wp-block-navigation-item__content::after {
		content: "";
		position: absolute;
		inset-inline: 0;
		bottom: -3px;
		height: 2px;
		background: var(--wp--preset--color--accent);
		transform: scaleX(0);
		transform-origin: center;
		transition: transform var(--pb-fast) var(--pb-ease-out);
	}

	.wp-block-navigation .wp-block-navigation-item__content:hover::after {
		transform: scaleX(1);
	}
}

/* --- Mobile navigation drawer ---------------------------------------------
 * Occasional action, so it earns real motion. iOS drawer curve. */

.wp-block-navigation__responsive-container.has-modal-open {
	animation: pb-drawer-in var(--pb-base) var(--pb-ease-drawer) both;
}

@keyframes pb-drawer-in {
	from { opacity: 0; transform: translateY(-8px); }
}

.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item {
	animation: pb-stagger-in 260ms var(--pb-ease-out) both;
}

.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item:nth-child(1) { animation-delay: 30ms; }
.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item:nth-child(2) { animation-delay: 70ms; }
.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item:nth-child(3) { animation-delay: 110ms; }
.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item:nth-child(4) { animation-delay: 150ms; }
.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item:nth-child(5) { animation-delay: 190ms; }

@keyframes pb-stagger-in {
	from { opacity: 0; transform: translateY(6px); }
}

/* --- Details / FAQ --------------------------------------------------------- */

.wp-block-details summary {
	cursor: pointer;
	transition: color var(--pb-fast) ease;
}

.wp-block-details[open] summary {
	color: var(--wp--preset--color--primary);
}

.wp-block-details[open] > :not(summary) {
	animation: pb-details-in var(--pb-fast) var(--pb-ease-out) both;
}

@keyframes pb-details-in {
	from { opacity: 0; transform: translateY(-4px); }
}

/* --- Gallery rail ---------------------------------------------------------- */

.pickleball-gallery__rail {
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: thin;
}

@media (hover: hover) and (pointer: fine) {
	.pickleball-gallery__item {
		transition: transform var(--pb-fast) var(--pb-ease-out);
	}

	.pickleball-gallery__item:hover {
		transform: scale(1.02);
	}
}

/* --- Scroll-driven polish --------------------------------------------------
 * Runs off the main thread, needs no JS, no IntersectionObserver, no scroll
 * listener. Browsers without support render the final state, so it is purely
 * additive and @supports keeps it that way. */

@supports (animation-timeline: scroll()) {
	.is-site-header {
		animation: pb-header-lift linear both;
		animation-timeline: scroll(root block);
		animation-range: 0 120px;
	}

	@keyframes pb-header-lift {
		from { box-shadow: 0 0 0 0 transparent; }
		to { box-shadow: 0 1px 0 0 var(--wp--preset--color--line), var(--wp--custom--shadow--card); }
	}
}

@supports (animation-timeline: view()) {
	/* Sections settle into place as they enter. Applied structurally to the
	 * top-level sections of the content area rather than by hand-tagging every
	 * pattern - the .pickleball-reveal class remains for anything that wants to
	 * opt in individually.
	 *
	 * :not(:first-child) skips the hero. It is above the fold and is the LCP
	 * element; fading it in would delay the largest paint to no benefit.
	 *
	 * Deliberately small: 10px and a fade. Anything larger stops being a
	 * detail and becomes the page's personality, and it is seen on every
	 * scroll of every page. */
	.entry-content > .alignfull:not(:first-child),
	.pickleball-reveal {
		animation: pb-reveal 460ms var(--pb-ease-out) both;
		animation-timeline: view(block);
		animation-range: entry 0% entry 42%;
	}

	@keyframes pb-reveal {
		from { opacity: 0; transform: translateY(10px); }
	}
}

/* --- Buttons, in detail ----------------------------------------------------
 * Buttons are the most-touched surface on the site, so they carry the most
 * interaction detail. Three layers, in the order the user meets them:
 * hover lift -> press -> the outline fill. */

@media (hover: hover) and (pointer: fine) {
	.wp-block-button__link:hover {
		transform: translateY(-1px);
		box-shadow: var(--wp--custom--shadow--soft);
	}

	/* Press must beat hover: without this, a pressed button keeps the -1px
	 * hover lift and the scale reads as a wobble instead of a press. */
	.wp-block-button__link:active {
		transform: translateY(0) scale(0.97);
		box-shadow: none;
	}
}

/* The outline button fills from the left on hover instead of snapping to a new
 * background. clip-path on a pseudo-element, so no layout and no repaint of
 * the text - and the label stays readable throughout because it sits above. */
.wp-block-button.is-style-outline .wp-block-button__link {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

.wp-block-button.is-style-outline .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	/* A wash of the button's OWN text colour, not a fixed brand colour.
	 *
	 * A fixed accent fill fails: the outline button appears both on the dark
	 * hero (white text) and on light sections (dark text). Filling with accent
	 * put near-white text on lime-yellow at roughly 1.3:1 - unreadable. And the
	 * text colour could not simply be overridden, because core emits its
	 * .has-base-color utility with !important.
	 *
	 * currentColor at 14% is always derived from the text sitting on it, so
	 * contrast is preserved on any ground, on any future section, with no
	 * per-context rules. */
	background: color-mix(in oklab, currentColor 14%, transparent);
	clip-path: inset(0 100% 0 0);
	transition: clip-path var(--pb-base) var(--pb-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	.wp-block-button.is-style-outline .wp-block-button__link:hover::before {
		clip-path: inset(0 0 0 0);
	}

	/* Border tracks the same wash so the outline does not float over the fill. */
	.wp-block-button.is-style-outline .wp-block-button__link:hover {
		border-color: currentColor;
	}
}

/* Arrow buttons nudge. The canvas writes several CTAs with a trailing arrow;
 * moving it on hover is the cheapest possible hint that it goes somewhere. */
.pickleball-arrow::after {
	content: " \2192";
	display: inline-block;
	transition: transform var(--pb-fast) var(--pb-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	a:hover > .pickleball-arrow::after,
	.wp-block-button__link:hover .pickleball-arrow::after,
	.pickleball-arrow:hover::after {
		transform: translateX(3px);
	}
}

/* --- Prose links -----------------------------------------------------------
 * Body links get an underline that grows rather than appearing. Scoped to
 * prose so it never touches nav, buttons or cards. */

@media (hover: hover) and (pointer: fine) {
	.entry-content p > a:not(.wp-block-button__link),
	.wp-block-post-content p > a:not(.wp-block-button__link) {
		background-image: linear-gradient(var(--wp--preset--color--success), var(--wp--preset--color--success));
		background-repeat: no-repeat;
		background-position: 0 100%;
		background-size: 0% 1.5px;
		transition: background-size var(--pb-fast) var(--pb-ease-out), color var(--pb-fast) ease;
	}

	.entry-content p > a:not(.wp-block-button__link):hover,
	.wp-block-post-content p > a:not(.wp-block-button__link):hover {
		background-size: 100% 1.5px;
	}
}

/* --- Form fields -----------------------------------------------------------
 * Gravity Forms, the checkout and the sort select. A field that responds when
 * focused is the difference between a form that feels built and one that feels
 * defaulted. */

input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
select,
textarea {
	transition:
		border-color var(--pb-fast) ease,
		box-shadow var(--pb-fast) ease,
		background-color var(--pb-fast) ease;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):focus,
select:focus,
textarea:focus {
	border-color: var(--wp--preset--color--success);
	box-shadow: 0 0 0 3px color-mix(in oklab, var(--wp--preset--color--success) 18%, transparent);
	outline: none;
}

/* --- Reduced motion --------------------------------------------------------
 * Fewer and gentler, not none. Colour and opacity stay; movement goes. */

@media (prefers-reduced-motion: reduce) {
	.pickleball-trip-card,
	.pickleball-trip-card:hover,
	.pickleball-trip-card:focus-within,
	.pickleball-trip-card:active,
	.pickleball-trip-card .pickleball-card__image,
	.pickleball-trip-card:hover .pickleball-card__image,
	.pickleball-gallery__item:hover,
	.wp-block-button__link:active,
	.pickleball-chip:active {
		transform: none;
	}

	.wp-block-button__link:active,
	.pickleball-chip:active {
		opacity: 0.82;
	}

	.wp-block-button__link:hover,
	.wp-block-button.is-style-outline .wp-block-button__link:hover::before {
		transform: none;
		clip-path: none;
	}

	.pickleball-arrow::after {
		transition: none;
	}

	.wp-block-navigation .wp-block-navigation-item__content::after {
		transition: opacity var(--pb-fast) ease;
		transform: scaleX(1);
		opacity: 0;
	}

	.wp-block-navigation .wp-block-navigation-item__content:hover::after {
		opacity: 1;
	}

	.pickleball-reveal,
	.entry-content > .alignfull:not(:first-child),
	.is-site-header,
	.wp-block-navigation__responsive-container.has-modal-open,
	.wp-block-navigation__responsive-container.has-modal-open .wp-block-navigation-item,
	.wp-block-details[open] > :not(summary) {
		animation: none;
	}

	.pickleball-gallery__rail {
		scroll-behavior: auto;
	}
}
