/* ==========================================================================
   360VR EFFECTS - THU VIEN HIEU UNG CHO PANO2VR 8

   Quy uoc:
   - fx-[hieu-ung]: class hieu ung.
   - kf-[hieu-ung]: keyframe noi bo.
   - shape-[hinh-dang]: class tao hinh tinh.
   - --fx-*: bien tuy chinh dung tren tung phan tu.

   Luu y:
   - effects.js luu transform dinh vi vao --fx-base-transform truoc khi chay.
   - Khong gan hai hieu ung cung dieu khien transform tren mot phan tu.
   - Cac hieu ung dung ::before hoac ::after khong nen gan chung tren mot phan tu.
   ========================================================================== */

/* Ho tro khi class duoc gan truc tiep vao img hoac svg. */

img[class*="fx-"],
svg[class*="fx-"] {
    backface-visibility: hidden;
    transform-box: fill-box;
}


/* ==========================================================================
   1. CHUYEN DONG
   ========================================================================== */

/* 1.1. Nhay nhe */

.fx-bounce {
    animation: kf-bounce var(--fx-speed, 1.3s) ease-in-out var(--fx-repeat, infinite);
    transform-origin: center bottom;
    will-change: transform;
}

@keyframes kf-bounce {
    0%,
    100% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0);
    }

    20% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(1px);
    }

    50% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(var(--fx-y, -6px));
    }

    75% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0);
    }

    85% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(-2px);
    }
}


/* 1.2. Phong to theo nhip */

.fx-pulse {
    animation: kf-pulse var(--fx-speed, 1.8s) ease-in-out var(--fx-repeat, infinite);
    transform-origin: center center;
    will-change: transform, filter;
}

@keyframes kf-pulse {
    0%,
    100% {
        filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.18));
        transform: var(--fx-base-transform, translate(0, 0)) scale(1);
    }

    50% {
        filter:
            drop-shadow(0 2px 3px rgba(0, 0, 0, 0.15))
            drop-shadow(0 0 10px var(--fx-color, rgba(94, 234, 212, 0.72)));
        transform: var(--fx-base-transform, translate(0, 0)) scale(var(--fx-scale, 1.12));
    }
}


/* 1.3. Troi nhe */

.fx-float {
    animation: kf-float var(--fx-speed, 3s) ease-in-out var(--fx-repeat, infinite);
    transform-origin: center center;
    will-change: transform;
}

@keyframes kf-float {
    0%,
    100% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0) rotate(-1deg);
    }

    50% {
        transform: var(--fx-base-transform, translate(0, 0)) translateY(var(--fx-y, -8px)) rotate(1deg);
    }
}


/* 1.4. Chop tat */

.fx-blink {
    animation: kf-blink var(--fx-speed, 1.2s) steps(1, end) var(--fx-repeat, infinite);
    will-change: opacity;
}

@keyframes kf-blink {
    0%,
    49% {
        opacity: 1;
    }

    50%,
    100% {
        opacity: var(--fx-min-opacity, 0);
    }
}


/* 1.5. Xoay vong lien tuc */

.fx-spin {
    animation: kf-spin var(--fx-speed, 2.4s) linear var(--fx-repeat, infinite);
    transform-origin: center center;
    will-change: transform;
}

@keyframes kf-spin {
    from {
        transform: var(--fx-base-transform, translate(0, 0)) rotate(0deg);
    }

    to {
        transform: var(--fx-base-transform, translate(0, 0)) rotate(var(--fx-spin-angle, 360deg));
    }
}


/* 1.6. Xuat hien bat len */

.fx-pop {
    animation: kf-pop var(--fx-speed, 500ms) cubic-bezier(0.2, 0.85, 0.3, 1.25) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    transform-origin: center center;
    will-change: transform, opacity;
}

@keyframes kf-pop {
    0% {
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) scale(0.72);
    }

    70% {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) scale(1.08);
    }

    100% {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) scale(1);
    }
}


/* 1.7. Xuat hien tu duoi len */

.fx-reveal {
    animation: kf-reveal var(--fx-speed, 650ms) cubic-bezier(0.22, 1, 0.36, 1) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    will-change: transform, opacity, filter;
}

@keyframes kf-reveal {
    0% {
        filter: blur(6px);
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) translateY(var(--fx-y, 18px));
    }

    100% {
        filter: blur(0);
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0);
    }
}


/* ==========================================================================
   2. XUAT HIEN
   ========================================================================== */

/* 2.1. Xuat hien dan bang do trong suot */

.fx-fade-in {
    animation: kf-fade-in var(--fx-speed, 700ms) ease-out var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    will-change: opacity;
}

@keyframes kf-fade-in {
    from {
        opacity: var(--fx-min-opacity, 0);
    }

    to {
        opacity: 1;
    }
}


/* 2.2. Mo dan tu duoi len */

.fx-fade-up {
    animation: kf-fade-up var(--fx-speed, 600ms) cubic-bezier(0.22, 1, 0.36, 1) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    transform-origin: center center;
    will-change: transform, opacity;
}

@keyframes kf-fade-up {
    from {
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) translateY(var(--fx-y, 18px));
    }

    to {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0);
    }
}


/* 2.3. Truot vao tu ben phai */

.fx-slide-left {
    animation: kf-slide-left var(--fx-speed, 650ms) cubic-bezier(0.22, 1, 0.36, 1) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    transform-origin: center center;
    will-change: transform, opacity;
}

@keyframes kf-slide-left {
    from {
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) translateX(var(--fx-x, 30px));
    }

    to {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) translateX(0);
    }
}


/* 2.4. Phong to khi xuat hien */

.fx-zoom-in {
    animation: kf-zoom-in var(--fx-speed, 520ms) cubic-bezier(0.2, 0.85, 0.3, 1.15) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    transform-origin: center center;
    will-change: transform, opacity;
}

@keyframes kf-zoom-in {
    from {
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) scale(var(--fx-from-scale, 0.72));
    }

    to {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) scale(1);
    }
}


/* 2.5. Xoay nhe khi xuat hien */

.fx-rotate-in {
    animation: kf-rotate-in var(--fx-speed, 580ms) cubic-bezier(0.2, 0.85, 0.3, 1.15) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    transform-origin: center center;
    will-change: transform, opacity;
}

@keyframes kf-rotate-in {
    from {
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) rotate(var(--fx-angle, -12deg)) scale(0.88);
    }

    to {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) rotate(0) scale(1);
    }
}


/* 2.6. Ro net khi xuat hien */

.fx-blur-in {
    animation: kf-blur-in var(--fx-speed, 650ms) ease-out var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    will-change: filter, opacity;
}

@keyframes kf-blur-in {
    from {
        filter: blur(var(--fx-blur, 10px));
        opacity: 0;
    }

    to {
        filter: blur(0);
        opacity: 1;
    }
}


/* 2.7. Lat vao tu canh tren */

.fx-swing-in {
    animation: kf-swing-in var(--fx-speed, 700ms) cubic-bezier(0.22, 1, 0.36, 1) var(--fx-delay, 0s) var(--fx-repeat, 1) both;
    backface-visibility: hidden;
    transform-origin: center top;
    will-change: transform, opacity;
}

@keyframes kf-swing-in {
    from {
        opacity: 0;
        transform: var(--fx-base-transform, translate(0, 0)) perspective(700px) rotateX(var(--fx-angle, -70deg));
    }

    to {
        opacity: 1;
        transform: var(--fx-base-transform, translate(0, 0)) perspective(700px) rotateX(0);
    }
}


/* ==========================================================================
   3. TUONG TAC
   ========================================================================== */

/* 3.1. Phong to khi tuong tac */

.fx-grow {
    transform-origin: center center;
    will-change: transform;
}

.fx-grow:hover,
.fx-grow:focus-visible,
.fx-grow:active {
    animation: kf-grow var(--fx-speed, 240ms) ease-out both;
}

@keyframes kf-grow {
    from {
        transform: var(--fx-base-transform, translate(0, 0)) scale(1);
    }

    to {
        transform: var(--fx-base-transform, translate(0, 0)) scale(var(--fx-scale, 1.08));
    }
}


/* 3.2. Nang len khi tuong tac */

.fx-lift {
    transform-origin: center center;
    will-change: transform, filter;
}

.fx-lift:hover,
.fx-lift:focus-visible,
.fx-lift:active {
    animation: kf-lift var(--fx-speed, 260ms) ease-out both;
}

@keyframes kf-lift {
    from {
        filter: drop-shadow(0 0 0 rgba(0, 0, 0, 0));
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0);
    }

    to {
        filter: drop-shadow(0 8px 10px rgba(0, 0, 0, 0.24));
        transform: var(--fx-base-transform, translate(0, 0)) translateY(var(--fx-y, -5px));
    }
}


/* 3.3. Thu nho khi tuong tac */

.fx-shrink {
    transform-origin: center center;
    will-change: transform;
}

.fx-shrink:hover,
.fx-shrink:focus-visible,
.fx-shrink:active {
    animation: kf-shrink var(--fx-speed, 220ms) ease-out both;
}

@keyframes kf-shrink {
    from {
        transform: var(--fx-base-transform, translate(0, 0)) scale(1);
    }

    to {
        transform: var(--fx-base-transform, translate(0, 0)) scale(var(--fx-scale, 0.94));
    }
}


/* 3.4. Lac nhe khi tuong tac */

.fx-wobble {
    transform-origin: center center;
    will-change: transform;
}

.fx-wobble:hover,
.fx-wobble:focus-visible,
.fx-wobble:active {
    animation: kf-wobble var(--fx-speed, 560ms) ease-in-out both;
}

@keyframes kf-wobble {
    0%,
    100% {
        transform: var(--fx-base-transform, translate(0, 0)) translateX(0) rotate(0);
    }

    25% {
        transform: var(--fx-base-transform, translate(0, 0)) translateX(-4px) rotate(-3deg);
    }

    50% {
        transform: var(--fx-base-transform, translate(0, 0)) translateX(3px) rotate(2deg);
    }

    75% {
        transform: var(--fx-base-transform, translate(0, 0)) translateX(-2px) rotate(-1deg);
    }
}


/* 3.5. Tang do sang khi tuong tac */

.fx-bright {
    transition: filter var(--fx-speed, 220ms) ease-out;
    will-change: filter;
}

.fx-bright:hover,
.fx-bright:focus-visible,
.fx-bright:active {
    filter: brightness(var(--fx-bright, 1.15)) saturate(var(--fx-saturate, 1.12));
}


/* 3.6. Nhan xuong khi bam */

.fx-press {
    transform-origin: center center;
    will-change: transform, filter;
}

.fx-press:active {
    animation: kf-press var(--fx-speed, 120ms) ease-out both;
}

@keyframes kf-press {
    from {
        filter: brightness(1);
        transform: var(--fx-base-transform, translate(0, 0)) translateY(0) scale(1);
    }

    to {
        filter: brightness(0.94);
        transform: var(--fx-base-transform, translate(0, 0)) translateY(2px) scale(var(--fx-scale, 0.97));
    }
}


/* ==========================================================================
   4. ANH SANG
   ========================================================================== */

/* 4.1. Phat sang theo nhip */

.fx-glow {
    animation: kf-glow var(--fx-speed, 2s) ease-in-out var(--fx-repeat, infinite);
    will-change: box-shadow, filter;
}

@keyframes kf-glow {
    0%,
    100% {
        box-shadow: 0 0 0 rgba(0, 0, 0, 0);
        filter: brightness(1);
    }

    50% {
        box-shadow:
            0 0 12px var(--fx-color, rgba(94, 234, 212, 0.55)),
            0 0 28px var(--fx-color, rgba(94, 234, 212, 0.35));
        filter: brightness(1.08);
    }
}


/* 4.2. Vet sang quet ngang */

.fx-shine {
    /* Preserve the inline absolute positioning generated by Pano2VR. */
    position: relative;
    overflow: hidden !important;
    isolation: isolate;
}

.fx-shine::after {
    content: "";
    position: absolute;
    top: -35%;
    bottom: -35%;
    left: -70%;
    z-index: 2;
    width: 34%;
    background: linear-gradient(
        90deg,
        transparent,
        var(--fx-color, rgba(255, 255, 255, 0.7)),
        transparent
    );
    pointer-events: none;
    transform: skewX(-18deg);
    animation: kf-shine var(--fx-speed, 2.8s) ease-in-out var(--fx-repeat, infinite);
}

@keyframes kf-shine {
    0%,
    25% {
        left: -70%;
    }

    70%,
    100% {
        left: 140%;
    }
}


/* ==========================================================================
   5. LAN TOA
   ========================================================================== */

/* 5.1. Vong lan toa quanh phan tu */

.fx-ripple {
    position: relative;
    overflow: visible !important;
}

.fx-ripple::before,
.fx-ripple::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100%;
    height: 100%;
    border-radius: var(--fx-radius, 999px);
    box-sizing: border-box;
    box-shadow:
        0 0 0 var(--fx-ring-width, 2px) var(--fx-color, rgba(255, 255, 255, 0.68)),
        0 0 var(--fx-glow-size, 6px) var(--fx-glow-color, rgba(255, 255, 255, 0.28));
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, -50%) scale(0.98);
    transform-origin: center center;
    animation: kf-ripple var(--fx-speed, 3.6s) linear var(--fx-repeat, infinite);
    will-change: transform, opacity;
}

.fx-ripple::after {
    animation-delay: var(--fx-delay, 1.8s);
}

@keyframes kf-ripple {
    0% {
        opacity: 0;
        transform: translate(-50%, -50%) scale(0.98);
    }

    8% {
        opacity: 0.75;
    }

    25% {
        opacity: 0.58;
        transform: translate(-50%, -50%) scale(1.08);
    }

    45% {
        opacity: 0.4;
        transform: translate(-50%, -50%) scale(1.18);
    }

    65% {
        opacity: 0.24;
        transform: translate(-50%, -50%) scale(1.28);
    }

    82% {
        opacity: 0.1;
        transform: translate(-50%, -50%) scale(1.36);
    }

    100% {
        opacity: 0;
        transform: translate(-50%, -50%) scale(var(--fx-scale, 1.42));
    }
}


/* 5.2. Cham lan toa, neo vao chinh giua canh duoi */

.fx-ripple-dot {
    /* Preserve Pano2VR positioning while keeping both rings in this layer. */
    position: relative;
    width: 4px !important;
    height: 4px !important;
    overflow: visible !important;
    background: var(--fx-center-color, #ff4d6d) !important;
    border-radius: 50% !important;
    isolation: isolate;
}

.fx-ripple-dot::before,
.fx-ripple-dot::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 50%;
    z-index: -1;
    width: 10px;
    height: 10px;
    border: 2px solid var(--fx-color, rgba(255, 255, 255, 0.9));
    border-radius: 50%;
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, 50%) scale(0.35);
    transform-origin: center center;
    animation: kf-ripple-dot var(--fx-speed, 3s) ease-out var(--fx-repeat, infinite);
}

.fx-ripple-dot::after {
    animation-delay: var(--fx-delay, 1.5s);
}

@keyframes kf-ripple-dot {
    0% {
        border-width: 2px;
        opacity: 0.9;
        transform: translate(-50%, 50%) scale(0.35);
    }

    40% {
        opacity: 0.6;
    }

    100% {
        border-width: 0.5px;
        opacity: 0;
        transform: translate(-50%, 50%) scale(4.5);
    }
}


/* 5.3. Vong lan toa ngang duoi pin */

.fx-ripple-x {
    /* Preserve Pano2VR positioning and contain both ring layers here. */
    position: relative;
    overflow: visible !important;
    isolation: isolate;
}

.fx-ripple-x > img,
.fx-ripple-x > svg {
    z-index: 1;
}

.fx-ripple-x::before,
.fx-ripple-x::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 50%;
    z-index: 0;
    width: 16px;
    height: 5px;
    border: 2px solid var(--fx-color, rgba(255, 255, 255, 0.9));
    border-radius: 50%;
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, 50%) scaleX(0.4) scaleY(0.4);
    animation: kf-ripple-x var(--fx-speed, 3s) ease-out var(--fx-repeat, infinite);
}

.fx-ripple-x::after {
    animation-delay: var(--fx-delay, 1.5s);
}

@keyframes kf-ripple-x {
    0% {
        border-width: 2px;
        opacity: 0.9;
        transform: translate(-50%, 50%) scaleX(0.4) scaleY(0.4);
    }

    40% {
        opacity: 0.65;
    }

    100% {
        border-width: 0.5px;
        opacity: 0;
        transform: translate(-50%, 50%) scaleX(5) scaleY(2.2);
    }
}


/* 5.4. Vong lan toa nhin tu tren xuong duoi pin */

.fx-ripple-top {
    /* Anchor the rings at center bottom without replacing Pano2VR positioning. */
    position: relative;
    overflow: visible !important;
    isolation: isolate;
}

.fx-ripple-top > img,
.fx-ripple-top > svg {
    z-index: 1;
}

.fx-ripple-top::before,
.fx-ripple-top::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 50%;
    z-index: 0;
    width: 12px;
    height: 12px;
    border: 2px solid var(--fx-color, rgba(255, 255, 255, 0.9));
    border-radius: 50%;
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, 50%) scale(0.35);
    transform-origin: center center;
    animation: kf-ripple-top var(--fx-speed, 3s) ease-out var(--fx-repeat, infinite);
}

.fx-ripple-top::after {
    animation-delay: var(--fx-delay, 1.5s);
}

@keyframes kf-ripple-top {
    0% {
        border-width: 2px;
        opacity: 0.9;
        transform: translate(-50%, 50%) scale(0.35);
    }

    40% {
        opacity: 0.65;
    }

    100% {
        border-width: 0.5px;
        opacity: 0;
        transform: translate(-50%, 50%) scale(var(--fx-ring-scale, 5));
    }
}


/* ==========================================================================
   6. HINH DANG
   ========================================================================== */

/* 6.1. Hinh tron co vien */

.shape-circle {
    border: var(--shape-border-width, 2px) solid var(--shape-border-color, #ffffff);
    border-radius: 50%;
    box-sizing: border-box;
}


/* ==========================================================================
   7. HAN CHE CHUYEN DONG
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .fx-bounce,
    .fx-pulse,
    .fx-float,
    .fx-blink,
    .fx-spin,
    .fx-pop,
    .fx-reveal,
    .fx-fade-in,
    .fx-fade-up,
    .fx-slide-left,
    .fx-zoom-in,
    .fx-rotate-in,
    .fx-blur-in,
    .fx-swing-in,
    .fx-grow,
    .fx-lift,
    .fx-shrink,
    .fx-wobble,
    .fx-press,
    .fx-glow,
    .fx-shine::after,
    .fx-ripple::before,
    .fx-ripple::after,
    .fx-ripple-dot::before,
    .fx-ripple-dot::after,
    .fx-ripple-x::before,
    .fx-ripple-x::after,
    .fx-ripple-top::before,
    .fx-ripple-top::after {
        animation: none !important;
    }

    .fx-bright {
        transition-duration: 0.01ms;
    }

    .fx-pop,
    .fx-reveal,
    .fx-fade-in,
    .fx-fade-up,
    .fx-slide-left,
    .fx-zoom-in,
    .fx-rotate-in,
    .fx-blur-in,
    .fx-swing-in {
        filter: none;
        opacity: 1;
    }
}
