/* wpc_ads.css — grey placeholders + responsive slot sizing.
 *
 * Each slot has its size baked into CSS per breakpoint, so the placeholder
 * occupies the correct dimensions BEFORE any JS runs. No CLS, no jank.
 *
 * The JS loader only swaps creative content; size logic lives here.
 */

/* ── Base placeholder chrome — flat grey box, no border, no label.
       Per request: house-ad placeholders should look like a neutral sized
       block, not a "missing image" frame. The grey block alone makes the
       slot's footprint clear without the dashed/uppercase noise. */
.wpc-ad {
  display: block;
  margin: 1rem auto;
  background: #e5e7eb;
  border: 0;
  box-sizing: border-box;
  overflow: hidden;
  border-radius: 6px;
  position: relative;
}

.wpc-ad-inner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Label + size text hidden in the new flat-grey design. Kept in DOM for
   admin-overlay debugging via `body.show-ad-labels .wpc-ad-label`. */
.wpc-ad-label, .wpc-ad-sizes { display: none; }
body.show-ad-labels .wpc-ad-label,
body.show-ad-labels .wpc-ad-sizes { display: inline-flex; }

/* When filled, drop placeholder chrome */
.wpc-ad--filled {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0;
}
.wpc-ad--filled .wpc-ad-label { display: none; }
.wpc-ad--filled .wpc-ad-inner { position: static; display: block; }

/* ── Ascend slot/fallback toggling — GLOBAL.
       These used to live in a <style> block in partials/ascend_slot.html,
       but that template is only ever pulled in via `{% from ... import %}`,
       which DISCARDS template body output — so the rules never reached any
       page. Result: when Ascend filled a slot, the house fallback stayed
       visible next to/below the creative (the "Try free banner beside the
       ad" + footer jitter bugs). They live here now so every page gets
       them. `is-ascend-filled` is set by ascend_prebid.html. */
.wpc-ascend-wrap { position: relative; }
.wpc-ascend-wrap.is-ascend-filled .wpc-ascend-fallback { display: none !important; }
.wpc-ascend-wrap:not(.is-ascend-filled) .wpc-ascend-slot:empty { display: none; }

/* Center whatever Ascend/GPT injects (a fixed-width div wrapping an iframe)
   inside the slot — the GPT div is a block element and otherwise sits at the
   container's left edge ("last horizontal slot is not centered"). */
.wpc-ascend-slot { text-align: center; }
.wpc-ascend-slot > div {
  margin-left: auto !important;
  margin-right: auto !important;
}
.wpc-ascend-slot iframe { margin-left: auto; margin-right: auto; }

/* ── STICKY_FOOTER — viewport-anchored wrapper.
       Ascend's bundle was expected to fix-position its own Sticky_Footer
       div, but it renders in normal flow (so the "sticky" ad just sat at
       the bottom of the document). Per ad-ops: give it a wrapper that is
       position:fixed to the viewport bottom. pointer-events:none on the
       wrapper keeps the page clickable when the slot is empty; the slot
       itself restores pointer-events for the creative. The mobile download
       bar on content detail re-pins this wrapper above itself via its own
       fixed-element scan (content_detail.html). */
.wpc-sticky-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1080;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  pointer-events: none;
}
.wpc-sticky-footer [ot-name],
.wpc-sticky-footer [id^="asc-"] { pointer-events: auto; }

/* ── In-cascade ad cards (keyword + content-detail related grids).
       Mobile/tablet only — on desktop (>1100px) the sticky sidebar rail
       carries the ads. Mirrors the keyword.html inline rules so the same
       card markup works on every template that renders a .kw-contents grid. */
.cascade-ad-mobile { display: none !important; }
@media (max-width: 1100px) {
  .cascade-ad-mobile { display: block !important; }
}
/* 250px so a 300×250 creative isn't cropped — the span-6 grid area is
   265px (6×40px rows + 5×5px gaps), so 250 still fits without overlap. */
.kw-contents .cascade-ad-card.housead-mr { height: 250px; }
/* Paid creative wins over the house fallback inside a cascade card
   (generic — keyword.html carries a main.wallpaper-scoped duplicate). */
.cascade-ad-card:has(.housead-paid .wpc-ad--filled) .housead-fallback { display: none; }

/* House-ad CLICKABILITY. The `.housead-paid` slot is an absolute overlay
   (inset:0; z-index:2) sitting ABOVE the house-ad fallback. When NO paid ad
   has filled it, that invisible layer still swallowed the click, so the house
   ad's <a> underneath was un-clickable. Let pointer events pass THROUGH the
   empty overlay to the house ad; restore them only once a real ad fills it. */
.housead-paid { pointer-events: none; }
.housead-paid:has(.wpc-ad--filled) { pointer-events: auto; }

/* ── Per-slot dimensions (mobile-first → tablet → desktop) ────────── */

/* HEADER_TOP — 320×50 mobile, 728×90 tablet/desktop centered in rail.
   Mobile height rides a CSS var: Ascend often fills 320×100 (not ×50), and
   a fixed 50px bar clipped the bottom half of the creative. The fill
   reporter (ascend_prebid.html) measures the rendered creative and sets
   --wpc-topad-h accordingly; 50px stays the no-fill default. */
.wpc-ad.wpc-ad--header_top {
  position: relative;
  top: 0;
  z-index: 1035;
  width: 100vw;
  max-width: 100vw;
  height: var(--wpc-topad-h, 50px);
  aspect-ratio: auto;
  margin: 0 0 0 calc(50% - 50vw);
  background: #000 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: height .18s ease, transform .18s ease, opacity .18s ease;
}
.wpc-ad.wpc-ad--header_top,
.wpc-ad.wpc-ad--header_top.wpc-ad--filled {
  border-radius: 0 !important;
  -webkit-border-radius: 0 !important;
  overflow: hidden !important;
}
body:not(.wpc-top-ad-hidden) .wpc-ad--header_top::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--wpc-topad-h, 50px);
  background: #000;
  z-index: -1;
  pointer-events: none;
}
body.wpc-top-ad-hidden .wpc-ad--header_top {
  display: none !important;
  height: 0 !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  opacity: 0 !important;
  overflow: hidden !important;
  pointer-events: none !important;
}
body.wpc-top-ad-hidden .wpc-ad--header_top::before {
  display: none !important;
  height: 0 !important;
}
.wpc-ad--header_top .wpc-ad-inner {
  position: static;
  width: 100%;
  max-width: 320px;
  height: 100%;
  margin: 0 auto;
  border-radius: 0 !important;
  box-shadow: none !important;
  overflow: hidden;
}
.wpc-ad--header_top .wpc-ad-inner > *,
.wpc-ad--header_top .wpc-ad-inner a,
.wpc-ad--header_top .wpc-ad-inner aside,
.wpc-ad--header_top .wpc-ad-inner img,
.wpc-ad--header_top .wpc-ad-inner iframe,
.wpc-ad--header_top .wpc-ad-inner div {
  border-radius: 0 !important;
  box-shadow: none !important;
}
.wpc-ad--header_top .wpc-ad-inner > * {
  margin: 0 !important;
}
/* Ascendeum top-leaderboard container. CRITICAL: the slot is NEVER `:empty`
   (it always holds the GPT <script>), so it can't be auto-collapsed — and the
   header bar is display:flex, so if the slot takes layout width it sits beside
   the house ad and shoves it into the right half (showing only its purple bg).
   Fix: lay the Ascend slot as an absolute, centered OVERLAY over the whole bar.
   It takes no flex space (house ad stays centered underneath); when Ascend
   actually fills, its creative paints on top (z-index) and the fill-reporter
   hides the house fallback. */
.wpc-ad.wpc-ad--header_top { position: relative; }
.wpc-ad--header_top .wpc-ascend-slot {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  margin: 0 auto;
  max-width: 320px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  z-index: 2;
}
/* The overlay sits ABOVE the house fallback (z-index 2). Until Ascend
   actually fills it, it must NOT swallow the clicks meant for the house AI
   banner underneath — and it can't be hidden via `:empty` because the slot
   always holds a GPT <script>. Let pointer events pass through until a
   creative lands; `.is-ascend-filled` (added by the fill reporter) restores
   them so the paid creative is clickable. */
.wpc-ad--header_top:not(.is-ascend-filled) .wpc-ascend-slot { pointer-events: none; }

/* ── House AI top-bar STANDOUT ─────────────────────────────────────────────
   When the house "Make AI Wallpaper" banner is showing (no Ascend fill yet),
   paint the whole bar with a vivid indigo→purple→pink AI gradient so it pops
   off the page instead of blending into the black letterbox. The instant
   Ascend fills, `.is-ascend-filled` lands → these rules stop matching → the
   bar reverts to its plain black letterbox (so a paid leaderboard isn't
   framed in purple). The house fallback also spans the full bar width so the
   gradient is edge-to-edge. */
.wpc-ad--header_top.wpc-topad--house:not(.is-ascend-filled),
.wpc-ad--header_top.wpc-topad--house:not(.is-ascend-filled)::before {
  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #ec4899 100%) !important;
}
.wpc-ad--header_top.wpc-topad--house .wpc-ad-inner { max-width: 100% !important; }
.wpc-ad--header_top .wpc-ascend-slot iframe,
.wpc-ad--header_top .wpc-ascend-slot > div {
  margin: 0 auto !important;
  /* Never let flex SQUEEZE a creative that's wider than the slot (a 970
     leaderboard in a 728 box rendered at half width); keep natural size and
     let the slot's overflow:hidden crop symmetrically instead. */
  flex-shrink: 0;
}
@media (min-width: 768px) {
  .wpc-ad--header_top .wpc-ascend-slot { max-width: 728px; }
}
@media (min-width: 1024px) {
  /* Ascend serves up to 970-wide creatives to the Desktop device class —
     give the overlay room so they render full size (refresh was landing
     970×90 creatives in the 728 cap and squeezing them to half width). */
  .wpc-ad--header_top .wpc-ascend-slot { max-width: 970px; }
}
@media (max-width: 767px) {
  body.wpc-top-ad-hidden .wpc-ad--header_top {
    height: 0;
    transform: none;
    opacity: 0;
    pointer-events: none;
  }
  body.wpc-top-ad-hidden .wpc-ad--header_top .wpc-ad-inner { height: 0; }
}
@media (min-width: 768px) {
  .wpc-ad.wpc-ad--header_top {
    height: 120px;
  }
  body:not(.wpc-top-ad-hidden) .wpc-ad--header_top::before { height: 120px; }
  .wpc-ad--header_top .wpc-ad-inner { max-width: 728px; height: 90px; }
  .wpc-ad--header_top ~ nav header.new-sticky { top: 0; }
  body.wpc-top-ad-hidden .wpc-ad--header_top {
    height: 0;
    transform: none;
    opacity: 0;
    pointer-events: none;
  }
  body.wpc-top-ad-hidden .wpc-ad--header_top .wpc-ad-inner { height: 0; }
  body.wpc-top-ad-hidden .wpc-ad--header_top ~ nav header.new-sticky { top: 0; }
}
@media (min-width: 1024px) {
  .wpc-ad.wpc-ad--header_top { height: 120px; }
  body:not(.wpc-top-ad-hidden) .wpc-ad--header_top::before { height: 120px; }
  .wpc-ad--header_top .wpc-ad-inner { max-width: 728px; height: 90px; }
  .wpc-ad--header_top ~ nav header.new-sticky { top: 0; }
  body.wpc-top-ad-hidden .wpc-ad--header_top {
    height: 0;
    transform: none;
    opacity: 0;
    pointer-events: none;
  }
  body.wpc-top-ad-hidden .wpc-ad--header_top .wpc-ad-inner { height: 0; }
  body.wpc-top-ad-hidden .wpc-ad--header_top ~ nav header.new-sticky { top: 0; }
}

/* House-ad creatives are injected with height:auto, so a creative taller than
   the slot (e.g. the Premium-Plan promo banner in a 50px leaderboard) gets
   clipped by the slot's overflow:hidden. In the compact banner slots, scale the
   image to FIT the slot height (object-fit:contain) instead of clipping it. */
.wpc-ad--header_top   .wpc-ad-inner img,
.wpc-ad--content_top  .wpc-ad-inner img,
.wpc-ad--content_mid  .wpc-ad-inner img,
.wpc-ad--footer_pre   .wpc-ad-inner img,
.wpc-ad--mobile_sticky .wpc-ad-inner img,
.wpc-ad--keyword_top  .wpc-ad-inner img {
  max-height: 100% !important;
  width: auto !important;
  max-width: 100% !important;
  height: auto !important;
  object-fit: contain;
  margin: 0 auto !important;
}

/* KEYWORD_TOP — compact 320×50 banner on mobile (NOT a 300×250 square right
   after the H1, which pushes content way down), 728×90 tablet, 970×250 desktop */
.wpc-ad--keyword_top {
  width: 320px; max-width: 100%;
  aspect-ratio: 320 / 50;
}
@media (max-width: 767px) {
  .wpc-ad--keyword_top { min-height: 0 !important; max-height: 60px; }
}
@media (min-width: 768px) {
  /* Tablet: centered 728×90 leaderboard. */
  .wpc-ad--keyword_top {
    width: 728px; aspect-ratio: 728 / 90;
    margin-left: auto; margin-right: auto;
  }
}
@media (min-width: 1024px) {
  /* Desktop: 970×250 billboard, centered. The keyword_top house creative
     (id=37) is now a true 970×250 AI-wallpaper billboard that fills this box
     (it used to be a 728×90 that rendered small inside the oversized slot). */
  .wpc-ad--keyword_top {
    width: 970px; aspect-ratio: 970 / 250;
    margin-left: auto; margin-right: auto;
  }
}

/* CONTENT_TOP — compact mobile banner, 728×90 tablet, 970-capable desktop.
   Ad-ops: the Horizontal unit can return creatives up to 970px wide on
   desktop; a 728px container cropped them. The box is 970 wide but the
   creative inside centers (see .wpc-ascend-slot rules above), so a 728×90
   fill still sits in the middle. */
.wpc-ad--content_top, .wpc-ad--content_mid {
  width: 320px; max-width: 100%;
  aspect-ratio: 320 / 50;
}
@media (min-width: 768px) {
  .wpc-ad--content_top, .wpc-ad--content_mid {
    width: 728px; aspect-ratio: 728 / 90;
  }
}
@media (min-width: 1024px) {
  .wpc-ad--content_top { width: 970px; aspect-ratio: 970 / 90; }
}

/* CONTENT_MOBILE — mobile-only 300×250 in-content unit, shown right after
   the main image on the wallpaper detail page. Hidden on tablet/desktop where
   the sticky sidebar rail carries the in-content ads instead. */
.wpc-ad--content_mobile { display: none; }
@media (max-width: 767px) {
  .wpc-ad--content_mobile {
    display: block;
    width: 300px; max-width: 100%;
    aspect-ratio: 300 / 250;
  }
}

/* CONTENT_BOTTOM — 300×250 mobile, 728×90 tablet, 970×250 desktop */
.wpc-ad--content_bottom {
  width: 300px; max-width: 100%;
  aspect-ratio: 300 / 250;
}
@media (min-width: 768px) {
  .wpc-ad--content_bottom { width: 728px; aspect-ratio: 728 / 90; }
}
@media (min-width: 1024px) {
  .wpc-ad--content_bottom { width: 970px; aspect-ratio: 970 / 250; }
}

/* SIDEBAR_TOP — 300×250 desktop+tablet, hidden mobile */
.wpc-ad--sidebar_top {
  display: none;
}
@media (min-width: 768px) {
  .wpc-ad--sidebar_top {
    display: block;
    width: 300px; max-width: 100%;
    aspect-ratio: 300 / 250;
  }
}

/* SIDEBAR_MID — 300×250 tablet, 300×600 desktop, hidden mobile */
.wpc-ad--sidebar_mid {
  display: none;
}
@media (min-width: 768px) {
  .wpc-ad--sidebar_mid {
    display: block; width: 300px; aspect-ratio: 300 / 250;
  }
}
@media (min-width: 1024px) {
  .wpc-ad--sidebar_mid { aspect-ratio: 300 / 600; }
}

/* CASCADE_INLINE — uniform 300×250 across breakpoints; sits in grid cell */
.wpc-ad--cascade_inline {
  width: 100%; max-width: 300px;
  aspect-ratio: 300 / 250;
  margin: 0 auto;
}

/* FOOTER_PRE — 320×100 mobile, 728×90 tablet, 970-capable desktop
   (Horizontal can serve 970-wide creatives on desktop; see CONTENT_TOP). */
.wpc-ad--footer_pre {
  width: 320px; max-width: 100%;
  aspect-ratio: 320 / 100;
  margin-bottom: 0;
}
@media (min-width: 768px) {
  .wpc-ad--footer_pre { width: 728px; aspect-ratio: 728 / 90; }
}
@media (min-width: 1024px) {
  .wpc-ad--footer_pre { width: 970px; aspect-ratio: 970 / 90; }
}

/* MOBILE_STICKY — only mobile, 320×50, fixed at viewport bottom */
.wpc-ad--mobile_sticky {
  display: none;
}
@media (max-width: 767px) {
  .wpc-ad--mobile_sticky {
    display: block;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    margin: 0;
    width: 100%; max-width: 100%;
    aspect-ratio: auto;
    height: 50px;
    z-index: 1000;
    border-radius: 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, .08);
  }
}

/* OUTSTREAM VIDEO — sitewide unit near the page foot (Ascend "Video").
   Self-sizing: the player manages its own height; we only center + cap width.
   Fully collapsed (no margin, no grey box) until Ascend fills it, so an unsold
   slot leaves zero footprint — and its expand/refresh reflow stays at the foot. */
.wpc-outstream { width: 100%; max-width: 970px; margin: 0 auto; }
.wpc-outstream .wpc-ascend-slot { display: block; }
.wpc-outstream .wpc-ascend-slot:empty { display: none; }
.wpc-outstream:has(.wpc-ascend-slot:not(:empty)) { margin: 1.5rem auto; }
/* Mobile: the outstream player self-sizes and auto-expands/collapses/refreshes
   directly above the footer, so every fill→refresh→collapse cycle shoved the
   footer + language dropdown up and down — the visible "banner keeps moving"
   jitter reported on phones. It's also the heaviest CLS/CWV offender on small
   screens. Suppress it under the tablet breakpoint; desktop keeps it (more room
   below the fold, reflow only nudges the very foot). */
@media (max-width: 768px) {
  .wpc-outstream { display: none !important; }
}

/* Sidebar sticky-on-scroll for desktop */
@media (min-width: 1024px) {
  .wpc-ad--sidebar_top, .wpc-ad--sidebar_mid {
    position: sticky; top: 1rem;
  }
}
