/*
 * All values and keyframe timings are verbatim from the Figma motion JSON of
 * "Loading [Looped]" (2217:3281) and "Transition" (2310:4694) — 7600ms loop,
 * 5090ms exit. Percentages are ms / timeline-duration. Radians converted to
 * degrees (0.122173rad = 7deg, PI = 180deg). Springs (mass 1, stiffness 100,
 * damping 20 / 15) are sampled into linear() easings.
 */

.root {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: 18px;
}

/* Background on its own layer so the exit can fade it with the line/copy,
 * revealing the dashboard (and its card entrances) behind the flying blob. */
.bg {
    position: absolute;
    inset: 0;
    /* Figma "Gray Linear" style — #efefef end stop is unbound in Figma */
    background: linear-gradient(180deg, var(--color-neutral-100) 34.217%, #efefef 100%);
    pointer-events: none;
}

.exiting .bg {
    animation: exitFade 5090ms forwards;
}

.exiting.root {
    pointer-events: none;
}

.inner {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-md, 16px);
    width: 100%;
}

/* ---------- track + line (node 2221:29978 / 2218:4410) ---------- */

.blop {
    position: relative;
    width: 628px;
    height: 88px;
}

.lineWrap {
    position: absolute;
    top: 40px;
    left: 47px;
    width: 540px;
    height: 6px;
}

.line {
    width: 100%;
    height: 100%;
    border-radius: var(--border-radius-xs);
    /* Figma: gradient-to-r via #81b1e2 @49.55% inside a 180deg + flipY wrapper = horizontal mirror */
    background: linear-gradient(270deg, rgba(129, 177, 226, 0.2) 0%, #81b1e2 49.55%, rgba(129, 177, 226, 0.2) 100%);
    opacity: 0.8;
    animation: linePulse 7600ms infinite;
}

@keyframes linePulse {
    0% {
        opacity: 0.8;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    12.5% {
        opacity: 0.5;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    22.8326% {
        opacity: 0.8;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    37.4737% {
        opacity: 0.5;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    48.2544% {
        opacity: 0.8;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    62.5526% {
        opacity: 0.5;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    72.2632% {
        opacity: 0.8;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    87.4605% {
        opacity: 0.5;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    98.0263% {
        opacity: 0.8;
    }
    100% {
        opacity: 0.8;
    }
}

/* ---------- blob (outer 2303:5655, core 2217:3737) ----------
 * Each Figma-animated transform channel gets its own wrapper so per-channel
 * keyframe times and easings stay independent, exactly as authored:
 * translateX > translateY > scaleX > scaleY > rotation (visual element). */

.coreX,
.outerX,
.blobY,
.blobSx,
.blobSy,
.coreVisual,
.outerVisual {
    width: 100%;
    height: 100%;
}

.coreX {
    position: absolute;
    top: calc(50% - 14px);
    left: 22px;
    width: 24px;
    height: 28px;
    animation: coreTravel 3800ms infinite;
}

.outerX {
    position: absolute;
    top: calc(50% - 30px);
    left: 14px;
    width: 60px;
    height: 60px;
    animation: outerTravel 3800ms infinite;
}

.blobY {
    animation: blobBob 1900ms infinite;
}

.blobSx {
    animation: blobSquashX 1900ms infinite;
}

.blobSy {
    animation: blobSquashY 1900ms infinite;
}

.coreVisual {
    border-radius: 50px;
    background: linear-gradient(
        270deg,
        rgba(255, 255, 255, 0.1) 35.833%,
        rgba(53, 153, 255, 0.81) 76.688%,
        #007eff 100%
    );
    animation: coreSpin 3800ms infinite;
}

.outerVisual {
    border-radius: 50px;
    background: rgba(255, 255, 255, 0.1);
    box-shadow: 0px 14px 24px 0px rgba(255, 255, 255, 0.75);
    /* Figma "blur-large" BACKGROUND_BLUR (radius 50 -> css 25px): the glass
     * orb blurs the blue core and line behind it — the water-droplet look */
    backdrop-filter: blur(25px);
    -webkit-backdrop-filter: blur(25px);
    animation: outerWobble 3800ms infinite;
}

@keyframes coreTravel {
    0% {
        transform: translateX(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    50% {
        transform: translateX(550px);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: translateX(0);
    }
}

@keyframes outerTravel {
    0% {
        transform: translateX(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    50% {
        transform: translateX(540px);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: translateX(0);
    }
}

@keyframes blobBob {
    0% {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    50% {
        transform: translateY(-12px);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: translateY(0);
    }
}

@keyframes blobSquashX {
    0% {
        transform: scaleX(1);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    34.2105% {
        transform: scaleX(1.35);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: scaleX(1);
    }
}

@keyframes blobSquashY {
    0% {
        transform: scaleY(1);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    34.2105% {
        transform: scaleY(0.76);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: scaleY(1);
    }
}

@keyframes coreSpin {
    0% {
        transform: rotate(0deg);
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    50% {
        transform: rotate(180deg);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: rotate(0deg);
    }
}

@keyframes outerWobble {
    0% {
        transform: rotate(0deg);
        animation-timing-function: cubic-bezier(0.42, 0, 1, 1);
    }
    10.5263% {
        transform: rotate(7deg);
    }
    39.4737% {
        transform: rotate(7deg);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    50% {
        transform: rotate(0deg);
        animation-timing-function: cubic-bezier(0.42, 0, 1, 1);
    }
    60.5263% {
        transform: rotate(-7deg);
    }
    89.4737% {
        transform: rotate(-7deg);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: rotate(0deg);
    }
}

/* ---------- copy (nodes 2217:3962-3963, 2228:549-551) ---------- */

.copy {
    position: relative;
    width: 208px;
    height: 22px;
    font-family: var(--font-default);
    font-size: var(--font-size-md);
    font-weight: 400;
    line-height: var(--line-height-lg);
    letter-spacing: -0.32px;
    text-align: center;
    white-space: nowrap;
    color: transparent;
}

.message {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    margin: 0;
    background-clip: text;
    -webkit-background-clip: text;
    animation-duration: 7600ms;
    animation-iteration-count: infinite;
}

.message1 {
    background-image: linear-gradient(175.03deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);
    opacity: 0;
    animation-name: msg1Cycle;
}

.message2 {
    left: calc(50% + 0.5px);
    background-image: linear-gradient(176.163deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);
    opacity: 0;
    animation-name: msg2Cycle;
}

.message3 {
    left: calc(50% + 0.5px);
    background-image: linear-gradient(176.358deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);
    opacity: 0;
    animation-name: msg3Cycle;
}

.message4 {
    background-image: linear-gradient(175.887deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);
    animation-name: msg4Cycle;
}

@keyframes msg1Cycle {
    0% {
        opacity: 0;
    }
    59.9334% {
        opacity: 0;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    66.692% {
        opacity: 1;
    }
    81.9078% {
        opacity: 1;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    88.5526% {
        opacity: 0;
    }
    100% {
        opacity: 0;
    }
}

/* Figma authors a 199% opacity keyframe at 56.4478%; clamped to 1. */
@keyframes msg2Cycle {
    0% {
        opacity: 0;
    }
    35.1711% {
        opacity: 0;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    42.2107% {
        opacity: 1;
    }
    56.4478% {
        opacity: 1;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    63.1757% {
        opacity: 0;
    }
    100% {
        opacity: 0;
    }
}

@keyframes msg3Cycle {
    0% {
        opacity: 0;
    }
    10.2802% {
        opacity: 0;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    17.3684% {
        opacity: 1;
    }
    31.7105% {
        opacity: 1;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    38.75% {
        opacity: 0;
    }
    100% {
        opacity: 0;
    }
}

@keyframes msg4Cycle {
    0% {
        opacity: 1;
    }
    6.9151% {
        opacity: 1;
        animation-timing-function: cubic-bezier(0.42, 0, 1, 1);
    }
    13.9372% {
        opacity: 0;
    }
    85.1842% {
        opacity: 0;
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    91.6774% {
        opacity: 1;
    }
    100% {
        opacity: 1;
    }
}

/* ---------- exit choreography (Transition frame, 5090ms from leg start) ----------
 * translateX spring (mass 1, stiffness 100, damping 20 — critically damped)
 * sampled into linear(); settles ~660ms into the 3190ms segment. */

.exiting .lineWrap,
.exiting .copy {
    animation: exitFade 5090ms forwards;
}

@keyframes exitFade {
    0% {
        opacity: 1;
    }
    31.0563% {
        opacity: 1;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    54.7769% {
        opacity: 0;
    }
    100% {
        opacity: 0;
    }
}

.exiting .coreX {
    animation: coreExitX 5090ms forwards;
}

.exiting .outerX {
    animation: outerExitX 5090ms forwards;
}

.exiting .coreX > .blobY {
    animation: coreExitY 5090ms forwards;
}

.exiting .outerX > .blobY {
    animation: outerExitY 5090ms forwards;
}

.exiting .blobSx {
    animation: exitScaleX 5090ms forwards;
}

.exiting .coreX .blobSy {
    animation: coreExitScaleY 5090ms forwards;
}

.exiting .outerX .blobSy {
    animation: outerExitScaleY 5090ms forwards;
}

.exiting .coreVisual {
    animation: coreExitSpin 5090ms forwards;
}

.exiting .outerVisual {
    animation: outerExitWobble 5090ms forwards;
}

@keyframes coreExitX {
    0% {
        transform: translateX(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: translateX(550px);
        animation-timing-function: linear(
            0 0%,
            0.3153 3.57%,
            0.6642 7.14%,
            0.8552 10.71%,
            0.9417 14.29%,
            0.9775 17.86%,
            0.9916 21.43%,
            0.9969 25%,
            0.9989 28.57%,
            1 32.14%,
            1 100%
        );
    }
    100% {
        transform: translateX(265px);
    }
}

@keyframes outerExitX {
    0% {
        transform: translateX(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: translateX(540px);
        animation-timing-function: linear(
            0 0%,
            0.3153 3.57%,
            0.6642 7.14%,
            0.8552 10.71%,
            0.9417 14.29%,
            0.9775 17.86%,
            0.9916 21.43%,
            0.9969 25%,
            0.9989 28.57%,
            1 32.14%,
            1 100%
        );
    }
    100% {
        transform: translateX(195px);
    }
}

@keyframes coreExitY {
    0% {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    18.664% {
        transform: translateY(-12px);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: translateY(-735px);
    }
}

@keyframes outerExitY {
    0% {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    18.664% {
        transform: translateY(-12px);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: translateY(-769px);
    }
}

@keyframes exitScaleX {
    0% {
        transform: scaleX(1);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    12.7701% {
        transform: scaleX(1.35);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: scaleX(1);
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    100% {
        transform: scaleX(39);
    }
}

@keyframes coreExitScaleY {
    0% {
        transform: scaleY(1);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    12.7701% {
        transform: scaleY(0.76);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: scaleY(1);
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    50.0981% {
        transform: scaleY(2.448);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    100% {
        transform: scaleY(11.8);
    }
}

@keyframes outerExitScaleY {
    0% {
        transform: scaleY(1);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    12.7701% {
        transform: scaleY(0.76);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: scaleY(1);
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    100% {
        transform: scaleY(10);
    }
}

@keyframes coreExitSpin {
    0% {
        transform: rotate(0deg);
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
    37.328% {
        transform: rotate(180deg);
    }
    100% {
        transform: rotate(180deg);
    }
}

@keyframes outerExitWobble {
    0% {
        transform: rotate(0deg);
        animation-timing-function: cubic-bezier(0.42, 0, 1, 1);
    }
    7.8585% {
        transform: rotate(7deg);
    }
    29.4695% {
        transform: rotate(7deg);
        animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
    }
    37.328% {
        transform: rotate(180deg);
    }
    100% {
        transform: rotate(180deg);
    }
}

/* ---------- reveal (Transition card entrances) ----------
 * Opacity spring (mass 1, stiffness 100, damping 15) sampled into linear();
 * ~2.8% overshoot clamps at opacity 1. Rise easing varies per card and is
 * passed in via --reveal-rise-easing. */

.reveal {
    opacity: 0;
    /* Hidden (not just transparent) while waiting on the entrance delay so
     * the concealed card can't be clicked or tab-focused; the keyframes'
     * fill-mode flips visibility the moment the animation starts. */
    visibility: hidden;
}

.revealRise {
    transform: translateY(20px);
    animation:
        revealFade var(--reveal-duration, 799ms) var(--reveal-delay, 0ms) both,
        revealRise var(--reveal-duration, 799ms) var(--reveal-delay, 0ms) both;
    animation-timing-function:
        linear(
            0 0%,
            0.06514 5%,
            0.2117 10%,
            0.3855 15%,
            0.5538 20%,
            0.6991 25%,
            0.8145 30%,
            0.8999 35%,
            0.9587 40%,
            0.9958 45%,
            1.017 50%,
            1.026 55%,
            1.028 60%,
            1.026 65%,
            1.022 70%,
            1.017 75%,
            1.012 80%,
            1.008 85%,
            1.005 90%,
            1.003 95%,
            1.001 100%
        ),
        var(--reveal-rise-easing, cubic-bezier(0.42, 0, 0.58, 1));
}

.revealFade {
    animation: revealFade var(--reveal-duration, 217ms) var(--reveal-delay, 0ms) both;
    animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
}

@keyframes revealFade {
    from {
        opacity: 0;
        visibility: hidden;
    }
    to {
        opacity: 1;
        visibility: visible;
    }
}

@keyframes revealRise {
    from {
        transform: translateY(20px);
    }
    to {
        transform: translateY(0);
    }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
    .coreX,
    .outerX,
    .blobY,
    .blobSx,
    .blobSy,
    .coreVisual,
    .outerVisual {
        animation: none;
    }

    .exiting.root {
        animation: exitFadeReduced 300ms forwards;
    }

    .exiting .lineWrap,
    .exiting .copy {
        animation: none;
    }

    /* Reduced motion: no rise, and no Figma stagger — the multi-second
     * entrance delays read as missing content when nothing animates. */
    .revealRise,
    .revealFade {
        transform: none;
        animation: revealFade var(--reveal-duration, 799ms) 0ms both;
        animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
    }
}

@keyframes exitFadeReduced {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}
