/* ==========================================================================
   Microanimations Library  v3.1.0
   Per-trigger data attributes: data-animate-hover / data-animate-click
   Speed and intensity driven by CSS custom properties set via inline style:
     --anim-speed-hover / --anim-speed-click        e.g. 0.3s
     --anim-intensity-hover / --anim-intensity-click units vary by animation
       scale-up / scale-down / press / lift / pulse  unitless factor, e.g. 1.06
       bounce / shake                                px amount,   e.g. 8px
       glow                                          px blur,     e.g. 16px

   Easing philosophy:
     Transition animations use asymmetric curves — a distinct timing for
     entering the state and returning to rest.  Keyframe animations bake
     per-segment easing directly inside @keyframes stops so the outer
     animation-timing-function is always `linear` (the segments own it).
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1. Base – applies to any element with at least one animation slot.
   Return (mouse-off) uses ease-out-cubic so the element decelerates softly
   back to its resting position.
   --------------------------------------------------------------------------- */

[data-animate-hover],
[data-animate-click] {
    will-change: transform, box-shadow, filter;
    transition-property: transform, box-shadow, filter;
}

/* ease-out-cubic: strong deceleration — objects feel like they have weight */
[data-animate-hover] {
    transition-timing-function: cubic-bezier(0.33, 1, 0.68, 1);
    transition-duration: var(--anim-speed-hover, 0.25s);
}

[data-animate-click] {
    transition-timing-function: cubic-bezier(0.33, 1, 0.68, 1);
    transition-duration: var(--anim-speed-click, 0.2s);
}

/* ---------------------------------------------------------------------------
   2. SCALE-UP
   Enter: spring curve (slight overshoot gives it a lively pop).
   Return: ease-out-cubic from base — settles smoothly.
   --------------------------------------------------------------------------- */

[data-animate-hover='scale-up']:hover {
    transform: scale(var(--anim-intensity-hover, 1.06));
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); /* spring */
}

[data-animate-click='scale-up']:active,
[data-animate-click='scale-up'].microanim-clicking {
    transform: scale(var(--anim-intensity-click, 1.06));
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ---------------------------------------------------------------------------
   3. SCALE-DOWN / PRESS
   Enter: fast ease-in snaps the element down immediately (feels responsive).
   Return: spring bounces it back to rest with a slight overshoot.
   --------------------------------------------------------------------------- */

/* Spring return lives on the base selector */
[data-animate-hover='scale-down'],
[data-animate-hover='press'] {
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}

[data-animate-click='scale-down'],
[data-animate-click='press'] {
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Fast ease-in on enter */
[data-animate-hover='scale-down']:hover,
[data-animate-hover='press']:hover {
    transform: scale(var(--anim-intensity-hover, 0.94));
    transition-timing-function: cubic-bezier(0.4, 0, 1, 1); /* ease-in: snaps down */
}

[data-animate-click='scale-down']:active,
[data-animate-click='scale-down'].microanim-clicking,
[data-animate-click='press']:active,
[data-animate-click='press'].microanim-clicking {
    transform: scale(var(--anim-intensity-click, 0.94));
    transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}

/* ---------------------------------------------------------------------------
   4. BOUNCE
   Per-segment easing simulates gravity:
     ascending  → ease-out (momentum decelerates toward peak)
     descending → ease-in  (gravity accelerates back down)
   Amplitude decays across two micro-bounces for a natural settling effect.
   Outer timing is `linear` — easing is fully owned by the keyframe stops.
   --------------------------------------------------------------------------- */

@keyframes microanim-bounce-hover {
    0%   {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0, 0, 0.2, 1); /* ease-out: launch */
    }
    38%  {
        transform: translateY(calc(-1 * var(--anim-intensity-hover, 8px)));
        animation-timing-function: cubic-bezier(0.8, 0, 1, 1); /* ease-in: gravity */
    }
    62%  {
        transform: translateY(calc(-0.28 * var(--anim-intensity-hover, 8px)));
        animation-timing-function: cubic-bezier(0, 0, 0.2, 1); /* ease-out: mini bounce */
    }
    80%  {
        transform: translateY(calc(-0.08 * var(--anim-intensity-hover, 8px)));
        animation-timing-function: cubic-bezier(0.8, 0, 1, 1); /* ease-in: final settle */
    }
    100% { transform: translateY(0); }
}

@keyframes microanim-bounce-click {
    0%   {
        transform: translateY(0);
        animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
    }
    38%  {
        transform: translateY(calc(-1 * var(--anim-intensity-click, 8px)));
        animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
    }
    62%  {
        transform: translateY(calc(-0.28 * var(--anim-intensity-click, 8px)));
        animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
    }
    80%  {
        transform: translateY(calc(-0.08 * var(--anim-intensity-click, 8px)));
        animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
    }
    100% { transform: translateY(0); }
}

[data-animate-hover='bounce']:hover {
    animation: microanim-bounce-hover var(--anim-speed-hover, 0.55s) linear both;
}

[data-animate-click='bounce']:active,
[data-animate-click='bounce'].microanim-clicking {
    animation: microanim-bounce-click var(--anim-speed-click, 0.55s) linear both;
}

/* ---------------------------------------------------------------------------
   5. GLOW
   Enter: decelerate curve — glow floods in rapidly then gently settles.
   Return: ease-in — glow fades with a natural tail (not a hard cut).
   --------------------------------------------------------------------------- */

[data-animate-hover='glow'] { --glow-color-hover: rgba(255, 255, 255, 0.50); }
[data-animate-click='glow'] { --glow-color-click: rgba(255, 255, 255, 0.50); }

/* ease-in return: glow lingers briefly then fades */
[data-animate-hover='glow'] {
    transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}

[data-animate-click='glow'] {
    transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}

[data-animate-hover='glow']:hover {
    box-shadow: 0 0 var(--anim-intensity-hover, 16px) var(--glow-color-hover, rgba(255, 255, 255, 0.50));
    transition-timing-function: cubic-bezier(0, 0, 0.2, 1); /* decelerate: bloom */
}

[data-animate-click='glow']:active,
[data-animate-click='glow'].microanim-clicking {
    box-shadow: 0 0 var(--anim-intensity-click, 16px) var(--glow-color-click, rgba(255, 255, 255, 0.50));
    transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}

/* ---------------------------------------------------------------------------
   6. LIFT  (scale + shadow)
   Enter: spring so it pops off the surface.
   Return: ease-out-cubic — gentle landing.
   --------------------------------------------------------------------------- */

[data-animate-hover='lift']:hover {
    transform: scale(var(--anim-intensity-hover, 1.04));
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); /* spring */
}

[data-animate-click='lift']:active,
[data-animate-click='lift'].microanim-clicking {
    transform: scale(var(--anim-intensity-click, 1.04));
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ---------------------------------------------------------------------------
   7. PULSE
   Sine-in-out on both halves gives the animation a breathing / heartbeat
   quality — smooth acceleration and deceleration at every inflection point.
   --------------------------------------------------------------------------- */

@keyframes microanim-pulse-hover {
    0%   {
        transform: scale(1);
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1); /* sine-in-out */
    }
    50%  {
        transform: scale(var(--anim-intensity-hover, 1.06));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    100% { transform: scale(1); }
}

@keyframes microanim-pulse-click {
    0%   {
        transform: scale(1);
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    50%  {
        transform: scale(var(--anim-intensity-click, 1.06));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    100% { transform: scale(1); }
}

[data-animate-hover='pulse']:hover {
    animation: microanim-pulse-hover var(--anim-speed-hover, 0.6s) linear both;
}

[data-animate-click='pulse']:active,
[data-animate-click='pulse'].microanim-clicking {
    animation: microanim-pulse-click var(--anim-speed-click, 0.6s) linear both;
}

/* ---------------------------------------------------------------------------
   8. SHAKE
   Sine-in-out easing at every reversal point gives the shake a natural,
   elastic feel (the element decelerates at each extreme before snapping back).
   Amplitude decays across the oscillation to simulate a damped vibration.
   --------------------------------------------------------------------------- */

@keyframes microanim-shake-hover {
    0%   {
        transform: translateX(0);
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    20%  {
        transform: translateX(calc(-1 * var(--anim-intensity-hover, 4px)));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    40%  {
        transform: translateX(var(--anim-intensity-hover, 4px));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    60%  {
        transform: translateX(calc(-0.65 * var(--anim-intensity-hover, 4px)));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    80%  {
        transform: translateX(calc(0.35 * var(--anim-intensity-hover, 4px)));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    100% { transform: translateX(0); }
}

@keyframes microanim-shake-click {
    0%   {
        transform: translateX(0);
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    20%  {
        transform: translateX(calc(-1 * var(--anim-intensity-click, 4px)));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    40%  {
        transform: translateX(var(--anim-intensity-click, 4px));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    60%  {
        transform: translateX(calc(-0.65 * var(--anim-intensity-click, 4px)));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    80%  {
        transform: translateX(calc(0.35 * var(--anim-intensity-click, 4px)));
        animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
    }
    100% { transform: translateX(0); }
}

[data-animate-hover='shake']:hover {
    animation: microanim-shake-hover var(--anim-speed-hover, 0.45s) linear both;
}

[data-animate-click='shake']:active,
[data-animate-click='shake'].microanim-clicking {
    animation: microanim-shake-click var(--anim-speed-click, 0.45s) linear both;
}

/* ---------------------------------------------------------------------------
   9. Accessibility – honour reduced motion preference
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    [data-animate-hover],
    [data-animate-click] {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }
}
