/* ==========================================================================
   2TELLERS — animations.css
   Keyframes, reveal states, split-text states, reduced-motion safety.
   ========================================================================== */

/* Rotating angle for the conic game-card border */
@property --angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

@keyframes borderSpin {
    to { --angle: 360deg; }
}

@keyframes grainShift {
    0%   { transform: translate(0, 0); }
    25%  { transform: translate(-40px, 24px); }
    50%  { transform: translate(28px, -32px); }
    75%  { transform: translate(-24px, -18px); }
    100% { transform: translate(0, 0); }
}

@keyframes fogDrift {
    from { transform: translate3d(-4%, 2%, 0) scale(1); }
    to   { transform: translate3d(5%, -3%, 0) scale(1.12); }
}

@keyframes raysSweep {
    from { transform: translateX(-6%); opacity: 0.7; }
    to   { transform: translateX(6%);  opacity: 1; }
}

@keyframes smokeDrift {
    from { transform: translate3d(-3%, 1%, 0) rotate(-1deg); }
    to   { transform: translate3d(3%, -2%, 0) rotate(1.5deg); }
}

@keyframes glowPulse {
    0%, 100% { opacity: 0.28; transform: translate(-50%, -50%) scale(1); }
    50%      { opacity: 0.45; transform: translate(-50%, -50%) scale(1.08); }
}

@keyframes logoBreath {
    0%, 100% { opacity: 0.92; text-shadow: 0 0 44px rgba(225, 6, 0, 0.35); }
    50%      { opacity: 1;    text-shadow: 0 0 90px rgba(225, 6, 0, 0.6); }
}

@keyframes scrollHint {
    0%   { top: -100%; }
    55%  { top: 100%; }
    100% { top: 100%; }
}

@keyframes eyesBlink {
    0%, 46%, 54%, 100% { transform: scaleY(1); opacity: 1; }
    50%                { transform: scaleY(0.1); opacity: 0.4; }
}

@keyframes dotPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(225, 6, 0, 0.5); }
    50%      { box-shadow: 0 0 0 10px rgba(225, 6, 0, 0); }
}

@keyframes redactedFlicker {
    0%, 92%, 100% { opacity: 1; }
    94%           { opacity: 0.35; }
    96%           { opacity: 0.8; }
}


/* ------------------------ Brain merge keyframes ------------------------ */
@keyframes brainDraw {
    to { stroke-dashoffset: 0; }
}

@keyframes brainFade {
    to { opacity: 0.7; }
}

@keyframes nodeBlink {
    from { opacity: 0.25; }
    to   { opacity: 1; }
}

@keyframes linkFire {
    0%   { opacity: 0; stroke-dashoffset: 48; }
    15%  { opacity: 1; }
    85%  { opacity: 1; }
    100% { opacity: 0; stroke-dashoffset: 0; }
}

/* The halves drift in, hold while synapses fire, then slam together */
@keyframes brainLeft {
    0%   { transform: translateX(-46px); opacity: 0; }
    22%  { transform: translateX(0);     opacity: 1; }
    78%  { transform: translateX(0);     opacity: 1; }
    100% { transform: translateX(52px);  opacity: 0; }
}

@keyframes brainRight {
    0%   { transform: translateX(46px);  opacity: 0; }
    22%  { transform: translateX(0);     opacity: 1; }
    78%  { transform: translateX(0);     opacity: 1; }
    100% { transform: translateX(-52px); opacity: 0; }
}

@keyframes oneAppear {
    0%   { opacity: 0; transform: scale(0.4); filter: blur(6px) brightness(3); }
    45%  { opacity: 1; transform: scale(1.18); filter: blur(0) brightness(1.8); }
    70%  { transform: scale(0.96); }
    100% { opacity: 1; transform: scale(1); filter: brightness(1); }
}

@keyframes mindPulse {
    0%, 100% { r: 14; opacity: 0.5; }
    50%      { r: 30; opacity: 0.12; }
}

@keyframes blastFlash {
    0%   { opacity: 0; }
    12%  { opacity: 1; }
    100% { opacity: 0; }
}

@keyframes shockwave {
    0%   { transform: translate(-50%, -50%) scale(0); opacity: 1; }
    100% { transform: translate(-50%, -50%) scale(11); opacity: 0; border-width: 1px; }
}

@keyframes blastKick {
    0%   { transform: scale(1); }
    18%  { transform: scale(1.14); filter: brightness(2); }
    52%  { transform: scale(0.97); }
    100% { transform: scale(1); filter: brightness(1); }
}

@keyframes cursorRipple {
    from { width: 10px;  height: 10px;  opacity: 0.9; }
    to   { width: 90px;  height: 90px;  opacity: 0; }
}

/* ----------------------- Scroll reveal base states --------------------- */
/* animations.js promotes these with GSAP; the CSS fallback below still
   works if JS fails, because is-inview is added by an IntersectionObserver
   fallback as well. */
[data-reveal] {
    opacity: 0;
    transform: translateY(46px);
    transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
    transition-delay: var(--reveal-delay, 0s);
    will-change: opacity, transform;
}

[data-reveal].is-inview {
    opacity: 1;
    transform: translateY(0);
}

/* SplitType output — lines are masked and slide up */
.split-line {
    display: block;
    overflow: hidden;
}

.split-line .line-inner {
    display: block;
    transform: translateY(110%);
}

/* Split chars (kicker/eyebrows) */
[data-split] .char {
    display: inline-block;
    opacity: 0;
    transform: translateY(0.6em) rotate(4deg);
}

/* Fallback: if JS never runs, nothing should stay invisible */
html.no-js [data-reveal],
html.no-js .split-line .line-inner,
html.no-js [data-split] .char {
    opacity: 1 !important;
    transform: none !important;
}

/* ---------------------------- Reduced motion --------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    [data-reveal],
    [data-split] .char,
    .split-line .line-inner {
        opacity: 1 !important;
        transform: none !important;
    }

    .grain, .hero__rays, .hero__eyes, .cursor__glow,
    .brains__flash, .brains__shock { display: none; }

    .brains__half, .brains__outline, .brains__gyri, .brains__one {
        animation: none !important;
        opacity: 1 !important;
        stroke-dashoffset: 0 !important;
    }
    .brains__half--left, .brains__half--right { opacity: 0 !important; }
}
