/* ==========================================================================
   Habitus Concept, makers marquee

   The nine partner marks on a seamless drift. Following the Break Maiden board
   in Website Styles & Motions/Styles, the marks sit as white ink directly on
   the ground: no pill, no card, no plate, no border, no shadow, zero radius.
   That board's Logo Stamp rule is "no fill, no background plate", and a mark
   with a container around it is a container you are looking at, not a mark.

   Because the marks ship as white ink keyed onto transparency, losing the
   plate means the band itself has to carry the dark. It takes --plate, a shade
   deeper than the navy the project wall sits on, so the two dark sections read
   as two bands rather than one long run.

   HOW THE SEAM IS HIDDEN
   The run of nine is printed twice inside one track and the track translates
   exactly -50% of its own width, so at the end of the cycle the second copy
   sits precisely where the first one started. Nothing is measured in script.
   The duplicate carries aria-hidden, so the marks are announced once.

   HOW THE MARKS ARE SCALED
   A single height multiplier does not balance a logo wall, which is why the
   old one looked uneven: at equal height a sparse four line lockup like Union
   Elmes and a long thin wordmark like Konner paint wildly different amounts of
   ink. Each mark is therefore contained into a shared box, which settles the
   gross size, and then nudged by a factor derived from its own measured ink
   area, which settles the optical weight. The derivation, per mark:

     1. trim the PNG to its alpha bounding box
     2. ink   = sum(alpha) / 255,  the mark's real painted area in source px
     3. fit   = min(boxW/w, boxH/h),  what object-fit: contain will apply
     4. shown = ink * fit^2,  the ink area the box actually paints
     5. nudge = (median(shown) / shown) ^ 0.30
     6. stack = 1.28 if the trimmed mark is squarer than 1.5:1, else 1.00
     7. --s   = clamp(nudge * stack, 0.84, 1.62)

   The 0.30 exponent is deliberate. A full 0.50 equalises painted area exactly
   and over-corrects: Athmer has a solid filled field and Turnstyle is mostly
   air, both by design, and forcing them to paint the same amount shrinks one
   and inflates the other past what either mark should look like. At 0.30 the
   box does most of the work and the nudge only takes the edge off.

   The stack factor exists because a stacked lockup is not a wordmark. Union
   Elmes carries four lines and Turnstyle three; given a wordmark's box they
   shrink until their lower lines stop being letters, so anything squarer than
   1.5:1 gets a taller box. Re-run the derivation if a mark is added; the
   numbers live inline on each <li> as --s.

   No JavaScript. The drift is one CSS animation, the pause is a hover state,
   and under prefers-reduced-motion the rail stops and becomes a plain
   horizontally scrollable row instead.
   ========================================================================== */

.makers {
  background: var(--plate);
  padding-block: clamp(52px, 7vw, 100px);
  overflow: hidden;
}
.makers-eyebrow { text-align: center; color: var(--blue-soft); }

.mq {
  position: relative;
  margin-top: clamp(30px, 3.6vw, 54px);
  /* the rail runs off both edges of the page rather than stopping inside the
     gutter, so it reads as continuous rather than as a widget in a box */
  width: 100%;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right,
    transparent 0, #000 clamp(56px, 11vw, 190px),
    #000 calc(100% - clamp(56px, 11vw, 190px)), transparent 100%);
  mask-image: linear-gradient(to right,
    transparent 0, #000 clamp(56px, 11vw, 190px),
    #000 calc(100% - clamp(56px, 11vw, 190px)), transparent 100%);
}

.mq-track {
  display: flex;
  width: max-content;
  animation: mq-drift 54s linear infinite;
  will-change: transform;
}
.mq:hover .mq-track,
.mq:focus-within .mq-track { animation-play-state: paused; }

@keyframes mq-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* With the plates gone the marks need real air, or they read as one long
   graphic rather than as nine separate houses. */
.mq-run {
  display: flex;
  align-items: center;
  gap: clamp(46px, 5.4vw, 96px);
  margin: 0;
  padding: 0 clamp(23px, 2.7vw, 48px);
  list-style: none;
  flex: none;
}

.mq-mark {
  /* the shared box, then the per mark optical nudge from --s */
  --box-w: clamp(112px, 13.6vw, 196px);
  --box-h: clamp(28px, 3.3vw, 48px);
  flex: none;
  display: block;
  line-height: 0;
}
/* The box is put on the image itself rather than on a wrapper the image is
   told to fit inside. max-width plus max-height on a centred grid item does
   not reliably apply both constraints, and the tall marks were overflowing
   and getting clipped by the rail; an explicit box plus object-fit: contain
   is the same computation, done by the property that exists for it. */
.mq-mark img {
  display: block;
  width:  calc(var(--box-w) * var(--s, 1));
  height: calc(var(--box-h) * var(--s, 1));
  object-fit: contain;
  /* the marks rest a shade back and come up to full white on hover, which is
     the whole interaction: no fill arrives, nothing lifts, nothing glows */
  opacity: 0.78;
  transition: opacity 0.35s linear;
}
.mq-run:hover .mq-mark img { opacity: 0.42; }
.mq-mark:hover img { opacity: 1; }

@media (max-width: 620px) {
  .mq-mark { --box-w: clamp(96px, 30vw, 132px); --box-h: clamp(24px, 7vw, 34px); }
  .mq-run  { gap: clamp(34px, 9vw, 52px); }
}

/* Reduced motion: nothing drifts. The rail becomes a row the reader pushes
   themselves, and the duplicate run is dropped so nothing repeats. */
@media (prefers-reduced-motion: reduce) {
  .mq {
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
  }
  .mq-track { animation: none; }
  .mq-run[aria-hidden="true"] { display: none; }
  .mq-run { padding-inline: var(--gut); }
  .mq-mark { scroll-snap-align: center; }
  .mq-mark img { transition: none; }
}
