/* Pinnacle — pronounced motion layer.
 * Progressive enhancement only: layout, visibility and navigation never depend on animation.
 */

/* The --motion-* scale this file runs on is defined in tokens.css alongside
 * --dur-*, not here. It used to be declared in a :root block at this point,
 * which put a second token scale outside the canonical source (§8.9). */

html { scroll-behavior: smooth; }

html.has-motion-reveal [data-motion-reveal] {
	opacity: 0;
	transform: translate3d(0, 48px, 0) scale(0.96);
	transition: opacity var(--motion-slow) var(--motion-ease), transform var(--motion-long) var(--motion-soft-ease);
	transition-delay: var(--motion-delay, 0ms);
	will-change: opacity, transform;
}

/* Card reveals stay on the block axis so stronger motion never reintroduces
 * the horizontal-overflow bug that sideways reveals caused on narrow screens. */
html.has-motion-reveal [data-motion-reveal="left"],
html.has-motion-reveal [data-motion-reveal="right"] {
	transform: translate3d(0, 64px, 0) scale(0.94);
}

html.has-motion-reveal [data-motion-reveal="scale"] { transform: scale(0.9); }
html.has-motion-reveal [data-motion-reveal].is-motion-visible { opacity: 1; transform: translate3d(0, 0, 0) scale(1); will-change: auto; }
html.has-motion-reveal .home-hero__copy > [data-motion-reveal] { transform: translate3d(0, 32px, 0) scale(0.97); }
html.has-motion-reveal .home-hero__copy > [data-motion-reveal].is-motion-visible { transform: none; }

.btn,
button:not(.faq__question),
input[type="submit"],
input[type="button"],
.product-card,
.woocommerce-loop-product__link,
.home-categories__item,
.hub-card,
.post-card,
.editorial-grid__cell,
.rail__item {
	transition: transform var(--motion-base) var(--motion-ease), box-shadow var(--motion-base) ease, border-color var(--motion-fast) ease, background-color var(--motion-fast) ease, color var(--motion-fast) ease;
}
.btn, button:not(.faq__question), input[type="submit"], input[type="button"] { will-change: transform; }

/* Buttons stay geometrically stable: interaction is a simple 2px lift only.
 * No scale-up on hover and no scale-down press effect. */
@media (hover: hover) and (pointer: fine) {
	.btn:hover,
	button:not(:disabled):not(.faq__question):hover,
	input[type="submit"]:hover,
	input[type="button"]:hover { transform: translateY(var(--lift)); }

	.product-card:hover,
	.hub-card:hover,
	.post-card:hover,
	.editorial-grid__cell:hover,
	.rail__item:hover { transform: translateY(-10px) scale(1.015); }

	/* Category cells share borders, so keep their boxes fixed and make the
	 * image/cue carry the stronger hover instead of pulling grid lines apart. */
	.home-categories__item:hover { transform: none; }

	.product-card:hover img,
	.home-categories .category-tile:hover > .category-tile__media > .category-tile__img,
	.home-categories .category-child:hover > .category-tile__media > .category-tile__img,
	.hub-card:hover img,
	.post-card:hover img,
	.editorial-grid__cell:hover img,
	.rail__item:hover img { transform: scale(1.08); }
}

.btn:active,
button:not(:disabled):not(.faq__question):active,
input[type="submit"]:active,
input[type="button"]:active { transform: translateY(var(--lift)); }

.product-card img,
.home-categories__item img,
.hub-card img,
.post-card img,
.editorial-grid__cell img,
.rail__item img,
.wp-post-image { transition: transform var(--motion-long) var(--motion-soft-ease), opacity var(--motion-base) ease; }

main a:not(.btn):not([class*="card"]):not(.woocommerce-loop-product__link) { transition: opacity var(--motion-fast) ease, color var(--motion-fast) ease; }
.site-header a:not(.btn), .site-footer a:not(.btn) { transition: color var(--motion-fast) ease, opacity var(--motion-fast) ease; }
@media (hover: hover) and (pointer: fine) {
	main a:not(.btn):not([class*="card"]):not(.woocommerce-loop-product__link):hover,
	.site-header a:not(.btn):hover,
	.site-footer a:not(.btn):hover { opacity: 0.64; }
}

[data-motion-depth] { --motion-depth-y: 0px; }
[data-motion-depth] img,
img[data-motion-depth] { transform: translate3d(0, var(--motion-depth-y), 0) scale(1.04); transition: transform 160ms linear; }

/* Dialogs: keep the top-layer dialog itself geometrically stable for reliable
 * mobile hit-testing; animate only opacity, backdrop, and inner surfaces. */
dialog[open] { animation: pinnacle-dialog-in var(--motion-base) var(--motion-ease) both; }
dialog[open]::backdrop { animation: pinnacle-backdrop-in var(--motion-base) ease both; }
dialog.is-motion-dialog-opening .modal__box,
dialog.is-motion-dialog-opening .mobile-nav__panel,
dialog.is-motion-dialog-opening .filter-drawer__panel,
dialog.is-motion-dialog-opening .compare-view__panel,
dialog.is-motion-dialog-opening .lightbox__box {
	animation: pinnacle-dialog-surface-in 620ms var(--motion-soft-ease) both;
}

#mobile-nav.is-motion-dialog-opening .mobile-nav__panel {
	animation-name: pinnacle-drawer-in;
	animation-duration: 560ms;
}

#compare-view.is-motion-dialog-opening .modal__box,
#compare-view.is-motion-dialog-opening .compare-view__panel {
	animation-name: pinnacle-compare-in;
	animation-duration: 620ms;
}

@keyframes pinnacle-dialog-in {
	from { opacity: 0; }
	to { opacity: 1; }
}
@keyframes pinnacle-dialog-surface-in {
	from { opacity: 0; transform: translate3d(0, 40px, 0) scale(0.94); }
	to { opacity: 1; transform: none; }
}
@keyframes pinnacle-drawer-in {
	from { opacity: 0; transform: translate3d(48px, 0, 0); }
	to { opacity: 1; transform: none; }
}
@keyframes pinnacle-compare-in {
	from { opacity: 0; transform: translate3d(0, 36px, 0) scale(0.94); }
	to { opacity: 1; transform: none; }
}
@keyframes pinnacle-backdrop-in { from { opacity: 0; } to { opacity: 1; } }

/* Estimator, appointment and stepped-form reveals. */
.is-motion-flow-enter {
	animation: pinnacle-flow-enter 680ms var(--motion-soft-ease) both;
}
@keyframes pinnacle-flow-enter {
	from { opacity: 0; transform: translate3d(0, 36px, 0) scale(0.96); clip-path: inset(0 0 24% 0); }
	to { opacity: 1; transform: none; clip-path: inset(0); }
}

/* Form submission feedback: the submit control itself stays on the universal
 * button interaction rule above. Validation and result surfaces can animate;
 * buttons never pulse, scale or run a second motion language while sending. */
[data-pinnacle-form].is-motion-form-error {
	animation: pinnacle-form-error 460ms var(--motion-ease) both;
}
[data-live-error] {
	animation: pinnacle-error-in 380ms var(--motion-ease) both;
}
[data-result-check].is-motion-result-pop,
.modal--result [data-result-check] {
	animation: pinnacle-result-pop 720ms var(--motion-soft-ease) both;
	transform-origin: center;
}

@keyframes pinnacle-form-error {
	0%, 100% { transform: translateX(0); }
	25% { transform: translateX(-8px); }
	50% { transform: translateX(8px); }
	75% { transform: translateX(-4px); }
}
@keyframes pinnacle-error-in {
	from { opacity: 0; transform: translateY(-10px); }
	to { opacity: 1; transform: none; }
}
@keyframes pinnacle-result-pop {
	0% { opacity: 0; transform: scale(0.58); }
	70% { opacity: 1; transform: scale(1.12); }
	100% { opacity: 1; transform: scale(1); }
}

/* Mobile drill-down behaves like a page swap inside the drawer. */
.mobile-nav__menu.is-motion-nav-drill .is-open,
.mobile-nav__menu.is-motion-nav-drill .is-open > * {
	animation: pinnacle-nav-forward 520ms var(--motion-soft-ease) both;
}
.mobile-nav__menu.is-motion-nav-back > li:not(.is-open) {
	animation: pinnacle-nav-back 480ms var(--motion-soft-ease) both;
}
@keyframes pinnacle-nav-forward {
	from { opacity: 0; transform: translateX(36px); }
	to { opacity: 1; transform: none; }
}
@keyframes pinnacle-nav-back {
	from { opacity: 0; transform: translateX(-28px); }
	to { opacity: 1; transform: none; }
}

/* Comparison tray and dynamically rendered comparison table. */
#compare-tray.is-motion-compare-tray {
	animation: pinnacle-compare-tray-in 560ms var(--motion-soft-ease) both;
}
[data-compare-table].is-motion-compare-content .compare-table__product,
[data-compare-table].is-motion-compare-content .compare-cell,
[data-compare-table].is-motion-compare-content .compare-table__label {
	animation: pinnacle-compare-cell-in 560ms var(--motion-soft-ease) both;
}
[data-compare-table].is-motion-compare-content .compare-table__product:nth-child(2),
[data-compare-table].is-motion-compare-content .compare-cell:nth-child(2) { animation-delay: 70ms; }
[data-compare-table].is-motion-compare-content .compare-table__product:nth-child(3),
[data-compare-table].is-motion-compare-content .compare-cell:nth-child(3) { animation-delay: 140ms; }
[data-compare-table].is-motion-compare-content .compare-table__product:nth-child(4),
[data-compare-table].is-motion-compare-content .compare-cell:nth-child(4) { animation-delay: 210ms; }
@keyframes pinnacle-compare-tray-in {
	from { opacity: 0; transform: translate3d(0, 36px, 0) scale(0.97); }
	to { opacity: 1; transform: none; }
}
@keyframes pinnacle-compare-cell-in {
	from { opacity: 0; transform: translateY(20px) scale(0.96); }
	to { opacity: 1; transform: none; }
}

/* FAQ disclosure and similar native details get a visible content arrival. */
details[open] > *:not(summary) { animation: pinnacle-details-in var(--motion-base) var(--motion-ease) both; }
@keyframes pinnacle-details-in {
	from { opacity: 0; transform: translateY(-14px); }
	to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		transition-delay: 0ms !important;
	}
	html.has-motion-reveal [data-motion-reveal] { opacity: 1 !important; transform: none !important; }
	[data-motion-depth] img,
	img[data-motion-depth] { transform: none !important; }
}

/* Reversible top-layer motion.
 *
 * The component styles already define each surface's entrance pose with
 * @starting-style. The missing half was the browser removing dialogs/popovers
 * from display/the top layer as soon as close() or light-dismiss ran, which
 * meant there was no painted frame in which an exit transition could happen.
 * Discrete display/overlay transitions keep that surface alive just long
 * enough to finish the fade/slide, while native dialog close events, focus
 * return and the shared scroll lock stay untouched. Unsupported engines keep
 * the existing progressive-enhancement behaviour: an instant close, never a
 * blocked control. */
@media (prefers-reduced-motion: no-preference) {
	dialog {
		opacity: 0;
		transition:
			opacity var(--motion-base) var(--motion-ease),
			display var(--motion-base) allow-discrete,
			overlay var(--motion-base) allow-discrete;
	}

	dialog[open] {
		opacity: 1;
		animation: none;
	}

	dialog::backdrop {
		opacity: 0;
		transition:
			opacity var(--motion-base) ease,
			display var(--motion-base) allow-discrete,
			overlay var(--motion-base) allow-discrete;
	}

	dialog[open]::backdrop {
		opacity: 1;
		animation: none;
	}

	dialog.is-motion-dialog-opening .modal__box,
	dialog.is-motion-dialog-opening .mobile-nav__panel,
	dialog.is-motion-dialog-opening .filter-drawer__panel,
	dialog.is-motion-dialog-opening .compare-view__panel,
	dialog.is-motion-dialog-opening .lightbox__box {
		animation: none;
	}

	/* Full-height drawers leave through the same inline-end edge they entered.
	 * Their existing component rules own the open pose and the entrance
	 * @starting-style; these selectors only add the formerly-missing exit pose. */
	#mobile-nav .mobile-nav__panel,
	#filter-drawer .filter-drawer__panel {
		opacity: 1;
		transition:
			translate var(--motion-base) var(--motion-soft-ease),
			opacity var(--motion-fast) ease;
	}

	#mobile-nav:not([open]) .mobile-nav__panel,
	#filter-drawer:not([open]) .filter-drawer__panel {
		opacity: 0;
		translate: 100% 0;
	}

	/* Comparison is a centred decision surface, not a drawer: a short downward
	 * settle feels related to the existing modal entrance without making a
	 * large table travel across the viewport. */
	#compare-view .modal__box,
	#compare-view .compare-view__panel {
		opacity: 1;
		translate: 0 0;
		scale: 1;
		transition:
			opacity var(--motion-fast) ease,
			translate var(--motion-base) var(--motion-soft-ease),
			scale var(--motion-base) var(--motion-soft-ease);
	}

	#compare-view:not([open]) .modal__box,
	#compare-view:not([open]) .compare-view__panel {
		opacity: 0;
		translate: 0 var(--s-5);
		scale: 0.97;
	}

	/* Desktop mega menus and the search panel are native popovers. Keeping
	 * display/overlay discrete makes native Esc and light-dismiss animate too,
	 * with a restrained vertical travel appropriate to header chrome. */
	.mega[popover] {
		opacity: 0;
		translate: 0 calc(var(--s-3) * -1);
		transition:
			opacity var(--motion-fast) ease,
			translate var(--motion-base) var(--motion-soft-ease),
			display var(--motion-base) allow-discrete,
			overlay var(--motion-base) allow-discrete;
	}

	.mega[popover]:popover-open {
		opacity: 1;
		translate: 0 0;
	}

	@starting-style {
		dialog[open] { opacity: 0; }
		dialog[open]::backdrop { opacity: 0; }
		.mega[popover]:popover-open {
			opacity: 0;
			translate: 0 calc(var(--s-3) * -1);
		}
	}
}