/* =====================================================================
   MEMBER STRIP — five systems on a dotted course line
   Maps to a WordPress flexible-content block with a repeater of members.
   ===================================================================== */

.mstrip{position:relative;margin:52px auto 0;max-width:1040px}

/* THE COURSE LINE IS A GRADIENT, NOT A BORDER, AND THE REASON IS THAT A
   BORDER HAS NO DRAW AXIS. `border-top:2px dotted` paints all at once or
   not at all — there is no property on it that can be animated from "no
   line" to "full line" left-to-right. A background image can: with
   `background-repeat:no-repeat`, animating `background-size` on the inline
   axis grows the painted box, and because the gradient's stops are in
   ABSOLUTE px the pitch does not stretch with it. Dots appear one after
   another at constant spacing, which is a draw rather than a scale.

   THE PATTERN MATCHES THE BORDER IT REPLACES, MEASURED — not eyeballed.
   The old `border-top:2px dotted var(--stone)` was screenshotted at
   deviceScaleFactor 4 and its runs counted along a sampled row: ink 1.9704
   CSS px, gap 2.2490 CSS px, pitch 4.2194 px by run-mean, 245 whole
   periods across 1040px, duty 46.70% ink.

   THE AUTHORED PITCH IS 4px AND IT RENDERS AT 4.2286px. THAT IS NOT A
   MISTAKE — DO NOT "CORRECT" IT TO 4.245. Chrome rasterises a repeating
   gradient coarser than authored, and the offset is large enough to see:
   authoring the border's own 4.245px measured back as 4.4644px and 232
   dots against the border's 245. Calibrated by sweeping the authored value
   and measuring each render on the SAME instrument (DSF 4, element
   screenshot, run-length along a sampled row):
       authored 3.900 -> 4.1171 px, 252 dots
       authored 4.000 -> 4.2286 px, 245 dots   <- shipped
       authored 4.100 -> 4.3039 px, 241 dots
       authored 4.245 -> 4.4644 px, 232 dots
       authored 4.250 -> 4.4892 px, 231 dots
   At 4px the rendered pitch is +0.0092 px off the border and the dot count
   is identical. Re-calibrate by measurement if the engine changes; the
   authored number is an input to a rasteriser, not the answer.

   ONE REAL DIFFERENCE, RECORDED: Chrome REFLOWS a dotted border to fit a
   whole number of dots into the run, so its pitch shifts slightly with the
   element's width. A gradient with px stops does not — it holds its pitch
   and lets the last period fall partial. Over 1040px that is a fraction of
   one dot. Do not "fix" it by switching the stops to percentages: that
   would make the pitch stretch during the draw and turn it back into a
   scale. */
.mstrip .line{
  position:absolute;left:0;right:0;top:9px;
  height:2px;
  background-image:repeating-linear-gradient(to right,
    var(--stone) 0 2px, transparent 2px 4px);
  background-repeat:no-repeat;
  background-position:left center;
  background-size:0 100%;
}
.mstrip .row{position:relative;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}

.mem{flex:1 1 168px;min-width:168px;text-align:center}

/* THE NODE DOTS SIT ON EACH LOGO'S OPTICAL CENTROID — the alpha-weighted
   ink centre of mass — NOT ON EVEN GEOMETRIC INTERVALS. The course line's
   rhythm follows the marks. Novant and Providence carry their weight
   ~8px left of bbox centre, which is what --cx corrects. These offsets
   are per-logo and die if the artwork is replaced.

   THEY ALSO SCALE WITH THE ARTWORK, AND B4 IS WHY THAT IS WRITTEN DOWN.
   2026-08-17: the five logo widths went +10% and these five values were
   multiplied by 1.1 in the same edit — -0.04 / -0.43 / -11.85 / -11.28 /
   -0.19, at the two-decimal precision they were authored in.

   THE MEASUREMENT THAT ALMOST GOT THIS WRONG. Asked whether the dots MOVE
   when the logos grow, the answer is no: `.mem` is `flex:1 1 168px` under
   `space-between`, so the box is sized by the flex algorithm and not by the
   logo, and the box widths held at 196.8px. **That is true and it answers the
   wrong question.** These values put the dot on the logo's INK CENTROID, and a
   centroid offset measured in px grows with the artwork — at +10% the dot fell
   1.08px behind on Novant and 1.03px on Providence. **THE DOT NOT MOVING IS
   NOT THE DOT STILL BEING ALIGNED.** Any future width change scales these by
   the same factor, and the delays below must be re-measured after it. */
.mem i{
  display:block;width:14px;height:14px;border-radius:50%;
  background:var(--ground-fill);
  margin:2px auto 16px;
  border:3px solid var(--ground-page);
  transform:translateX(var(--cx,0));
}
.mem.m-bay{--cx:-0.04px}
.mem.m-mem{--cx:-0.43px}
.mem.m-nov{--cx:-11.85px}
.mem.m-pro{--cx:-11.28px}
.mem.m-mic{--cx:-0.19px}

/* MEMBER LOGOS — placeholder artwork, PAIRED WITH THE NAMES, never
   replacing them. Widths come from equal ink-area normalisation, not from
   uniform width or height: uniform width would swamp the row with
   Providence, uniform height with Michigan's block M. The zone is a fixed
   84px so the tall marks cannot push their names below the short ones —
   every name baseline lands on the same line. */
.mem .lg{display:flex;align-items:center;justify-content:center;height:84px;margin:0 0 11px}
.mem .lg img{height:auto;max-width:100%;display:block}
.mem.m-bay .lg img{width:172.7px}
.mem.m-mem .lg img{width:133.1px}
.mem.m-nov .lg img{width:121px}
.mem.m-pro .lg img{width:136.4px}
.mem.m-mic .lg img{width:124.3px}

/* `.rl` AND ITS TWO RULES ARE GONE (2026-08-07, client change list). They
   styled "Governing member" x4 and "Member · May 2025" x1 beneath the
   logos; all five spans were removed from the markup, so the selectors
   matched nothing and were deleted rather than left to rot.

   THAT CLOSES AN INHERITED AA ITEM BY DELETION, WHICH IS WORTH SAYING
   PLAINLY. The rule carried a standing note: 3.1144 against a 4.5
   threshold, five elements, --ink-muted on --cream, blocked on palette
   canon. The five elements no longer exist on this page, so the failure
   cannot be measured any more — it was not fixed, the copy that carried it
   was cut. `tokens.css` still describes `span.rl 3.1144 on cream` in its
   --ink-muted comment; that file is barred to this session and its note is
   now stale for the home page. --ink-muted still has its footer consumer. */

.where{margin:40px auto 0;font-size:16px;color:var(--on-page-body);max-width:62ch}

/* =====================================================================
   ENTRY — the line draws left to right and each logo arrives as it is
   reached. One-shot, never reverses, no scroll-position coupling.
   =====================================================================

   NO NEW OBSERVER. `.mstrip` already carries `.rv`, and js/reveal.js's
   existing one-shot observer adds `.on` at threshold 0.16 and unobserves
   immediately. Driving off `.mstrip.rv.on` reuses that — the page's
   IntersectionObserver count is unchanged. Same idiom as
   components/stat-arc.css, which staggers `.pbub` off the same class.

   ANIMATIONS, NOT TRANSITIONS, and that is deliberate. `animation` with
   `both` fill holds the from-state through the delay and the to-state
   after, runs once by default, and — unlike a transition — exists as a
   seekable object in `getAnimations()` whether or not it is mid-flight.
   CSS animations do not advance in a headless run without a compositor, so
   the only way to measure this is to seek `currentTime`; a transition that
   only materialises while running cannot be seeked the same way.

   THE DELAYS ARE NOT A UNIFORM STAGGER, AND THAT IS THE POINT. Each logo
   starts when the drawn line reaches ITS node dot, so delay = the dot's
   own fraction of the line x the line's duration. The dots sit on each
   logo's optical centroid (see --cx above), not on even intervals, so the
   intervals between arrivals are uneven too. RE-MEASURE THE FRACTIONS IF
   --cx, the logo widths or the row's justification change — these five numbers
   encode the current layout and nothing warns you when it moves.

   RE-MEASURED AT B4, 2026-08-17, BECAUSE ALL THREE TRIGGERS FIRED AT ONCE:
   the logo widths went +10% and --cx scaled x1.1 with them. Fractions at 1440,
   measured against the FINAL 2-decimal --cx values rather than derived from
   the width change:

     m-bay .09457 -> .09457    delay .123s   unchanged
     m-mem .29694 -> .29690    delay .386s   unchanged
     m-nov .48964 -> .48861    delay .637s -> .635s   CHANGED
     m-pro .69283 -> .69184    delay .901s -> .899s   CHANGED
     m-mic .90522 -> .90520    delay 1.177s  unchanged

   TWO OF FIVE MOVED AT THE WRITTEN PRECISION, and both by 2ms. The other three
   shifted by less than a millisecond and round to the same value. **The
   instruction above was followed rather than reasoned around: the shift is far
   below any perceptual threshold, and re-measuring was still the only way to
   learn WHICH two moved.** The two that moved are Novant and Providence — the
   same two whose --cx corrections are large, which is why they were the only
   dots the scale visibly displaced. Both edits are byte-neutral. */
@keyframes memRise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes lineDraw{from{background-size:0 100%}to{background-size:100% 100%}}

.mstrip .mem{opacity:0;transform:translateY(14px)}
.mstrip.rv.on .mem{animation:memRise .52s cubic-bezier(.22,.85,.3,1) both}
.mstrip.rv.on .mem.m-bay{animation-delay:.123s}
.mstrip.rv.on .mem.m-mem{animation-delay:.386s}
.mstrip.rv.on .mem.m-nov{animation-delay:.635s}
.mstrip.rv.on .mem.m-pro{animation-delay:.899s}
.mstrip.rv.on .mem.m-mic{animation-delay:1.177s}
.mstrip.rv.on .line{animation:lineDraw 1.3s linear both}

/* REDUCED MOTION — final state, not a shortened animation: all five logos
   present and the line complete, with no motion at any point.
   BOTH SELECTORS ARE LISTED ON EACH LINE ON PURPOSE. `.mstrip .mem` is
   (0,2,0) and `.mstrip.rv.on .mem` is (0,4,0), so a media-query rule
   written only against the low-specificity one would lose to the .on rule
   the moment the observer fires — a media query adds no specificity. Same
   trap, same fix, as the block at the end of components/stat-arc.css. */
@media(prefers-reduced-motion:reduce){
  .mstrip .mem,.mstrip.rv.on .mem{opacity:1;transform:none;animation:none}
  .mstrip .line,.mstrip.rv.on .line{background-size:100% 100%;animation:none}
}
