/* ==========================================================================
   Connect 2026 - Ad slot                                                T-10
   --------------------------------------------------------------------------
   38 placements across the 22 screens. The pattern is regular enough to be a
   rule rather than per-page markup:

     listing   1 skyscraper, top of the rail
     reader    2 half slots, one usually the CeFPro Academy house promo
     landing   1 skyscraper
     Home      the exception - left rail + two in-column horizontals

   SIZES - measured from the artboards, converted at 1pt = 2.4px

     skyscraper   452 x 1357   right rail, full height        (p2 and every listing)
     half         452 x  679   right rail, half height        (p3, p9, p14, p16...)
     horizontal   774 x  156   in-column band                 (p1 "connect + advert",
                                                                  "sponsored advert")

   EVERY SLOT RESERVES ITS SPACE. Ads load late or fail to load; without a
   reserved box the page reflows underneath the reader, which is the single
   biggest cumulative-layout-shift risk in this design given 38 placements.

   OPEN QUESTION - 452px is not a standard IAB size. Standard skyscraper is
   160 or 300px, half-page 300x600. Real creative dimensions unconfirmed.

   DEPENDS ON: tokens.css
   ========================================================================== */

.cn-ad {
  display: block;
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--cn-band-grey);
}

/*
   CONTAIN, NEVER COVER. AN ADVERT IS SHOWN WHOLE OR NOT AT ALL.

   This was `cover`, and cover crops whenever the creative and the slot are not
   the same shape. Measured at 1440 on the In-depth reader: the ad service
   returns one portrait creative at 515 x 1546 (1:3), the reader's half slot is
   452 x 679 (2:3), so the image rendered 452 x 1357 inside a 679-tall box with
   overflow:hidden - EXACTLY HALF THE ADVERT CUT OFF, and the half carrying the
   dates and the call to action was the half that went.

   Cover is the right default for editorial imagery, where a crop loses
   scenery. It is the wrong default for an advert, where a crop loses the
   offer. The responsive blocks below already made this argument twice and set
   contain by hand at each breakpoint; it belongs here, once, as the rule -
   so no slot added later can quietly start cropping again.

   NOTHING CHANGES ON THE EIGHT LISTINGS. Their skyscraper slot is 452 x 1357,
   which is 1:3 to four decimal places against the creative's 515 x 1546, and
   at an exact match contain and cover render identically. What changes is
   every slot that does NOT match, which is where the damage was.

   A mismatch now letterboxes against the slot's own grey ground instead of
   losing the logo or the CTA.
*/
/*
   AND THE <picture> HAS TO FILL THE SLOT, or contain above does nothing.

   adSlot.tag wraps the image in a <picture> so the wide creative can be
   swapped in below 1280. That wrapper sits between the slot and the image, and
   it is auto-height - so `height: 100%` on the image resolved against "auto",
   fell back to the image's own intrinsic ratio, and the image sized itself as
   if object-fit were not set at all. Then the slot's overflow:hidden cropped
   whatever stuck out.

   Measured at 768 with the fix half-applied: slot 653 x 81, image 653 x 89,
   8px of the banner still sliced off the bottom. Small, but the same bug as
   the 677px slice at desktop - contain was never getting a box to work in.

   With the wrapper filling the slot the image is finally 653 x 81 and contain
   does its job: the banner scales to 593 x 81 and centres, and the 30px each
   side falls on the slot's own grey ground. Letterboxed, not cropped, which is
   the whole point.
*/
.cn-ad picture {
  display: block;
  width: 100%;
  height: 100%;
}


.cn-ad__img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ------------------------------------------------------------- sizes ---- */
/* aspect-ratio rather than fixed height, so the box scales with the rail
   while still reserving proportional space. */
.cn-ad--skyscraper { aspect-ratio: 452 / 1357; }
.cn-ad--half       { aspect-ratio: 452 / 679; }
/* p1 draws the wide bars 774 x 156. The wide creatives are 1100 x 150, and
   stretched to 156 tall they looked squat (asked 17 Sep) - so the bar is
   120 tall instead: the creative's own 106 plus a little, a far smaller
   stretch. Placeholders take the same height so the page does not move
   when a creative arrives. */
.cn-ad--horizontal { aspect-ratio: 774 / 120; }
/* p13's "survey banner ad to take part": 743.6 x 251 in the content column.
   Drawn at the wide bars' 120 instead (asked 17 Sep): the wide creatives
   are 1100 x 150 and stretched to 251 the banner looked twice its height.
   Same landscape handling as --horizontal everywhere. */
.cn-ad--banner     { aspect-ratio: 744 / 120; }

/*
   THE BOARD'S BOX, FILLED - 17 Sep 2026. Every slot is the size the board
   draws it (the aspect ratios above) and the creative is stretched to it
   (object-fit: fill, the live site's own rule). Vertical creatives are 1:3
   like the skyscraper so they are untouched; the wide bars squeeze a little
   (1100 x 150 into 775 x 156). Cover, contain, a blurred ground and natural
   height were each tried on screen and turned down.
*/
.cn-ad:not(.cn-ad--placeholder) .cn-ad__img { object-fit: fill; }
}

/* --------------------------------------------------------- disclosure -- */
/*
   Sponsored placements must be visibly labelled - it is an advertising
   disclosure requirement, not a design nicety. House promos (CeFPro Academy,
   Connect Plus) are first-party and do not need it.
*/
.cn-ad__label {
  position: absolute;
  top: var(--cn-space-2);
  left: var(--cn-space-2);
  z-index: var(--cn-z-base);
  padding: 2px var(--cn-space-3);
  border-radius: var(--cn-radius-sm);
  background: rgba(0, 28, 100, .78);
  color: var(--cn-ink-invert);
  font-size: 11px;
  font-weight: var(--cn-fw-semibold);
  letter-spacing: var(--cn-tracking-label);
  text-transform: uppercase;
}

/* ------------------------------------------------------- placeholder --- */
/*
   Artboard state: the lime block with its caption. Renders whenever no
   creative is supplied, so pages are reviewable before real assets exist.

   MUST NOT SHIP. Check with:
     grep -rn "cn-ad--placeholder" src/main/webapp/WEB-INF/views/connect2026/
*/
.cn-ad--placeholder {
  display: grid;
  place-items: center;
  padding: var(--cn-space-6);
  background: var(--cn-ph-ad);
  color: var(--cn-ink-invert);
  font-size: var(--cn-text-card);
  font-weight: var(--cn-fw-semibold);
  text-align: center;
}

/* =========================================================== RESPONSIVE == */
/*
   T-40 DECISION: once the rail stacks below the content column, rail slots
   become BANNERS. A 452x1357 skyscraper rendered full width would be several
   screens tall.

   IMPORTANT - THIS IS AN AD-OPS QUESTION, NOT ONLY A CSS ONE.
   A skyscraper creative cannot be reflowed into a banner; it is a different
   asset at a different aspect ratio. Mobile needs its own creative sizes.
   Raise with the client alongside "452px is not a standard IAB size".

   Until that is answered the box reserves banner-shaped space so layout does
   not shift, and the placeholder still reads correctly.
*/
@media (max-width: 1279px) {
  /* The reserved shape. Placeholders keep this - it is the artboard state. */
  .cn-ad--skyscraper,
  .cn-ad--half {
    aspect-ratio: 970 / 250;   /* standard billboard banner */
    min-height: 160px;
  }

  /*
     A PORTRAIT CREATIVE WITH NO LANDSCAPE ALTERNATIVE. Hide it.

     --tall-only means exactly that: adSlot.tag sets it when the record has an
     `image` but no `imageWide`. Cover would crop it - measured at 800, a
     515x1546 skyscraper in the 682x176 box showed 8.6% of the advert. An
     advert nobody can read is worse for the advertiser than one that did not
     appear, and ad.js reports no impression for a hidden slot, so the count
     stays honest. The live site hides its vertical column for the same reason.

     This used to sit at 767, which meant the crop was merely hidden on phones
     and left on show across the whole 768-1279 tablet band.
  */
  .cn-ad--tall-only { display: none; }

  /*
     A LANDSCAPE CREATIVE. Reserve a leaderboard and show it whole.

     Where imageWide exists the <picture> in adSlot.tag now swaps to it at this
     same breakpoint, so the slot holds a wide banner rather than a portrait
     one. The 970x250 billboard above is too tall for it: a 1633x223 banner
     contained into 682x176 letterboxes 83px of grey. 728x90 is the standard
     leaderboard and sits much closer to the creative's own 7.3:1.

     contain, never cover - the same rule live applies to its horizontal
     placements. An advert has to be shown whole; any mismatch letterboxes
     against the slot's grey ground instead of losing the logo or the CTA.
  */
  .cn-ad--skyscraper:not(.cn-ad--tall-only):not(.cn-ad--placeholder),
  .cn-ad--half:not(.cn-ad--tall-only):not(.cn-ad--placeholder) {
    aspect-ratio: 728 / 90;    /* standard leaderboard */
    min-height: 0;
  }

  .cn-ad--skyscraper:not(.cn-ad--placeholder) .cn-ad__img,
  .cn-ad--half:not(.cn-ad--placeholder) .cn-ad__img {
    object-fit: contain;
  }
}

@media (max-width: 767px) {
  .cn-ad--skyscraper,
  .cn-ad--half,
  .cn-ad--horizontal,
  .cn-ad--banner {
    aspect-ratio: 320 / 100;   /* standard large mobile banner */
    min-height: 100px;
  }
  .cn-ad--placeholder { font-size: var(--cn-text-meta); }

  /* --tall-only is already hidden and the creative already contained by the
     1279 block above; 767 only needs the tighter mobile sizes. */

  /*
     THE SLOT TAKES THE CREATIVE'S SHAPE, IT DOES NOT IMPOSE ONE.

     With a landscape creative in place the crop is smaller but still a crop:
     the supplied banner measures 1633x223 - 7.3:1 - and a 3.2:1 box on cover
     cut more than half its width away, which on an advert means losing the
     logo or the call to action.

     So drop the reserved ratio here and let the image set the height. The
     reflow risk the fixed ratio guards against does not apply: the image is
     the only thing in the slot, and at 343px wide this banner is 47px tall
     rather than the 107px the ratio was reserving.

     contain rather than cover for the same reason live sets object-fit:
     contain on its horizontal placements - an advert has to be shown whole.
  */
  .cn-ad--skyscraper:not(.cn-ad--tall-only):not(.cn-ad--placeholder),
  .cn-ad--half:not(.cn-ad--tall-only):not(.cn-ad--placeholder) {
    /*
       320x50, the standard mobile leaderboard, and NOT aspect-ratio: auto.

       auto looked right and deadlocked: with no reserved height the slot
       computed to 0x0, a lazily-loaded image inside a zero-height box never
       enters the viewport, so it never loads, so the box never gains height.
       The advert vanished completely - measured 0x0 at 375.

       A reserved ratio keeps the lazy load working and holds the space
       against layout shift; contain below does the job auto was meant to.
    */
    aspect-ratio: 320 / 50;
    min-height: 0;
  }

}
