/* ═══════════════════════════════════════════════════════════
   SCENE 08 — THE PARTNERS

   AN ORDINARY SECTION. Everything before it on this page is pinned:
   the hero holds, the picture travels, the monogram closes over the
   film. After four screens that take the scroll away from the
   visitor, this one simply scrolls past — and that is the point of
   it. A page that never lets go stops feeling composed and starts
   feeling stuck, so the release is as deliberate as the holds were.

   A BAND, NOT A ROW OF CARDS. The reference for this was a ruled
   strip of cells and it is right about the important thing: a logo
   wall wants to be airy. Put each mark in a filled card and the
   cards become the subject — a row of identical rectangles with
   something small in the middle of each. Take the boxes away and
   leave only the rules that divide them, and the logos are the only
   things on the screen with any weight.

   A card version was built and taken out again: each one a title
   block off an architectural drawing, ruled in gold, with the firm's
   role and its number in the set. It said more about the client than
   this does, and it was heavier — sixteen outlines where there had
   been none. If it is wanted back, it is in the history.

   WHAT THIS DOES NOT TAKE from the reference is the badge in the
   corner of every cell. That mark says nothing — nothing to add,
   nothing to open — and repeated across a row it is a texture to be
   looked past.

   THE LOGOS ARE NOT THE DESIGN. They arrive at whatever size, weight
   and colour their owners chose, which is the one place a careful
   page usually falls apart. So the page supplies the consistency
   they cannot: one box each, fitted rather than stretched, and every
   mark reduced to the same ink until you point at one — see the note
   on the filter, which is the only way the row reads as a set.
   ═══════════════════════════════════════════════════════════ */

.lg {
  position: relative;
  /* ABOVE THE TRAVELLING PICTURE, which sits at z-index 5 and would
     otherwise paint over this section as it rises into view. Same
     lift as .fx, .tl, .wk and .fm. */
  z-index: 6;
  /* THE BAND TURNS WITH THE INVITATION BELOW IT. --page is paper
     until that panel is half up the screen and blue after it; one
     token, switched on <html> by js/core/theme.js. The transition
     lives on the element that READS the token, because a custom
     property cannot itself be transitioned — only the properties
     resolved from it. */
  background: var(--page);
  transition: background-color .9s var(--ease);
  padding-block: 14rem 5rem;
  overflow: hidden;
}

/* ── The seam ────────────────────────────────────────────
   A THEME THAT CHANGES PART OF THE WAY DOWN A PAGE HAS AN EDGE
   SOMEWHERE, and the only question is whether you can see it. This
   is that edge. Three sections turn — this band, the invitation and
   the reviews — so there is no join between any of them; the one
   that is left is at the top of this one, where the monogram screen
   above resolves to paper and stays there. Without this the turn
   draws a hard horizontal rule across the window, which is exactly
   what it did.

   PAPER TO TRANSPARENT, NOT PAPER TO BLUE. The veil never changes —
   it is the same gradient before and after — and what changes is
   what shows through it. Before the turn it is paper over paper and
   invisible; after, it is the screen above coming down into the
   blue. Nothing here needs a transition of its own, and there is no
   second copy of the night colour to keep in step.

   IT IS A FEATHER ON THE JOIN, NOT A FADE DOWN THE SECTION. It ran
   the full depth of the top padding first, and at twelve rems the
   band opened on paper and only arrived at the blue somewhere around
   the title — so the colour appeared to change at the head rather
   than at the section, which is not where the section starts. Five
   is enough to take the hard edge off the boundary and short enough
   that the change belongs to the boundary.

   z-index: -1, NOT 0. A positioned child at 0 paints ABOVE the
   section's in-flow text — the veil would be a sheet of paper laid
   over the head. At -1 it paints above .lg's own background and
   below everything in it, which is the whole job. .lg is position:
   relative with a z-index, so it holds the negative child inside its
   own stacking context. */
.lg::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  z-index: -1;
  height: var(--seam, 5rem);
  /* EIGHT STOPS, NOT TWO. A straight paper-to-transparent ramp
     interpolates alpha linearly, and the eye does not read it that
     way: the tail arrives too fast and leaves a visible shelf where
     the gradient lands, which is a softer version of the hard line
     this is here to remove. These stops ease it — slow to leave the
     paper, long and low through the tail, so there is no point along
     it where the rate of change jumps. */
  background: linear-gradient(180deg,
    rgb(var(--paper-rgb) / 1)    0%,
    rgb(var(--paper-rgb) / .96) 18%,
    rgb(var(--paper-rgb) / .86) 34%,
    rgb(var(--paper-rgb) / .70) 48%,
    rgb(var(--paper-rgb) / .50) 61%,
    rgb(var(--paper-rgb) / .30) 73%,
    rgb(var(--paper-rgb) / .14) 84%,
    rgb(var(--paper-rgb) / .04) 93%,
    rgb(var(--paper-rgb) / 0)  100%);
  pointer-events: none;
}

/* ── The head ────────────────────────────────────────────
   Same eyebrow-title-note as the projects section, because it is
   the same kind of screen and inventing a second heading style for
   it would be a difference that means nothing. */
.lg-head {
  grid-column: content;
  /* TWO COLUMNS, THE SAME SPLIT AS THE PROJECTS HEAD. Held to one
     column the claim ran to about forty per cent of the window and
     left the rest of the line empty — not white space, which is
     shaped on purpose, but a gap where the measure simply stopped.
     The note moves up beside it and the head fills its own width. */
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: var(--gap);
  align-items: center;
  margin-bottom: 7rem;
}

.lg-eyebrow {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  margin-bottom: 2.2rem;
  font-family: var(--font-sans);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.lg-eyebrow i { width: 3.4rem; height: var(--hair); background: currentColor; opacity: .5; }

.lg-title {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 5.6rem;
  line-height: 1.1;
  letter-spacing: -.024em;
}

.lg-note {
  font-family: var(--font-sans);
  /* 500 rather than the body weight, for the same reason as the
     projects note: at reduced contrast beside a 5.6rem claim, a 400
     reads as thin rather than as quiet. */
  font-weight: 500;
  font-size: 1.65rem;
  line-height: 1.6;
  color: var(--on-light);
}

/* ── The band ────────────────────────────────────────────
   FULL BLEED, AND IT HAS TO BE. A marquee held inside the content
   column starts and stops at two hard edges, which tells the eye
   exactly how long the loop is and turns an endless row into a
   short one going round. Running it the whole width of the window
   and dissolving both ends says the row continues past the screen,
   which is the only honest reading of a loop with no beginning.

   AND NOTHING ABOVE OR BELOW IT. There were tick rails along both
   edges, borrowed from the monogram screen. Two ruled lines the
   width of the window is a lot of drawing to spend on saying "the
   row is here" — the row is plainly there. */
.lg-band {
  position: relative;
  grid-column: full;
}

.lg-rail {
  position: relative;
  overflow: hidden;
  /* THE GESTURE BELONGS TO THE ROW, BUT ONLY SIDEWAYS. pan-y leaves
     a vertical swipe to the page and takes a horizontal one for the
     drag; without it the browser claims both and the row never moves
     under a finger. The rest stops a drag from becoming a text
     selection or one of the browser's own image drags. */
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  /* THE ENDS DISSOLVE, AND WITH A MASK RATHER THAN TWO OVERLAYS.
     Overlays would have to be painted in the section's own colour,
     and the moment this section sits on anything but paper they
     become two pale rectangles. A mask removes the pixels instead,
     so whatever is behind shows through and there is nothing to
     keep in step. */
  -webkit-mask-image: linear-gradient(90deg,
    transparent 0, #000 14rem, #000 calc(100% - 14rem), transparent 100%);
          mask-image: linear-gradient(90deg,
    transparent 0, #000 14rem, #000 calc(100% - 14rem), transparent 100%);
}

.lg-track {
  display: flex;
  align-items: stretch;
  /* NO GAP. The divider between two cells is a rule, and a rule wants
     to sit ON the join rather than float in a gap beside it — with
     space either side there are three edges where there should be
     one. The cells carry their own padding instead. */
  width: max-content;
  /* The transform is written sixty times a second; this keeps the row
     on its own layer instead of repainting the section. */
  will-change: transform;
}

/* ── The cell ────────────────────────────────────────────
   NO BOX. Each logo has a column and a rule to its right, and that
   is the whole of it. Put every mark in a filled card and the cards
   become the subject — a row of identical rectangles with something
   small in the middle of each; take the boxes away and the logos are
   the only things on the screen with any weight.

   ONE RULE EACH, ON THE RIGHT, so the row is divided without
   anything being drawn twice at the joins. It is inset from both
   ends rather than run full height: a rule that runs the whole way
   closes the cell into a box, which is the thing this section is
   not, and held clear it reads as a division instead of a
   container. */
.lg-cell {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  grid-template-rows: 1fr auto;
  gap: 1.8rem;
  align-items: center;
  /* --cell-w is written by logos.js: the same width snapped to a
     whole number of DEVICE pixels. Every divider then shares one
     sub-pixel phase, so they all rasterise identically instead of
     some landing clean and some straddling. The rem value is the
     fallback and the intent; the variable is the correction. */
  width: var(--cell-w, 30rem);
  padding: 4.6rem 3.4rem 4rem;
}

.lg-cell::after {
  content: '';
  position: absolute;
  top: 22%;
  bottom: 22%;
  right: 0;

  /* TWO PIXELS, NOT ONE HAIRLINE, AND THAT IS THE WHOLE FIX. The row
     is positioned by a transform, so it sits at a fractional offset
     almost always; the cell is 30rem against a fluid root, so its
     width is fractional too. A 1px rule therefore lands on a pixel
     boundary for some dividers and straddles two for others, and a
     straddled hairline is drawn at half strength in each column. In
     a screenshot of the live row the same rule measured .184 ink at
     three dividers and .154 at the other two — visibly patchy, with
     nothing wrong in the CSS.

     Two CSS pixels always cover at least one device column outright,
     so the darkest point of the rule is the same wherever it falls.
     Measured over twelve sub-pixel offsets: at 1px the peak varies
     by .078, which is most of its own value; at 2px the variation is
     exactly zero.

     .45 RATHER THAN .62 because the rule is now twice as wide. At
     that alpha its peak measures .114 against the hairline's .119 —
     the same weight on the page, arrived at honestly.

     It is deliberately NOT --hair. Everything else on the site that
     uses that token sits in static layout, where a hairline lands
     where it is put; this one is being carried past on a transform. */
  width: 2px;

  /* GOLD, at the strength the corner marks use on the monogram
     screen. It is the one coloured thing in the band — the logos are
     reduced to one ink — so the dividers are what carries the brand
     through a row of other people's marks. */
  background: rgba(217, 179, 120, .45);
}

/* ── The logo itself ─────────────────────────────────────
   ONE BOX, WHATEVER ARRIVES. The client uploads at whatever size
   their own designer handed them — a wordmark eight times as wide as
   it is tall, an icon that is square, a stacked lockup taller than
   either. All three get the same box and are fitted inside it, never
   stretched: the cap decides for the tall ones, the width for the
   wide ones, and neither is ever cropped.

   ONE NUMBER DECIDES THE BOX AND THE CAP, and it took two goes to
   get here. First the box was a min-height, so it grew to whatever
   the tallest upload wanted and every cell ended up a different
   height. Then it was a fixed height with max-height:100% on the
   image — which silently did nothing, because the image sat in an
   auto-sized grid row and a percentage against an auto row is
   indefinite. A 220px lockup came through at 220px, overflowing a
   box 91px tall, with no warning anywhere. Flex rather than grid,
   and --box in rem for both the box and the cap, so the two can no
   longer disagree.

   THE WIDTH IS CAPPED SHORTER THAN THE HEIGHT — 88% against the full
   box — because a long wordmark fitted edge to edge reads as louder
   than a square icon fitted top to bottom, even though both
   technically fill it. Holding the wide ones off the sides evens out
   the weight, which is the difference between a row that looks set
   and a row that looks pasted. */
.lg-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  --box: 10rem;
  height: var(--box);
}

.lg-logo img {
  -webkit-user-drag: none;
  max-width: 88%;
  max-height: var(--box);
  width: auto;
  height: auto;
  object-fit: contain;
  /* ONE SILHOUETTE, NOT ONE GREYSCALE, and the difference is the
     whole point. Greyscale keeps a colour's lightness: a navy
     wordmark lands near black, a mid-brown lands as mid-grey, a teal
     somewhere between. The row came out visibly patchy — some marks
     heavier than others for no reason a visitor could see, because
     the reason was a colour choice made by somebody else's designer
     years ago.

     brightness(0) throws lightness away and keeps only alpha, so
     every mark is the same ink and only its own coverage varies.
     Measured across the eight: greyscale left a spread of .026 in
     perceived darkness, this leaves .016 — and the remainder is
     antialiasing, which is as even as it gets.

     WHAT WAS TRIED AND REJECTED: raising contrast, which sounds like
     it should pull everything to the extremes and instead made it
     worse (.037 at 3x, .043 at 2x) — it amplifies exactly the
     mid-tone differences that were the problem.

     THE COST, AND IT IS REAL: a logo whose counters are filled with
     opaque white rather than cut out will come through as a solid
     block. Two of the placeholders did; they were redrawn as
     outlines. A client upload that does the same will need the same
     fix, and that is worth knowing before the logos arrive.

     Colour comes back on hover — the reward for looking. */
  filter: grayscale(1) brightness(0);
  opacity: .72;
  transition: filter .55s var(--ease-out), opacity .55s var(--ease-out);
}
.lg-cell:hover .lg-logo img { filter: none; opacity: 1; }

/* What the firm actually does, which is the thing a logo on its own
   never tells you. Faint until the cell is pointed at, so the row
   reads as logos first. */
.lg-role {
  text-align: center;
  font-family: var(--font-sans);
  font-size: 1.1rem;
  font-weight: 500;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--on-light-faint);
  transition: color .5s var(--ease-out);
}
.lg-cell:hover .lg-role { color: var(--gold-deep); }

/* ── The pre-JS state ────────────────────────────────────
   There is none, deliberately. If the script never runs the row sits
   still and can be scrolled by hand — the same arrangement reduced
   motion gets below. A marquee that needs JavaScript to be readable
   is a marquee that is blank. */

/* ── Reduced motion ──────────────────────────────────────
   The loop is exactly the kind of continuous movement the setting is
   asking not to have. It stops, and the rail becomes an ordinary
   horizontal scroller so every logo is still reachable. */
@media (prefers-reduced-motion: reduce) {
  .lg-rail {
    overflow-x: auto;
    scrollbar-width: none;
  }
  .lg-rail::-webkit-scrollbar { display: none; }
}

/* ── Responsive ──────────────────────────────────────────── */
@media (max-width: 1200px) {
  .lg-title { font-size: 4.6rem; }
  .lg-cell { width: var(--cell-w, 26rem); padding: 4rem 2.8rem 3.4rem; }
}
@media (max-width: 991px) {
  .lg { padding-block: 11rem 6rem; --seam: 4rem; }
  /* Back to one column: below this the note's column is narrower
     than its own measure and it sets to four or five words a line. */
  .lg-head { grid-template-columns: 1fr; gap: 2.4rem; margin-bottom: 5.5rem; }
  .lg-title { font-size: 3.9rem; }
  .lg-cell { width: var(--cell-w, 23rem); }
  .lg-rail {
    -webkit-mask-image: linear-gradient(90deg,
      transparent 0, #000 7rem, #000 calc(100% - 7rem), transparent 100%);
            mask-image: linear-gradient(90deg,
      transparent 0, #000 7rem, #000 calc(100% - 7rem), transparent 100%);
  }
}
@media (max-width: 767px) {
  .lg { padding-block: 9rem 4rem; --seam: 3.5rem; }
  .lg-title { font-size: 3.2rem; }
  .lg-note { font-size: 1.55rem; }
  .lg-cell { width: var(--cell-w, 19rem); padding: 3.4rem 2.2rem 3rem; gap: 1.4rem; }
  .lg-logo { --box: 7.6rem; }
  .lg-role { font-size: 1rem; letter-spacing: .18em; }
  .lg-rail {
    -webkit-mask-image: linear-gradient(90deg,
      transparent 0, #000 3.5rem, #000 calc(100% - 3.5rem), transparent 100%);
            mask-image: linear-gradient(90deg,
      transparent 0, #000 3.5rem, #000 calc(100% - 3.5rem), transparent 100%);
  }
}

/* ── After the page turns ────────────────────────────────
   THE SAME BAND IN THE OTHER REGISTER, not a second design. The
   switch is a class on <html> written by js/core/theme.js.

   THE LOGOS INVERT RATHER THAN DIM. On paper they are knocked to
   solid black — one silhouette weight for marks that arrive at every
   size and every colour, which is the only thing making the row read
   as a set rather than as six unrelated files. Black on navy is not
   a quieter version of that, it is an absence, so the night value is
   the same knock-out the other way up: brightness(0) makes them
   black, invert(1) makes that white. The tone stays uniform, which
   was the entire point of the filter.

   HOVER STILL RETURNS THE REAL MARK. A full-colour logo on navy is
   the same reveal it is on paper, and it is the one moment a
   consultant's own brand is allowed to be itself.

   EVERY COLOUR TRANSITIONS ON THE SAME .9s AS THE GROUND. If the
   type snapped while the background faded, the band would read as
   two changes rather than one. */
html.is-night .lg-title { color: var(--paper); }
html.is-night .lg-note  { color: var(--on-dark); }
html.is-night .lg-role  { color: var(--on-dark-faint); }
html.is-night .lg-eyebrow { color: var(--gold-lift); }
html.is-night .lg-cell:hover .lg-role { color: var(--gold-lift); }

html.is-night .lg-logo img { filter: grayscale(1) brightness(0) invert(1); }
html.is-night .lg-cell:hover .lg-logo img { filter: none; }

/* Lifted from .45: the same gold that reads as a fine rule on paper
   is nearly gone against navy. */
html.is-night .lg-cell::after { background: rgba(217, 179, 120, .58); }

.lg-title, .lg-note, .lg-role, .lg-eyebrow { transition: color .9s var(--ease); }
