/**
 * Nexio Toolkit — GSAP marquee widget styles (Vertical Marquee + Logo Marquee).
 */

/* --------------------------------------------------------------------
 * Vertical GSAP Marquee
 * ------------------------------------------------------------------ */

.nexio-v-marquee {
	position: relative;
	display: flex;
	align-items: stretch;
	overflow: hidden;
	min-height: var(--min-height, 600px);
	max-height: var(--min-height, 600px);
}

.nexio-v-column {
	position: relative;
	flex: 1 1 0;
	min-width: 0;
	overflow: hidden;
}

/*
 * Layer promotion note: the JS sets will-change inline at build time, on
 * the elements that genuinely move — the ITEMS for the vertical engine
 * (the rail itself never moves there) and the RAIL for the horizontal
 * strip. It is deliberately permanent: toggling promotion with
 * visibility forces a re-rasterization at the moment the section
 * scrolls in, which is a visible hitch on weaker machines. Nothing is
 * promoted under prefers-reduced-motion because the JS never builds.
 */
.nexio-v-rail {
	display: flex;
	flex-direction: column;
}

.nexio-v-item {
	flex: 0 0 auto;
	line-height: 0;
	transition: none !important; /* Theme transitions must not fight GSAP. */
}

.nexio-v-item img {
	display: block;
	width: 100%;
	height: auto;
}

.nexio-v-item a {
	display: block;
	line-height: 0;
}

/* Fade overlay — solid at the very top/bottom, 25% of the picked color
   around the 20% / 80% marks, fully transparent through the middle.
   color-mix() lets any picked color work with the partial stops. */
.nexio-vm-overlay-yes .nexio-v-marquee::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 2;
	background: linear-gradient(
		180deg,
		var(--nexio-overlay-color, #fdfdff) 0%,
		color-mix(in srgb, var(--nexio-overlay-color, #fdfdff) 25%, transparent) 20%,
		transparent 35%,
		transparent 65%,
		color-mix(in srgb, var(--nexio-overlay-color, #fdfdff) 25%, transparent) 80%,
		var(--nexio-overlay-color, #fdfdff) 100%
	);
}

/* Soft layered drop shadow — hugs the image shape (radius/transparency). */
.nexio-vm-softshadow-yes .nexio-v-item img {
	filter: drop-shadow(0 24px 14px rgba(0, 0, 0, 0.01))
		drop-shadow(0 11px 11px rgba(0, 0, 0, 0.02))
		drop-shadow(0 3px 6px rgba(0, 0, 0, 0.02));
}

/* --------------------------------------------------------------------
 * Testimonial Marquee
 *
 * Shares the vertical engine and classes above; the extra
 * .nexio-t-marquee wrapper class neutralizes the image-marquee's
 * line-height/full-width-img resets, and the .nexio-t-* classes style
 * the card. Everything below is a sensible default — the widget's
 * Style tab overrides any of it per instance.
 * ------------------------------------------------------------------ */

/*
 * The generic engine uses overflow: hidden on the marquee and each
 * column to mask the loop, but that also clips the card box-shadows at
 * the left/right edges. The testimonial variant needs the shadows to
 * breathe — but it must still clip for LAYOUT, not just for paint.
 *
 * clip-path alone was the wrong tool: it hides the overflowing rail
 * visually while the rail (several thousand pixels of stacked, cloned
 * cards) still counts towards the page's scrollable area. That is what
 * added a tall band of empty space below the footer.
 *
 * `overflow-clip-margin` was the wrong tool for that headroom: it
 * applies to all four sides, so the 80px that let the shadows breathe
 * sideways also punched an 80px hole in the top and bottom mask — the
 * two edges the marquee exists to hide. Cards were left painting a
 * third of the way out of the section, above and below.
 *
 * visible/clip is the one axis pairing CSS does NOT coerce (any other
 * mix of visible with a clipping value computes to auto/hidden), so it
 * gives shadows unlimited sideways room while the vertical edges stay
 * hard-masked with no clip margin at all. Only the shadow bleed is lost
 * where clip is unsupported, hence the @supports guard — declaring
 * overflow-x: visible unguarded would pair with the hidden fallback and
 * coerce to auto, i.e. a horizontal scrollbar.
 */
.nexio-t-marquee.nexio-v-marquee,
.nexio-t-marquee .nexio-v-column {
	overflow: hidden;
	clip-path: none;
}

@supports (overflow: clip) {
	.nexio-t-marquee.nexio-v-marquee,
	.nexio-t-marquee .nexio-v-column {
		overflow-x: visible;
		overflow-y: clip;
		overflow-clip-margin: 0;
	}
}

.nexio-t-marquee .nexio-v-item {
	line-height: normal;
}

.nexio-t-marquee .nexio-v-item img {
	width: auto;
	max-width: 100%;
}

.nexio-t-card {
	background-color: #ffffff;
	border: 1px solid #eef1f5;
	border-radius: 20px;
	padding: 32px 26px;
	text-align: center;
	/* Soft, diffuse elevation: one large blurred layer pulled in with a
	   negative spread (no hard edge) plus a faint contact shadow. */
	box-shadow: 0 24px 48px -20px rgba(15, 23, 42, 0.16),
		0 1px 2px rgba(15, 23, 42, 0.04);
}

.nexio-t-avatar {
	line-height: 0;
	margin-bottom: 14px;
}

.nexio-t-avatar img {
	width: 64px;
	height: 64px;
	object-fit: cover;
	border-radius: 50%;
	display: inline-block;
}

.nexio-t-name {
	font-size: 18px;
	font-weight: 600;
	line-height: 1.3;
	color: #1f2430;
}

.nexio-t-role {
	margin-top: 2px;
	font-size: 13px;
	line-height: 1.4;
	color: #8a8f98;
}

.nexio-t-divider {
	width: 160px;
	max-width: 70%;
	height: 1px;
	background-color: #e6e8ec;
	margin-top: 16px;
	margin-bottom: 16px;
	margin-left: var(--nexio-t-divider-ml, auto);
	margin-right: var(--nexio-t-divider-mr, auto);
}

.nexio-t-quote {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 17px;
	line-height: 1.6;
	color: #1f2430;
}

/* Automatic typographic quotation marks (widget switcher). */
.nexio-tm-quotes-yes .nexio-t-quote::before {
	content: "\201C";
}

.nexio-tm-quotes-yes .nexio-t-quote::after {
	content: "\201D";
}

/* --------------------------------------------------------------------
 * Horizontal Logo Marquee
 * ------------------------------------------------------------------ */

.nexio-h-marquee {
	position: relative;
	overflow: hidden;
	width: 100%;
	/*
	 * The rail is several times wider than the viewport and repaints as
	 * it moves. `contain` tells the browser that nothing inside can
	 * affect layout or painting outside this box, so those repaints stop
	 * invalidating the rest of the page while the visitor scrolls. Safe
	 * here because the strip already clips with overflow: hidden.
	 */
	contain: layout paint;
}

.nexio-h-rail {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	width: max-content;
	/* will-change is applied inline by the JS at build time — see the
	   layer promotion note on .nexio-v-rail above. */
}

.nexio-h-item {
	flex: 0 0 auto;
	line-height: 0;
	transition: none !important; /* Theme transitions must not fight GSAP. */
}

/* Width/height are overridden per instance by the widget's Logo
   Width / Logo Height controls (and per-logo Custom Width/Height in
   the repeater); object-fit keeps logos undistorted when both axes
   are fixed. */
.nexio-h-item img {
	display: block;
	width: auto;
	height: 68px;
	object-fit: contain;
}

.nexio-h-item a {
	display: block;
	line-height: 0;
}

/* Separator icon rendered between logos (widget "Icon Between
   Logos"). font-size drives <i> font icons; uploaded SVG icons get an
   explicit box from the Icon Size control and fall back to 1em here. */
.nexio-h-sep {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 24px;
	line-height: 1;
	transition: none !important; /* Theme transitions must not fight GSAP. */
}

.nexio-h-sep svg {
	display: block;
	width: 1em;
	height: 1em;
	fill: currentColor;
}

/* Grayscale until hover. */
.nexio-hm-grayscale-yes .nexio-h-item img {
	filter: grayscale(1);
	opacity: 0.75;
	transition: filter 0.3s ease, opacity 0.3s ease;
}

.nexio-hm-grayscale-yes .nexio-h-item:hover img {
	filter: grayscale(0);
	opacity: 1;
}

/* Edge fade — two mechanisms sharing --nexio-h-fade-width (widget
   "Fade Width" control, default 8%):

   1. Default (no Fade Color picked): a mask fades the strip to full
      transparency, so it blends into ANY background.
   2. Fade Color picked: the widget outputs --nexio-h-fade-color and
      flips --nexio-h-mask to `none`, which disables the mask below and
      activates the ::before/::after gradients that fade into the
      chosen color instead. While the color var is unset, those
      gradients contain an unresolvable var() — invalid at
      computed-value time — so the pseudo-elements paint nothing.

   The two can't simply be stacked because a mask on the marquee also
   masks its own pseudo-elements, which would erase the color overlay
   exactly where it's needed. */
.nexio-hm-fade-yes .nexio-h-marquee {
	-webkit-mask-image: var(
		--nexio-h-mask,
		linear-gradient(
			90deg,
			transparent 0%,
			#000 var(--nexio-h-fade-width, 8%),
			#000 calc(100% - var(--nexio-h-fade-width, 8%)),
			transparent 100%
		)
	);
	mask-image: var(
		--nexio-h-mask,
		linear-gradient(
			90deg,
			transparent 0%,
			#000 var(--nexio-h-fade-width, 8%),
			#000 calc(100% - var(--nexio-h-fade-width, 8%)),
			transparent 100%
		)
	);
}

.nexio-hm-fade-yes .nexio-h-marquee::before,
.nexio-hm-fade-yes .nexio-h-marquee::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: var(--nexio-h-fade-width, 8%);
	pointer-events: none;
	z-index: 2;
}

.nexio-hm-fade-yes .nexio-h-marquee::before {
	left: 0;
	background: linear-gradient(
		90deg,
		var(--nexio-h-fade-color) 0%,
		transparent 100%
	);
}

.nexio-hm-fade-yes .nexio-h-marquee::after {
	right: 0;
	background: linear-gradient(
		270deg,
		var(--nexio-h-fade-color) 0%,
		transparent 100%
	);
}

/* --------------------------------------------------------------------
 * Reduced motion
 * ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
	/* The JS refuses to start a loop at all under reduced motion; this
	   belt-and-braces rule beats any inline will-change should a build
	   somehow have happened before the preference changed. */
	.nexio-v-rail,
	.nexio-h-rail,
	.nexio-v-item {
		will-change: auto !important;
	}
}
