/**
 * Motion Text widget styles.
 *
 * The scrolling animation's *duration* and *keyframe choice* are
 * computed by assets/js/motion-text.js (based on rendered content
 * width, the Speed control, and the current direction), but the
 * animation itself runs purely on CSS transforms so the browser can
 * hand it off to the compositor thread. JS never mutates transform
 * on every frame -- it only sets `animation` once per (re)layout.
 */

.scrmarq-marquee {
	position: relative;
	display: flex;
	overflow: hidden;
	width: 100%;
	/* Isolate layout/paint so the continuously animating track never
	   forces recalculation of the surrounding page. */
	contain: layout paint;
}

/**
 * Fade edges.
 *
 * Purely decorative overlays -- not animated themselves -- so they
 * are unaffected by prefers-reduced-motion. --scrmarq-fade-width and
 * --scrmarq-fade-color are set inline by Elementor's responsive Fade
 * Width / Fade Color controls (see MotionText::register_advanced_motion_section()),
 * so both values -- and therefore the fade -- automatically resize
 * per breakpoint with no JavaScript involved. pointer-events: none
 * keeps items underneath the fade fully clickable/focusable.
 */
.scrmarq-marquee[data-fade-enabled="1"]::before,
.scrmarq-marquee[data-fade-enabled="1"]::after {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	width: var( --scrmarq-fade-width, 60px );
	pointer-events: none;
	z-index: 2;
}

.scrmarq-marquee[data-fade-enabled="1"]::before {
	left: 0;
	background: linear-gradient( to right, var( --scrmarq-fade-color, transparent ), transparent );
}

.scrmarq-marquee[data-fade-enabled="1"]::after {
	right: 0;
	background: linear-gradient( to left, var( --scrmarq-fade-color, transparent ), transparent );
}

.scrmarq-marquee__track {
	--scrmarq-gap: 50px;

	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	gap: var( --scrmarq-gap );
	white-space: nowrap;
	width: max-content;

	/* GPU acceleration hints. translate3d() (applied in the keyframes
	   below) promotes the track to its own compositor layer so the
	   animation runs off the main thread. */
	will-change: transform;
	transform: translate3d( 0, 0, 0 );
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
}

/**
 * Flicker-free measuring state.
 *
 * motion-text.js adds this class for a single frame while it resets,
 * measures, and (re)builds the duplicated item sets needed for a
 * seamless loop. The track fades back in once the animation has been
 * assigned, so editors never see unstyled/unsized content flash or
 * pop into place. If JavaScript never runs at all (blocked, error,
 * no-JS), this class is simply never added and the track stays fully
 * visible as a static, non-animated line of text -- a safe fallback.
 */
.scrmarq-marquee__track--measuring {
	opacity: 0;
}

.scrmarq-marquee__track--ready {
	opacity: 1;
	transition: opacity 0.25s ease;
}

.scrmarq-marquee__item {
	display: inline-flex;
	align-items: center;
	white-space: nowrap;
	text-decoration: none;
	transition: color 0.2s ease;

	/* Style > Advanced > Text Stroke. Always applied: with no stroke
	   width set the custom property falls back to 0, so this is a
	   no-op until an editor opts in via the Text Stroke Width control. */
	-webkit-text-stroke: var( --scrmarq-text-stroke-width, 0px ) var( --scrmarq-text-stroke-color, transparent );
}

.scrmarq-marquee__item a {
	color: inherit;
	text-decoration: none;
}

/* Duplicated sets injected by JS for the seamless loop are purely
   decorative/visual repeats of the same content, so they're hidden
   from assistive tech and never keyboard-focusable. */
.scrmarq-marquee__item[data-scrmarq-clone="1"] a {
	pointer-events: none;
}

/**
 * Pausing (hover, viewport-visibility, and browser-tab-visibility) is
 * driven entirely by motion-text.js, which combines all active pause
 * reasons for a given instance and sets animation-play-state directly
 * on the track. This keeps a single source of truth instead of having
 * inline JS and CSS class-based rules race for control of the same
 * property.
 */

/**
 * GPU acceleration toggle.
 *
 * On by default (see .scrmarq-marquee__track's will-change above). When
 * an editor disables it via the "GPU Acceleration" control, drop the
 * compositor-layer hint -- the track still animates via translate3d()
 * in the keyframes below, but the browser is no longer asked to keep
 * a dedicated layer promoted for it.
 */
.scrmarq-marquee[data-gpu-acceleration="0"] .scrmarq-marquee__track {
	will-change: auto;
}

@keyframes scrmarq-marquee-scroll-rtl {
	from {
		transform: translate3d( 0, 0, 0 );
	}
	to {
		transform: translate3d( -50%, 0, 0 );
	}
}

@keyframes scrmarq-marquee-scroll-ltr {
	from {
		transform: translate3d( -50%, 0, 0 );
	}
	to {
		transform: translate3d( 0, 0, 0 );
	}
}

@keyframes scrmarq-marquee-scroll-rtl-once {
	from {
		transform: translate3d( 0, 0, 0 );
	}
	to {
		transform: translate3d( -100%, 0, 0 );
	}
}

@keyframes scrmarq-marquee-scroll-ltr-once {
	from {
		transform: translate3d( -100%, 0, 0 );
	}
	to {
		transform: translate3d( 0, 0, 0 );
	}
}

/**
 * Icons (Style > Icons).
 *
 * Markup is only ever printed by MotionText::render_items() when the
 * corresponding switcher is enabled, so this rule has no effect (and no
 * cost) on widgets that don't use icons. Size/color/gap are all driven by
 * their own Elementor controls' `selectors`.
 */
.scrmarq-marquee__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
}

.scrmarq-marquee__icon svg {
	width: 1em;
	height: 1em;
	fill: currentColor;
}

/**
 * Dividers (Style > Dividers).
 *
 * Only printed between items when "Enable Divider" is on. Implemented as
 * a zero-width element with a left border so Style > Dividers' Style/
 * Width/Height/Color controls can each target a single, independent CSS
 * property via their own `selectors` (see register_style_dividers_section()).
 */
.scrmarq-marquee__divider {
	display: inline-block;
	align-self: center;
	border-left: 1px solid currentColor;
	flex-shrink: 0;
}

/**
 * Gradient text (Style > Advanced).
 *
 * Each of the three Gradient Text controls writes its own CSS custom
 * property on the wrapper (see register_style_advanced_section()); this
 * rule combines them into a single `linear-gradient()` and is gated by
 * `data-gradient-text`, set from the "Gradient Text" switcher in render().
 */
.scrmarq-marquee[data-gradient-text="1"] .scrmarq-marquee__item {
	background-image: linear-gradient(
		var( --scrmarq-text-gradient-angle, 90deg ),
		var( --scrmarq-text-gradient-color-1, currentColor ),
		var( --scrmarq-text-gradient-color-2, currentColor )
	);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

/**
 * Backdrop blur (Style > Advanced).
 *
 * Gated by `data-backdrop-blur`, set from the "Backdrop Blur" switcher in
 * render(); the blur radius itself comes from the Backdrop Blur Amount
 * control's own custom property.
 */
.scrmarq-marquee[data-backdrop-blur="1"] {
	backdrop-filter: blur( var( --scrmarq-backdrop-blur, 8px ) );
	-webkit-backdrop-filter: blur( var( --scrmarq-backdrop-blur, 8px ) );
}

/**
 * Glass effect (Style > Advanced).
 *
 * A frosted-glass preset gated by `data-glass-effect`, set from the
 * "Glass Effect" switcher in render(). Opacity is tunable via the Glass
 * Opacity control's custom property; works best over a page area that
 * isn't already opaque.
 */
.scrmarq-marquee[data-glass-effect="1"] {
	background-color: rgba( 255, 255, 255, var( --scrmarq-glass-opacity, 0.15 ) );
	backdrop-filter: blur( 10px );
	-webkit-backdrop-filter: blur( 10px );
	border: 1px solid rgba( 255, 255, 255, 0.2 );
}

/**
 * Accessibility: respect the user's OS/browser-level reduced-motion
 * preference. `!important` is required here because it must win over
 * the inline `animation` shorthand that JS assigns to the track.
 */
@media ( prefers-reduced-motion: reduce ) {
	.scrmarq-marquee__track {
		animation: none !important;
		transform: none !important;
	}

	.scrmarq-marquee__track--measuring {
		opacity: 1;
	}
}
