/* ===========================================================================
   ads.css — styling for every ad placement.

   WHY THIS FILE EXISTS AT ALL
   The original .ad-container / .ad-label / .bottom-sticky-ad / .sticky-ad-*
   rules live in classic-wheel-styles.css and are duplicated across ~8 page
   stylesheets. A converted picker page does not load ANY of them, so an ad on
   one of those ~150 pages would have rendered completely unstyled. Same
   deliberate arrangement picker-ui.css already uses: shared chrome lives in a
   shared file, loaded from commoncss.php.

   THEMING
   Colours come from the site's theme variables with literal fallbacks, so the
   ad frame follows light / dark / high-contrast without a per-theme block.
   =========================================================================== */

.wsp-ad {
    /* Never let an ad widen the page. A third-party unit that ignores its
       container is the classic source of horizontal scroll on mobile. */
    max-width: 100%;
    overflow: hidden;
}

.wsp-ad__label {
    display: block;
    font-size: .68rem;
    line-height: 1.2;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-align: center;
    /* DERIVED FROM THE THEME TEXT COLOUR, NOT FROM --theme-muted.
       Measured 2026-08-24: --theme-muted resolves to #1f2937 in the
       high-contrast theme because that token assumes a light background. This
       card is deliberately near-transparent, so on high-contrast the label
       landed as dark ink on a BLACK ground -> 1.43:1, far under AA 4.5.
       --theme-text always contrasts with whatever ground the theme paints, and
       trimming it with opacity keeps the "quieter than body copy" look without
       inventing a second colour per theme.
       MEASURED after this change (compositing the opacity over the real
       painted ground, instrument validated against black-on-white = 21.0):
       light 6.30 / dark 8.18 / high-contrast 10.54 - all above AA 4.5 for
       10.9px text. */
    color: var(--theme-text, #222);
    opacity: .72;
    margin-bottom: .35rem;
}

.wsp-ad__body {
    display: block;
    text-align: center;
}

.wsp-ad__body > * {
    max-width: 100%;
}

.wsp-ad-img {
    max-width: 100%;
    height: auto;
    display: inline-block;
    border-radius: 6px;
}

/* ── In-page placements ───────────────────────────────────────────────── */

.wsp-ad--inline {
    margin: 2rem auto;
    padding: 1rem;
    max-width: 970px;
    border-radius: 10px;
    border: 1px solid var(--theme-border, rgba(0, 0, 0, .08));
    background: var(--theme-card-bg, rgba(0, 0, 0, .015));
}

/* ── Mobile anchor bar ────────────────────────────────────────────────── */

.wsp-ad--anchor {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    padding: .4rem .5rem;
    background: var(--theme-card-bg, #fff);
    border-top: 1px solid var(--theme-border, rgba(0, 0, 0, .12));
    box-shadow: 0 -2px 14px rgba(0, 0, 0, .12);
}

/* Desktop never sees the anchor — it is a phone placement by design. */
@media (min-width: 768px) {
    .wsp-ad--anchor { display: none !important; }
}

/* Mounted by ads.js only once consent has been answered. Measured 2026-08-14
   at 390x844: #wsp-consent-bar (z-index 9997) completely covered this bar
   (z-index 1000), so Google would have counted an impression on a unit nobody
   could see — a policy problem, not an aesthetic one. */
.wsp-ad--anchor.is-pending { display: none !important; }

/* ── An unfilled slot leaves NO box ──────────────────────────────────────
   AdSense answers a request it cannot fill by setting
   data-ad-status="unfilled" and rendering nothing, which left the wrapper's
   label and padding around a blank space on every page (owner, 2026-08-30 —
   and measured: every unit on production came back unfilled, desktop included).

   The wrapper ships with this class and ads.js removes it only when a unit
   actually reports data-ad-status="filled".

   ⚠️ `display: none` and NOT `visibility`/`opacity`: an invisible-but-laid-out
   ad still reserves its height, which is the same empty gap by another name.

   ⚠️ It also must not be `!important`. body.zen-mode .wsp-ad and the print rule
   below both need to win over it, and they are plain rules. */
.wsp-ad--awaiting {
  /* ⛔ NOT `display: none`. AdSense measures the slot to decide what to serve,
     and a display:none container has ZERO WIDTH — the bundle then threw twice
     per page ("Uncaught Y"), and worse, a unit it cannot measure is a unit it
     may decline to fill. Hiding the box would have suppressed the very ads we
     want shown.
     Collapsing the HEIGHT keeps the full width available for measurement while
     occupying no vertical space, so an unfilled slot leaves nothing behind. */
  /* ⛔ max-height, NOT height. AdSense writes `style="height: auto !important"`
     onto the wrapper of any unit it processes, and an INLINE !important beats a
     stylesheet !important — so `height: 0` simply loses on exactly the slots
     that matter. It sets `height`, so clamping a DIFFERENT property still wins.
     Measured: with `height` the processed wrapper stayed 333px; with
     `max-height` it collapses. */
  max-height: 0;
  min-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  margin-top: 0;
  margin-bottom: 0;
  border-top-width: 0;
  border-bottom-width: 0;
  overflow: hidden;
}

.wsp-ad__close {
    position: absolute;
    top: -12px;
    right: 8px;
    width: 26px;
    height: 26px;
    line-height: 1;
    padding: 0;
    font-size: 1.1rem;
    border-radius: 50%;
    cursor: pointer;
    color: var(--theme-text, #222);
    background: var(--theme-card-bg, #fff);
    border: 1px solid var(--theme-border, rgba(0, 0, 0, .18));
    box-shadow: 0 1px 4px rgba(0, 0, 0, .15);
}

/* A dismiss control has to be comfortably tappable, so give it a hit area
   larger than its painted size rather than making the button itself bigger. */
.wsp-ad__close::before {
    content: "";
    position: absolute;
    inset: -11px;
}

/* ── Fullscreen / zen ─────────────────────────────────────────────────── */

/* themes.css already hides .bottom-sticky-ad in zen. The helper also refuses
   to emit the anchor there, but belt and braces: an ad must never cover a
   picker in fullscreen. */
body.zen-mode .wsp-ad {
    display: none !important;
}

/* ── Print ────────────────────────────────────────────────────────────── */

@media print {
    .wsp-ad { display: none !important; }
}
