/* ==========================================================================
   08 — Premium micro-interactions & animations
   Scope: scroll reveal, card tilt, magnetic CTAs, ripples, timeline pulse,
   filter underline, hero cascade. Transform + opacity only (60fps).
   ========================================================================== */

/* ---------- Easing tokens ---------- */
:root {
    --ease-out-soft: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in-out-soft: cubic-bezier(0.65, 0, 0.35, 1);
    --reveal-duration: 600ms;
    --reveal-distance: 20px;
}

/* ==========================================================================
   1. Scroll reveal — sections fade up via IntersectionObserver (.in-view)
   ========================================================================== */

/* Scroll-reveal volledig disabled — gaf onverklaarbare gaten + dim content
   wanneer observer niet fired. Cards en secties zijn direct zichtbaar. */
.section[data-reveal],
.hero[data-reveal],
.section[data-reveal] > *,
.hero[data-reveal] > * {
    opacity: 1;
    transform: none;
}

/* Same fix voor .reveal CLASS (style.css regel 4968 zet die op opacity:0).
   IntersectionObserver kan op mobiel of slow connections falen, met als
   gevolg permanent onzichtbare featured cards / stats / sub-blocks =
   "groot leeg gat" tussen Over Mij en Werkervaring. Force visible. */
.reveal {
    opacity: 1 !important;
    transform: none !important;
}

.section[data-reveal].in-view > *:nth-child(1) { transition-delay: 60ms; }
.section[data-reveal].in-view > *:nth-child(2) { transition-delay: 140ms; }
.section[data-reveal].in-view > *:nth-child(3) { transition-delay: 220ms; }
.section[data-reveal].in-view > *:nth-child(4) { transition-delay: 300ms; }
.section[data-reveal].in-view > *:nth-child(5) { transition-delay: 380ms; }
.section[data-reveal].in-view > *:nth-child(6) { transition-delay: 460ms; }

/* ==========================================================================
   2. Card tilt — mouse-position driven, CSS-only consumption
   JS writes --mx and --my (range -1 to 1) on hover.
   ========================================================================== */

.ai-project-card,
.featured-project {
    --mx: 0;
    --my: 0;
    --tilt-strength: 5deg;
    transform-style: preserve-3d;
    transition: transform 400ms var(--ease-out-soft),
                box-shadow 400ms var(--ease-out-soft);
}

/* Mouse-tilt op cards disabled - voelt rommelig samen met andere hover states.
   Cleaner hover wordt nu door 10-projects.css gehanteerd. */

/* ==========================================================================
   3. Magnetic CTAs — subtle lift, scale, deeper shadow
   ========================================================================== */

.hero-actions .btn,
.hero-actions a[class*="btn"],
.contact-actions .btn,
a.btn-primary,
a.btn-secondary,
button.btn-primary,
button.btn-secondary {
    transition: transform 280ms var(--ease-out-soft),
                box-shadow 280ms var(--ease-out-soft),
                background-color 280ms var(--ease-out-soft),
                color 280ms var(--ease-out-soft);
    will-change: transform;
}

@media (hover: hover) and (pointer: fine) {
    .hero-actions .btn:hover,
    .hero-actions a[class*="btn"]:hover,
    .contact-actions .btn:hover,
    a.btn-primary:hover,
    a.btn-secondary:hover,
    button.btn-primary:hover,
    button.btn-secondary:hover {
        transform: translate3d(0, -2px, 0) scale(1.03);
        box-shadow: 0 12px 32px -8px rgba(var(--accent-rgb), 0.45),
                    0 4px 12px -4px rgba(0, 0, 0, 0.35);
    }

    .hero-actions .btn:active,
    .hero-actions a[class*="btn"]:active,
    a.btn-primary:active,
    a.btn-secondary:active {
        transform: translate3d(0, 0, 0) scale(0.99);
        transition-duration: 120ms;
    }
}

/* ==========================================================================
   4. Stat counter — CSS hook (.counter-animate)
   Real numeric counting requires JS; this is a visual emphasis pulse.
   ========================================================================== */

.counter-animate {
    display: inline-block;
    transform: scale(0.9);
    opacity: 0;
    transition: transform 700ms var(--ease-out-soft),
                opacity 500ms ease-out;
}

.in-view .counter-animate,
.counter-animate.in-view {
    transform: scale(1);
    opacity: 1;
}

/* ==========================================================================
   5. Skill chip ripple — mint glow expanding from center on hover
   ========================================================================== */

.skill-chip {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: transform 240ms var(--ease-out-soft),
                border-color 240ms ease-out,
                color 240ms ease-out;
}

.skill-chip::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 120%;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    background: radial-gradient(circle,
                rgba(var(--accent-rgb), 0.35) 0%,
                rgba(var(--accent-rgb), 0.0) 60%);
    transform: translate(-50%, -50%) scale(0);
    transform-origin: center;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    transition: transform 500ms var(--ease-out-soft),
                opacity 400ms ease-out;
}

@media (hover: hover) and (pointer: fine) {
    .skill-chip:hover::after {
        transform: translate(-50%, -50%) scale(1);
        opacity: 1;
    }

    .skill-chip:hover {
        transform: translateY(-1px);
    }
}

/* ==========================================================================
   6. Timeline current-role pulse — only the first .timeline-item
   ========================================================================== */

@keyframes timelinePulse {
    0% {
        box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.55),
                    0 0 0 0 rgba(var(--accent-rgb), 0.0);
    }
    70% {
        box-shadow: 0 0 0 12px rgba(var(--accent-rgb), 0.0),
                    0 0 18px 4px rgba(var(--accent-rgb), 0.25);
    }
    100% {
        box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.0),
                    0 0 0 0 rgba(var(--accent-rgb), 0.0);
    }
}

/* Apply pulse to the marker element of the current (first) role.
   Targets common marker class names; harmless if absent. */
#experience .timeline-item:first-child .timeline-dot,
#experience .timeline-item:first-child .timeline-marker,
#experience .timeline-item:first-child > .dot {
    animation: timelinePulse 2.2s var(--ease-in-out-soft) infinite;
    border-radius: 50%;
}

/* ==========================================================================
   7. Filter buttons — animated mint underline progress bar on .active
   ========================================================================== */

.filter-btn {
    position: relative;
    overflow: visible;
}

.filter-btn::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -2px;
    height: 2px;
    background: linear-gradient(90deg,
                rgba(var(--accent-rgb), 0.0),
                rgba(var(--accent-rgb), 1),
                rgba(var(--accent-rgb), 0.0));
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 450ms var(--ease-out-soft);
    pointer-events: none;
    border-radius: 2px;
}

.filter-btn.active::before {
    transform: scaleX(1);
}

@media (hover: hover) and (pointer: fine) {
    .filter-btn:not(.active):hover::before {
        transform: scaleX(0.4);
    }
}

/* ==========================================================================
   8. Hero page-load cascade
   ========================================================================== */

@keyframes heroFadeUp {
    from {
        opacity: 0;
        transform: translate3d(0, 16px, 0);
    }
    to {
        opacity: 1;
        transform: translate3d(0, 0, 0);
    }
}

.hero .hero-content .hero-eyebrow,
.hero .hero-content h1,
.hero .hero-content .hero-subtitle,
.hero .hero-content .hero-actions,
.hero .hero-content .hero-stats {
    animation: heroFadeUp 700ms var(--ease-out-soft) both;
}

.hero .hero-content .hero-eyebrow   { animation-delay: 50ms; }
.hero .hero-content h1              { animation-delay: 150ms; }
.hero .hero-content .hero-subtitle  { animation-delay: 300ms; }
.hero .hero-content .hero-actions   { animation-delay: 450ms; }
.hero .hero-content .hero-stats     { animation-delay: 600ms; }

/* ==========================================================================
   9. Reduced motion — cancel everything, keep instant state changes
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .section[data-reveal],
    .hero[data-reveal],
    .section[data-reveal] > * {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }

    .ai-project-card,
    .ai-project-card:hover,
    .featured-project,
    .featured-project:hover {
        transform: none !important;
        transition: none !important;
    }

    .hero-actions .btn:hover,
    a.btn-primary:hover,
    a.btn-secondary:hover,
    button.btn-primary:hover,
    button.btn-secondary:hover {
        transform: none !important;
        box-shadow: none !important;
    }

    .skill-chip::after { display: none !important; }
    .skill-chip:hover { transform: none !important; }

    #experience .timeline-item:first-child .timeline-dot,
    #experience .timeline-item:first-child .timeline-marker,
    #experience .timeline-item:first-child > .dot {
        animation: none !important;
    }

    .filter-btn::before {
        transition: none !important;
    }

    .hero .hero-content .hero-eyebrow,
    .hero .hero-content h1,
    .hero .hero-content .hero-subtitle,
    .hero .hero-content .hero-actions,
    .hero .hero-content .hero-stats {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
    }

    .counter-animate {
        transform: none !important;
        opacity: 1 !important;
        transition: none !important;
    }
}
