/* public/css/ads.css — ad-unit placement wrappers.
 *
 * Sticky ads DO NOT overlay content. Instead, ads.js measures the rendered
 * wrapper height, sets it as a CSS custom property (--ad-sticky-bottom-h or
 * --ad-sticky-top-h), and adds a body class that applies matching padding
 * to the body so page content and the footer are pushed out of the ad's
 * way. This keeps the entire site usable at all scroll positions without
 * covering any content.
 *
 * Because there's no close button, the ad stays visible for the whole
 * session — site owner's deliberate choice. AdSense program policy allows
 * this provided the ad does not cover essential page content, which our
 * space-reservation pattern guarantees.
 */

.ad-inline { margin: 16px 0; }

/* ------------------------------------------------------------------
   Sticky / floating wrappers
   ------------------------------------------------------------------ */

.ad-sticky, .ad-float {
    position: fixed;
    z-index: 850;                   /* above page content, below modals (1100+) */
    background: #fff;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.12);
    border-top: 1px solid #e5e7eb;
    padding: 6px 10px;
    max-width: 100%;
    box-sizing: border-box;
}

/* Bottom-stuck banner pins itself to the bottom of the viewport. Body
   padding (set below) keeps page content from scrolling underneath it. */
.ad-sticky--bottom {
    bottom: 0;
    left: 0;
    right: 0;
}

/* Top-stuck banner pins to top:0 ABOVE the site header. The header is
   already position:sticky — we push it down by the ad's height so the
   two stack cleanly. */
.ad-sticky--top {
    top: 0;
    left: 0;
    right: 0;
    border-top: 0;
    border-bottom: 1px solid #e5e7eb;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    z-index: 1001;                  /* above the sticky header */
}

.ad-float--corner {
    bottom: 16px;
    right: 16px;
    width: 320px;
    max-width: calc(100vw - 32px);
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

.ad-sticky-body {
    min-height: 40px;
    text-align: center;     /* centre the fixed-size sticky banner */
}
.ad-float--corner .ad-sticky-body { min-height: 100px; }

/* Fixed-size sticky ad: 728x90 leaderboard on desktop, 320x50 on mobile.
   AdSense responsive can't measure through a position:fixed wrapper, so
   for sticky placements we use explicit pixel sizes. Same slot serves
   both sizes — AdSense picks the right creative for what we request. */
.ad-sticky-ins {
    display: inline-block;
    max-width: 100%;
}
@media (max-width: 767px) {
    .ad-sticky-ins {
        width: 320px !important;
        height: 50px !important;
    }
    .ad-sticky--top, .ad-sticky--bottom { min-height: 60px; }
}

/* ------------------------------------------------------------------
   Space reservation — applied by ads.js after measuring the wrapper.
   --ad-sticky-bottom-h / --ad-sticky-top-h are set to the rendered
   height in pixels. The matching body class is added/removed whenever
   the ad is visible / hidden / resized.
   ------------------------------------------------------------------ */

body.has-ad-sticky-bottom {
    padding-bottom: var(--ad-sticky-bottom-h, 0px);
}
body.has-ad-sticky-top {
    padding-top: var(--ad-sticky-top-h, 0px);
}
/* Push the site header down so the sticky-top ad sits above it cleanly */
body.has-ad-sticky-top .site-header {
    top: var(--ad-sticky-top-h, 0px);
}
/* Initial reservation before ads.js measures — prevents the header from
   being briefly covered while JS boots. AdSense horizontal banners are
   typically 90-100px; 90 is a safe default which ads.js will refine to
   the actual rendered size. */
.ad-sticky--top, .ad-sticky--bottom {
    min-height: 90px;
}

/* ------------------------------------------------------------------
   Auto-hide empty wrappers
   ------------------------------------------------------------------ */

/* When AdSense reports the slot as unfilled (data-ad-status="unfilled"),
   hide the wrapper so it doesn't take up reserved space. AdSense needs
   the wrapper to be VISIBLE with real dimensions while it's trying to
   fill — hiding pre-emptively causes "No slot size for availableWidth=0". */
.ad-sticky:has(ins.adsbygoogle[data-ad-status="unfilled"]),
.ad-float:has(ins.adsbygoogle[data-ad-status="unfilled"]) {
    display: none !important;
}
/* NOTE: we intentionally do NOT hide wrappers when marketing consent is
   denied. Consent Mode v2 tells AdSense to serve non-personalised
   "limited ads" in that case, so ads still show and the site still earns
   revenue. AdSense throws "No slot size" if the wrapper is display:none,
   so we keep it visible and let Google's own consent signals govern
   whether a personalised or limited ad is shown. */

/* Dark theme: keep the wrapper visually neutral — dark grey, not blue.
   (Some themes use a blue-tinted --card-bg which makes an empty slot
   look like a Google loading bar.) */
[data-theme="dark"] .ad-sticky,
[data-theme="dark"] .ad-float {
    background: #1f2937;
    border-color: #374151;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.4);
}
[data-theme="dark"] .ad-sticky--top {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}

/* Print — ads never visible in printed output */
@media print {
    .ad-inline, .ad-sticky, .ad-float { display: none !important; }
}
