/* ================================================================== */
/*  Hero stage — one sticky pin container, two absolute layers        */
/*                                                                    */
/*  .hero-stage          (relative, 320vh)  scroll spacer             */
/*    .hero-stage__pin   (sticky top:0, 100vh)  the pinned viewport   */
/*      .hero            (absolute, inset:0)    video layer z:1       */
/*      .next-section    (absolute, inset:0)    crossfade layer z:5   */
/*                                                                    */
/*  Phases (scrollY relative to .hero-stage top):                     */
/*    0   → 120vh   SCRUB       --hero-progress 0→1   (video plays)   */
/*    120 → 140vh   CROSSFADE   --hero-exit 0→1       (fade swap)     */
/*    140 → 220vh   HOLD        --hero-exit = 1       (still pinned)  */
/*    220 → 320vh   SCROLL-OUT  pin unsticks, both scroll up together */
/*                                                                    */
/*  One sticky element makes the pin behavior bulletproof — no        */
/*  overlapping-siblings edge cases. Both layers share its box so     */
/*  they always occupy the same 100vh until the stage ends.           */
/* ================================================================== */

.hero-stage {
    position: relative;
    height: 320vh;
    /* Pull the stage up under the (sticky) navbar so the video shows through
       the transparent navbar at scrollY=0. As the user scrolls, --hero-progress
       ramps the navbar bg from transparent to white. */
    margin-top: -64px;
}

.hero-stage__pin {
    position: sticky;
    top: 0;                             /* full-bleed: pin extends behind the navbar */
    height: 100vh;
    overflow: hidden;
    isolation: isolate;
    background: #000;
}

.hero {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: #000;
    opacity: clamp(0, calc(1 - var(--hero-exit, 0)), 1);
    /* No will-change: opacity — it promotes the layer to a GPU texture
       which then gets bilinear-scaled on >1080p displays, softening the
       video. The opacity-only transition is cheap enough without it. */
}

/* ---------- Layer 1: full-bleed scrub video ---------- */

.hero__visual {
    position: absolute;
    inset: 0;
    z-index: 1;
}

.hero__frame {
    position: absolute;
    inset: 0;
    background: #0b1220;
    overflow: hidden;
    animation: heroFadeIn 0.9s 0.15s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Poster image — shown while the video loads or when video is suppressed
   (reduced-motion / reduced-data). Sits behind the video at z:0. */
.hero__fallback {
    position: absolute;
    inset: 0;
    display: block;
    z-index: 0;
    pointer-events: none;
}
.hero__fallback-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 0%;        /* anchor top — never crop the top of the frame */
    background: #0b1220;
}

.hero__video {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 0%;        /* anchor top — never crop the top of the frame */
    /* Hint browsers to use high-quality scaling on the video sample (vs. bilinear). */
    image-rendering: high-quality;
    image-rendering: -webkit-optimize-contrast;
}

/* Film grain — disabled (was softening the video). Element kept in markup
   so the noise pattern can be re-enabled later if desired. */
.hero__grain {
    display: none;
}

/* Dark vignette — lifts text contrast over the video */
.hero__vignette {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 50% 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.45) 100%),
        linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0) 30%);
    opacity: clamp(0, calc(1 - var(--hero-progress, 0) * 0.8), 1);
}

/* ---------- Layer 2: text overlay ---------- */

.hero__content {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 24px;
    text-align: center;
    gap: 22px;
    pointer-events: none;
    /* Scroll-driven fade — disappears at progress 0.667 (= 4 s of 6 s) */
    opacity: clamp(0, calc(1 - var(--hero-progress, 0) * 1.5), 1);
    transform: translateY(calc(var(--hero-progress, 0) * -30px));
    /* Stacking context for the pseudo-scrim below */
    isolation: isolate;
}

/* Soft frosted-glass scrim behind the text — blurs the video pixels directly
   under the headline/subhead/buttons so text stays legible on any frame.
   Wide ellipse covers the entire text block; gentle blur keeps it subtle. */
.hero__content::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgba(0, 0, 0, 0.10);
    backdrop-filter: blur(6px) saturate(115%);
    -webkit-backdrop-filter: blur(5px) saturate(115%);
    -webkit-mask-image: radial-gradient(ellipse 30% 40% at 50% 40%, #000 0%, #000 70%, transparent 100%);
    mask-image: radial-gradient(ellipse 30% 40% at 50% 40%, #000 0%, #000 70%, transparent 100%);
    pointer-events: none;
}

.hero__content > * { pointer-events: auto; }

/* ---------- Typography (on dark video) ---------- */

.hero__headline {
    margin: 0;
    max-width: 18ch;
    font-size: var(--fs-h1);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-heading);
    letter-spacing: var(--ls-heading);
    color: #ffffff;
    /* Multi-layer shadow: tight 1 px for crispness on light frames + 2 wider
       drops for separation on busy backgrounds. Fallback when backdrop blur
       isn't supported (older Firefox, etc.) so text stays readable anyway. */
    text-shadow:
        0 1px 2px rgba(0, 0, 0, 0.55),
        0 2px 14px rgba(0, 0, 0, 0.45),
        0 8px 36px rgba(0, 0, 0, 0.35);
    animation: heroFadeUp 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.hero__subhead {
    margin: 0;
    max-width: 520px;
    font-size: var(--fs-lead);
    font-weight: var(--fw-regular);
    line-height: var(--lh-body);
    color: var(--text-on-dark);
    text-shadow:
        0 1px 2px rgba(0, 0, 0, 0.55),
        0 2px 12px rgba(0, 0, 0, 0.40);
    animation: heroFadeUp 0.9s 0.08s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.hero__actions {
    display: inline-grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 12px;
    margin-top: 6px;
    animation: heroFadeUp 0.9s 0.16s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.hero__actions > .hero__cta {
    width: 100%;
}

.hero__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 48px;
    padding: 10px 24px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-body-sm);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-tight);
    line-height: 1.2;
    white-space: nowrap;
    border: 1px solid transparent;
    transition:
        background-color var(--dur-fast) var(--ease-out),
        border-color var(--dur-fast) var(--ease-out),
        transform var(--dur-fast) var(--ease-out),
        box-shadow var(--dur-med) var(--ease-out);
}

.hero__cta--primary {
    background: var(--brand-fill);
    color: #ffffff;
    border-color: var(--brand-fill);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.14) inset,
        0 10px 24px -10px rgba(4, 44, 113, 0.55);
}
.hero__cta--primary:hover {
    background: var(--brand-fill-600);
    border-color: var(--brand-fill-600);
    transform: translateY(-1px);
}

.hero__cta--secondary {
    /* Darker glass tint + stronger border so the button stays readable over
       any frame of the scrub video, including light/washed-out moments. */
    background: rgba(11, 18, 32, 0.40);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.55);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
    backdrop-filter: saturate(180%) blur(10px);
    -webkit-backdrop-filter: saturate(180%) blur(10px);
    box-shadow: 0 8px 18px -10px rgba(0, 0, 0, 0.45);
}
.hero__cta--secondary:hover {
    background: rgba(11, 18, 32, 0.55);
    border-color: rgba(255, 255, 255, 0.75);
    transform: translateY(-1px);
}
.hero__cta--secondary svg { opacity: 1; }

@keyframes heroFadeUp {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}
@keyframes heroFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (max-width: 767px) {
    /* Shorter overall scroll distance on small screens.
       Phases: 100vh scrub + 20vh crossfade + 60vh hold + 100vh scroll-out. */
    .hero-stage { height: 280vh; }

    /* Wider + heavier blur ellipse on mobile (viewport is narrow already). */
    .hero__content::before {
        backdrop-filter: blur(8px) saturate(115%);
        -webkit-backdrop-filter: blur(8px) saturate(115%);
        -webkit-mask-image: radial-gradient(ellipse 39.93% 33.88% at 50% 45%, #000 0%, #000 60%, transparent 100%);
        mask-image: radial-gradient(ellipse 39.93% 33.88% at 50% 45%, #000 0%, #000 60%, transparent 100%);
    }
}

@media (max-width: 520px) {
    .hero__actions { display: flex; width: 100%; flex-direction: column; align-items: stretch; }
    .hero__cta { width: 100%; }
}

[dir="rtl"] .hero__cta--secondary svg { transform: scaleX(-1); }

@media (prefers-reduced-motion: reduce) {
    .hero,
    .hero__content,
    .hero__headline,
    .hero__subhead,
    .hero__actions,
    .hero__frame { animation: none !important; opacity: 1 !important; transform: none !important; }
    /* Hide the video — poster image becomes the permanent background. */
    .hero__video { display: none; }
}

/* Respect data-saver — don't pull the 2 MB scrub video; fall back to poster. */
@media (prefers-reduced-data: reduce) {
    .hero__video { display: none; }
}
