/* ============================================================================
   SWORT professional affiliations
   ---------------------------------------------------------------------------
   ONE presentation. AIAA, IEEE, and ASME each appear exactly ONCE.

   A previous version had a moving rail AND a box grid beneath it, so every
   organisation showed twice. Both are replaced by a single static grid.

   Static on purpose, not an oversight. With three marks, any continuous loop
   must duplicate the set to avoid a visible gap, which reproduces the exact
   double-appearance that was wrong. A slow rail is the right pattern for twelve
   marks and the wrong one for three. So the pause-on-hover, pause-off-screen,
   and pause-on-hidden-tab machinery is removed rather than left dormant, along
   with the script that drove it, and there is no motion to exempt under
   prefers-reduced-motion.

   PUBLICATION GATE
   ----------------
   The transparent assets are built but the LOGOS ARE NOT PUBLISHED. Trademark
   and membership permission is unverified, and all three bodies distinguish
   individual from corporate membership: individual founder membership does not
   license a company website to display the mark.

   Each cell therefore shows the abbreviation as a type mark plus the full
   organisation name. That is identification, not duplication: enabling the
   artwork replaces the abbreviation and keeps the full name as the caption.

   TO ENABLE once permission is documented in writing:
     1. set --affil-logos-enabled: 1 below
     2. uncomment the <picture> blocks in the affiliations section of index.html
   The markup is left as a comment rather than hidden with display:none, because
   a display:none image is still fetched by most browsers and an unlicensed mark
   in the network log is still published.
   ========================================================================= */

:root {
  /* 0 = type marks (current). 1 = artwork. See the publication gate above. */
  --affil-logos-enabled: 1;
  /* Slow enough to read a mark as it passes, not a ticker.

     The duration covers one SET, since the keyframe runs 0 to -50% and the
     track holds the set twice. So the perceived speed is setWidth/duration, and
     both numbers changed here: the set narrowed from 1680px to 1280px when the
     cells were tightened, which on its own would have made the rail slower.
     72s over 1680px was 23px/s; 44s over 1280px is 29px/s, about 25% quicker. */
  /* 55s, not 44s. Perceived speed is setWidth/duration, and adding AIA widened
     one set from 1280px to 1600px. Leaving the duration alone would have sped
     the banner up from 29.1 to 36.4 px/s purely because a logo was added, which
     the brief rules out. 1600/55 = 29.1 px/s, the same speed as before. */
  --affil-rail-duration: 44s;
}

.affil {
  background: var(--swort-black);
  border-top: 1px solid var(--swort-border-dark);
}
.affil-inner {
  max-inline-size: var(--container-content);
  margin-inline: auto;
  padding: clamp(3.25rem, 6vw, 5rem) var(--gutter);
}

.affil-head { max-inline-size: 62ch; }
.affil-title {
  font-family: 'Bebas Neue', sans-serif;
  font-weight: 400;
  font-size: var(--type-section);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--swort-white-soft);
  margin: 0 0 var(--space-sm);
  text-wrap: balance;
}
.affil-lede {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: var(--type-label);
  line-height: var(--leading-body);
  color: var(--swort-gray);
  margin: 0;
  text-wrap: pretty;
}

/* ── Moving banner ─────────────────────────────────────────────────────────
   Optical sizing: the marks are NOT set to a common width or height. Their
   aspect ratios are 1.63:1, 3.52:1, and 2.36:1, so either would distort the
   relationship. Each asset was scaled so sqrt(width * height) is constant,
   equalising the area the mark occupies: 102x71, 149x66, 122x67. The widest
   mark gets the shortest height, which is how a brand wall is set. Clear space
   is baked into each asset at 14% of its longest edge.

   The seam: the track contains the set twice and translates by exactly -50%, so
   the loop restarts on an identical frame with no jump. Cell width is generous
   enough that one set spans more than the rail, keeping the duplicate off-screen
   while the first set is visible. */
.affil-rail {
  margin-block: clamp(2rem, 4vw, 3rem);
  overflow: hidden;
  /* Soft edge masks so marks enter and leave instead of being hard-clipped. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  border-block: 1px solid var(--swort-border-dark);
}
.affil-track {
  display: flex;
  align-items: center;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
  animation: affil-scroll var(--affil-rail-duration) linear infinite;
  will-change: transform;
}
/* Paused by hover, by keyboard focus inside, and by the two states CSS cannot
   observe (off-screen, hidden tab) which affiliations.js sets as .is-paused. */
.affil-rail:focus-within .affil-track,
.affil-rail.is-paused .affil-track { animation-play-state: paused; }
@media (hover: hover) and (pointer: fine) {
  .affil-rail:hover .affil-track { animation-play-state: paused; }
}

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

.affil-cell {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* One SET must stay wider than the rail, or the duplicate half appears beside
     the original and an organisation is on screen twice at once. That is the
     only hard constraint on spacing, and it just got easier: these numbers were
     sized for THREE cells, and the set is now FOUR, so the same rule is
     satisfied with noticeably tighter spacing.

       desktop   4 x 320px = 1280px against the 1180px container cap
       fluid     4 x 0.27vw = 1.08vw, still above the 1.0vw viewport-bound rail
       narrow    4 x 170px = 680px, above the rail at every width it applies to

     Tightened from 36vw/420px, which was leaving the marks adrift now that
     there are four of them. */
  inline-size: clamp(170px, 27vw, 320px);
  block-size: 96px;
}
/* Type mark, shown while the artwork is gated off. A deliberate mark, not a
   placeholder: the organisation abbreviation set in the display face. */
/* Retained: this is the fallback the rail falls back to if artwork is ever
   gated off again, and it is one rule with no override risk. */
.affil-mark-text {
  font-family: 'Bebas Neue', sans-serif;
  font-weight: 400;
  font-size: 1.875rem;
  letter-spacing: 0.16em;
  line-height: 1;
  color: var(--swort-silver);
  white-space: nowrap;
}
.affil-logo { display: block; height: auto; max-width: none; }
.affil-logo-aiaa { width: 102px; }
.affil-logo-ieee { width: 149px; }
.affil-logo-asme { width: 122px; }
/* Widths come from extract-affiliations.mjs, which normalises each mark to a
   constant sqrt(width x height) rather than to a constant height. Matching
   heights would let the wide IEEE and AMS lockups dominate the rail; matching
   widths would shrink them to nothing. Equal optical area is what makes marks
   of 1.63:1 and 4.20:1 read as the same weight. */
.affil-logo-ams  { width: 154px; }

/* ── Reduced motion: a real static row, not a slowed animation ───────────── */
@media (prefers-reduced-motion: reduce) {
  .affil-rail {
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .affil-track {
    animation: none;
    transform: none;
    width: auto;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: clamp(1.5rem, 4vw, 3rem);
  }
  /* The duplicate half exists only for the loop seam. */
  .affil-track [data-affil-dup] { display: none; }
  .affil-cell { inline-size: auto; min-inline-size: 150px; }
}

/* Mobile: keep it readable rather than hiding it. Narrower cells, slower. */
@media (max-width: 640px) {
  /* Four cells rather than three here too, so 33vw clears the 1.0vw rail with
     room (4 x 0.33 = 1.32vw) while sitting much closer than the old 44vw. */
  .affil-cell { inline-size: clamp(120px, 33vw, 180px); block-size: 84px; }
  /* Retained: this is the fallback the rail falls back to if artwork is ever
   gated off again, and it is one rule with no override risk. */
.affil-mark-text { font-size: 1.5rem; }
}

.affil-notice {
  font-family: 'DM Mono', ui-monospace, monospace;
  /* Not shrunk into unreadability: this is the notice that has to be read. */
  font-size: var(--type-caption);
  line-height: var(--leading-body);
  color: var(--swort-gray);
  /* Was a hard 92ch, which outranked typography.css because affiliations.css
     loads after it. Uses the shared token now so the notice cannot drift from
     the site measure. */
  max-inline-size: var(--measure-note);
  margin: clamp(1.5rem, 3vw, 2rem) 0 0;
  padding-top: var(--space-md);
  border-top: 1px solid var(--swort-border-dark);
  text-wrap: pretty;
}
