/* =========================================================
   VILLORA
   Luxury Motion System

   File:
   assets/css/animations.css

   Purpose:
   - Scroll reveal
   - Mask reveal
   - Image reveal
   - Stagger system
   - Hero entrance
   - Dialog entrance
   - Elegant interactive motion
   - Parallax preparation
   - Reduced motion support
========================================================= */


/* =========================================================
   01. MOTION TOKENS
========================================================= */

:root {

    /* -----------------------------------------------------
       Reveal Distance
    ----------------------------------------------------- */

    --reveal-distance-sm: 18px;
    --reveal-distance-md: 32px;
    --reveal-distance-lg: 56px;


    /* -----------------------------------------------------
       Reveal Duration
    ----------------------------------------------------- */

    --reveal-duration-fast: 700ms;
    --reveal-duration: 1000ms;
    --reveal-duration-slow: 1300ms;
    --reveal-duration-image: 1500ms;


    /* -----------------------------------------------------
       Reveal Delay
    ----------------------------------------------------- */

    --reveal-delay: 0ms;

    --stagger-1: 80ms;
    --stagger-2: 160ms;
    --stagger-3: 240ms;
    --stagger-4: 320ms;
    --stagger-5: 400ms;
    --stagger-6: 480ms;


    /* -----------------------------------------------------
       Luxury Motion Curves
    ----------------------------------------------------- */

    --motion-ease-out:
        cubic-bezier(0.22, 1, 0.36, 1);

    --motion-ease-luxury:
        cubic-bezier(0.16, 1, 0.3, 1);

    --motion-ease-soft:
        cubic-bezier(0.25, 0.46, 0.45, 0.94);
}


/* =========================================================
   02. PROGRESSIVE ENHANCEMENT
========================================================= */

/*
   IMPORTANT

   Tanpa class .reveal-ready:
   semua content tetap visible.

   animations.js nanti akan menambahkan:

   document.documentElement.classList.add('reveal-ready');

   Setelah itu animation system aktif.
*/


/* =========================================================
   03. GENERIC REVEAL
========================================================= */

.reveal-ready [data-reveal] {
    --reveal-delay: 0ms;

    transition-delay: var(--reveal-delay);
}


/* =========================================================
   04. REVEAL UP
========================================================= */

.reveal-ready [data-reveal="up"] {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-md),
            0);

    transition:
        opacity var(--reveal-duration) var(--motion-ease-luxury) var(--reveal-delay),

        transform var(--reveal-duration) var(--motion-ease-luxury) var(--reveal-delay);
}

.reveal-ready [data-reveal="up"].is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   05. REVEAL FADE
========================================================= */

.reveal-ready [data-reveal="fade"] {
    opacity: 0;

    transition:
        opacity var(--reveal-duration-slow) var(--motion-ease-soft) var(--reveal-delay);
}

.reveal-ready [data-reveal="fade"].is-visible {
    opacity: 1;
}


/* =========================================================
   06. MASK REVEAL
========================================================= */

/*
   Digunakan untuk:
   - Section heading
   - Hero heading
   - Final CTA heading

   Memberikan efek tulisan keluar dari bawah
   tanpa animation yang terlalu flashy.
*/

.reveal-ready [data-reveal="mask"] {
    opacity: 0;

    clip-path:
        inset(0 0 100% 0);

    transform:
        translate3d(0,
            var(--reveal-distance-lg),
            0);

    transition:
        opacity 500ms ease var(--reveal-delay),

        clip-path var(--reveal-duration-slow) var(--motion-ease-luxury) var(--reveal-delay),

        transform var(--reveal-duration-slow) var(--motion-ease-luxury) var(--reveal-delay);
}

.reveal-ready [data-reveal="mask"].is-visible {
    opacity: 1;

    clip-path:
        inset(0 0 0 0);

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   07. IMAGE REVEAL
========================================================= */

/*
   Container diberi:
   data-reveal="image"

   Image di dalam container mendapatkan
   subtle scale ketika muncul.
*/

.reveal-ready [data-reveal="image"] {
    opacity: 0;

    clip-path:
        inset(8% 0 8% 0);

    transform:
        translate3d(0,
            var(--reveal-distance-md),
            0);

    transition:
        opacity 800ms var(--motion-ease-soft) var(--reveal-delay),

        clip-path var(--reveal-duration-image) var(--motion-ease-luxury) var(--reveal-delay),

        transform var(--reveal-duration-image) var(--motion-ease-luxury) var(--reveal-delay);
}

.reveal-ready [data-reveal="image"] img {
    transform: scale(1.08);

    transition:
        transform 1800ms var(--motion-ease-luxury);
}

.reveal-ready [data-reveal="image"].is-visible {
    opacity: 1;

    clip-path:
        inset(0 0 0 0);

    transform:
        translate3d(0,
            0,
            0);
}

.reveal-ready [data-reveal="image"].is-visible img {
    transform: scale(1);
}


/* =========================================================
   08. SCALE REVEAL
========================================================= */

.reveal-ready [data-reveal="scale"] {
    opacity: 0;

    transform:
        scale(0.965);

    transition:
        opacity var(--reveal-duration) var(--motion-ease-soft) var(--reveal-delay),

        transform var(--reveal-duration-slow) var(--motion-ease-luxury) var(--reveal-delay);
}

.reveal-ready [data-reveal="scale"].is-visible {
    opacity: 1;

    transform:
        scale(1);
}


/* =========================================================
   09. REVEAL LEFT / RIGHT
========================================================= */

.reveal-ready [data-reveal="left"] {
    opacity: 0;

    transform:
        translate3d(var(--reveal-distance-lg),
            0,
            0);

    transition:
        opacity var(--reveal-duration) var(--motion-ease-soft) var(--reveal-delay),

        transform var(--reveal-duration-slow) var(--motion-ease-luxury) var(--reveal-delay);
}

.reveal-ready [data-reveal="right"] {
    opacity: 0;

    transform:
        translate3d(calc(var(--reveal-distance-lg) * -1),
            0,
            0);

    transition:
        opacity var(--reveal-duration) var(--motion-ease-soft) var(--reveal-delay),

        transform var(--reveal-duration-slow) var(--motion-ease-luxury) var(--reveal-delay);
}

.reveal-ready [data-reveal="left"].is-visible,
.reveal-ready [data-reveal="right"].is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   10. STAGGER UTILITIES
========================================================= */

[data-reveal-delay="1"] {
    --reveal-delay: var(--stagger-1);
}

[data-reveal-delay="2"] {
    --reveal-delay: var(--stagger-2);
}

[data-reveal-delay="3"] {
    --reveal-delay: var(--stagger-3);
}

[data-reveal-delay="4"] {
    --reveal-delay: var(--stagger-4);
}

[data-reveal-delay="5"] {
    --reveal-delay: var(--stagger-5);
}

[data-reveal-delay="6"] {
    --reveal-delay: var(--stagger-6);
}


/* =========================================================
   11. HERO ENTRANCE
========================================================= */

/*
   JS nanti menambahkan:

   body.is-page-loaded

   Ini berbeda dengan scroll reveal.
   Hero entrance hanya terjadi sekali saat page load.
*/

.reveal-ready .hero__media {
    opacity: 0;

    transform:
        scale(1.045);

    transition:
        opacity 1400ms var(--motion-ease-soft),

        transform 2200ms var(--motion-ease-luxury);
}

.reveal-ready body.is-page-loaded .hero__media {
    opacity: 1;

    transform:
        scale(1);
}


/* ---------------------------------------------------------
   Hero Eyebrow
--------------------------------------------------------- */

.reveal-ready .hero__eyebrow {
    transition-delay: 250ms;
}


/* ---------------------------------------------------------
   Hero Heading
--------------------------------------------------------- */

.reveal-ready .hero__title {
    transition-delay: 380ms;
}


/* ---------------------------------------------------------
   Hero Description
--------------------------------------------------------- */

.reveal-ready .hero__description {
    transition-delay: 560ms;
}


/* ---------------------------------------------------------
   Hero Actions
--------------------------------------------------------- */

.reveal-ready .hero__actions {
    transition-delay: 690ms;
}


/* ---------------------------------------------------------
   Hero Categories
--------------------------------------------------------- */

.reveal-ready .hero__categories {
    transition-delay: 820ms;
}


/* ---------------------------------------------------------
   Hero Search
--------------------------------------------------------- */

.reveal-ready .hero-search {
    opacity: 0;

    transform:
        translateY(calc(50% + var(--reveal-distance-md)));

    transition:
        opacity 1000ms var(--motion-ease-soft) 850ms,

        transform 1200ms var(--motion-ease-luxury) 850ms;
}

.reveal-ready body.is-page-loaded .hero-search {
    opacity: 1;

    transform:
        translateY(50%);
}


/* =========================================================
   12. HERO IMAGE SLOW ZOOM
========================================================= */

@keyframes villoraHeroDrift {

    from {
        transform:
            scale(1.01);
    }

    to {
        transform:
            scale(1.055);
    }

}

.reveal-ready body.is-page-loaded .hero__image {
    animation:
        villoraHeroDrift 18s var(--motion-ease-soft) forwards;
}


/* =========================================================
   13. VILLA CARD REVEAL
========================================================= */

.reveal-ready .villa-card {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-lg),
            0);

    transition:
        opacity var(--reveal-duration) var(--motion-ease-soft),

        transform var(--reveal-duration-slow) var(--motion-ease-luxury);
}

.reveal-ready .villa-card.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* ---------------------------------------------------------
   Villa Image
--------------------------------------------------------- */

.reveal-ready .villa-card__media img {
    transform:
        scale(1.075);

    transition:
        transform 1600ms var(--motion-ease-luxury);
}

.reveal-ready .villa-card.is-visible .villa-card__media img {
    transform:
        scale(1);
}

.reveal-ready .villa-card.is-visible:hover .villa-card__media img {
    transform:
        scale(1.035);
}


/* =========================================================
   14. EXPERIENCE CARDS
========================================================= */

.reveal-ready .experience-card {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-md),
            0);

    transition:
        opacity 900ms var(--motion-ease-soft),

        transform 1100ms var(--motion-ease-luxury),

        background-color var(--duration-normal) var(--ease-default);
}

.reveal-ready .experience-card.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* ---------------------------------------------------------
   Automatic stagger
--------------------------------------------------------- */

.reveal-ready .experience-card:nth-child(1) {
    transition-delay: 0ms;
}

.reveal-ready .experience-card:nth-child(2) {
    transition-delay: 100ms;
}

.reveal-ready .experience-card:nth-child(3) {
    transition-delay: 200ms;
}

.reveal-ready .experience-card:nth-child(4) {
    transition-delay: 300ms;
}


/* =========================================================
   15. EXPERIENCE CARD HOVER
========================================================= */

.experience-card {
    transition:
        background-color var(--duration-normal) var(--ease-default);
}

.experience-card:hover {
    background:
        rgba(255,
            255,
            255,
            0.025);
}


/* =========================================================
   16. OCCASION REVEAL
========================================================= */

.reveal-ready .occasion-item {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-sm),
            0);

    transition:
        opacity 800ms var(--motion-ease-soft),

        transform 900ms var(--motion-ease-luxury),

        background-color var(--duration-normal) var(--ease-default),

        color var(--duration-normal) var(--ease-default),

        border-color var(--duration-normal) var(--ease-default);
}

.reveal-ready .occasion-item.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}

.reveal-ready .occasion-item.is-visible:hover {
    transform:
        translate3d(0,
            -3px,
            0);
}


/* ---------------------------------------------------------
   Occasion Stagger
--------------------------------------------------------- */

.reveal-ready .occasion-item:nth-child(1) {
    transition-delay: 0ms;
}

.reveal-ready .occasion-item:nth-child(2) {
    transition-delay: 70ms;
}

.reveal-ready .occasion-item:nth-child(3) {
    transition-delay: 140ms;
}

.reveal-ready .occasion-item:nth-child(4) {
    transition-delay: 210ms;
}

.reveal-ready .occasion-item:nth-child(5) {
    transition-delay: 280ms;
}

.reveal-ready .occasion-item:nth-child(6) {
    transition-delay: 350ms;
}

.reveal-ready .occasion-item:nth-child(7) {
    transition-delay: 420ms;
}


/* =========================================================
   17. GALLERY REVEAL
========================================================= */

.reveal-ready .gallery-item {
    opacity: 0;

    clip-path:
        inset(5% 0 5% 0);

    transform:
        translate3d(0,
            var(--reveal-distance-md),
            0);

    transition:
        opacity 900ms var(--motion-ease-soft),

        clip-path 1300ms var(--motion-ease-luxury),

        transform 1300ms var(--motion-ease-luxury);
}

.reveal-ready .gallery-item.is-visible {
    opacity: 1;

    clip-path:
        inset(0 0 0 0);

    transform:
        translate3d(0,
            0,
            0);
}


/* ---------------------------------------------------------
   Gallery stagger
--------------------------------------------------------- */

.reveal-ready .gallery-item:nth-child(1) {
    transition-delay: 0ms;
}

.reveal-ready .gallery-item:nth-child(2) {
    transition-delay: 100ms;
}

.reveal-ready .gallery-item:nth-child(3) {
    transition-delay: 170ms;
}

.reveal-ready .gallery-item:nth-child(4) {
    transition-delay: 240ms;
}

.reveal-ready .gallery-item:nth-child(5) {
    transition-delay: 310ms;
}


/* =========================================================
   18. FAQ REVEAL
========================================================= */

.reveal-ready .faq-item {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-sm),
            0);

    transition:
        opacity 800ms var(--motion-ease-soft),

        transform 900ms var(--motion-ease-luxury);
}

.reveal-ready .faq-item.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   19. FAQ CONTENT ANIMATION
========================================================= */

.faq-item__content {
    overflow: hidden;
}

.faq-item__content p {
    transition:
        opacity var(--duration-normal) var(--motion-ease-soft),

        transform var(--duration-normal) var(--motion-ease-luxury);
}

.faq-item:not(.is-open) .faq-item__content p {
    opacity: 0;

    transform:
        translate3d(0,
            -8px,
            0);
}

.faq-item.is-open .faq-item__content p {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   20. BOOKING PANEL REVEAL
========================================================= */

.reveal-ready .booking-panel {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-lg),
            0);

    transition:
        opacity 1000ms var(--motion-ease-soft),

        transform 1300ms var(--motion-ease-luxury);
}

.reveal-ready .booking-panel.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   21. LOCATION CARD REVEAL
========================================================= */

.reveal-ready .location-card {
    opacity: 0;

    transform:
        translate3d(0,
            var(--reveal-distance-md),
            0);

    transition:
        opacity 900ms var(--motion-ease-soft),

        transform 1100ms var(--motion-ease-luxury);
}

.reveal-ready .location-card.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}

.reveal-ready .location-card:nth-child(even) {
    transition-delay: 90ms;
}


/* =========================================================
   22. TESTIMONIAL MOTION
========================================================= */

.testimonial-card {
    animation:
        testimonialEnter 800ms var(--motion-ease-luxury) both;
}

@keyframes testimonialEnter {

    from {
        opacity: 0;

        transform:
            translate3d(24px,
                0,
                0);
    }

    to {
        opacity: 1;

        transform:
            translate3d(0,
                0,
                0);
    }

}


/* =========================================================
   23. DIALOG ENTRANCE
========================================================= */

dialog[open] {
    animation:
        dialogFadeIn 350ms var(--motion-ease-soft) both;
}

dialog[open]::backdrop {
    animation:
        dialogBackdropIn 350ms ease both;
}


/* ---------------------------------------------------------
   Dialog content
--------------------------------------------------------- */

dialog[open]>* {
    animation:
        dialogContentIn 650ms var(--motion-ease-luxury) both;
}


@keyframes dialogFadeIn {

    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }

}


@keyframes dialogBackdropIn {

    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }

}


@keyframes dialogContentIn {

    from {
        opacity: 0;

        transform:
            translate3d(0,
                22px,
                0) scale(0.985);
    }

    to {
        opacity: 1;

        transform:
            translate3d(0,
                0,
                0) scale(1);
    }

}


/* =========================================================
   24. SUCCESS ORDER ID
========================================================= */

.booking-success__order strong {
    animation:
        orderIdReveal 700ms var(--motion-ease-luxury) 300ms both;
}

@keyframes orderIdReveal {

    from {
        opacity: 0;

        letter-spacing: 0.18em;

        transform:
            translate3d(0,
                8px,
                0);
    }

    to {
        opacity: 1;

        letter-spacing: 0.04em;

        transform:
            translate3d(0,
                0,
                0);
    }

}


/* =========================================================
   25. PARALLAX PREPARATION
========================================================= */

[data-parallax] {
    will-change: transform;

    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;

    transform:
        translate3d(0,
            0,
            0);
}

[data-parallax] img {
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}


/* =========================================================
   26. INTERACTIVE IMAGE MOTION
========================================================= */

.villa-card__media,
.gallery-item,
.weddings-section__image-wrap {
    isolation: isolate;
}


/* =========================================================
   27. LUXURY LINK MOTION
========================================================= */

.site-footer__column a,
.site-footer__bottom a {
    position: relative;
}

.site-footer__column a::after {
    content: "";

    position: absolute;

    right: 0;
    bottom: -4px;
    left: 0;

    height: 1px;

    background: currentColor;

    transform:
        scaleX(0);

    transform-origin:
        right center;

    transition:
        transform var(--duration-normal) var(--motion-ease-luxury);
}

.site-footer__column a:hover::after {
    transform:
        scaleX(1);

    transform-origin:
        left center;
}


/* =========================================================
   28. HEADER LOGO MOTION
========================================================= */

.site-header__logo {
    transition:
        opacity var(--duration-normal) var(--motion-ease-soft),

        transform var(--duration-normal) var(--motion-ease-luxury);
}

.site-header__brand:hover .site-header__logo {
    opacity: 0.9;

    transform:
        scale(0.985);
}


/* =========================================================
   29. BUTTON PRESS FEEDBACK
========================================================= */

.button {
    transform:
        translate3d(0,
            0,
            0);
}

.button:active {
    transform:
        translate3d(0,
            1px,
            0) scale(0.99);
}


/* =========================================================
   30. MOBILE CTA ENTRANCE
========================================================= */

.mobile-booking-cta {
    transition:
        opacity 500ms var(--motion-ease-soft),

        transform 700ms var(--motion-ease-luxury);
}

.mobile-booking-cta.is-entering {
    opacity: 0;

    transform:
        translate3d(0,
            100%,
            0);
}

.mobile-booking-cta.is-visible {
    opacity: 1;

    transform:
        translate3d(0,
            0,
            0);
}


/* =========================================================
   31. IMAGE LOADING TRANSITION
========================================================= */

img[data-fallback-query] {
    transition:
        opacity 600ms var(--motion-ease-soft),

        filter 800ms var(--motion-ease-soft);
}

img[data-fallback-query].is-loading {
    opacity: 0.5;

    filter:
        blur(8px);
}

img[data-fallback-query].is-loaded {
    opacity: 1;

    filter:
        blur(0);
}


/* =========================================================
   32. DATA CONTENT ENTRANCE
========================================================= */

[data-villa-list],
[data-location-list],
[data-faq-list],
[data-testimonial-slider] {
    transition:
        opacity 450ms var(--motion-ease-soft);
}

[data-villa-list].is-loading,
[data-location-list].is-loading,
[data-faq-list].is-loading,
[data-testimonial-slider].is-loading {
    opacity: 0.4;
}

[data-villa-list].is-ready,
[data-location-list].is-ready,
[data-faq-list].is-ready,
[data-testimonial-slider].is-ready {
    opacity: 1;
}


/* =========================================================
   33. REDUCED MOTION
========================================================= */

@media (prefers-reduced-motion: reduce) {

    [data-reveal],
    .villa-card,
    .experience-card,
    .occasion-item,
    .gallery-item,
    .faq-item,
    .booking-panel,
    .location-card {
        opacity: 1 !important;

        clip-path: none !important;

        transform: none !important;
    }


    .hero__media,
    .hero__image,
    .hero-search {
        opacity: 1 !important;

        transform: none !important;

        animation: none !important;
    }


    [data-reveal="image"] img,
    .villa-card__media img {
        transform: none !important;
    }


    [data-parallax] {
        transform: none !important;

        will-change: auto;
    }


    dialog[open],
    dialog[open]::backdrop,
    dialog[open]>*,
    .testimonial-card,
    .booking-success__order strong {
        animation: none !important;
    }


    .mobile-booking-cta {
        transform: none !important;
    }

}