/*
 * uBind Logo Marquee - the complete presentation, defined once.
 *
 * Every rule is scoped to .ubind-logo-marquee, the wrapper the component renders itself,
 * and every class is namespaced. Nothing here can collide with a host page's own
 * .marquee / .customers / .logo-* rules, and nothing here depends on them.
 *
 * WHY THE !important ON BOX-MODEL PROPERTIES
 * Each uBind page opens its Elementor custom CSS with a blanket reset - some bare
 * (`* { margin: 0; padding: 0 }`), some scoped to a page wrapper this component renders
 * inside (`.ubind-about-page *`, `.ubind-elementor-page *`, `.ubind-features-page *`).
 * Those live in post-<id>.css, which WordPress prints *after* plugin stylesheets, so at
 * equal specificity they win on order. Marking the box-model declarations !important is
 * what keeps the band from collapsing on those pages. Colour and typography are left
 * unmarked deliberately, so a page can still retheme the strip.
 *
 * The strip's vertical padding needed that treatment too and is no longer here at all.
 * `ubind-section-rhythm` sets it for every full-bleed band on the site from a stylesheet
 * printed at wp_head 103 - after post-<id>.css - so it outranks those resets on order
 * without !important. Its --ub-strip-py is this component's own 60px/44px.
 *
 * Design tokens are used where the host page defines them, each with a literal fallback so
 * the component renders correctly on a page that defines none.
 */

.ubind-logo-marquee {
	--ubind-logo-marquee-fade: 160px;
	--ubind-logo-marquee-gap: 88px;
	--ubind-logo-marquee-duration: 52s;
	--ubind-logo-marquee-height: 28px;

	position: relative;
	overflow: hidden;
	margin: 0 !important;
	background: var(--ubind-logo-marquee-background);
}

/* ---- background variants ------------------------------------------------
 * The variant sets three things together: the band colour, the colour the edge
 * fades to (it has to match the band exactly or the fade shows a seam), and the
 * filter that flattens every logo to a single-colour silhouette.
 *
 * brightness(0) forces any source - colour, navy, black or an already-reversed
 * white asset - to flat black with its alpha intact; adding invert(1) makes that
 * white. So one logo file serves both variants, and reversed assets such as the
 * AXA mark do not disappear on the light band.
 */

.ubind-logo-marquee--dark {
	--ubind-logo-marquee-background: var(--ink-1000, #05100b);
	--ubind-logo-marquee-edge: var(--ink-1000, #05100b);
	--ubind-logo-marquee-label-color: rgba(255, 255, 255, .4);
	--ubind-logo-marquee-ink: brightness(0) invert(1);
	--ubind-logo-marquee-logo-opacity: .55;

	color: #fff;
	border-top: 1px solid rgba(255, 255, 255, .05);
}

.ubind-logo-marquee--light {
	--ubind-logo-marquee-background: #fff;
	--ubind-logo-marquee-edge: #fff;
	--ubind-logo-marquee-label-color: var(--ink-400, #6b7a73);
	--ubind-logo-marquee-ink: brightness(0);
	--ubind-logo-marquee-logo-opacity: .45;

	color: var(--ink-900, #0d1a13);
	border-top: 1px solid var(--ink-100, #e7ece9);
	border-bottom: 1px solid var(--ink-100, #e7ece9);
}

/* ---- label ---- */

.ubind-logo-marquee__label {
	margin: 0 0 32px !important;
	padding: 0 20px !important;
	text-align: center;
	color: var(--ubind-logo-marquee-label-color);
	font-family: var(--mono, var(--ubind-font-mono, "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace));
	font-size: 12px;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: .18em;
	text-transform: uppercase;
}

/* ---- track ----
 * The animation translates the track -50%, so the two halves must be exactly equal
 * in width. Spacing is therefore a trailing margin on every logo rather than a flex
 * gap: a gap leaves one fewer space than there are items, which makes the halves
 * unequal and the loop visibly jump.
 */

.ubind-logo-marquee__track {
	display: flex;
	align-items: center;
	width: max-content;
	margin: 0 !important;
	padding: 0 !important;
	/*
	 * The logos arrive from <template>s after `load`, so until then the track has no children to
	 * give it a height. The renderer measures the tallest logo in the set and passes it here, so
	 * the strip occupies its final height from first paint and promoting the logos shifts nothing.
	 */
	min-height: var(--ubind-logo-marquee-reserve, var(--ubind-logo-marquee-height));
	animation: ubind-logo-marquee-scroll var(--ubind-logo-marquee-duration) linear infinite;

	/*
	 * Held still until the logos have actually painted (UBW-251).
	 *
	 * The animation is declared on the track, so it starts at page load - long before the script
	 * promotes the logos and long before 300KB of logo files have arrived. It was therefore
	 * scrolling an empty track: by the time a logo finished downloading, its slot had already been
	 * carried off to the left, and the visitor was looking at a band that had the label, the right
	 * height, and nothing in it. On a phone on a slow connection that lasted for tens of seconds
	 * and read as broken.
	 *
	 * A paused animation does not advance, so un-pausing starts it from translateX(0) with the
	 * first logos where they belong - at the left edge, on screen. The strip is fully visible the
	 * whole time it is paused; this defers motion, never content.
	 */
	animation-play-state: paused;
}

.ubind-logo-marquee--ready .ubind-logo-marquee__track {
	animation-play-state: running;
}

/* The track deliberately does NOT pause on hover, and the logos have no hover state.
 *
 * Pausing existed to make a moving hover target hittable, but nothing here is clickable -
 * the logos are plain images, so there was nothing to hit and the stop read as a glitch.
 *
 * The per-logo brighten went with it: browsers only re-evaluate :hover on mouse events, not
 * when a transform slides a new element under a stationary cursor, so on a running track the
 * highlight sticks to the wrong logo. Correct behaviour needs the pause, and the pause is
 * what we are removing.
 *
 * Accessibility is unaffected. Hover-pause never satisfied WCAG 2.2.2 (Pause, Stop, Hide) -
 * it is not keyboard operable and not discoverable. The mechanism here is the
 * prefers-reduced-motion block at the foot of this file, which is untouched.
 */

/* ---- logos ----
 * Sized by height with width left to the intrinsic ratio. The !important on the
 * dimensions also neutralises WP Rocket, which adds width/height attributes to
 * images; those act as presentational hints and, against a max-width rule, make the
 * browser clamp each axis independently instead of preserving the ratio.
 */

/* Imagify's next-gen display wraps optimised rasters as <picture><source><img></picture>. That puts
 * a node between the track and the image, so a `> img` rule stops matching them - while continuing
 * to match the SVG logos, which Imagify never converts. The result is a strip where half the logos
 * keep the silhouette filter and the 88px spacing and half render in full colour, flush against
 * their neighbours, at whatever height their width/height attributes imply. Nothing errors.
 *
 * `display: contents` removes the wrapper from layout entirely, so the <img> is once again the flex
 * item of the track and `flex`, `margin` and `height` behave exactly as they do for an unwrapped
 * logo. The custom properties the renderer sets on the wrapper (--ubind-logo-h, --ubind-logo-shift)
 * still inherit through it.
 *
 * The selector below is widened rather than loosened to a descendant combinator: `> picture > img`
 * says precisely which extra structure is expected, so an unrelated nested image would still not be
 * caught by it. */
.ubind-logo-marquee__track > picture {
	display: contents;
}

.ubind-logo-marquee__track > img,
.ubind-logo-marquee__track > picture > img {
	flex: none;
	display: block;
	width: auto !important;
	height: var(--ubind-logo-h, var(--ubind-logo-marquee-height)) !important;
	max-width: none !important;
	max-height: none !important;
	margin: 0 var(--ubind-logo-marquee-gap) 0 0 !important;
	object-fit: contain;
	filter: var(--ubind-logo-marquee-ink);
	opacity: var(--ubind-logo-marquee-logo-opacity);
	transform: translateY(var(--ubind-logo-shift, 0));
}

/* ---- edge fades ---- */

.ubind-logo-marquee::before,
.ubind-logo-marquee::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: var(--ubind-logo-marquee-fade);
	z-index: 2;
	pointer-events: none;
}

.ubind-logo-marquee::before {
	left: 0;
	background: linear-gradient(90deg, var(--ubind-logo-marquee-edge), transparent);
}

.ubind-logo-marquee::after {
	right: 0;
	background: linear-gradient(-90deg, var(--ubind-logo-marquee-edge), transparent);
}

/* 160px of fade each side swallows a 375px viewport - keep the edges soft but leave
   the logos room to read on a phone */
@media (max-width: 600px) {
	.ubind-logo-marquee {
		--ubind-logo-marquee-fade: 56px;
	}
}

/* Motion off: the strip becomes a static, centred, wrapping logo wall. The duplicate
   half is hidden so nothing appears twice once it is all visible at once. */
@media (prefers-reduced-motion: reduce) {
	.ubind-logo-marquee__track {
		animation: none;
		width: auto;
		flex-wrap: wrap;
		justify-content: center;
		gap: 34px 60px !important;
		padding: 0 28px !important;
	}

	.ubind-logo-marquee__track > img,
	.ubind-logo-marquee__track > picture > img {
		margin-right: 0 !important;
	}

	/* The duplicate half is marked aria-hidden on the <img>, so once Imagify wraps a logo the
	 * attribute sits one level below the track and the first selector alone stops hiding it -
	 * every raster logo would then appear twice in the reduced-motion wall. */
	.ubind-logo-marquee__track > [aria-hidden="true"],
	.ubind-logo-marquee__track > picture > [aria-hidden="true"] {
		display: none;
	}

	.ubind-logo-marquee::before,
	.ubind-logo-marquee::after {
		display: none;
	}
}

@keyframes ubind-logo-marquee-scroll {
	from {
		transform: translateX(0);
	}

	to {
		transform: translateX(-50%);
	}
}
