/* ==================================================================
   MAZHARUL MAHIN — animations.css
   Keyframes, intro sequence, scroll reveals and reduced-motion.
   Everything that hides content before animating is scoped to
   html.js — without JavaScript the site is fully visible.
   ================================================================== */

/* ---------- Keyframes ---------- */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes blink { 50% { opacity: 0; } }
@keyframes char-up { to { transform: translateY(0); } }

@keyframes pulse-dot {
    0% { box-shadow: 0 0 0 0 rgba(61, 220, 132, .6); }
    70% { box-shadow: 0 0 0 10px rgba(61, 220, 132, 0); }
    100% { box-shadow: 0 0 0 0 rgba(61, 220, 132, 0); }
}

@keyframes scroll-wheel {
    0% { transform: translateY(0); opacity: 1; }
    70% { transform: translateY(10px); opacity: 0; }
    100% { transform: translateY(0); opacity: 0; }
}

@keyframes ripple {
    0% { transform: scale(1); opacity: .8; }
    100% { transform: scale(1.6); opacity: 0; }
}

@keyframes float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50% { transform: translateY(-14px) rotate(-2deg); }
}

@keyframes drift-1 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33% { transform: translate(8vw, 6vh) scale(1.1); }
    66% { transform: translate(-4vw, 10vh) scale(.95); }
}
@keyframes drift-2 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50% { transform: translate(-10vw, -8vh) scale(1.15); }
}

@keyframes gradient-pan {
    0% { background-position: 0% 50%; }
    100% { background-position: 200% 50%; }
}

@keyframes rings-spin { to { transform: translate(-50%, -50%) rotate(360deg); } }

@keyframes glitch-1 {
    0%, 100% { clip-path: inset(0 0 100% 0); transform: none; }
    8% { clip-path: inset(10% 0 60% 0); transform: translate(-6px, 2px); }
    10% { clip-path: inset(50% 0 20% 0); transform: translate(6px, -2px); }
    12% { clip-path: inset(0 0 100% 0); transform: none; }
    60% { clip-path: inset(70% 0 5% 0); transform: translate(-4px, 0); }
    62% { clip-path: inset(0 0 100% 0); transform: none; }
}
@keyframes glitch-2 {
    0%, 100% { clip-path: inset(0 0 100% 0); transform: none; }
    20% { clip-path: inset(30% 0 40% 0); transform: translate(5px, 1px); }
    22% { clip-path: inset(0 0 100% 0); transform: none; }
    75% { clip-path: inset(15% 0 70% 0); transform: translate(-5px, -1px); }
    77% { clip-path: inset(0 0 100% 0); transform: none; }
}

/* ---------- Ambient motion ---------- */
.bg-fx__blob--1 { animation: drift-1 26s ease-in-out infinite; }
.bg-fx__blob--2 { animation: drift-2 32s ease-in-out infinite; }
.bg-fx__blob--3 { animation: drift-1 22s ease-in-out infinite reverse; }

.hero__rings span:nth-child(2) { animation: rings-spin 80s linear infinite; }

.chip-float { animation: float 6s ease-in-out infinite; }
.chip-float--2 { animation-delay: -2s; animation-duration: 7s; }
.chip-float--3 { animation-delay: -4s; animation-duration: 8s; }

.btn--primary,
.marquee,
.scroll-progress {
    background-size: 200% 100%;
    animation: gradient-pan 6s linear infinite;
}
.btn--primary { animation-duration: 4s; }

/* ==================================================================
   INTRO SEQUENCE (runs when body gets .is-ready after the preloader)
   ================================================================== */
html.js .hero__name .ch {
    transform: translateY(108%);
}
html.js body.is-ready .hero__name .ch {
    transform: none;
    transition: transform 1.2s var(--ease) calc(.05s + var(--i) * .045s);
}

html.js .hero__portrait {
    opacity: 0;
    scale: 1.08;
    translate: 0 60px;
    filter: blur(12px);
}
html.js body.is-ready .hero__portrait {
    opacity: 1;
    scale: 1;
    translate: 0 0;
    filter: blur(0);
    transition: opacity 1.2s var(--ease) .35s, scale 1.6s var(--ease) .35s, translate 1.6s var(--ease) .35s, filter 1.2s var(--ease) .35s;
}

html.js [data-hero] {
    opacity: 0;
    transform: translateY(28px);
}
html.js .chip-float[data-hero] { transform: none; scale: .6; }

html.js body.is-ready [data-hero] {
    opacity: 1;
    transform: none;
    transition: opacity 1s var(--ease), transform 1.1s var(--ease), scale 1s var(--ease);
}
html.js body.is-ready .chip-float[data-hero] { scale: 1; transform: initial; transition: opacity 1s var(--ease), scale 1s var(--ease); }
html.js body.is-ready [data-hero="1"] { transition-delay: .25s; }
html.js body.is-ready [data-hero="2"] { transition-delay: 1s; }
html.js body.is-ready [data-hero="3"] { transition-delay: .85s; }

/* ==================================================================
   SCROLL REVEALS (IntersectionObserver adds .is-visible)
   ================================================================== */
html.js [data-reveal]:not([data-reveal="clip"]) {
    opacity: 0;
    transform: translateY(46px);
    transition: opacity 1s var(--ease) calc(var(--d, 0) * .12s),
                transform 1.1s var(--ease) calc(var(--d, 0) * .12s),
                translate .5s var(--ease),
                border-color .4s;
}
html.js [data-reveal]:not([data-reveal="clip"]).is-visible {
    opacity: 1;
    transform: none;
}
/* Tilt cards need a snappier transform transition once revealed */
html.js [data-tilt][data-reveal].is-visible {
    transition: opacity 1s var(--ease) calc(var(--d, 0) * .12s), transform .45s var(--ease), border-color .4s;
}

/* Clip / image reveal */
html.js [data-reveal="clip"] {
    clip-path: inset(100% 0 0 0);
    transition: clip-path 1.4s var(--ease-in-out), transform .45s var(--ease);
}
html.js [data-reveal="clip"].is-visible { clip-path: inset(0 0 0 0); }
html.js [data-reveal="clip"] img {
    scale: 1.25;
    transition: scale 1.8s var(--ease), transform 1.2s var(--ease);
}
html.js [data-reveal="clip"].is-visible img { scale: 1; }

/* Split-word headings */
.w {
    display: inline-block;
    overflow: hidden;
    vertical-align: top;
    padding-bottom: .12em;
    margin-bottom: -.12em;
}
.w__in { display: inline-block; }
/* Gradient is painted per word so it survives the transform */
.section-title em { background: none; color: inherit; }
.section-title em .w__in {
    background: var(--grad);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
html.js [data-split] .w__in { transform: translateY(110%); }
html.js [data-split].is-visible .w__in {
    transform: none;
    transition: transform 1.1s var(--ease) calc(var(--i) * .07s);
}
html.js [data-split] em .w__in { transition-delay: calc(.2s + var(--i) * .07s); }

/* ==================================================================
   REDUCED MOTION — respect the user's preference
   ================================================================== */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        transition-delay: 0s !important;
    }

    html.js [data-reveal],
    html.js [data-hero],
    html.js .hero__portrait {
        opacity: 1 !important;
        transform: none !important;
        clip-path: none !important;
        filter: none !important;
        scale: 1 !important;
        translate: none !important;
    }
    html.js [data-reveal="clip"] img { scale: 1 !important; }
    html.js .hero__name .ch,
    html.js [data-split] .w__in { transform: none !important; }
    .hero__portrait { transform: translateX(-50%) !important; }
    .marquee__track { transform: none !important; }
    .cursor { display: none !important; }
}
