/* ==========================================================================
   Lumiére Élégance — motion layer
   Spring easing, scroll-linked depth, view transitions.
   Everything here is decorative: the page is complete and usable without it.
   ========================================================================== */

:root {
	/* Apple-ish springs: fast attack, long gentle settle, slight overshoot. */
	--lx-spring:        linear(0, .0039 1.95%, .0162 3.98%, .0725 8.5%, .2178 15.75%, .5273 28.2%, .6362 32.7%, .7159 36.8%, .7746 40.6%, .8232 44.5%, .8637 48.5%, .8974 52.7%, .9252 57.1%, .9475 61.8%, .9651 66.9%, .9783 72.5%, .9879 78.8%, .9943 86%, .9981 94.2%, 1);
	--lx-spring-soft:   linear(0, .0033 1.6%, .0146 3.5%, .0637 7.8%, .1912 14.5%, .4625 26%, .6188 32.4%, .7256 37.9%, .8042 43.3%, .8628 48.8%, .9063 54.6%, .9379 60.9%, .9603 67.8%, .9756 75.5%, .9856 84.2%, .9937 94%, 1);
	--lx-out-expo:      cubic-bezier(.16, 1, .3, 1);
	--lx-out-quint:     cubic-bezier(.22, 1, .36, 1);
	--lx-in-out-quint:  cubic-bezier(.83, 0, .17, 1);

	--lx-t-fast: 280ms;
	--lx-t-base: 520ms;
	--lx-t-slow: 900ms;
	--lx-t-epic: 1400ms;
}

/* --------------------------------------------------------------------------
   Reveal — one shared system, driven by IntersectionObserver
   -------------------------------------------------------------------------- */

.lx-js [data-lx-in] {
	--lx-in-y: 34px;
	--lx-in-x: 0px;
	--lx-in-scale: 1;
	--lx-in-blur: 0px;
	opacity: 0;
	transform: translate3d(var(--lx-in-x), var(--lx-in-y), 0) scale(var(--lx-in-scale));
	filter: blur(var(--lx-in-blur));
	transition:
		opacity var(--lx-t-slow) var(--lx-out-expo),
		transform var(--lx-t-slow) var(--lx-out-expo),
		filter var(--lx-t-base) var(--lx-out-expo);
	transition-delay: var(--lx-in-delay, 0ms);
	will-change: opacity, transform;
}
.lx-js [data-lx-in].is-in {
	opacity: 1;
	transform: translate3d(0, 0, 0) scale(1);
	filter: blur(0);
}
/* Drop the compositing hint once the animation has played. */
.lx-js [data-lx-in].is-settled { will-change: auto; }

.lx-js [data-lx-in="rise"]   { --lx-in-y: 44px; }
.lx-js [data-lx-in="fade"]   { --lx-in-y: 0px; }
.lx-js [data-lx-in="left"]   { --lx-in-y: 0px; --lx-in-x: -40px; }
.lx-js [data-lx-in="right"]  { --lx-in-y: 0px; --lx-in-x: 40px; }
.lx-js [data-lx-in="zoom"]   { --lx-in-y: 0px; --lx-in-scale: .94; }
.lx-js [data-lx-in="soften"] { --lx-in-y: 18px; --lx-in-blur: 14px; }
.lx-js [data-lx-in="unveil"] { --lx-in-y: 0px; --lx-in-scale: 1.06; --lx-in-blur: 10px; }

/* Stagger: children animate in sequence. Delay is set from JS so the step is
   uniform no matter how many children there are. */
.lx-js [data-lx-stagger-in] > * {
	opacity: 0;
	transform: translate3d(0, 30px, 0);
	transition:
		opacity var(--lx-t-base) var(--lx-out-expo),
		transform var(--lx-t-base) var(--lx-out-expo);
}
.lx-js [data-lx-stagger-in].is-in > * {
	opacity: 1;
	transform: none;
}

/* --------------------------------------------------------------------------
   Line-by-line headline reveal (the Apple product-page move)
   -------------------------------------------------------------------------- */

.lx-lines { display: block; }
.lx-lines__line {
	display: block;
	overflow: hidden;
	/* A hair of vertical padding so descenders are not clipped. */
	padding-block: .08em;
	margin-block: -.08em;
}
.lx-js .lx-lines__inner {
	display: block;
	transform: translate3d(0, 110%, 0);
	opacity: 0;
	transition:
		transform var(--lx-t-epic) var(--lx-out-expo),
		opacity var(--lx-t-slow) var(--lx-out-expo);
	transition-delay: var(--lx-line-delay, 0ms);
	will-change: transform;
}
.lx-lines.is-in .lx-lines__inner {
	transform: translate3d(0, 0, 0);
	opacity: 1;
}

/* Word-level variant for shorter phrases. */
.lx-js .lx-words__word {
	display: inline-block;
	opacity: 0;
	transform: translate3d(0, .5em, 0);
	transition:
		opacity var(--lx-t-base) var(--lx-out-expo),
		transform var(--lx-t-base) var(--lx-out-expo);
	transition-delay: var(--lx-word-delay, 0ms);
}
.lx-words.is-in .lx-words__word { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   Scroll-linked depth
   -------------------------------------------------------------------------- */

/* Parallax: JS writes --lx-par (-1 … 1) as the element crosses the viewport. */
[data-lx-parallax] {
	will-change: transform;
	transform: translate3d(0, calc(var(--lx-par, 0) * var(--lx-par-depth, 60px)), 0);
}
[data-lx-parallax] > img,
[data-lx-parallax] > video {
	/* Oversize so the parallax shift never reveals an edge. */
	width: 100%;
	height: calc(100% + (var(--lx-par-depth, 60px) * 2));
	object-fit: cover;
}

/* Hero: scales down and softens as it leaves, so the next section feels like
   it rises over it. */
.lx-hero__media {
	will-change: transform;
	transform: scale(var(--lx-hero-scale, 1));
	transform-origin: 50% 35%;
}
.lx-hero__inner {
	opacity: var(--lx-hero-fade, 1);
	transform: translate3d(0, calc(var(--lx-hero-lift, 0) * -70px), 0);
}

/* Native scroll-driven animation where the browser supports it — zero JS. */
@supports (animation-timeline: view()) {
	.lx-scroll-zoom {
		animation: lx-scroll-zoom linear both;
		animation-timeline: view();
		animation-range: entry 0% cover 60%;
	}
	@keyframes lx-scroll-zoom {
		from { transform: scale(1.14); }
		to   { transform: scale(1); }
	}

	.lx-scroll-rise {
		animation: lx-scroll-rise linear both;
		animation-timeline: view();
		animation-range: entry 10% entry 90%;
	}
	@keyframes lx-scroll-rise {
		from { opacity: 0; transform: translate3d(0, 50px, 0); }
		to   { opacity: 1; transform: none; }
	}
}

/* Scroll progress hairline under the header. */
.lx-progress {
	position: fixed;
	top: 0; left: 0;
	height: 2px;
	width: 100%;
	transform: scaleX(var(--lx-progress, 0));
	transform-origin: 0 50%;
	background: linear-gradient(90deg, var(--wp--preset--color--nude), var(--wp--preset--color--gold));
	z-index: 600;
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--lx-t-fast) var(--lx-out-expo);
}
.lx-progress.is-visible { opacity: 1; }

/* --------------------------------------------------------------------------
   Magnetic / pressure-sensitive interactions
   -------------------------------------------------------------------------- */

[data-lx-magnetic] {
	transition: transform var(--lx-t-base) var(--lx-spring);
	will-change: transform;
}
[data-lx-magnetic].is-pulled {
	transition: transform 120ms linear;
	transform: translate3d(var(--lx-mx, 0px), var(--lx-my, 0px), 0);
}

/* Press feedback with a spring release — reads as physical. */
.wp-block-button__link,
.lx-atc__btn,
.lfit__btn,
.lx-quick,
.lx-chip {
	transition:
		transform 220ms var(--lx-spring),
		background-color var(--lx-t-fast) var(--lx-out-expo),
		color var(--lx-t-fast) var(--lx-out-expo),
		border-color var(--lx-t-fast) var(--lx-out-expo),
		box-shadow var(--lx-t-fast) var(--lx-out-expo);
}
.wp-block-button__link:active,
.lx-atc__btn:active:not(:disabled),
.lfit__btn:active,
.lx-quick:active,
.lx-chip:active {
	transform: scale(.96);
	transition-duration: 90ms;
}

/* Sheen that sweeps once on hover — restrained, not a casino. */
.wp-block-button__link { position: relative; overflow: hidden; isolation: isolate; }
.wp-block-button__link::after {
	content: "";
	position: absolute; inset: 0;
	z-index: -1;
	background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.17) 50%, transparent 62%);
	transform: translateX(-120%);
	transition: transform 820ms var(--lx-out-expo);
}
.wp-block-button__link:hover::after { transform: translateX(120%); }

/* --------------------------------------------------------------------------
   Product cards
   -------------------------------------------------------------------------- */

.lx-card__media {
	transition: box-shadow var(--lx-t-base) var(--lx-out-expo);
}
.lx-card:hover .lx-card__media {
	box-shadow: 0 18px 44px -22px rgba(26, 20, 22, .34);
}

/* The image lift is spring-eased rather than linear. */
.lx-card__media img {
	transition:
		opacity var(--lx-t-base) var(--lx-out-expo),
		transform var(--lx-t-epic) var(--lx-out-expo);
}

/* Card body rises a touch with the image — one gesture, not two. */
.lx-card__body {
	transition: transform var(--lx-t-base) var(--lx-out-expo);
}
.lx-card:hover .lx-card__body { transform: translateY(-2px); }

/* Hover actions spring up instead of sliding. */
.lx-card__actions {
	transition:
		opacity var(--lx-t-fast) var(--lx-out-expo),
		transform 420ms var(--lx-spring);
}

/* Wishlist heart: a real pop with a settle. */
.lx-wish { transition: all 320ms var(--lx-spring); }
.lx-wish.is-pulse svg { animation: lx-heart 620ms var(--lx-spring); }
@keyframes lx-heart {
	0%   { transform: scale(1); }
	28%  { transform: scale(.82); }
	52%  { transform: scale(1.3); }
	100% { transform: scale(1); }
}

/* Blur-up: images fade in from a soft blur once decoded. */
.lx-card__media img,
.lx-gallery img,
.lx-tile img {
	animation: lx-blurup 700ms var(--lx-out-expo) both;
}
@keyframes lx-blurup {
	from { opacity: 0; filter: blur(12px); transform: scale(1.03); }
	to   { opacity: 1; filter: blur(0);    transform: scale(1); }
}
/* Do not re-run the blur-up on hover swaps. */
.lx-card:hover .lx-card__media img { animation: none; }

/* --------------------------------------------------------------------------
   Category tiles
   -------------------------------------------------------------------------- */

.lx-tile {
	transition:
		transform 520ms var(--lx-spring),
		box-shadow var(--lx-t-base) var(--lx-out-expo);
}
.lx-tile:hover {
	transform: translateY(-5px);
	box-shadow: 0 26px 56px -30px rgba(26, 20, 22, .45);
}
.lx-tile img { transition: transform 1100ms var(--lx-out-expo); }
.lx-tile__label { transition: transform var(--lx-t-base) var(--lx-out-expo); }
.lx-tile:hover .lx-tile__label { transform: translateY(-3px); }

/* --------------------------------------------------------------------------
   Header & drawers
   -------------------------------------------------------------------------- */

.lx-header {
	transition:
		transform 560ms var(--lx-out-expo),
		border-color var(--lx-t-base) var(--lx-out-expo),
		background-color var(--lx-t-base) var(--lx-out-expo),
		box-shadow var(--lx-t-base) var(--lx-out-expo),
		backdrop-filter var(--lx-t-base) var(--lx-out-expo);
}

/* Drawers glide with a spring and the page behind recedes very slightly. */
.lx-drawer { transition: transform 620ms var(--lx-spring-soft); }
.lx-search { transition: transform 680ms var(--lx-spring-soft); }

.lx-drawer__body > * {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 420ms var(--lx-out-expo), transform 420ms var(--lx-out-expo);
}
.lx-drawer.is-open .lx-drawer__body > * {
	opacity: 1;
	transform: none;
	transition-delay: 160ms;
}

.lx-overlay { transition: opacity 420ms var(--lx-out-expo), visibility 0s linear 420ms; }
.lx-overlay.is-open { transition-delay: 0s; }

/* Utility icons get a gentle spring on press. */
.lx-util { transition: background-color var(--lx-t-fast) var(--lx-out-expo), transform 260ms var(--lx-spring); }
.lx-util:active { transform: scale(.9); }

/* Cart badge pops when the count changes. */
.lx-util__count.is-bump { animation: lx-bump 540ms var(--lx-spring); }
@keyframes lx-bump {
	0%   { transform: scale(1); }
	30%  { transform: scale(1.45); }
	100% { transform: scale(1); }
}

/* --------------------------------------------------------------------------
   Toast
   -------------------------------------------------------------------------- */

.lx-toast {
	transition: transform 520ms var(--lx-spring), opacity 320ms var(--lx-out-expo);
}

/* --------------------------------------------------------------------------
   Marquee — pauses politely, eases on hover
   -------------------------------------------------------------------------- */

.lx-marquee__track { animation-timing-function: linear; }
.lx-marquee:hover .lx-marquee__track { animation-play-state: paused; }

/* --------------------------------------------------------------------------
   Counters
   -------------------------------------------------------------------------- */

[data-lx-count] { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   Page transitions (View Transitions API)
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

::view-transition-old(root) {
	animation: lx-vt-out 240ms var(--lx-out-expo) both;
}
::view-transition-new(root) {
	animation: lx-vt-in 420ms var(--lx-out-expo) both;
}
@keyframes lx-vt-out {
	to { opacity: 0; transform: translateY(-8px) scale(.994); }
}
@keyframes lx-vt-in {
	from { opacity: 0; transform: translateY(10px) scale(.996); }
}

/* The header should not animate between pages — it is persistent chrome. */
.lx-header { view-transition-name: lx-header; }
.lx-footer { view-transition-name: lx-footer; }
::view-transition-group(lx-header),
::view-transition-group(lx-footer) { animation-duration: 240ms; }

/* Product image morphs from the grid into the product page. */
[data-lx-vt-image] { view-transition-name: var(--lx-vt-name); }

/* --------------------------------------------------------------------------
   Rails — drag with momentum, elastic ends
   -------------------------------------------------------------------------- */

.lx-rail { scroll-behavior: smooth; }
.lx-rail.is-dragging {
	scroll-behavior: auto;
	cursor: grabbing;
	scroll-snap-type: none;
	user-select: none;
}
.lx-rail.is-dragging a { pointer-events: none; }
.lx-rail-nav button { transition: all 260ms var(--lx-spring); }
.lx-rail-nav button:active:not(:disabled) { transform: scale(.88); }

/* --------------------------------------------------------------------------
   Accordions
   -------------------------------------------------------------------------- */

.wp-block-details.is-style-lumiere-accordion > *:not(summary) {
	animation: lx-accordion 420ms var(--lx-out-expo);
}
@keyframes lx-accordion {
	from { opacity: 0; transform: translateY(-6px); }
	to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   Focus ring that grows rather than snapping
   -------------------------------------------------------------------------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
	transition: outline-offset 180ms var(--lx-spring);
	outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   Honour the user's motion preference — this whole file goes quiet
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	@view-transition { navigation: none; }

	[data-lx-in],
	[data-lx-stagger-in] > *,
	.lx-lines__inner,
	.lx-words__word {
		opacity: 1 !important;
		transform: none !important;
		filter: none !important;
		transition: none !important;
	}
	[data-lx-parallax],
	.lx-hero__media,
	.lx-hero__inner { transform: none !important; opacity: 1 !important; }
	[data-lx-parallax] > img,
	[data-lx-parallax] > video { height: 100%; }

	.lx-card__media img,
	.lx-gallery img,
	.lx-tile img { animation: none; }

	.lx-tile:hover,
	.lx-card:hover .lx-card__body { transform: none; }

	.wp-block-button__link::after { display: none; }
	.lx-progress { display: none; }
	.lx-wish.is-pulse svg,
	.lx-util__count.is-bump { animation: none; }
	.wp-block-details.is-style-lumiere-accordion > *:not(summary) { animation: none; }

	*, *::before, *::after {
		animation-duration: .001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .001ms !important;
	}
}
