/* =========================================================
   Centrix Bento Gallery
   A pinned bento grid that expands to full-bleed on scroll.
   Markup:    template-parts/bento-gallery.php
   Behaviour: assets/js/bento-gallery.js  (GSAP Flip)

   Two states are described here:
     .cx-bento            — the resting bento layout
     .cx-bento--final     — the expanded layout
   The JS never animates between them with CSS. It measures the final
   state with Flip.getState(), reverts to the resting one, and tweens the
   difference against scroll. So both states must be real, complete
   layouts on their own.
   ========================================================= */

.cx-bento-wrap {
    position: relative;
    width: 100%;
    height: 100vh;
    height: 100svh;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #0B1526;
}

.cx-bento {
    position: relative;
    width: 100%;
    height: 100%;
    flex: none;

    /* Tracks are fractions of this element, not fixed viewport units, so the
       grid fills the wrap exactly at every size with no dead band top or
       bottom. Fixed vh rows previously summed to less than the viewport —
       harmless on desktop (23px) but leaving 108px on tablet and 125px on
       phone. 1fr also sidesteps the vh-vs-svh mismatch: the wrap is sized in
       svh, so rows measured in vh would disagree with it on any mobile
       browser with a collapsing toolbar. */
    display: grid;
    gap: 1vh 1vw;
    /* minmax(0, ...) is load-bearing, not decoration. A bare 1fr means
       minmax(auto, 1fr), whose auto minimum grows to fit content — and Flip
       animates by writing an inline width/height onto each tile. Those
       inline sizes would then inflate the very tracks the layout is built
       from, shifting every other tile and desyncing the positions Flip
       measured, so the expansion collapsed into a quarter-screen mess.
       A zero minimum pins the tracks to their fraction and lets the tiles
       overflow cleanly, which is exactly what the expansion needs. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(4, minmax(0, 1fr));
    /* Only meaningful in the expanded state below, where the tracks are
       deliberately larger than the viewport and need centring on it. */
    justify-content: center;
    align-content: center;
}

/* Expanded state. The centre column resolves to exactly 100vw, and tile 3
   spans two rows plus the gap between them — 49.5vh + 1vh + 49.5vh = 100vh.
   That is what lets the video tile land filling the viewport precisely
   rather than approximately. Changing these numbers breaks that.

   Doubled class (0,2,0) rather than a bare .cx-bento--final (0,1,0): the
   responsive overrides further down this file re-declare .cx-bento inside
   media queries, and at equal specificity those later rules would win —
   which silently made the expanded state identical to the resting one on
   tablet and phone, so the animation measured a no-op there while working
   fine on desktop. */
.cx-bento.cx-bento--final {
    grid-template-columns: repeat(3, 100vw);
    grid-template-rows: repeat(4, 49.5vh);
    gap: 1vh;
}

.cx-bento__item {
    position: relative;
    flex: none;
    overflow: hidden;
    background: #10254D;
}

.cx-bento__img,
.cx-bento__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}

/* Poster stand-in beneath the video, for when no poster image is set. */
.cx-bento__img--under {
    z-index: 0;
}

.cx-bento__video {
    z-index: 1;
    /* Hidden until it actually has a source and a frame to show, so an
       un-started video never paints a black rectangle over the fallback
       image beneath it. */
    opacity: 0;
    transition: opacity 400ms ease;
}

.cx-bento__video.is-ready {
    opacity: 1;
}

/* ── Tile placement ──
   Authored for exactly 8 tiles (CENTRIX_BENTO_TILES). Tile 3 is the centre
   video cell; see the note on .cx-bento--final above. */
.cx-bento__item:nth-child(1) { grid-area: 1 / 1 / 3 / 2; }
.cx-bento__item:nth-child(2) { grid-area: 1 / 2 / 2 / 3; }
.cx-bento__item:nth-child(3) { grid-area: 2 / 2 / 4 / 3; }
.cx-bento__item:nth-child(4) { grid-area: 1 / 3 / 3 / 4; }
.cx-bento__item:nth-child(5) { grid-area: 3 / 1 / 4 / 2; }
.cx-bento__item:nth-child(6) { grid-area: 3 / 3 / 5 / 4; }
.cx-bento__item:nth-child(7) { grid-area: 4 / 1 / 5 / 2; }
.cx-bento__item:nth-child(8) { grid-area: 4 / 2 / 5 / 3; }

/* ── Phone ──
   No track overrides needed any more: 1fr already adapts the resting grid
   to any viewport. Only the gap is tightened, so the tiles do not lose
   usable area to gutters on a small screen. */
@media (max-width: 640px) {
    .cx-bento {
        gap: 0.6vh 0.6vw;
    }
}

/* ── Reduced motion ──
   No pin, no Flip, no scroll hijack. The section becomes an ordinary
   bento grid that simply sits in the page at a sensible height. The JS
   also refuses to build the timeline under this preference, so nothing
   here is fighting an animation — this is the whole presentation. */
@media (prefers-reduced-motion: reduce) {
    .cx-bento-wrap {
        height: auto;
        padding: 4vh 0;
    }

    .cx-bento {
        height: auto;
        grid-template-columns: repeat(3, 30vw);
        grid-template-rows: repeat(4, 20vh);
    }

    .cx-bento__video {
        opacity: 1;
    }
}
