/* ============================================================
   BuhayAhente — Phase 2.1 UI/UX Polish
   Component: Animation & Micro-interaction Utilities
   ------------------------------------------------------------
   PURPOSE
   Site-wide, additive micro-interaction layer: button feedback,
   card hover, sidebar active states, form focus/validation
   feedback, and lightweight page-fade transitions.

   This file is purely presentational. It does not add or change
   any markup requirements beyond optional utility classes
   (documented per section below) that existing elements can opt
   into without breaking anything that doesn't use them.

   Load order (every layout):
     1. Bootstrap
     2. Font Awesome
     3. design-system.css   (tokens)
     4. app.css
     5. components/animations.css   <-- this file
     6. components/toast.css
     7. components/skeleton.css
     8. components/empty-state.css
     9. page/layout-specific CSS
   ============================================================ */

/* ------------------------------------------------------------
   0. Global motion tokens (extends design-system.css tokens)
   ------------------------------------------------------------ */
:root {
    --ba-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
    --ba-ease-out:      cubic-bezier(0, 0, 0.2, 1);
    --ba-lift-sm:       -2px;
    --ba-lift-md:       -4px;
}

/* Respect user preference — kills all opt-in motion below in one place */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ------------------------------------------------------------
   1. Buttons — hover / active / focus / loading / disabled
   Applies to Bootstrap .btn everywhere (no markup change needed).
   ------------------------------------------------------------ */
.btn {
    transition: transform var(--ba-transition-fast, .15s ease),
                box-shadow var(--ba-transition-fast, .15s ease),
                background-color var(--ba-transition-fast, .15s ease),
                border-color var(--ba-transition-fast, .15s ease);
    will-change: transform;
}
.btn:not(:disabled):not(.disabled):hover {
    transform: translateY(-1px);
    box-shadow: var(--ba-shadow-sm, 0 .125rem .375rem rgba(15,27,45,.08));
}
.btn:not(:disabled):not(.disabled):active {
    transform: translateY(0) scale(0.97);
    transition-duration: .08s;
}
.btn:disabled,
.btn.disabled {
    transform: none;
    box-shadow: none;
    cursor: not-allowed;
}

/* Opt-in loading state — toggled by loading-button.js via
   BA.setButtonLoading(btn, true/false). Preserves original label
   in a data attribute so it can be restored exactly. */
.btn.ba-btn-loading {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}
.btn.ba-btn-loading::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 1rem; height: 1rem;
    margin: -0.5rem 0 0 -0.5rem;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    color: inherit;
    -webkit-text-fill-color: initial;
    animation: ba-spin 0.7s linear infinite;
}
/* currentColor trick needs a real color since text is transparent above */
.btn-primary.ba-btn-loading::after,
.btn-danger.ba-btn-loading::after,
.ba-btn-navy.ba-btn-loading::after { border-color: #fff; border-right-color: transparent; }
.btn-outline-secondary.ba-btn-loading::after,
.btn-light.ba-btn-loading::after { border-color: #555; border-right-color: transparent; }
.btn-outline-danger.ba-btn-loading::after { border-color: var(--ba-danger, #c0392b); border-right-color: transparent; }
.btn-outline-primary.ba-btn-loading::after { border-color: var(--ba-accent, #0d6efd); border-right-color: transparent; }

@keyframes ba-spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------
   2. Cards — subtle lift + shadow + border highlight on hover
   Opt-in: add `.ba-card-interactive` to any .card that should
   feel clickable/hoverable (e.g. vehicle cards, plan cards).
   Existing .card usage elsewhere is untouched.
   ------------------------------------------------------------ */
.ba-card-interactive,
.ba-card.ba-card-interactive {
    transition: transform var(--ba-transition-base, .2s ease),
                box-shadow var(--ba-transition-base, .2s ease),
                border-color var(--ba-transition-base, .2s ease);
}
.ba-card-interactive:hover {
    transform: translateY(var(--ba-lift-sm));
    box-shadow: var(--ba-shadow-md, 0 .375rem 1rem rgba(15,27,45,.1));
    border-color: rgba(225, 29, 46, 0.18);
}

/* Stat cards already exist in design-system.css (.ba-stat-card) —
   give their parent .card a matching, consistent hover lift. */
.card:has(> .ba-stat-card) {
    transition: transform var(--ba-transition-base, .2s ease),
                box-shadow var(--ba-transition-base, .2s ease);
}
.card:has(> .ba-stat-card):hover {
    transform: translateY(var(--ba-lift-sm));
    box-shadow: var(--ba-shadow-md, 0 .375rem 1rem rgba(15,27,45,.1));
}

/* ------------------------------------------------------------
   3. Sidebar — active indicator, icon transition, submenu
   ------------------------------------------------------------ */
.sidebar-link {
    position: relative;
    border-radius: var(--ba-radius-sm, .5rem);
    transition: background-color var(--ba-transition-fast, .15s ease),
                padding-left var(--ba-transition-fast, .15s ease);
    overflow: hidden;
}
.sidebar-link i {
    transition: transform var(--ba-transition-fast, .15s ease);
}
.sidebar-link:hover i {
    transform: translateX(2px) scale(1.05);
}
.sidebar-link:hover {
    background-color: rgba(255, 255, 255, 0.08);
}
/* Animated left-edge active indicator — bar grows in on activation */
.sidebar-link.active,
.sidebar-link[aria-current="page"] {
    background-color: rgba(255, 255, 255, 0.12);
    font-weight: 600;
}
.sidebar-link.active::before,
.sidebar-link[aria-current="page"]::before {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 60%;
    background: var(--ba-primary, #e11d2e);
    border-radius: 0 3px 3px 0;
    animation: ba-indicator-grow .25s var(--ba-ease-out) both;
}
@keyframes ba-indicator-grow {
    from { height: 0; opacity: 0; }
    to   { height: 60%; opacity: 1; }
}

/* Submenu expand/collapse — opt-in wrapper, used with
   `aria-expanded` toggling on the trigger (no JS dependency to
   render correctly; sidebar-nav.js just toggles the class). */
.sidebar-submenu {
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--ba-transition-base, .2s ease);
}
.sidebar-submenu.is-open {
    max-height: 600px;
}

/* ------------------------------------------------------------
   4. Forms — focus, validation, password toggle, required dot
   ------------------------------------------------------------ */
.form-control,
.form-select {
    transition: border-color var(--ba-transition-fast, .15s ease),
                box-shadow var(--ba-transition-fast, .15s ease);
}
.form-control:focus,
.form-select:focus {
    transform: translateZ(0); /* GPU layer, no visual shift */
}

/* Validation feedback fade-in (Bootstrap already toggles display;
   this just animates the appearance instead of a hard cut). */
.valid-feedback,
.invalid-feedback {
    animation: ba-fade-slide-in .18s var(--ba-ease-out) both;
}
@keyframes ba-fade-slide-in {
    from { opacity: 0; transform: translateY(-3px); }
    to   { opacity: 1; transform: translateY(0); }
}

.is-valid, .is-invalid { transition: border-color .15s ease, box-shadow .15s ease; }

/* Password visibility toggle icon — opt-in `.ba-pw-toggle` button
   placed inside an input-group next to a password field. */
.ba-pw-toggle {
    transition: color var(--ba-transition-fast, .15s ease), transform .15s ease;
}
.ba-pw-toggle:active { transform: scale(0.9); }

/* ------------------------------------------------------------
   5. Page fade transition (progressive enhancement)
   Applied unconditionally via pure CSS — the page always renders
   immediately (no opacity:0 gate, no white flash, no dependency
   on JS timing) and simply animates its own entrance. This alone
   satisfies "gracefully degrade if JS unavailable": with zero JS,
   you still get the fade-in, just not the fade-OUT-before-navigate
   flourish, which page-transitions.js adds via `.ba-page-fade-out`
   on click of an internal link (see that file for exclusions).
   ------------------------------------------------------------ */
body {
    animation: ba-page-fade-in .18s var(--ba-ease-out) both;
}
body.ba-page-fade-out {
    animation: ba-page-fade-out .11s var(--ba-ease-standard) both;
}
@keyframes ba-page-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes ba-page-fade-out {
    from { opacity: 1; }
    to   { opacity: 0.4; }
}

/* ------------------------------------------------------------
   6. Animated stat counters (counter.js targets [data-counter-to])
   ------------------------------------------------------------ */
[data-counter-to] {
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------
   7. Scroll-reveal fade-in (opt-in via [data-reveal])
   Progressive enhancement — see scroll-reveal.js. The element is
   always fully visible in the markup; only once the script
   confirms JS + IntersectionObserver support does it add
   `.ba-reveal-ready` (starting state) and later `.is-visible`
   (revealed state) on first scroll-into-view. If JS never runs,
   nothing is hidden — the content just skips the animation.
   ------------------------------------------------------------ */
[data-reveal].ba-reveal-ready {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity .5s var(--ba-ease-out, ease),
                transform .5s var(--ba-ease-out, ease);
    will-change: opacity, transform;
}
[data-reveal].ba-reveal-ready.is-visible {
    opacity: 1;
    transform: translateY(0);
}
