/* ==========================================================================
   News

   The Carroll Group's #new_media, rebuilt: the section header in a narrow
   left column, a horizontal press rail beside it, and a full width outlet
   logo marquee nested inside the same section rather than following it.

   Theirs is Swiper with 78 slides, each slide a bare press clipping with no
   outlet, no date and no link, opening a document level lightbox keyed by a
   hand written 1-based integer. Six things changed, and only the first is
   taste:

   1. LEFT ALIGNED. Theirs is centred. Client direction, and the same call
      every other section on this page makes.

   2. THE CARD IS A LINK. Theirs is a <div class="js-active-preview"
      data-href> with no cursor, no hover, no focus ring and no keyboard
      route; the article URL is never used as an href, jQuery reads it to
      build a modal. Ours is an <a> around the whole card, so the press is
      reachable by keyboard, by screen reader, by middle click and by a
      crawler. The lightbox and its parallel 78-slide DOM go away with it,
      and so does the data-item cross-index that silently opens the wrong
      article the moment anything is reordered.

   3. OUTLET AND DATE ARE TEXT. Theirs bakes the masthead into the clipping
      pixels, which leaves the marquee alt attributes as the only machine
      readable outlet signal in the whole section. Every card here carries a
      headline, an outlet and a <time datetime>, which the existing press
      page already holds as real data.

   4. NATIVE SCROLL. The rail is overflow-x with scroll snap: it swipes on
      touch, takes a trackpad, and Tab walks the cards, all with no script.
      The arrows are enhancement, see the nav note below.

   5. ONE ASPECT RATIO, taken from the real files. Theirs locks 100:78 with a
      padding-bottom pseudo element and then covers, which crops. Yaritza's
      clippings are all 605x378, so the frame is set to that and a headline
      never loses its top line.

   6. SIX CARDS, not 78. The homepage rail is the recent run; press.html
      holds the archive. Their section alone is roughly 1,400 lines of the
      served HTML because every item ships twice, once per Swiper.

   Depends on _shared.css for .yp-wrap, the .yp-shead-* header type and the
   .yp-rise reveal contract. Only this section's delays and its two
   directional splits live here.
   ========================================================================== */

/* Sand. Neighborhoods above and Social below are both Shell, so the press
   block is the one darker band in that run and the white cards have a ground
   to sit on instead of dissolving into it. */
.yp-news {
  position: relative;
  background: var(--yp-sand);
  /* The watermark deliberately runs wider than the column it sits behind.
     This is what stops that bleed from becoming a page level sideways
     scrollbar, and it is the same guard Carroll puts on #new_media. */
  overflow: hidden;
}

/* ---- two columns ---------------------------------------------------------
   Carroll's 360px header column, kept. minmax(0, 1fr) rather than 1fr on the
   rail: a grid track sized 1fr floors at its content's min-content width, so
   a row of six cards would push the track wider than the page instead of
   scrolling inside it. The 0 minimum is what lets the rail overflow itself. */

@media (min-width: 1024px) {
  .yp-news-inner {
    display: grid;
    grid-template-columns: 360px minmax(0, 1fr);
    column-gap: clamp(40px, 4vw, 72px);
    align-items: center;
  }
}

.yp-news-intro {
  position: relative;
  /* Declared, not inherited. Every section header on this site is left
     aligned, and Divi centres text on several of its own wrappers, so an
     inherited alignment is one stray ancestor away from silently centring the
     one thing the client asked never to be centred. */
  text-align: left;
  padding-bottom: clamp(26px, 3.2vw, 42px);
}

@media (min-width: 1024px) {
  .yp-news-intro { padding-bottom: 0; }
}

/* Everything in the column has to sit over the watermark, which is the one
   positioned child with a stacking order below them. */
.yp-news-intro > :not(.yp-news-mark) { position: relative; }

/* ---- watermark -----------------------------------------------------------
   Carroll hangs the brokerage logo off the top left of the header column at
   360px wide. Same idea, on the wordmark, sized to the column rather than to
   a fixed pixel width so it holds the same proportion at every viewport.

   The opacity lives on the <img>, not on this span: the reveal animates the
   span's opacity from 0 to 1, and a resting 0.07 here would be overwritten by
   it and blow the watermark out to full strength the moment the section
   revealed. */
.yp-news-mark {
  position: absolute;
  z-index: 0;
  /* Bleeding off the top left corner, which is where Carroll hangs theirs.
     Sized at twice the column and cropped by the section's overflow so the
     letterforms arrive as texture rather than as a second, smaller, legible
     copy of the logo the header is already carrying. At the column's own
     width it read as a stray logo sitting on the button. */
  left: -34%;
  /* Pixels, not a percentage: the intro column runs about 80px shorter at
     1024 than at 1440, and a percentage offset drops the ghost that much
     lower on the narrower screen, straight onto the eyebrow, which happens to
     read the same two words. */
  top: -180px;
  width: 200%;
  pointer-events: none;
  /* Desktop only, and not for want of trying. Below 1024 the intro is a full
     width block with the deck running under the heading, so a bleed at this
     scale lands squarely behind body copy, and shrinking it to fit turns the
     ghost back into a small second copy of the header's own logo. Carroll's
     narrow-screen answer is a 160px logo, which for a brokerage mark is a
     second identity and for a personal wordmark is just the logo again. */
  display: none;
}

@media (min-width: 1024px) {
  .yp-news-mark { display: block; }
}

.yp-news-mark img {
  display: block;
  width: 100%;
  height: auto;
  /* Ink on Sand is 16:1. A watermark has to stay far under that or it reads
     as a second headline behind the first, and the headline sits directly on
     top of it here. */
  opacity: 0.055;
}

/* ---- header type ---------------------------------------------------------
   The eyebrow and the label are _shared.css's .yp-shead-name / .yp-shead-label
   so the eight sections keep one header component. Two things are local:

   The label steps back down at 1330 the way #new_media does. Carroll's global
   ladder is 32 to 50 to 60px and the news section walks that last step back
   to 55; here the reason is the column, not the reference. At 60px with the
   brand's 0.14em display tracking, "IN THE" alone measures close to the whole
   360px, leaving the line no rag at all. */

@media (min-width: 1330px) {
  .yp-news-label { font-size: 3.4375rem; }
}

/* Two words, and the split is load bearing: they enter from opposite sides
   and meet, which is the one piece of choreography this section has. Keep the
   spans even if the words change. inline-block is what makes the transform
   apply at all. */
.yp-news-word { display: inline-block; }

/* Same scale as .yp-shead-note. It is a separate class only because the deck
   carries the air down to the button, which the shared note does not. */
.yp-news-deck {
  margin: clamp(12px, 1.4vw, 18px) 0 clamp(22px, 2.4vw, 30px);
  max-width: 42ch;
  color: rgb(var(--yp-ink-rgb) / 0.74);
  font-family: var(--yp-serif);
  font-size: clamp(0.9375rem, 0.3vw + 0.85rem, 1.125rem);
  line-height: 1.6;
  letter-spacing: 0.005em;
}

/* ---- call to action ------------------------------------------------------
   Carroll's button is a 50px pill. Squared here, matching the Social section's
   buttons: a pill is the one shape on their page that is not in this brand's
   vocabulary, and two button shapes on one page reads as two designers.

   The label appears twice in the markup, once in this column for wide screens
   and once in the nav bar for narrow ones, exactly as theirs does. Both copies
   carry the same href and the same words; change them together. */

.yp-news-cta { margin: 0; }

.yp-news-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 45px;
  padding: 13px 26px;
  color: var(--yp-white);
  background: var(--yp-ink);
  font-family: var(--yp-serif);
  font-size: clamp(0.75rem, 0.2vw + 0.7rem, 0.875rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--yp-track-nav, 0.18em);
  /* Cancels the trailing letter-space so the label sits optically centred in
     its box rather than a fraction left of it. */
  text-indent: var(--yp-track-nav, 0.18em);
  text-transform: uppercase;
  text-decoration: none;
  transition: background-color 0.25s cubic-bezier(0.22, 1, 0.36, 1),
              color 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

.yp-news-btn:hover { background: rgb(var(--yp-ink-rgb) / 0.82); }
.yp-news-btn:focus-visible { outline: 2px solid var(--yp-ink); outline-offset: 3px; }

@media (min-width: 1024px) {
  .yp-news-btn { min-height: 55px; padding: 17px 30px; }
}

/* The wide copy is hidden first and shown at 1024 rather than the other way
   round, so the copy that is visible with no media query support is the one
   that sits in a bar of its own and cannot collide with anything. */
.yp-news-cta-wide { display: none; }

@media (min-width: 1024px) {
  .yp-news-cta-wide   { display: block; }
  .yp-news-cta-narrow { display: none; }
}

/* ---- the rail ------------------------------------------------------------
   Negative margins cancel .yp-wrap's gutter so the track runs the full width
   of the container, and the matching padding puts the first card back on the
   same left edge as the headline. Bleeding to the viewport edge instead would
   mean 100vw, which counts the scrollbar and overflows on every desktop
   browser that shows one.

   scroll-behavior lives here rather than in the script so the reduced motion
   branch at the foot of this file can switch the arrows to an instant jump
   without the script knowing anything about it. */

.yp-news-rail {
  display: flex;
  gap: clamp(16px, 1.6vw, 28px);
  margin: 0 -30px;
  /* 10px of top room and 26px of bottom room so the card shadow is not
     sheared off by the scroll container's own edge. */
  padding: 10px 30px 26px;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 30px;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: rgb(var(--yp-ink-rgb) / 0.3) transparent;
}

@media (min-width: 1024px) {
  /* Left edge is the grid column edge now, so only the right side bleeds. */
  .yp-news-rail {
    margin: 0 -30px 0 0;
    padding-left: 0;
    padding-right: 30px;
    scroll-padding-left: 0;
  }
}

/* Three bands rather than Carroll's single 640 breakpoint, and the numbers
   overlap on purpose: a card is 300px at 639 and 280px at 640, then 320px at
   1023 and 300px at 1024. Sized independently, each of those boundaries drops
   the card by 60 to 80px in one pixel of viewport, which reads as the rail
   glitching rather than as a layout adapting. */
.yp-news-item {
  flex: 0 0 auto;
  width: min(76vw, 300px);
  scroll-snap-align: start;
}

@media (min-width: 640px)  { .yp-news-item { width: clamp(280px, 34vw, 320px); } }
@media (min-width: 1024px) { .yp-news-item { width: clamp(300px, 24vw, 400px); } }

/* ---- the card ------------------------------------------------------------
   Carroll's 7px white mat, kept; their 6px radius is not, for the same reason
   the pill is not. The shadow is theirs at a quarter less weight and on the
   ink token: rgba(0,0,0,0.25) goes cold and slightly blue against a warm
   beige, which is exactly the mismatch tokens.css exists to prevent.

   Note their .ms-img-news declares `transition` twice in one block, `all 0.3s`
   then `opacity 0.3s`, so the second silently wins and the card can only ever
   fade. Declared once here, which is why the lift below actually moves. */

.yp-news-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 7px 7px 20px;
  background: var(--yp-white);
  color: var(--yp-ink);
  text-decoration: none;
  box-shadow: 0 0 8px 0 rgb(var(--yp-ink-rgb) / 0.14);
  transition: box-shadow 0.3s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.yp-news-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 26px 0 rgb(var(--yp-ink-rgb) / 0.18);
}

.yp-news-card:focus-visible {
  outline: 2px solid var(--yp-ink);
  outline-offset: 3px;
}

/* aspect-ratio rather than a padding-bottom pseudo element: it reserves the
   space before the lazy image arrives, so the rail does not reflow card by
   card as they load. Sand underneath is what fills that reserved box. */
.yp-news-shot {
  display: block;
  aspect-ratio: 605 / 378;
  overflow: hidden;
  background: var(--yp-sand);
}

.yp-news-shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Headlines run 5 to 12 words. Three lines holds every one of them, and
   clamping is what keeps the cards a common height without a hard pixel
   height that a longer headline would spill out of. */
.yp-news-headline {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  margin: 16px 12px 0;
  font-family: var(--yp-serif);
  font-size: clamp(0.9375rem, 0.35vw + 0.85rem, 1.0625rem);
  line-height: 1.38;
  letter-spacing: 0.005em;
}

.yp-news-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  /* margin-top: auto pins the credit to the foot of the card, so the outlet
     line stays on one horizontal across the rail even when a headline runs
     two lines instead of three. */
  margin: auto 12px 0;
  padding-top: 12px;
  font-family: var(--yp-serif);
  font-size: clamp(0.6875rem, 0.15vw + 0.66rem, 0.8125rem);
  line-height: 1.3;
  letter-spacing: var(--yp-track-sub, 0.09em);
  text-transform: uppercase;
  color: rgb(var(--yp-ink-rgb) / 0.58);
}

.yp-news-outlet { color: var(--yp-ink); }

/* ---- nav bar -------------------------------------------------------------
   Carroll floats the two circles over the cards at 1024 and up, and drops
   them into a bar with the narrow-screen button between them below that. The
   bar is kept; the float is not. Their cards are bare clippings, so a disc
   over the artwork costs nothing. Ours carry a headline and a credit line
   under the image, and an ink disc over reading matter is a legibility
   problem rather than a flourish.

   The arrows are enhancement and stay hidden until the fragment's inline
   script marks the section. With the script blocked the rail is still a
   native scroller, so nothing is lost, and a visible control that does
   nothing is worse than no control at all. This is the only thing in the
   section JS gates, and it gates a control, never content. */

.yp-news-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding-top: clamp(16px, 1.8vw, 24px);
}

.yp-news-navslot { display: none; }
.yp-news-js .yp-news-navslot { display: block; }

@media (min-width: 1024px) {
  .yp-news-nav { justify-content: flex-end; gap: 10px; }
}

.yp-news-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 45px;
  height: 45px;
  padding: 0;
  border: 1px solid var(--yp-ink);
  border-radius: 50%;
  color: var(--yp-white);
  background: var(--yp-ink);
  cursor: pointer;
  transition: background-color 0.25s cubic-bezier(0.22, 1, 0.36, 1),
              color 0.25s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (min-width: 1024px) {
  .yp-news-arrow { width: 50px; height: 50px; }
}

/* Carroll's glyph is an icon font that 404s in the mirror, and its base
   codepoint points DOWN, which is why their buttons carry rotate(90deg) and
   rotate(-90deg). An inline chevron already points the right way, so there is
   no rotation here to fight the reveal's translate. */
.yp-news-arrow svg {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
}

.yp-news-arrow:hover:not(:disabled) {
  color: var(--yp-ink);
  background: var(--yp-white);
}

.yp-news-arrow:focus-visible {
  outline: 2px solid var(--yp-ink);
  outline-offset: 3px;
}

.yp-news-arrow:disabled {
  opacity: 0.28;
  cursor: default;
}

/* ---- outlet marquee ------------------------------------------------------
   Nested inside the section, as theirs is, and full bleed: it sits outside
   .yp-wrap so the logos run edge to edge.

   Unlike theirs it is not masked by anything. Their marquee animates from
   page load behind a parent stuck at opacity 0 until ScrollMagic fires, so on
   a slow connection it has already scrolled some distance by the time the
   section appears. Here the section is visible by default, so the loop starts
   where the markup says it starts. */

.yp-news-outlets {
  margin-top: clamp(44px, 5vw, 84px);
}

.yp-news-marquee {
  display: flex;
  align-items: center;
  /* This gap and the -1rem in the keyframe are one value in two places. Change
     one without the other and the loop visibly jumps every 40 seconds. */
  column-gap: 1rem;
  overflow: hidden;
}

.yp-news-marquee-list {
  display: flex;
  flex: none;
  min-width: 100%;
  align-items: center;
  justify-content: space-around;
  margin: 0;
  padding: 0;
  list-style: none;
  animation: yp-news-marquee 40s linear infinite;
}

@keyframes yp-news-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% - 1rem)); }
}

/* Carroll sizes each logo to max-content under an em cap because their seven
   files have seven different widths. All ten of these are the same 300x200
   canvas with the mark centred in it, so a fixed box gives an even rhythm and
   no logo ends up twice the size of its neighbour on canvas padding alone. */
.yp-news-logo {
  flex: 0 0 auto;
  width: clamp(108px, 12vw, 168px);
  padding: 0 15px;
}

.yp-news-logo img {
  display: block;
  width: 100%;
  height: auto;
  /* Ten mastheads arrive in ten brand colours at ten different weights.
     Grayscale and a held-back opacity make them read as one row of
     credentials rather than as ten logos competing with the press cards. */
  filter: grayscale(1);
  opacity: 0.55;
}

@media (min-width: 1024px) {
  .yp-news-marquee-list { animation-duration: 60s; }
  .yp-news-logo { padding: 0 30px; }
}

/* ---- reveal --------------------------------------------------------------
   The site contract, unchanged: the CSS default is VISIBLE, sections.js adds
   .yp-anim only when it is actually running, and .yp-in plays the reveal. The
   transition curve and the plain translateY resting state live in _shared.css
   so all eight sections move together.

   The delay ladder is Carroll's, and its order is the point: the RAIL arrives
   first at 0.3s, a full 0.3s before the headline. In the DOM the rail comes
   after the whole header block, so replacing these with a generic nth-child
   stagger would silently invert the intent.

     0.3s  rail
     0.6s  eyebrow
     0.7s  both title words, splitting from opposite sides
     0.8s  deck
     0.9s  buttons
     1.0s  arrows, mirroring each other, and the watermark

   Specificity is deliberately one class above _shared.css so the order the two
   files load in cannot matter. */

.yp-news.yp-anim .yp-news-rail.yp-rise  { transition-delay: 0.30s; }
.yp-news.yp-anim .yp-shead-name.yp-rise { transition-delay: 0.60s; }
.yp-news.yp-anim .yp-news-deck.yp-rise  { transition-delay: 0.80s; }
.yp-news.yp-anim .yp-news-cta.yp-rise   { transition-delay: 0.90s; }

/* The three below are not .yp-rise: each needs a resting transform the shared
   class does not have, so they carry their own copy of the same curve. */
.yp-news-word,
.yp-news-navslot,
.yp-news-mark {
  transition: opacity 0.3s ease,
              transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.yp-news.yp-anim .yp-news-word,
.yp-news.yp-anim .yp-news-navslot,
.yp-news.yp-anim .yp-news-mark { opacity: 0; }

.yp-news.yp-anim .yp-news-word { transition-delay: 0.70s; }
.yp-news.yp-anim .yp-news-navslot,
.yp-news.yp-anim .yp-news-mark { transition-delay: 1s; }

.yp-news.yp-anim .yp-news-word:first-child        { transform: translateX(-20px); }
.yp-news.yp-anim .yp-news-word + .yp-news-word    { transform: translateX(20px); }
.yp-news.yp-anim .yp-news-navslot-prev            { transform: translateX(-20px); }
.yp-news.yp-anim .yp-news-navslot-next            { transform: translateX(20px); }
.yp-news.yp-anim .yp-news-mark                    { transform: scale(0.86); }

.yp-news.yp-anim.yp-in .yp-news-word,
.yp-news.yp-anim.yp-in .yp-news-navslot,
.yp-news.yp-anim.yp-in .yp-news-mark {
  opacity: 1;
  transform: none;
}

/* ---- responsive ----------------------------------------------------------
   540, not 640: this is the width where .yp-wrap and the header both drop to
   a 16px gutter, and the rail's negative margin has to track that exactly or
   the first card stops starting on the headline's left edge. */

@media (max-width: 540px) {
  .yp-news-rail {
    margin: 0 -16px;
    padding-left: 16px;
    padding-right: 16px;
    scroll-padding-left: 16px;
  }

  /* The label needs about 256px to stay on one line, and a 375px screen
     leaves it 244 between the two arrows. Rather than shrink the type or cut
     the words, the button takes its own row: a two line label inside a pill
     sized for one reads as a break, not as a wrap. Arrows stay on the first
     row because they belong to the rail directly above them. */
  .yp-news-nav { flex-wrap: wrap; row-gap: 16px; }
  .yp-news-cta-narrow { order: 3; width: 100%; }
  .yp-news-cta-narrow .yp-news-btn { width: 100%; }

  .yp-news-logo { padding: 0 10px; }
}

/* ---- reduced motion ------------------------------------------------------
   _shared.css already neutralises .yp-rise. Everything below is motion this
   file adds on its own: the two directional splits, the watermark scale, the
   card lift, the smooth scroll the arrows trigger, and the marquee, which in
   the source runs forever with no opt out at all.

   The marquee cannot simply stop and stay cropped, or the logos past the fold
   of the strip become unreachable, so the strip becomes a plain scroller and
   the duplicate list is dropped: the duplicate exists only to make the loop
   seamless, and with no loop it is ten logos read twice. */

@media (prefers-reduced-motion: reduce) {
  .yp-news-card,
  .yp-news-btn,
  .yp-news-arrow {
    transition: none;
  }

  .yp-news-card:hover { transform: none; }
  .yp-news-rail { scroll-behavior: auto; }

  .yp-news-marquee { overflow-x: auto; }
  .yp-news-marquee-list { animation: none; }
  .yp-news-marquee-list[aria-hidden="true"] { display: none; }

  .yp-news-word,
  .yp-news-navslot,
  .yp-news-mark,
  .yp-news.yp-anim .yp-news-word,
  .yp-news.yp-anim .yp-news-navslot,
  .yp-news.yp-anim .yp-news-mark,
  .yp-news.yp-anim.yp-in .yp-news-word,
  .yp-news.yp-anim.yp-in .yp-news-navslot,
  .yp-news.yp-anim.yp-in .yp-news-mark,
  .yp-news.yp-anim .yp-news-rail.yp-rise,
  .yp-news.yp-anim .yp-shead-name.yp-rise,
  .yp-news.yp-anim .yp-news-deck.yp-rise,
  .yp-news.yp-anim .yp-news-cta.yp-rise {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}
