/* ============================================================================
 * MOTION — scroll reveals + hover/entrance utilities.
 *
 * Pairs with the `v-reveal` directive (directives/reveal.ts). The directive
 * adds `.bgl-reveal` (hidden + pre-transformed) and toggles `.bgl-reveal-in`
 * when the element scrolls into view. Direction comes from [data-reveal-dir],
 * stagger from --bgl-reveal-delay. Everything is opt-in and respects
 * prefers-reduced-motion.
 * ========================================================================== */

:root {
    --bgl-reveal-distance: 24px;
    --bgl-reveal-duration: 0.6s;
    --bgl-reveal-ease: cubic-bezier(0.16, 1, 0.3, 1);
    /* gentle "out-expo" */
}

/* Hidden initial state — set by v-reveal on mount. We animate the entrance with
 * a keyframe (not a `transition`) so it can't be clobbered when the element ALSO
 * carries a `transition`-based utility like `.hover-lift` (both would otherwise
 * declare `transition` and the later one wins, silently dropping the opacity
 * fade — which looked "abrupt"). Keyframes are independent of `transition`. */
.bgl-reveal {
    opacity: 0;
    /* per-direction starting offset, consumed by the keyframes via custom prop */
    --bgl-reveal-x: 0px;
    --bgl-reveal-y: var(--bgl-reveal-distance);
    transform: translate3d(var(--bgl-reveal-x), var(--bgl-reveal-y), 0);
    will-change: opacity, transform;
}

.bgl-reveal[data-reveal-dir="down"] {
    --bgl-reveal-y: calc(-1 * var(--bgl-reveal-distance));
}

.bgl-reveal[data-reveal-dir="left"] {
    --bgl-reveal-x: var(--bgl-reveal-distance);
    --bgl-reveal-y: 0px;
}

.bgl-reveal[data-reveal-dir="right"] {
    --bgl-reveal-x: calc(-1 * var(--bgl-reveal-distance));
    --bgl-reveal-y: 0px;
}

/* Revealed: run a fade+move keyframe, then settle at the resting state (the
   declared opacity/transform below) so a `transition` utility like .hover-lift
   can still drive :hover transforms afterwards. NOTE: no `both`/`forwards`
   fill-mode on purpose — a persisted fill would lock `transform` and defeat
   hover-lift. `backwards` only holds the FROM frame during the start delay. */
.bgl-reveal-in {
    opacity: 1;
    transform: none;
    animation: bgl-reveal-enter var(--bgl-reveal-duration) var(--bgl-reveal-ease) var(--bgl-reveal-delay, 0ms) backwards;
}

@keyframes bgl-reveal-enter {
    from {
        opacity: 0;
        transform: translate3d(var(--bgl-reveal-x), var(--bgl-reveal-y), 0);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* ---- Hover lift: standardize the "card floats up on hover" pattern. -------- */
.hover-lift {
    transition: transform 0.4s var(--bgl-reveal-ease), box-shadow 0.2s var(--bgl-reveal-ease), filter 0.2s var(--bgl-reveal-ease);
}

.hover-lift:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 28px -8px var(--bgl-shadow);
}

.hover-lift:active {
    transform: translateY(-2px);
    filter: var(--bgl-hover-filter);
}

/* Hover grow — for thumbnails/media inside an overflow-hidden frame. */
.hover-grow {
    transition: transform 0.4s var(--bgl-reveal-ease);
    filter: var(--bgl-hover-filter);
}

.hover-grow:hover {
    transform: scale(1.04);
}

.hover-grow:active {
    transform: scale(1.02);
    filter: var(--bgl-hover-filter);
}

/* ---- One-shot entrance animations (no scroll trigger needed). ------------- */
@keyframes bgl-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes bgl-rise-in {
    from {
        opacity: 0;
        transform: translateY(var(--bgl-reveal-distance));
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes bgl-pop-in {
    0% {
        opacity: 0;
        transform: scale(0.92);
    }

    100% {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes bgl-float {

    0%,
    100% {
        transform: translateY(0);
    }

    50% {
        transform: translateY(-8px);
    }
}

.animate-fade-in {
    animation: bgl-fade-in var(--bgl-reveal-duration) var(--bgl-reveal-ease) both;
}

.animate-rise-in {
    animation: bgl-rise-in var(--bgl-reveal-duration) var(--bgl-reveal-ease) both;
}

.animate-pop-in {
    animation: bgl-pop-in 0.4s var(--bgl-reveal-ease) both;
}

.animate-float {
    animation: bgl-float 4s ease-in-out infinite;
}

/* Respect user motion preferences — kill all of the above. */
@media (prefers-reduced-motion: reduce) {

    .bgl-reveal,
    .bgl-reveal-in,
    .bgl-reveal[data-reveal-dir],
    .hover-lift,
    .hover-grow,
    .animate-fade-in,
    .animate-rise-in,
    .animate-pop-in,
    .animate-float {
        opacity: 1 !important;
        transform: none !important;
        animation: none !important;
        transition: none !important;
    }
}