/**
 * RMS MOTION — one vocabulary, used everywhere.
 *
 * Five movements, and no more. A site that animates five things
 * consistently reads as designed; one that animates fifteen things
 * differently reads as decorated.
 *
 *   1. RISE      a band arrives from 14px below, its children staggered.
 *   2. DRAW      an underline grows from the left under a link.
 *   3. CONDENSE  the header tightens and gains a shadow once you scroll.
 *   4. SHIMMER   a placeholder that is obviously loading, not obviously broken.
 *   5. LIFT      a card rises a brand-specific distance on hover.
 *   6. TRACE     a section's brand rule draws itself as you reach it.
 *   7. COUNT     a number climbs to its value the first time it is seen.
 *   8. GLINT     light travels once across a product photograph on hover.
 *   9. STICK     a sticky element deepens the moment it starts sticking.
 *  10. PROGRESS  a hairline under the header showing how far down a long
 *                technical page you have read.
 *  11. NOTICE    a control that has just changed acknowledges it, once.
 *
 * Six more than the original five, and each one earns its place by telling
 * the reader something: how big the catalogue is, where a section starts,
 * that an element is now pinned, how much of a guide is left, that the
 * basket took the click. None of them is decoration for its own sake, and
 * every one of them is silent under prefers-reduced-motion.
 *
 * Three rules that are not negotiable:
 *
 *   - Nothing here may leave content invisible. Every hidden state is added
 *     by script and released by a timer as well as by an observer, so a
 *     browser that never fires the observer still shows the page.
 *   - Every duration comes from --rms-dur, which each brand sets for
 *     itself: ABB .28s (industrial), EM .35s, Schneider .42s. The same
 *     movement therefore has a different temperament per storefront
 *     without a single per-brand rule.
 *   - prefers-reduced-motion removes all of it. Not "reduces" — removes.
 */

/* ---- 1. RISE ---------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	[data-rms-reveal].rms-reveal-pending {
		opacity: 0;
		transform: translate3d(0, 14px, 0);
	}

	[data-rms-reveal].is-in {
		opacity: 1;
		transform: none;
		transition:
			opacity .55s cubic-bezier(.22, .61, .36, 1),
			transform .55s cubic-bezier(.22, .61, .36, 1);
	}

	/*
	 * The stagger is what makes it read as hand-made rather than as a
	 * blanket fade: the heading arrives, then the copy, then the cards.
	 * Capped at six steps so a long row never delays its own last card by
	 * half a second.
	 */
	[data-rms-reveal].is-in > * {
		animation: rms-rise .5s cubic-bezier(.22, .61, .36, 1) both;
	}

	[data-rms-reveal].is-in > :nth-child(1) { animation-delay: 0ms; }
	[data-rms-reveal].is-in > :nth-child(2) { animation-delay: 60ms; }
	[data-rms-reveal].is-in > :nth-child(3) { animation-delay: 120ms; }
	[data-rms-reveal].is-in > :nth-child(4) { animation-delay: 180ms; }
	[data-rms-reveal].is-in > :nth-child(5) { animation-delay: 240ms; }
	[data-rms-reveal].is-in > :nth-child(n + 6) { animation-delay: 300ms; }

	@keyframes rms-rise {
		from { opacity: 0; transform: translate3d(0, 10px, 0); }
		to   { opacity: 1; transform: none; }
	}

	/* A grid of cards staggers by card, not by row. */
	.rms-prow__list.is-in > li,
	.rms-cats__grid.is-in > li {
		animation: rms-rise .45s cubic-bezier(.22, .61, .36, 1) both;
	}
}

/* ---- 2. DRAW ---------------------------------------------------------- */

.rms-link-draw,
.rms-chrome__nav a,
.rms-pnet__card,
.rms-crumb__list a,
.rms-catsubs__chips .rms-pill {
	position: relative;
}

.rms-link-draw::after,
.rms-chrome__nav > ul > li > a::after,
.rms-crumb__list a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -3px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--rms-dur, .3s) cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
	.rms-link-draw::after,
	.rms-chrome__nav > ul > li > a::after,
	.rms-crumb__list a::after {
		transition: none;
	}
}

.rms-link-draw:hover::after,
.rms-link-draw:focus-visible::after,
.rms-chrome__nav > ul > li > a:hover::after,
.rms-chrome__nav > ul > li > a:focus-visible::after,
.rms-crumb__list a:hover::after,
.rms-crumb__list a:focus-visible::after {
	transform: scaleX(1);
}

/* ---- 3. CONDENSE ------------------------------------------------------ */

.rms-chrome--header {
	transition:
		box-shadow var(--rms-dur, .3s) ease,
		background-color var(--rms-dur, .3s) ease;
}

.rms-chrome--header.is-condensed {
	box-shadow: 0 6px 24px rgba(11, 18, 32, .10);
}

@media (prefers-reduced-motion: no-preference) {
	.rms-chrome--header .rms-chrome__top {
		overflow: hidden;
		transition:
			max-height var(--rms-dur, .3s) cubic-bezier(.22, .61, .36, 1),
			opacity var(--rms-dur, .3s) ease;
		max-height: 60px;
	}

	/*
	 * The announcement strip folds away once the reader has committed to
	 * the page, giving the nav back ~36px on every scroll. It returns the
	 * moment they scroll back to the top, so nothing is lost.
	 */
	.rms-chrome--header.is-condensed .rms-chrome__top {
		max-height: 0;
		opacity: 0;
	}
}

/* ---- 4. SHIMMER ------------------------------------------------------- */

.rms-skel {
	position: relative;
	overflow: hidden;
	background: var(--rms-muted, #f5f7f9);
	border-radius: var(--rms-radius-sm, 6px);
}

@media (prefers-reduced-motion: no-preference) {
	.rms-skel::after {
		content: "";
		position: absolute;
		inset: 0;
		transform: translateX(-100%);
		background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .65), transparent);
		animation: rms-shimmer 1.35s ease-in-out infinite;
	}

	@keyframes rms-shimmer {
		100% { transform: translateX(100%); }
	}
}

/* ---- 5. LIFT ---------------------------------------------------------- */

.rms-lift {
	transition:
		transform var(--rms-dur, .3s) cubic-bezier(.22, .61, .36, 1),
		box-shadow var(--rms-dur, .3s) ease;
}

.rms-lift:hover,
.rms-lift:focus-within {
	transform: translateY(var(--rms-lift, -2px));
	box-shadow: 0 12px 28px rgba(11, 18, 32, .10);
}

/* ---- The blanket switch ----------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}

	/* And nothing may be left hidden by a reveal that no longer runs. */
	[data-rms-reveal],
	[data-rms-reveal].rms-reveal-pending {
		opacity: 1 !important;
		transform: none !important;
	}
}

/* ---- 6. TRACE ---------------------------------------------------------
 *
 * The accent rule under a section heading draws itself from the left as the
 * section is reached.
 *
 * It already had an animation, `rms-rule-in`, but that fired on page load —
 * so on a page with eight sections, seven of them drew their rule while
 * still far below the fold and the reader never saw any of it. Bound to the
 * reveal state instead, it happens where the eye already is.
 * -------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	[data-rms-trace]::after {
		transform: scaleX(0);
		transform-origin: left;
	}

	[data-rms-trace].is-in::after,
	.is-in [data-rms-trace]::after {
		transform: scaleX(1);
		transition: transform var(--rms-dur, .35s) cubic-bezier(.22, .61, .36, 1) 80ms;
	}
}

/* ---- 7. COUNT ---------------------------------------------------------
 *
 * "3,593 PRODUCTS" climbs to its value the first time it is scrolled to.
 *
 * The number is the argument: a distributor's credibility is its depth of
 * stock, and a figure that arrives rather than simply being there is read
 * rather than skipped. The final value is always the real one — the script
 * counts to the number already in the markup and never invents it, and a
 * browser with no script shows the number exactly as rendered.
 * -------------------------------------------------------------------- */

.rms-count {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

@media (prefers-reduced-motion: no-preference) {
	.rms-count.is-counting {
		color: var(--rms-primary-d, currentColor);
		transition: color .6s ease;
	}
}

/* ---- 8. GLINT ---------------------------------------------------------
 *
 * A band of light travels once across a product photograph on hover.
 *
 * Every image in this catalogue is a piece of hardware shot on white, and a
 * single slow specular pass is how those products are lit in a showroom. It
 * runs once per hover, over 700ms, at 12% opacity — enough to notice, not
 * enough to interfere with reading a terminal marking.
 * -------------------------------------------------------------------- */

.rms-glint {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.rms-glint::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	opacity: 0;
	background: linear-gradient(
		105deg,
		transparent 38%,
		rgba(255, 255, 255, .62) 47%,
		rgba(255, 255, 255, .82) 50%,
		rgba(255, 255, 255, .62) 53%,
		transparent 62%
	);
	transform: translate3d(-120%, 0, 0);
}

@media (prefers-reduced-motion: no-preference) {
	.rms-glint:hover::after,
	.rms-glint:focus-within::after,
	a:hover > .rms-glint::after,
	.rms-item:hover .rms-glint::after {
		opacity: .55;
		animation: rms-glint .7s cubic-bezier(.3, .1, .2, 1) 1;
	}

	@keyframes rms-glint {
		from { transform: translate3d(-120%, 0, 0); }
		to   { transform: translate3d(120%, 0, 0); }
	}
}

/* ---- 9. STICK ---------------------------------------------------------
 *
 * A sticky element says so the moment it starts sticking.
 *
 * The buy column, the filter rail and the section nav all pin themselves,
 * and until now nothing marked the transition — so the page appeared to
 * stop scrolling in one column for no visible reason. A shadow and a
 * hairline arriving at the moment of pinning explain it in one frame.
 * A sentinel element and an observer detect it; no scroll handler.
 * -------------------------------------------------------------------- */

.rms-stick__sentinel {
	position: absolute;
	top: 0;
	left: 0;
	width: 1px;
	height: 1px;
	pointer-events: none;
	opacity: 0;
}

[data-rms-stick] {
	transition:
		box-shadow var(--rms-dur, .35s) var(--rms-ease, cubic-bezier(.2, .8, .2, 1)),
		border-color var(--rms-dur, .35s) var(--rms-ease, cubic-bezier(.2, .8, .2, 1));
}

[data-rms-stick].is-stuck {
	box-shadow: var(--rms-shadow-2, 0 14px 30px rgba(16, 26, 42, .10));
	border-color: var(--rms-line, #e3e7ee);
}

/* ---- 10. PROGRESS -----------------------------------------------------
 *
 * A hairline under the header, filling as a long page is read.
 *
 * A 4,000-word installation guide or a product page with eleven sections
 * gives no sense of its own length. This is the one indicator that answers
 * "how much of this is left" without taking any space to do it. It appears
 * only on pages long enough to need it — the script leaves it at zero width
 * otherwise — and it is painted in the brand's own rule fill.
 * -------------------------------------------------------------------- */

.rms-progress {
	position: fixed;
	top: var(--rms-head-h, 0px);
	left: 0;
	z-index: 60;
	width: 100%;
	height: 3px;
	pointer-events: none;
	background: transparent;
}

.rms-progress__bar {
	display: block;
	height: 100%;
	width: 0;
	border-radius: 0 var(--rms-rule-cap, 2px) var(--rms-rule-cap, 2px) 0;
	background: var(--rms-rule-fill, var(--rms-primary-d, #085a83));
	transform-origin: left;
	will-change: width;
}

@media (prefers-reduced-motion: no-preference) {
	.rms-progress__bar {
		transition: width .12s linear;
	}
}

/* ---- 11. NOTICE -------------------------------------------------------
 *
 * A control acknowledges a change, once.
 *
 * The cart and quote badges are the two numbers on the page that change
 * because of something the customer just did, and a number that changes
 * silently is a number that gets missed — which is how someone ends up
 * clicking "add" three times. One 420ms pop, and it never repeats on its
 * own.
 * -------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	.rms-notice-pop {
		animation: rms-pop .42s cubic-bezier(.34, 1.56, .64, 1) 1;
	}

	@keyframes rms-pop {
		0%   { transform: scale(1); }
		38%  { transform: scale(1.38); }
		100% { transform: scale(1); }
	}
}

/* =========================================================================
 * REDUCED MOTION — removes, never "reduces".
 *
 * Restated at the end of the file so it wins over every movement above,
 * including any added later. Anything that could leave content invisible is
 * forced back to its resting state here.
 * ====================================================================== */

@media (prefers-reduced-motion: reduce) {
	.rms-glint::after,
	[data-rms-trace]::after {
		animation: none !important;
		transition: none !important;
		opacity: 0;
		transform: none !important;
	}

	[data-rms-trace]::after {
		opacity: 1;
	}

	.rms-progress__bar,
	[data-rms-stick],
	.rms-notice-pop,
	.rms-count.is-counting {
		transition: none !important;
		animation: none !important;
	}
}
