/* ---------------------------------------------------------------------------
   Logo Marquee
   Continuous left-to-right logo strip, CSS-animation only.

   Custom properties set inline by module.html:
     --lm-bg        background colour (rgba)
     --lm-duration  seconds per full pass of the logo set
     --lm-shift     translateX end offset = exactly one group width, negated
--------------------------------------------------------------------------- */

.logo-marquee {
  --lm-logo-h: 40px;
  --lm-logo-max-w: 170px;
  --lm-gap: 64px;
  --lm-pad-y: 40px;
  --lm-fade: 96px;

  background: var(--lm-bg, #ffffff);
  padding: var(--lm-pad-y) 0;
  width: 100%;
  max-width: 100%;
  /* Belt and braces: the strip can never contribute to page-level scrolling. */
  overflow: hidden;
}

/* The clipping window. Everything wider than this is simply not painted. */
.logo-marquee__viewport {
  overflow: hidden;
  width: 100%;
  max-width: 100%;
}

@supports (mask-image: linear-gradient(#000, #000)) or
          (-webkit-mask-image: linear-gradient(#000, #000)) {
  .logo-marquee__viewport {
    -webkit-mask-image: linear-gradient(
      to right,
      transparent 0,
      #000 var(--lm-fade),
      #000 calc(100% - var(--lm-fade)),
      transparent 100%
    );
    mask-image: linear-gradient(
      to right,
      transparent 0,
      #000 var(--lm-fade),
      #000 calc(100% - var(--lm-fade)),
      transparent 100%
    );
  }
}

/* ---- The moving track ---------------------------------------------------
   Holds N identical groups laid out in a row. The animation moves it right by
   exactly one group width and snaps back. Because group N+1 is identical to
   group N, the snap is invisible: the last painted frame of a cycle and the
   first frame of the next are the same pixels.
------------------------------------------------------------------------- */
.logo-marquee__track {
  display: flex;
  flex-wrap: nowrap;
  width: max-content;
  animation-name: logo-marquee-scroll;
  animation-duration: var(--lm-duration, 40s);
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  will-change: transform;
  /* Avoid subpixel shimmer on the logo edges during the transform. */
  backface-visibility: hidden;
  transform: translateZ(0);
}

@keyframes logo-marquee-scroll {
  from {
    transform: translate3d(var(--lm-shift, -50%), 0, 0);
  }
  to {
    transform: translate3d(0, 0, 0);
  }
}

.logo-marquee__group {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--lm-gap);
  /* Reset list styling without relying on the host theme. */
  margin: 0;
  padding: 0 0 0 var(--lm-gap);
  list-style: none;
}

.logo-marquee__item {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  /* Fixed slot height keeps every logo on the same optical baseline. */
  height: var(--lm-logo-h);
  margin: 0;
  padding: 0;
  list-style: none;
}

.logo-marquee__link {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  border: 0;
  text-decoration: none;
}

/* ---- The logos ----------------------------------------------------------
   brightness(0) flattens every pixel to black regardless of the source
   colour; invert(1) then lifts it to pure white. Alpha is untouched, so the
   logo silhouette and its antialiased edges survive. Both variants are
   idempotent: the result is the same whether the PNG is the original colour
   artwork or has already been baked to a single tone.

   Which of the two applies comes from the logo_tone field, rendered as a
   class on the root element by module.html — not an inline style, so the
   visual editor cannot strip it.
------------------------------------------------------------------------- */
.logo-marquee__img {
  display: block;
  height: var(--lm-logo-h);
  width: auto;
  max-width: var(--lm-logo-max-w);
  /* contain guarantees the artwork is never stretched or squashed, whatever
     aspect ratio the source PNG has. */
  object-fit: contain;
  object-position: center;
  -webkit-user-select: none;
  user-select: none;
  pointer-events: none;
}

/* Dark logos for a light background. Held just short of full black so the
   strip reads as supporting proof rather than competing with the headline. */
.logo-marquee--tone-dark .logo-marquee__img {
  filter: brightness(0);
  opacity: 0.55;
}

/* White logos for a dark background. */
.logo-marquee--tone-light .logo-marquee__img {
  filter: brightness(0) invert(1);
  opacity: 0.9;
}

.logo-marquee__link .logo-marquee__img {
  pointer-events: auto;
}

/* ---- Pause on hover (only when the field is on) ------------------------- */
.logo-marquee--pause-hover:hover .logo-marquee__track,
.logo-marquee--pause-hover:focus-within .logo-marquee__track {
  animation-play-state: paused;
}

/* Set by module.js when the strip scrolls out of the viewport. */
.logo-marquee.is-offscreen .logo-marquee__track {
  animation-play-state: paused;
}

/* ---- Responsive ---------------------------------------------------------
   Logos and gaps shrink together so the rhythm stays the same; nothing here
   changes the overflow behaviour, so no breakpoint can introduce a horizontal
   page scrollbar.
------------------------------------------------------------------------- */
@media (max-width: 991px) {
  .logo-marquee {
    --lm-logo-h: 34px;
    --lm-logo-max-w: 140px;
    --lm-gap: 48px;
    --lm-pad-y: 32px;
    --lm-fade: 64px;
  }
}

@media (max-width: 599px) {
  .logo-marquee {
    --lm-logo-h: 26px;
    --lm-logo-max-w: 110px;
    --lm-gap: 32px;
    --lm-pad-y: 24px;
    --lm-fade: 40px;
  }
}

/* ---- Reduced motion -----------------------------------------------------
   Stop entirely rather than pausing: with no animation the track sits at its
   untransformed position, so the first group is fully visible from the left
   edge and the logos still read as a static strip.
------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .logo-marquee__track {
    animation: none;
    transform: none;
    will-change: auto;
  }

  .logo-marquee__viewport {
    /* Let the strip wrap into a static block instead of clipping most of it. */
    overflow: hidden;
  }

  .logo-marquee__track {
    width: 100%;
    flex-wrap: wrap;
  }

  .logo-marquee__group {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 24px;
    width: 100%;
    padding-left: 0;
  }

  /* One static set is enough; the duplicates exist only for the animation. */
  .logo-marquee__group[aria-hidden="true"] {
    display: none;
  }
}
