/* ============================================================
   Animations — scroll reveal + entrance
   ============================================================ */

/* Reveal on scroll (toggled by IntersectionObserver -> .in-view) */
.reveal {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.65, 0.3, 1);
    will-change: opacity, transform;
}
.reveal.in-view {
    opacity: 1;
    transform: translateY(0);
}

/* When GSAP drives the reveals, let it own the inline styles (no CSS
   transition fighting the per-frame tween). */
html.has-gsap .reveal:not(.hero .reveal) {
    transition: none;
}

/* Stagger children of a revealed container */
.reveal.in-view:nth-child(1) { transition-delay: 0s; }
.reveal.in-view:nth-child(2) { transition-delay: 0.05s; }
.reveal.in-view:nth-child(3) { transition-delay: 0.1s; }

/* Hero entrance — sequential fade-up on load */
.hero .reveal {
    opacity: 0;
    transform: translateY(24px);
    animation: heroFadeUp 0.8s cubic-bezier(0.2, 0.65, 0.3, 1) forwards;
}
.hero .hero-content .eyebrow { animation-delay: 0.1s; }
.hero .hero-content h1 { animation-delay: 0.2s; }
.hero .hero-content h2 { animation-delay: 0.3s; }
.hero .hero-content p { animation-delay: 0.4s; }
.hero .hero-content .cta-buttons { animation-delay: 0.5s; }
.hero .hero-content .social-icons { animation-delay: 0.6s; }
.hero .hero-image { animation-delay: 0.35s; }
.hero .hero-stats { animation-delay: 0.7s; }

@keyframes heroFadeUp {
    to { opacity: 1; transform: translateY(0); }
}

/* Typed.js cursor */
.typed-cursor {
    color: var(--accent-2);
    font-weight: 400;
}

/* Project filter transition */
.project-card {
    animation: cardIn 0.4s ease both;
}
@keyframes cardIn {
    from { opacity: 0; transform: scale(0.96); }
    to { opacity: 1; transform: scale(1); }
}
