/**
 * Expressive motion — slides, sweeps, flips, and theme curtains.
 */

:root {
    --duration-slow: 520ms;
    --duration-theme: 720ms;
    --ease-spring: cubic-bezier(0.34, 1.45, 0.64, 1);
    --ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-snap: cubic-bezier(0.76, 0, 0.24, 1);
}

/* ── Keyframes ── */

@keyframes hero-name-sweep {
    from {
        opacity: 0;
        transform: translateX(-5rem) skewX(-6deg);
        clip-path: inset(0 100% 0 0);
    }

    to {
        opacity: 1;
        transform: translateX(0) skewX(0);
        clip-path: inset(0 0 0 0);
    }
}

@keyframes hero-tagline-sweep {
    from {
        opacity: 0;
        transform: translateX(4rem) skewX(4deg);
        clip-path: inset(0 0 0 100%);
    }

    to {
        opacity: 1;
        transform: translateX(0) skewX(0);
        clip-path: inset(0 0 0 0);
    }
}

@keyframes hero-rise-spin {
    from {
        opacity: 0;
        transform: translateY(2.5rem) rotate(-4deg);
    }

    to {
        opacity: 1;
        transform: translateY(0) rotate(0);
    }
}

@keyframes hero-links-cascade {
    from {
        opacity: 0;
        transform: translateY(3rem) scale(0.85);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes header-drop-swing {
    from {
        opacity: 0;
        transform: translateY(-120%) rotate(-8deg);
    }

    to {
        opacity: 1;
        transform: translateY(0) rotate(0);
    }
}

@keyframes timeline-line-grow {
    from {
        transform: translateX(-50%) scaleY(0);
    }

    to {
        transform: translateX(-50%) scaleY(1);
    }
}

@keyframes theme-sweep-beam {
    from {
        transform: translateX(-120%) skewX(-16deg);
        opacity: 0.85;
    }

    to {
        transform: translateX(120%) skewX(-16deg);
        opacity: 0;
    }
}

@keyframes theme-ring-expand {
    from {
        transform: translate(-50%, -50%) scale(0);
        opacity: 0.55;
    }

    to {
        transform: translate(-50%, -50%) scale(28);
        opacity: 0;
    }
}

@keyframes theme-btn-spin {
    from {
        transform: rotate(-180deg) scale(0.6);
    }

    to {
        transform: rotate(0) scale(1);
    }
}

@keyframes pulse-soft {
    0%,
    100% {
        opacity: 0.55;
        transform: translateX(-0.5rem);
    }

    50% {
        opacity: 1;
        transform: translateX(0.5rem);
    }
}

/* ── Theme transition curtain (class toggled from theme.js, animations run in CSS) ── */

.theme-sweep {
    position: fixed;
    inset: 0;
    z-index: 200;
    pointer-events: none;
    overflow: hidden;
    visibility: hidden;
}

html.theme-sweeping .theme-sweep {
    visibility: visible;
}

.theme-sweep-beam {
    position: absolute;
    top: -20%;
    left: 0;
    width: 55%;
    height: 140%;
    background: linear-gradient(
        105deg,
        transparent 0%,
        color-mix(in srgb, var(--color-accent) 35%, transparent) 42%,
        color-mix(in srgb, var(--color-accent) 75%, white) 50%,
        color-mix(in srgb, var(--color-accent) 35%, transparent) 58%,
        transparent 100%
    );
    filter: blur(2px);
}

html.theme-sweeping .theme-sweep-beam {
    animation: theme-sweep-beam 0.85s var(--ease-snap) forwards;
}

.theme-sweep-ring {
    position: absolute;
    left: var(--sweep-x, 50%);
    top: var(--sweep-y, 0%);
    width: 4rem;
    height: 4rem;
    border: 3px solid color-mix(in srgb, var(--color-accent) 70%, transparent);
    border-radius: 50%;
}

html.theme-sweeping .theme-sweep-ring {
    animation: theme-ring-expand 0.9s var(--ease-smooth) forwards;
}

html.theme-transitioning,
html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
    transition-duration: var(--duration-theme) !important;
    transition-timing-function: var(--ease-smooth) !important;
    transition-property:
        background-color, color, border-color, box-shadow, fill, stroke, outline-color, opacity !important;
}

/* ── Hero entrance ── */

.hero-name {
    animation: hero-name-sweep 1s var(--ease-snap) 0.08s both;
}

.hero-tagline {
    animation: hero-tagline-sweep 1s var(--ease-snap) 0.28s both;
}

.hero-meta {
    animation: hero-rise-spin 0.9s var(--ease-spring) 0.48s both;
}

.hero .social-links {
    animation: hero-links-cascade 0.85s var(--ease-spring) 0.62s both;
}

.hero .social-link {
    animation: hero-links-cascade 0.7s var(--ease-spring) both;
}

.hero .social-link:nth-child(1) {
    animation-delay: 0.72s;
}

.hero .social-link:nth-child(2) {
    animation-delay: 0.81s;
}

.hero .social-link:nth-child(3) {
    animation-delay: 0.9s;
}

.page-header {
    animation: header-drop-swing 0.9s var(--ease-spring) 0s both;
}

@keyframes scroll-fade-up {
    entry 0% {
        opacity: 0;
        transform: translateY(1.25rem);
    }

    entry 100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes scroll-slide-left {
    entry 0% {
        opacity: 0;
        transform: translateX(-4.5rem);
        clip-path: inset(0 100% 0 0);
    }

    entry 100%,
    exit 0% {
        opacity: 1;
        transform: translateX(0);
        clip-path: inset(0 0 0 0);
    }

    exit 100% {
        opacity: 0;
        transform: translateX(-3.5rem);
        clip-path: inset(0 100% 0 0);
    }
}

@keyframes scroll-slide-right {
    entry 0% {
        opacity: 0;
        transform: translateX(4.5rem);
        clip-path: inset(0 0 0 100%);
    }

    entry 100%,
    exit 0% {
        opacity: 1;
        transform: translateX(0);
        clip-path: inset(0 0 0 0);
    }

    exit 100% {
        opacity: 0;
        transform: translateX(3.5rem);
        clip-path: inset(0 0 0 100%);
    }
}

@keyframes scroll-sweep-up {
    entry 0% {
        opacity: 0;
        transform: translateY(4rem);
        clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
    }

    entry 100%,
    exit 0% {
        opacity: 1;
        transform: translateY(0);
        clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    }

    exit 100% {
        opacity: 0;
        transform: translateY(3rem);
        clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
    }
}

@keyframes scroll-flip {
    entry 0% {
        opacity: 0;
        transform: perspective(900px) rotateX(18deg) translateY(3rem);
    }

    entry 100%,
    exit 0% {
        opacity: 1;
        transform: perspective(900px) rotateX(0) translateY(0);
    }

    exit 100% {
        opacity: 0;
        transform: perspective(900px) rotateX(-14deg) translateY(2rem);
    }
}

@keyframes scroll-skill-in {
    entry 0% {
        opacity: 0;
        transform: translateX(-2rem) rotate(-5deg) scale(0.8);
    }

    entry 100% {
        opacity: 1;
        transform: translateX(0) rotate(0) scale(1);
    }
}

@keyframes scroll-skill-in-alt {
    entry 0% {
        opacity: 0;
        transform: translateX(2rem) rotate(5deg) scale(0.8);
    }

    entry 100% {
        opacity: 1;
        transform: translateX(0) rotate(0) scale(1);
    }
}

@keyframes scroll-timeline-in {
    entry 0% {
        opacity: 0;
        transform: translateY(0.75rem);
    }

    entry 100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes scroll-title-underline {
    entry 0% {
        transform: scaleX(0) skewX(-12deg);
    }

    entry 100% {
        transform: scaleX(1) skewX(0);
    }
}

@keyframes scroll-dashboard {
    entry 0% {
        opacity: 0;
        transform: translateY(0.75rem);
    }

    entry 100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes scroll-stat {
    entry 0% {
        opacity: 0;
        transform: translateY(0.5rem);
    }

    entry 100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes scroll-graph {
    entry 0% {
        opacity: 0;
    }

    entry 100% {
        opacity: 1;
    }
}

.section-header::after {
    content: "";
    display: block;
    width: min(12rem, 40%);
    height: 3px;
    margin-top: var(--space-3);
    background: linear-gradient(90deg, var(--color-accent), transparent);
    transform: scaleX(0);
    transform-origin: left;
}

/* ── Scroll reveals: CSS scroll-driven animations (no JS) ── */

@supports (animation-timeline: view()) {
    [data-reveal] {
        overflow-x: clip;
    }

    [data-reveal="fade-up"] {
        animation: scroll-fade-up linear both;
        animation-timeline: view();
        animation-range: cover 0% cover 35%;
    }

    [data-reveal="slide-left"] {
        animation: scroll-slide-left linear both;
        animation-timeline: view();
        animation-range: entry 0% exit 100%;
    }

    [data-reveal="slide-right"] {
        animation: scroll-slide-right linear both;
        animation-timeline: view();
        animation-range: entry 0% exit 100%;
    }

    [data-reveal="sweep-up"] {
        animation: scroll-sweep-up linear both;
        animation-timeline: view();
        animation-range: entry 0% exit 100%;
    }

    [data-reveal="flip"] {
        animation: scroll-flip linear both;
        animation-timeline: view();
        animation-range: entry 0% exit 100%;
    }

    .section-header::after {
        animation: scroll-title-underline linear both;
        animation-timeline: view();
        animation-range: entry 5% cover 35%;
    }

    [data-stagger="skills"] > * {
        animation: scroll-skill-in linear both;
        animation-timeline: view();
        animation-range: entry 0% cover 32%;
    }

    [data-stagger="skills"] > *:nth-child(even) {
        animation-name: scroll-skill-in-alt;
    }

    .timeline-item {
        animation: scroll-timeline-in linear both;
        animation-timeline: view();
        animation-range: cover 0% cover 28%;
    }

    .timeline-item .timeline-marker::after {
        animation: timeline-line-grow linear both;
        animation-timeline: view();
        animation-range: cover 5% cover 32%;
    }

    .github-dashboard {
        animation: scroll-dashboard linear both;
        animation-timeline: view();
        animation-range: cover 0% cover 30%;
    }

    .github-stat {
        animation: scroll-stat linear both;
        animation-timeline: view();
        animation-range: cover 0% cover 24%;
    }

    .contrib-graph-scroll {
        animation: scroll-graph linear both;
        animation-timeline: view();
        animation-range: cover 5% cover 32%;
    }
}

@supports not (animation-timeline: view()) {
    [data-reveal]:not([data-reveal="hero"]) {
        opacity: 1;
        transform: none;
        clip-path: none;
    }

    [data-stagger] > *,
    .github-dashboard,
    .github-stat,
    .contrib-graph-scroll {
        opacity: 1;
        transform: none;
        clip-path: none;
    }

    .section-header::after {
        transform: scaleX(1);
    }
}

/* ── Interactive ── */

.social-link,
.github-dashboard-link,
.theme-btn {
    transition:
        background-color var(--duration-fast) var(--ease-out),
        border-color var(--duration-fast) var(--ease-out),
        color var(--duration-fast) var(--ease-out),
        transform var(--duration-normal) var(--ease-spring),
        box-shadow var(--duration-normal) var(--ease-out);
}

.theme-btn[aria-pressed="true"] svg {
    animation: theme-btn-spin 0.55s var(--ease-spring);
}

.social-link:hover {
    color: var(--color-text);
    background: var(--color-bg-muted);
    border-color: var(--color-border-strong);
    transform: translateY(-3px) scale(1.04) rotate(-1deg);
}

.skill-tag:hover,
[data-stagger="skills"] > *:hover {
    transform: translateY(-4px) rotate(2deg) scale(1.05);
}

.github-stat:hover {
    transform: translateY(-4px) skewX(-2deg);
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    .theme-sweep {
        display: none;
    }

    html.theme-transitioning,
    html.theme-transitioning *,
    html.theme-transitioning *::before,
    html.theme-transitioning *::after {
        transition-duration: 0.01ms !important;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    [data-reveal],
    [data-stagger] > *,
    .github-dashboard,
    .github-stat,
    .contrib-graph-scroll,
    .contrib-cell {
        opacity: 1 !important;
        transform: none !important;
        clip-path: none !important;
        animation: none !important;
        pointer-events: auto !important;
    }
}
