/* ==========================================================================
   Motion layer — the things that make the site feel like it's on the road.
   Paired with js/motion.js, which sets the classes and custom properties used
   here. Everything animates transform, opacity or clip-path only, so it stays
   on the compositor and never shifts layout. All of it switches off under
   prefers-reduced-motion at the bottom of this file.
   ========================================================================== */

/* ---------- Heroes: slow push-in on arrival, parallax on scroll ----------
   Individual `scale` and `translate` properties rather than `transform`, so the
   intro zoom and the scroll drift can run on the same image without fighting.
   The home cut-out uses the same class as the photo beneath it, so both layers
   move identically and stay in register. */
.hero .hero__photo,
.destination-hero .destination-hero__photo {
    animation: mbsKenBurns 2.8s cubic-bezier(0.16, 1, 0.3, 1) both;
    translate: 0 calc(var(--mbs-parallax, 0) * 1px);
    will-change: translate;
}

@keyframes mbsKenBurns {
    from { scale: 1.1; }
    to { scale: 1.02; }
}

/* A touch of scale kept at rest, so parallax drift never opens a gap at the edge. */
.destination-hero .destination-hero__photo {
    scale: 1.02;
}

.hero .hero__photo {
    scale: 1.02;
}

/* ---------- Desert dust over the home hero ---------- */
/* Explicit width and height, not just inset: a canvas is a replaced element,
   so with auto sizing it takes its size from its own pixel buffer — which the
   script sets from its measured size, and the two would grow each other forever. */
.mbs-dust {
    position: absolute;
    top: 0;
    left: 24%;
    width: 76%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 1.6s ease 0.6s;
}

    .mbs-dust.is-on {
        opacity: 1;
    }

/* ---------- Reading progress: a thin road along the top ---------- */
.mbs-road {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 1000;
    pointer-events: none;
    transform-origin: left;
    transform: scaleX(var(--mbs-progress, 0));
    background: linear-gradient(90deg, var(--color-terracotta), var(--color-gold));
    box-shadow: 0 0 10px rgba(191, 151, 101, 0.55);
    opacity: 0;
    transition: opacity 0.3s ease;
}

    .mbs-road.is-on {
        opacity: 1;
    }

/* ---------- Route cards: photo curtain, hover push-in, light on the card ---- */
.route-card__photo-wrap {
    overflow: hidden;
}

.route-card.reveal .route-card__photo {
    clip-path: inset(0 0 100% 0);
    scale: 1.14;
    transition:
        clip-path 1s cubic-bezier(0.77, 0, 0.18, 1) 0.1s,
        scale 1.4s cubic-bezier(0.16, 1, 0.3, 1) 0.1s;
}

.route-card.reveal.is-visible .route-card__photo {
    clip-path: inset(0 0 0 0);
    scale: 1;
}

.route-card.reveal.is-visible:hover .route-card__photo {
    scale: 1.06;
    transition: scale 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

/* A soft light that follows the pointer across any card. */
.card {
    position: relative;
}

    .card::after {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: inherit;
        pointer-events: none;
        background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%),
            rgba(255, 255, 255, 0.22), transparent 45%);
        opacity: 0;
        transition: opacity 0.35s ease;
        z-index: 2;
    }

    .card:hover::after {
        opacity: 1;
    }

/* ---------- Buttons: a sweep of light on hover ---------- */
.btn--primary,
.btn--whatsapp,
.btn--gold {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

    .btn--primary::before,
    .btn--whatsapp::before,
    .btn--gold::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: -60%;
        width: 45%;
        z-index: -1;
        pointer-events: none;
        background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.35), transparent);
        transform: skewX(-18deg) translateX(0);
        transition: transform 0s;
    }

    .btn--primary:hover::before,
    .btn--whatsapp:hover::before,
    .btn--gold:hover::before {
        transform: skewX(-18deg) translateX(420%);
        transition: transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
    }

/* ---------- Route stops strip: the road draws itself ---------- */
.route-map::after {
    content: "";
    position: absolute;
    top: 21px;
    left: 21px;
    right: 21px;
    height: 2px;
    z-index: 0;
    background: repeating-linear-gradient(90deg,
        var(--color-teal) 0 10px, transparent 10px 16px);
    transform-origin: left;
    transform: scaleX(0);
    transition: transform 1.6s cubic-bezier(0.65, 0, 0.35, 1) 0.2s;
}

.route-map.is-drawn::after {
    transform: scaleX(1);
}

.route-map .route-map__circle {
    scale: 0.3;
    transition: scale 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
    transition-delay: calc(0.25s + var(--i, 0) * 0.22s);
}

.route-map.is-drawn .route-map__circle {
    scale: 1;
}

/* ---------- Day by day: a road that fills as you read ---------- */
@media (min-width: 700px) {
    .day-list {
        position: relative;
    }

        .day-list::before,
        .day-list::after {
            content: "";
            position: absolute;
            top: 8px;
            bottom: 8px;
            left: -22px;
            width: 2px;
            border-radius: 2px;
        }

        .day-list::before {
            background: rgba(23, 20, 18, 0.1);
        }

        .day-list::after {
            background: linear-gradient(180deg, var(--color-gold), var(--color-terracotta));
            transform-origin: top;
            transform: scaleY(var(--mbs-fill, 0));
        }

    /* The glowing marker riding the end of the filled line — "you are here". */
    .mbs-marker {
        position: absolute;
        left: -27px;
        top: 8px;
        width: 12px;
        height: 12px;
        border-radius: 50%;
        background: var(--color-terracotta);
        box-shadow: 0 0 0 4px rgba(191, 117, 90, 0.18), 0 0 14px rgba(191, 117, 90, 0.6);
        transform: translateY(calc(var(--mbs-fill-px, 0) * 1px));
        pointer-events: none;
        z-index: 1;
    }
}

@media (max-width: 699.98px) {
    .mbs-marker {
        display: none;
    }
}

/* ---------- Page arrival on in-app navigation ----------
   Only after a navigation (motion.js sets the class briefly), never on the
   first load, so the initial paint is never held back. */
html.mbs-nav main > * {
    animation: mbsPageIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
}

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

/* ==========================================================================
   Second layer. Anything that starts hidden or faded is gated on .mbs-motion,
   which motion.js puts on <html> only once it's running — so if the script
   never loads, nothing is left stuck half-developed or clipped.
   ========================================================================== */

/* ---------- Photos develop as they come into view ----------
   Faded, warm and slightly soft, then into full colour: a print coming up in
   the tray. Heroes and route cards are left out — the first is the page's
   main image and shouldn't wait, the second has its own curtain. */
.mbs-motion :is(.route-gallery__photo, .day-item__photo, .journal-tile__photo, .journal-post__photo,
    .journal-strip__photo, .filmstrip__photo, .postcard__photo, .region-card__photo,
    .meet-syphax__photo, .the-van__photo, .about-hero__photo, .gallery-tile img) {
    filter: grayscale(0.85) sepia(0.35) brightness(1.12) contrast(0.85) blur(3px);
    opacity: 0.55;
    transition: filter 1.6s cubic-bezier(0.16, 1, 0.3, 1), opacity 1.2s ease;
}

.mbs-motion :is(.route-gallery__photo, .day-item__photo, .journal-tile__photo, .journal-post__photo,
    .journal-strip__photo, .filmstrip__photo, .postcard__photo, .region-card__photo,
    .meet-syphax__photo, .the-van__photo, .about-hero__photo, .gallery-tile img).is-developed {
    filter: none;
    opacity: 1;
}

/* ---------- Section headings wipe up from behind a mask ---------- */
.mbs-motion .section-heading.reveal :is(h1, h2) {
    clip-path: inset(0 0 100% 0);
    translate: 0 0.35em;
    transition:
        clip-path 0.9s cubic-bezier(0.77, 0, 0.18, 1) 0.12s,
        translate 1s cubic-bezier(0.16, 1, 0.3, 1) 0.12s;
}

/* Negative insets so descenders and accents aren't shaved off once it's open. */
.mbs-motion .section-heading.reveal.is-visible :is(h1, h2) {
    clip-path: inset(-20% -5% -30% -5%);
    translate: 0 0;
}

/* ---------- Route cards lean toward the pointer ---------- */
@media (hover: hover) and (pointer: fine) {
    .mbs-motion .card.route-card:hover {
        transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-6px);
        transition: transform 0.18s ease-out, box-shadow 0.25s ease;
    }
}

/* ---------- Magnetic buttons ----------
   motion.js sets --mag-x/--mag-y as the pointer comes near. The separate
   `translate` property leaves each button's own hover transform untouched. */
.mbs-magnet {
    translate: var(--mag-x, 0px) var(--mag-y, 0px);
    transition: translate 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- Dunes drifting above the footer ---------- */
.mbs-dunes {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 72px;
    overflow: hidden;
    pointer-events: none;
}

.mbs-dunes__layer {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 200%;
    height: 100%;
    animation: mbsDunes linear infinite;
}

.mbs-dunes__layer--back {
    fill: var(--color-gold);
    opacity: 0.22;
    animation-duration: 140s;
}

.mbs-dunes__layer--mid {
    fill: var(--color-terracotta);
    opacity: 0.26;
    animation-duration: 95s;
    animation-direction: reverse;
}

.mbs-dunes__layer--front {
    fill: var(--color-teal);
    opacity: 0.32;
    animation-duration: 70s;
}

@keyframes mbsDunes {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

/* ---------- FAQ answers glide open ----------
   Uses ::details-content and interpolate-size where the browser supports
   them (current Chrome and Edge); elsewhere the answer simply opens as before. */
.faq-item,
.page-faqs__item {
    interpolate-size: allow-keywords;
}

    .faq-item::details-content,
    .page-faqs__item::details-content {
        height: 0;
        overflow: clip;
        transition: height 0.45s cubic-bezier(0.16, 1, 0.3, 1), content-visibility 0.45s allow-discrete;
    }

    .faq-item[open]::details-content,
    .page-faqs__item[open]::details-content {
        height: auto;
    }

    .faq-item[open] > p,
    .page-faqs__item[open] > p {
        animation: mbsAnswerIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
    }

@keyframes mbsAnswerIn {
    from { opacity: 0; translate: 0 -6px; }
    to { opacity: 1; translate: 0 0; }
}

/* ---------- Place chips pop in one after another ---------- */
.mbs-motion .route-places .chip-row .chip {
    opacity: 0;
    scale: 0.7;
    transition: opacity 0.4s ease, scale 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
    transition-delay: calc(0.15s + var(--ci, 0) * 0.06s);
}

.mbs-motion .route-places .chip-row.is-visible .chip {
    opacity: 1;
    scale: 1;
}
/* ---------- A page that ends on the sunset ----------
   The homepage's last section is a desert evening with its own ridges. The
   footer's gap and drifting dunes above it made two landscapes with a strip of
   empty page between them; here the footer closes up instead, so the ridges run
   straight into the footer's brand line like a horizon. */
main:has(> .route-cta-banner:last-child) + .site-footer {
    margin-top: 0;
}

    main:has(> .route-cta-banner:last-child) + .site-footer .mbs-dunes {
        display: none;
    }

    /* No seam: the footer's own gradient starts in the front ridge's colour
       (SiteFooter.razor.css), and the brand line is left out. */

    main:has(> .route-cta-banner:last-child) + .site-footer .site-footer__rule {
        display: none;
    }
/* ---------- Off for anyone who's asked for less motion ---------- */
@media (prefers-reduced-motion: reduce) {
    .hero .hero__photo,
    .destination-hero .destination-hero__photo {
        animation: none;
        translate: none;
    }

    .mbs-dust,
    .mbs-road,
    .mbs-marker,
    .day-list::after {
        display: none;
    }

    .route-card.reveal .route-card__photo,
    .route-card.reveal.is-visible:hover .route-card__photo {
        clip-path: none;
        scale: 1;
        transition: none;
    }

    .card::after,
    .btn--primary::before,
    .btn--whatsapp::before,
    .btn--gold::before {
        display: none;
    }

    .route-map::after {
        transform: scaleX(1);
        transition: none;
    }

    .route-map .route-map__circle {
        scale: 1;
        transition: none;
    }

    html.mbs-nav main > * {
        animation: none;
    }

    .mbs-dunes__layer,
    .faq-item[open] > p,
    .page-faqs__item[open] > p {
        animation: none;
    }

    .faq-item::details-content,
    .page-faqs__item::details-content {
        transition: none;
    }

    .mbs-magnet {
        translate: none;
    }
}
