/* =========================================================================
   Bassar Production — home page
   Scoped to body.bp-home so the rest of the site is untouched.

   Two header states:
     hero      — transparent over the showreel, logo and icons white
     .bp-scrolled — sticky, blurred, still white, with the category menu shown
   White is the constant because both the showreel and the slider behind the
   header are dark imagery.
   ========================================================================= */

.bp-home {
    --bp-header-h: 84px;
    --bp-hairline: rgba(255, 255, 255, 0.14);
    --bp-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --bp-gutter: clamp(20px, 5vw, 72px);
    --bp-max: 1440px;
    --bp-accent-rgb: 253, 67, 2;
}

.bp-home .bp-main {
    overflow: clip;
    padding-top: 0;
}

/* =========================================================================
   1. Header
   ========================================================================= */

/* Sit over the hero rather than pushing it down. */
.bp-home .main-header {
    position: absolute !important;
    top: 0;
    left: 0;
    width: 100%;
    height: auto;
    min-height: 0;
    z-index: 30;
}

.bp-home .main-header__layout {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    margin-top: 0;
    z-index: 30;
    background-color: transparent !important;
    transition: background-color 0.45s var(--bp-ease),
                -webkit-backdrop-filter 0.45s var(--bp-ease),
                backdrop-filter 0.45s var(--bp-ease),
                box-shadow 0.45s var(--bp-ease);
}

.bp-home .main-header__inner {
    min-height: var(--bp-header-h);
    padding-inline: var(--bp-gutter);
    max-width: var(--bp-max);
    transition: min-height 0.45s var(--bp-ease);
}

/* Sticky state — frosted, over the slider. */
.bp-home.bp-scrolled .main-header__layout {
    background-color: rgba(12, 13, 16, 0.38) !important;
    -webkit-backdrop-filter: blur(22px) saturate(1.35);
    backdrop-filter: blur(22px) saturate(1.35);
    box-shadow: 0 1px 0 0 var(--bp-hairline);
}

.bp-home.bp-scrolled .main-header__inner {
    min-height: 62px;
}

/* -- the logo stays the light one in both states --------------------------- */
.bp-home .ms-nb--white .logo-light {
    opacity: 1 !important;
}

.bp-home .ms-nb--white .logo-dark {
    opacity: 0 !important;
}

/* -- header icons stay white in both states ------------------------------- */
.bp-home .ms-nb--white .main-header__inner .header__search-icon svg path {
    stroke: #fff !important;
}

.bp-home .ms-nb--white .main-header__inner .ms_theme_mode .toggle-label::before {
    background-color: #fff;
}

/* -- the category menu: hidden over the hero, revealed once sticky --------- */
@media only screen and (min-width: 1024px) {
    .bp-home .main-header__default {
        opacity: 0;
        visibility: hidden;
        transform: translateY(-8px);
        pointer-events: none;
        transition: opacity 0.45s var(--bp-ease),
                    transform 0.45s var(--bp-ease),
                    visibility 0s linear 0.45s;
    }

    .bp-home.bp-scrolled .main-header__default {
        opacity: 1;
        visibility: visible;
        transform: none;
        pointer-events: auto;
        transition: opacity 0.45s var(--bp-ease) 0.05s,
                    transform 0.45s var(--bp-ease) 0.05s,
                    visibility 0s linear 0s;
    }

    /* Twelve categories will not fit beside the logo and the CTA on one row,
       so the sticky header gives them a row of their own. */
    .bp-home.bp-scrolled .main-header__inner {
        flex-wrap: wrap;
        align-items: center;
        align-content: center;
        row-gap: 0;
    }

    /* Gives the top line a real height so the logo centres in it. */
    .bp-home.bp-scrolled .main-header__logo {
        --bp-logo-inset: 11px;
        padding-block: var(--bp-logo-inset);
    }

    /* The parent theme pins .logo-light with position:absolute; top:0, so the
       padding above only centres the in-flow (and invisible) .logo-dark — the
       white mark that actually shows stays stuck to the header's top edge.
       Offset it by the same inset so it sits centred in the top line. */
    .bp-home.bp-scrolled .main-header__layout .main-header__inner .logo-light {
        top: var(--bp-logo-inset);
    }

    .bp-home.bp-scrolled .navbar__menu__container {
        order: 4;
        flex: 1 0 100%;
        width: 100%;
        max-width: 100%;
        margin: 0;
        border-top: 1px solid var(--bp-hairline);
    }

    .bp-home.bp-scrolled .main-header__default {
        width: 100%;
        max-width: 100%;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .bp-home.bp-scrolled .main-header__default::-webkit-scrollbar {
        display: none;
    }

    /* max-content + min-width:100% means the strip spreads edge to edge while
       the labels fit, and scrolls instead of clipping when they don't. The
       theme styles this list through #primary-menu-default, so the id has to
       be carried here to win. */
    .bp-home.bp-scrolled .main-header__default > #primary-menu-default.navbar-nav {
        display: flex;
        flex-wrap: nowrap;
        justify-content: space-between;
        align-items: center;
        gap: clamp(9px, 1.4vw, 22px);
        width: -webkit-max-content;
        width: max-content;
        min-width: 100%;
        padding: 11px 0;
        margin: 0;
    }

    /* Spacing comes from the gap alone — the theme's per-item padding is what
       pushes the labels past the available width. */
    .bp-home.bp-scrolled .main-header__default > #primary-menu-default > .menu-item {
        padding: 0;
        margin: 0;
        height: auto;
    }

    .bp-home .main-header__default > #primary-menu-default > .menu-item > a {
        padding-inline: 0;
        font-size: 0.75rem;
        letter-spacing: 0.005em;
        white-space: nowrap;
    }

    /* White menu text, over both the hero and the slider. */
    .bp-home .ms-nb--white .main-header__layout .main-header__default > #primary-menu-default > .menu-item > a,
    .bp-home .ms-nb--white .main-header__layout .main-header__default > #primary-menu-default > .menu-item > a::after {
        color: rgba(255, 255, 255, 0.82);
    }

    .bp-home .main-header__default > #primary-menu-default > .menu-item > a:hover {
        color: #fff;
    }

    /* Category matching the slide on screen. */
    .bp-home .main-header__default > #primary-menu-default > .menu-item.bp-active > a,
    .bp-home .ms-nb--white .main-header__layout .main-header__default > #primary-menu-default > .menu-item.bp-active > a {
        color: var(--color-primary);
    }

    /* A category with no slide of its own — dimmed, still clickable. */
    .bp-home .main-header__default > #primary-menu-default > .menu-item.bp-no-slide > a {
        opacity: 0.55;
    }
}

/* =========================================================================
   2. Hero — showreel, overlay, and nothing but a scroll cue
   ========================================================================= */

.bp-hero {
    position: relative;
    min-height: 100vh;
    min-height: 100svh;
    overflow: hidden;
    background-color: #0b0c0e;
    isolation: isolate;
}

/* The template sets --bp-hero-poster inline when a still is available; the
   gradient is the fallback layer when it is not. This is the ground before the
   video fades in, and the whole hero for a reduced-motion visitor, who never
   gets the video at all. */
.bp-hero__media {
    position: absolute;
    inset: 0;
    z-index: 0;
    background-color: #0b0c0e;
    background-image:
        radial-gradient(120% 90% at 22% 12%, rgba(var(--bp-accent-rgb), 0.14) 0%, transparent 58%),
        var(--bp-hero-poster, linear-gradient(160deg, #17181c 0%, #0b0c0e 62%));
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* 16:9 iframe scaled to cover the viewport in both directions. */
.bp-hero__video {
    position: absolute;
    top: 50%;
    left: 50%;
    /* The extra scale pushes YouTube's own title bar and corner logo outside
       the visible area — belt and braces for the fallback embed, which has no
       player events to gate the reveal on. */
    transform: translate(-50%, -50%) scale(1.2);
    width: 100vw;
    height: 56.25vw;
    min-height: 100vh;
    min-width: 177.7778vh;
    pointer-events: none;
    /* Revealed only once the player reports PLAYING — otherwise YouTube's
       paused overlay (title, channel, centre controls) shows through. */
    opacity: 0;
    transition: opacity 0.9s ease;
}

@supports (height: 100svh) {
    .bp-hero__video {
        min-height: 100svh;
        min-width: 177.7778svh;
    }
}

.bp-hero.bp-video-ready .bp-hero__video {
    opacity: 1;
}

.bp-hero__video > *,
.bp-hero__video iframe,
.bp-hero__video #bp-hero-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    pointer-events: none;
}

/* Black rising from the bottom and fading out as it goes up, so the showreel
   stays open at the top and settles into the dark section below. The short top
   scrim only keeps the white logo legible over a bright frame. */
.bp-hero__overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        linear-gradient(
            to top,
            rgba(0, 0, 0, 0.78) 0%,
            rgba(0, 0, 0, 0.55) 16%,
            rgba(0, 0, 0, 0.28) 38%,
            rgba(0, 0, 0, 0.08) 62%,
            rgba(0, 0, 0, 0) 82%
        ),
        linear-gradient(
            to bottom,
            rgba(0, 0, 0, 0.34) 0%,
            rgba(0, 0, 0, 0) 22%
        );
}

/* -- scroll cue ----------------------------------------------------------- */
.bp-scroll-cue {
    position: absolute;
    left: 50%;
    bottom: clamp(28px, 5vh, 52px);
    z-index: 3;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 999px;
    color: #fff;
    text-decoration: none;
    transition: background-color 0.3s var(--bp-ease), transform 0.3s var(--bp-ease);
}

.bp-scroll-cue:hover,
.bp-scroll-cue:focus-visible {
    background-color: rgba(255, 255, 255, 0.12);
}

.bp-scroll-cue__arrow {
    display: block;
    width: 17px;
    filter: drop-shadow(0 1px 5px rgba(0, 0, 0, 0.55));
    animation: bp-cue 2.1s var(--bp-ease) infinite;
}

.bp-scroll-cue__arrow svg {
    display: block;
    width: 100%;
    height: auto;
}

@keyframes bp-cue {
    0%   { transform: translateY(-5px); opacity: 0; }
    28%  { opacity: 1; }
    68%  { opacity: 1; }
    100% { transform: translateY(9px); opacity: 0; }
}

/* =========================================================================
   3. The slider section below the hero
   ========================================================================= */

/* The slider carries a position:fixed gradient scrim sized for the old
   full-screen layout; being fixed it floats over the hero too. The header
   supplies its own backdrop now, so the scrim is not needed. */
.bp-home .ms-page-content .e-con.e-child::before {
    background-image: none !important;
}

/* The slider's custom "SCROLL" cursor is position:fixed and parks at the
   viewport origin until the pointer first moves, showing through in the hero's
   top-left corner. Keep it hidden until the pointer is over the slider. */
.bp-home .slider-cursor-w {
    opacity: 0;
    transition: opacity 0.2s ease;
}

.bp-home .elementor-widget-ms_slider:hover .slider-cursor-w {
    opacity: 1;
}

/* =========================================================================
   4. Responsive
   ========================================================================= */

@media only screen and (max-width: 1023px) {
    .bp-home {
        --bp-header-h: 72px;
    }

    .bp-scroll-cue {
        width: 44px;
        height: 44px;
    }

    .bp-scroll-cue__arrow {
        width: 15px;
    }
}

/* =========================================================================
   5. Contact item inside the mobile dropdown
   The header pill is hidden below 1024px, so the menu carries the CTA there.
   ========================================================================= */

@media only screen and (min-width: 1024px) {
    .menu-item.bp-menu-cta {
        display: none !important;
    }
}

@media only screen and (max-width: 1023px) {
    .menu-item.bp-menu-cta {
        margin-top: 18px;
    }

    .menu-item.bp-menu-cta > a {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        padding: 14px 26px !important;
        border-radius: 999px;
        background: var(--color-primary);
        color: #fff !important;
        font-size: 0.9375rem !important;
        font-weight: 700;
        text-decoration: none;
    }

    /* ms-nb--white forces the menu links white so they read over the showreel,
       but the mobile dropdown panel is light — restate the colour inside it. */
    .bp-home .ms-nb--white .main-header__layout .main-header__default > #primary-menu-default > .menu-item > a,
    .bp-home .ms-nb--white .main-header__layout .main-header__default > #primary-menu-default > .menu-item > a::after {
        color: #0e0f12;
    }

    .bp-home .ms-nb--white .main-header__layout .main-header__default > #primary-menu-default > .menu-item.bp-menu-cta > a {
        color: #fff;
    }

    .bp-home .main-header__default > #primary-menu-default > .menu-item.bp-active > a {
        color: var(--color-primary);
    }
}

/* =========================================================================
   6. Reduced motion
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
    .bp-scroll-cue__arrow {
        animation: none;
    }

    .bp-home .main-header__layout,
    .bp-home .main-header__default,
    .bp-contact-btn {
        transition: none;
    }
}

/* -------------------------------------------------------------------------
   Client band over the hero.

   Addressed by element id: Elementor 4.x does not render a container's CSS
   Classes field, so a class cannot be attached from the editor side. The id is
   stable in the page's stored data.

   The block is an absolutely positioned Elementor container whose offset
   parent is .ms-page-content — its top edge is the hero's floor. Anchoring
   with `bottom: 100%` therefore puts the block's own bottom exactly on that
   floor, and the margin lifts it clear of the scroll cue. Height-independent,
   so a second logo row or a shorter hero cannot push it back into the cue.
   ---------------------------------------------------------------------- */

.bp-home .elementor-element-b664250 {
    top: auto !important;
    bottom: 100% !important;
    margin-bottom: clamp(88px, 12vh, 132px) !important;
    pointer-events: none;
}

.bp-home .elementor-element-b664250 .ms-tt li,
.bp-home .elementor-element-b664250 .ms-tt a {
    pointer-events: auto;
}

/* The logos are one flat ink for the whole site; over the dark hero they have
   to read the other way round. Inverting is exact here precisely because every
   mark is that single grey — swap in full-colour artwork and this must go. */
.bp-home .elementor-element-b664250 img {
    filter: invert(1);
}

/* The caption is white text over the video, not grey text on a page. */
.bp-home .elementor-element-b664250 .elementor-heading-title {
    color: rgba(255, 255, 255, 0.72) !important;
}

/* The band is decorative over a video; don't let it fight the hero for focus. */
.bp-home .elementor-element-b664250 .ms-text-ticker {
    opacity: 0.85;
}

@media only screen and (max-width: 1023px) {
    .bp-home .elementor-element-b664250 {
        display: none !important;
    }
}

/* The caption is flush right against the viewport; give it the page gutter. */
.bp-home .elementor-element-b664250 > .e-con {
    padding-right: clamp(16px, 3vw, 40px);
}

/* ------------------------------------------------------------------
   Scroll-linked category slider

   The slider used to advance by eating wheel gestures, which is what made
   the page stop dead at every category. Releasing the wheel fixed the
   stopping but left the slider frozen on the first slide and the whole home
   page barely two screens tall.

   So the slider is pinned instead and its progress is driven from the page's
   own scroll position (see initSliderScrollLink in bassar-home.js). Scrolling
   is ordinary native scrolling the whole way down — nothing is intercepted,
   nothing snaps — and the categories move as you go.

   #bp-work is the child theme's own wrapper around the Elementor page, so
   giving it the runway does not disturb any Elementor container. The runway
   length is set from the slide count in JS via --bp-slider-runway.
   ------------------------------------------------------------------ */

body.bp-home #bp-work {
	height: var(--bp-slider-runway, 500vh);
}

body.bp-home #bp-work > section {
	position: sticky;
	/* The card block is 115vh, so pin it 7.5vh above the top edge to sit it
	   centred in the viewport rather than hanging off the bottom. */
	top: -7.5vh;
	height: 115vh;
}

/* Swiper marks a vertical slider touch-action:pan-x so that finger drags go
   to the slider rather than the page. With the slider no longer taking
   gestures that only stops phones scrolling at all, because it covers the
   viewport. */
body.bp-home .swiper.ms-slider-zeffir,
body.bp-home .ms-slider.zeffir-slider {
	touch-action: auto !important;
}

/* No runway on a browser without JS: the pin would strand the reader in an
   empty five-screen gap with a slider that never advances. */
body.bp-home.no-js #bp-work,
body.bp-home:not(.bp-slider-linked) #bp-work {
	height: auto;
}

body.bp-home:not(.bp-slider-linked) #bp-work > section {
	position: static;
	height: auto;
}
