/**
 * Front-end styles for `bl_promo` output (render.php).
 *
 * No font or overlay-position control exists anywhere in this module -
 * see render.php and promo.php for why. The CTA button colors below ARE
 * admin-controllable as of 2026-08-26 (Mike's approval): three color
 * fields in meta-box.php let an editor override button color, button
 * hover color, and button text color per promo. What is declared here is
 * the DEFAULT, used whenever a promo has not set its own colors and as
 * the fail-safe render.php falls back to if a stored pair ever fails
 * contrast. These three values MUST stay byte-identical to the PHP
 * defaults in promo.php (BLA11Y_PROMO_DEFAULT_CTA_BG /
 * _CTA_BG_HOVER / _CTA_FG): the contract gate parses both and asserts
 * they agree, because a silent drift here would make the admin preview
 * lie about what actually renders. #ffffff on #a50f15 is 7.84:1
 * (SC 1.4.3 AA needs 4.5:1); every per-promo override is checked against
 * the same 4.5:1 minimum before it can publish
 * (bla11y_promo_enforce_contrast_before_publish() in meta-box.php), with
 * a render-time re-check behind that.
 *
 * v2 (2026-08-18): media is a stage; logo overlays top-right, CTA
 * bottom-left, video toggle bottom-right - all fixed positions, no
 * controls. Below 768px the video (and its toggle) never display; the
 * mobile image stands in. promo.js enforces the same breakpoint in
 * behavior (no .play() on mobile).
 */

.bl-promo {
    --bl-promo-cta-bg: #a50f15;
    --bl-promo-cta-bg-hover: #7f0b10;
    --bl-promo-cta-fg: #ffffff;
}

/* Text sits above the media strip; centered and sized to read as the
   banner's title rather than body copy (Mike, 2026-08-18). */
.bl-promo__content {
    text-align: center;
}

.bl-promo__headline {
    font-size: clamp(1.6rem, 3vw, 2.4rem);
    font-weight: 700;
    line-height: 1.15;
    margin: 0 auto 0.4em;
}

.bl-promo__subheadline {
    font-size: 1.15rem;
    margin: 0 auto 0.75em;
}

.bl-promo__media {
    display: block;
    margin-top: 1em;
}

.bl-promo__image,
.bl-promo__video {
    max-width: 100%;
    height: auto;
    display: block;
}

/* The stage is a full-width cinematic strip, matching the LayerSlider
   banners this module replaces (measured 2026-08-18: the three live
   banners render 1140x401 / 1140x445 / 1140x418 - all ~2.7:1). The
   media fills and center-crops the strip (object-fit: cover), exactly
   as LayerSlider cropped its background layers. The ratio is a design
   constant, deliberately not an editor control. */
.bl-promo__stage {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 1140 / 420;
    overflow: hidden;
}

.bl-promo__stage .bl-promo__video,
.bl-promo__stage .bl-promo__image,
.bl-promo__stage picture {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
}

.bl-promo__stage picture .bl-promo__image {
    position: static;
}

/* The overlay container never intercepts clicks meant for the media or
   the toggle; only its children (logo image, CTA button) are hit
   targets. Layout matches all three original banners: logo centered,
   CTA pill centered below it - fixed, deliberately not configurable. */
.bl-promo__overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 20px;
    padding: 24px;
    pointer-events: none;
}

.bl-promo__overlay > * {
    pointer-events: auto;
}

.bl-promo__overlay .bl-promo__logo {
    max-width: min(40%, 320px);
    max-height: 55%;
    width: auto;
    height: auto;
    object-fit: contain;
}

/* CTA styling applies wherever the CTA renders (overlay or the
   fail-safe content fallback): a solid pill whose colors are the fixed
   pair above, plus a non-color affordance (border) so it never depends
   on the media behind it. */
.bl-promo__cta {
    display: inline-block;
    background: var(--bl-promo-cta-bg);
    color: var(--bl-promo-cta-fg);
    border: 2px solid var(--bl-promo-cta-fg);
    border-radius: 999px;
    padding: 10px 24px;
    font-weight: 700;
    line-height: 1.2;
    text-decoration: none;
}

/* border-color pinned with !important: the theme's own a:hover rule
   out-specifies this class and repaints the bottom border green
   (rgb(12,96,14) - probed 2026-08-18), which reads as a glitch on a
   pill button. Same rationale as the !important focus rules below:
   this element's colors are a compliance/design constant, never the
   theme's to restyle. */
.bl-promo__cta:hover,
.bl-promo__cta:focus {
    background: var(--bl-promo-cta-bg-hover);
    color: var(--bl-promo-cta-fg);
    border-color: var(--bl-promo-cta-fg) !important;
    text-decoration: none;
}

/* Same focus treatment as the video toggle (and for the same
   forced-colors reason - see that rule's comment below). */
.bl-promo__cta:focus-visible {
    outline: 2px solid #ffffff !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px #1a4d8f !important;
}

@supports not selector(:focus-visible) {
    .bl-promo__cta:focus {
        outline: 2px solid #ffffff !important;
        outline-offset: 2px !important;
        box-shadow: 0 0 0 5px #1a4d8f !important;
    }
}

@media (forced-colors: active) {
    .bl-promo__cta {
        border: 2px solid LinkText;
    }

    .bl-promo__cta:focus-visible {
        outline: 3px solid Highlight;
        outline-offset: 2px;
    }
}

/* Mobile never gets a video background (v2). Both the video and its
   pause control disappear below the breakpoint - a visible control for
   an invisible video would be a lie - and the mobile image stands in.
   promo.js independently refuses to autoplay below this same
   breakpoint, so a hidden video is also a non-playing video.
   Double-class selector on purpose: the theme styles bare img at
   (0,1,1), which beat the single-class display:none and left a blank
   360px box inflating every video stage (measured 2026-08-18). */
.bl-promo .bl-promo__mobile-image {
    display: none;
}

@media (max-width: 767px) {
    /* Phones get a taller crop; the desktop strip ratio goes illegibly
       short at phone widths. */
    .bl-promo__stage {
        aspect-ratio: 4 / 3;
    }

    .bl-promo--video .bl-promo__video,
    .bl-promo--video .bl-promo__video-toggle {
        display: none;
    }

    .bl-promo--video .bl-promo__mobile-image {
        display: block;
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        max-width: none;
        object-fit: cover;
    }
}

/* The toggle sits over the video/poster deliberately: it is a control,
   not text-over-imagery, so SC 1.4.3 does not apply to it the way it
   applies to the headline (which never enters this stacking context -
   it lives in .bl-promo__content, before .bl-promo__media in the DOM). */
/* Visually hidden, still read aloud. The toggle's accessible name lives
   in a span using this class (v1.3.2) instead of being visible text: the
   full "Pause background video for <promo>" sentence was covering a
   sizeable part of the artwork. Never use display:none here - that would
   remove the name from the accessibility tree and leave an unlabelled
   button. */
.bl-promo__sr-only {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.bl-promo__video-toggle {
    position: absolute;
    right: 16px;
    bottom: 16px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px square: comfortably above the 24px minimum target size and
       small enough to sit out of the artwork's way. */
    width: 44px;
    height: 44px;
    padding: 0;
    background: #000000;
    color: #ffffff;
    border: 2px solid #ffffff;
    border-radius: 50%;
    line-height: 0;
    cursor: pointer;
}

.bl-promo__video-icon {
    display: block;
    width: 18px;
    height: 18px;
    pointer-events: none;
}

/* One glyph at a time, chosen from the same state promo.js writes when
   it updates the accessible name. Server-rendered default is paused, so
   the play triangle shows before any script runs. */
.bl-promo__video-toggle .bl-promo__icon-pause { display: none; }
.bl-promo__video-toggle .bl-promo__icon-play { display: inline; }

.bl-promo__video-toggle[data-bl-promo-playing="true"] .bl-promo__icon-pause { display: inline; }
.bl-promo__video-toggle[data-bl-promo-playing="true"] .bl-promo__icon-play { display: none; }

.bl-promo__video-toggle:hover {
    background: #272727;
}

/* Differs from the sitewide button:focus-visible ring
   (assets/css/bootleggers-a11y.css) in outline-offset only: that ring
   uses offset 0 everywhere else, but this button's own 2px white border
   sits flush against a 2px white outline at offset 0, so in Windows High
   Contrast / forced-colors mode - where box-shadow is dropped and both
   outline and border resolve to the same system color - the two rings
   merge into what reads as a single 2px edge with no visible focus
   change at all (finding 12, 2026-08-11). Offsetting the outline keeps
   it a visibly distinct ring outside the border in every mode. */
.bl-promo__video-toggle:focus-visible {
    outline: 2px solid #ffffff !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px #1a4d8f !important;
}

@supports not selector(:focus-visible) {
    .bl-promo__video-toggle:focus {
        outline: 2px solid #ffffff !important;
        outline-offset: 2px !important;
        box-shadow: 0 0 0 5px #1a4d8f !important;
    }
}

/* forced-colors (Windows High Contrast Mode) drops box-shadow entirely
   and forces both outline and border to the same system color, so the
   rule above alone is not enough - restore a visibly distinct ring using
   forced-colors-safe system color keywords (finding 12, 2026-08-11). */
@media (forced-colors: active) {
    .bl-promo__video-toggle {
        border: 2px solid ButtonText;
    }

    .bl-promo__video-toggle:focus-visible {
        outline: 3px solid Highlight;
        outline-offset: 2px;
    }
}

/* CSS cannot pause a <video> element that is already playing - only JS
   can. promo.js checks prefers-reduced-motion before it ever calls
   .play(), and separately listens for the media query changing mid-
   session so a visitor who turns Reduce Motion on after the video
   started still gets it paused (that JS listener, not this rule, is the
   actual SC 2.2.2/2.3.3 mechanism - finding 5, 2026-08-11). This rule is
   just the ordinary reduced-motion courtesy of not animating the toggle
   button's own hover/focus transition, since a state-change animation is
   itself motion; it is not doing anything to the video. */
@media (prefers-reduced-motion: reduce) {
    .bl-promo__video-toggle {
        transition: none;
    }
}
