/* ==========================================================================
   myk-hero-video — the hero VIDEO VARIANT
   ==========================================================================

   FOUNDER PREDICATE G3 (FT-20260817-vista-pacifico-review.md):
     "It just makes sense for all hero images to be able to have a video.
      Assume not that they all will have one — they all need to be ABLE to
      easily have a video in the design shape... And I would say that about
      all pages on the website. They all need to be video capable in the hero."

   WHAT THIS FILE IS — AND, MORE IMPORTANTLY, WHAT IT IS NOT
   --------------------------------------------------------
   It is NOT an implementation of a video background. Salient's own video
   background is already vendored into this build and already correct; the
   whole mechanic is four rules in
   `vendor/wp-content/themes/salient/css/build/style.q-98889c766d.css`:

     .wpb_row .nectar-video-wrap        {position:absolute;top:0;left:0;
                                         width:100%;height:100%;
                                         padding-bottom:0;overflow:hidden;
                                         opacity:1;z-index:1}
     .wpb_row .nectar-video-wrap video  {object-fit:cover;width:100%;
                                         height:100%;position:absolute;
                                         left:0;object-position:center}
     .wpb_row .nectar-video-wrap video  {transition:opacity .25s ease}
     .video-color-overlay               {width:100%;height:100%;opacity:0;
                                         position:absolute;top:0;left:0;
                                         padding-bottom:0;z-index:3;
                                         backface-visibility:hidden}
     .nectar-video-wrap[data-bg-alignment*=top]    video {object-position:center top}
     .nectar-video-wrap[data-bg-alignment*=bottom] video {object-position:center bottom}
     .mobile-video-image                {position:absolute;z-index:1;top:0;
                                         left:0;display:none;height:100%;
                                         width:100%;background-position:center;
                                         background-repeat:no-repeat;
                                         background-size:cover}
     .using-mobile-browser .mobile-video-image {display:block}

   This file is only the DELTA between that donor and what this build needs.
   Six rules. If you find yourself re-declaring `object-fit:cover` or
   `position:absolute` here, stop — the donor already did it, and duplicating
   it is how a lift silently becomes a reimplementation.

   THE STACKING ORDER, RESOLVED FROM THE VENDORED BYTES RATHER THAN ASSUMED
   -----------------------------------------------------------------------
   This is the one thing about the mechanic that is not obvious, and it is the
   thing that decides whether the hero headline stays legible once footage
   lands. `.nectar-video-wrap` is z-index 1. Our 180deg scrim is
   `.row-bg-overlay`, z-index 3, and it lives INSIDE `.row-bg-wrap` — so the
   question is whether `.row-bg-wrap` is a stacking context, because if it is,
   the scrim is trapped under the video and the headline loses its contrast.

   It is not:

     .full-width-section .row-bg-wrap,
     .wpb_row .row-bg-wrap {width:100%;height:100%;position:absolute;top:0;left:0}

   `position:absolute` with `z-index:auto` does not establish one. The scrim's
   z-index 3 therefore resolves in the ROW's context (`.wpb_row.top-level`,
   `position:relative` + inline `z-index:100`), as a peer of the video wrap.
   The painting order in that context is:

     z1   .row-bg-wrap > .inner-wrap        the <picture> still  <- LCP element
     z1   .nectar-video-wrap                the video           <- later in DOM
     z3   .row-bg-wrap > .row-bg-overlay    the 180deg scrim    <- OUR scrim
     z3   .video-color-overlay              Salient's optional flat tint
     z10  .row_col_wrap_12                  headline, body, CTA

   So the video slots in as one extra paint between the still and the scrim,
   and layers (a) base white, (c) scrim and the whole content stack are
   genuinely unchanged. That is what makes this a drop-in rather than a
   re-layer. It is asserted by review/hero-video/assert-fallback.py, not by
   this comment.

   TWO DELIBERATE DEVIATIONS FROM THE DONOR, BOTH MEASURED
   -------------------------------------------------------
   D-1 · NO `poster` ATTRIBUTE (§2). architect's <video> carries
        `poster="video-preview-ar-small-1.jpg"` because on that demo there is
        nothing underneath it — the row's background is a flat `#2b323a`. On
        OUR hero the still is a full `<picture>` with three media-scoped
        sources and a `fetchpriority="high"` preload, and it is the LCP
        element. A `poster` pointing at the same photograph would be a second,
        unpreloaded, non-responsive copy of an image that is already painted —
        185 KB of pure duplicate on desktop. The video is inserted at
        `opacity:0` and faded up only once it is actually playing, so the
        <picture> IS the poster for every frame before that. Heroes that have
        no still of their own can still set one with
        `data-myk-hero-video-poster`.

   D-2 · `.mobile-video-image` IS NEUTRALISED (§5). Salient shows it under
        `.using-mobile-browser` as the mobile stand-in for the video. Here it
        would paint a `background-image` of the 1600 JPEG on top of the
        `<picture>`, which at <=690px has already correctly selected the 800
        WebP — an extra 286 KB download to render a worse plate over a better
        one. The element is kept in the lifted markup for donor fidelity and
        turned off here. The `<picture>` is our mobile still, and it is the
        better one.

   RELATIONSHIP TO reduced-motion.css
   ----------------------------------
   §4 duplicates a guard that js/myk-hero-video.js also enforces (it refuses to
   insert the video at all under `prefers-reduced-motion: reduce`). That is
   deliberate belt-and-braces: the JS guard is the real one, but a hero whose
   markup someone later hard-codes instead of letting the component build it
   would otherwise autoplay for exactly the visitors who asked it not to. The
   CSS guard costs nothing and cannot be bypassed by a markup mistake.
   It lives HERE rather than in reduced-motion.css because that file is loaded
   last and shared by every lane; a component's own guard belongs with the
   component. Both files agree on the rule: reduced motion shows the FINAL
   state, and for a video background the final state is the still.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. THE SLOT — the wrap must cover the row it was inserted into.

   Salient's own `.wpb_row .nectar-video-wrap{width:100%;height:100%}` already
   does this for a normal row. The one case it does not cover is a row that has
   been given a min-height taller than its content — which is every hero on
   this site, because css/grid-fluid.css §9 sets `.mk-hero{min-height:100vh}`
   and sections/00-hero.css raises it to `max(900px, 100vh)`. `height:100%` of
   a percentage-less parent resolves against the parent's USED height, which is
   the min-height, so it happens to be right — but only while the wrap's
   offset parent is the row. `inset:0` states the intent directly and survives
   someone later making the row `display:flex`, which is the change that would
   otherwise silently collapse it.
   -------------------------------------------------------------------------- */
.myk-hero-video {
  inset: 0;
}


/* --------------------------------------------------------------------------
   2. THE FADE-IN — this is D-1 above, expressed as two rules.

   The component inserts the <video> at opacity 0 and sets
   `data-myk-hero-video-state="playing"` on the section only after the element
   has actually produced frames (the `playing` event, not `canplay` — `canplay`
   fires on a video that autoplay policy is about to refuse). Until then the
   <picture> underneath is what the visitor sees, which is exactly the
   no-video render. There is therefore no frame in which the hero is blank,
   and no frame in which a half-decoded video is visible.

   0.6s rather than Salient's 0.25s: Salient fades a video in over a flat
   colour, where a quick cut reads as decisive. Ours crossfades one photograph
   into moving footage OF THE SAME PLACE, where a quick cut reads as a glitch.
   `--myk-hero-video-fade` is the knob; set it per page if a hero wants the
   donor's timing back.
   -------------------------------------------------------------------------- */
.myk-hero-video video {
  opacity: 0;
  transition: opacity var(--myk-hero-video-fade, 0.6s) ease;
}

[data-myk-hero-video-state="playing"] .myk-hero-video video {
  opacity: 1;
}


/* --------------------------------------------------------------------------
   3. THE OPTIONAL TINT — `.video-color-overlay`.

   Vendored at `opacity:0`, because on the donor Salient's PHP emits the
   colour and the opacity as inline style when the editor sets them, and emits
   nothing when they do not. We keep that contract: the component writes
   `background-color` + `opacity` inline from `data-myk-hero-video-overlay`,
   and with no field the layer stays fully transparent and paints nothing.

   00-hero does not use it — its scrim is the 180deg gradient on
   `.row-bg-overlay`, which is richer than a flat tint and already tuned to
   the comp. The field exists for the OTHER heroes G3 covers: a hero whose
   still needed no scrim may well need one once the same frame starts moving,
   and this is the layer to put it on, because it is the one that paints above
   the video.
   -------------------------------------------------------------------------- */
.myk-hero-video-tint {
  transition: opacity var(--myk-hero-video-fade, 0.6s) ease;
}


/* --------------------------------------------------------------------------
   4. REDUCED MOTION — see the header. Show the still, never the loop.

   `display:none` and not `opacity:0`: an invisible autoplaying video still
   decodes every frame, still spins the GPU and still drains the battery of a
   visitor who asked their OS for less motion. Hiding it is a courtesy; not
   decoding it is the actual accommodation.

   Scoped to the wrap, not to `video` — so the wrap's own paint (and any tint
   that was configured against it) goes with it, leaving the <picture> and the
   scrim exactly as the no-video render draws them.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .myk-hero-video {
    display: none !important;
  }
}


/* --------------------------------------------------------------------------
   5. `.mobile-video-image` — D-2 above.

   Kept in the lifted markup, turned off here. `!important` beats Salient's own
   `.using-mobile-browser .mobile-video-image{display:block}` and
   `body[data-remove-m-video-bgs="1"] .mobile-video-image{display:block}`,
   neither of which is reachable by specificity from a component sheet loaded
   before the section sheets. CONVENTIONS §8.6 case, and the rules being
   beaten are named.

   If a hero is ever built WITHOUT a <picture> still — the only situation in
   which this element earns its place — set `data-myk-hero-video-poster` and
   the component will point this layer at it and re-enable it by adding
   `.myk-hero-video-still--active`, below.
   -------------------------------------------------------------------------- */
.mobile-video-image {
  display: none !important;
}

.mobile-video-image.myk-hero-video-still--active {
  display: block !important;
}


/* --------------------------------------------------------------------------
   6. THE FAILURE STATES ARE NOT STYLED, AND THAT IS THE POINT.

   `data-myk-hero-video-state` takes: absent · reduced-motion · save-data ·
   suppressed-mobile · pending · playing · failed. Only `playing` has a rule
   (§2). Every other value renders the hero exactly as it renders with no video
   field at all, because in every other case the component has either not
   inserted the element or has removed it again.

   That is the fallback guarantee stated as CSS: there is no selector here that
   can make a hero look different from today unless a video is genuinely
   playing. review/hero-video/assert-fallback.py proves the same thing at the
   pixel level.

   The attribute is on the section purely so tests and QA can read it. If you
   are tempted to hang a style off `failed` or `pending` — don't. A hero that
   visibly announces its own degraded state is worse than one that quietly
   looks correct.
   -------------------------------------------------------------------------- */
