/* ===========================================================================
   NMA Motion System
   Centralized animation layer for the Academy ERP (Bootstrap 4 + vanilla JS).

   Philosophy: hierarchy, feedback, focus, continuity, responsiveness.
   Calm and confident — short durations, small offsets, no bounce.
   Animate only transform/opacity. See public/assets/js/motion/ for the JS
   half (entrance staggering, page transitions, count-up, etc).
   =========================================================================== */

:root {
    /* Timing (ms) — reconciled against "The Art of Beautiful Website
       Animations" reference table (hover 150-250, press 80-150, card
       180-250, dropdown 200-300, modal 250-350, page 300-500,
       hero 500-700, scroll reveal 250-450). Values below are the
       midpoints of each documented range. */
    --nma-t-hover: 200ms;
    --nma-t-press: 120ms;
    --nma-t-card: 220ms;
    --nma-t-page: 380ms;
    --nma-t-modal: 300ms;
    --nma-t-drawer: 350ms;
    --nma-t-toast: 220ms;
    --nma-t-tooltip: 150ms;
    --nma-t-dropdown: 250ms;
    --nma-t-hero: 600ms;
    --nma-t-scroll-reveal: 350ms;

    /* Easing — calm deceleration for entrances, quick ease for exits */
    --nma-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --nma-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
    --nma-ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1);

    /* Entrance offsets */
    --nma-rise: 10px;
    --nma-rise-sm: 6px;
}

/* ---------------------------------------------------------------------------
   prefers-reduced-motion — global kill switch
   --------------------------------------------------------------------------- */
@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;
    }
}
/* JS also sets this class on <html> when the media query matches, so
   animation code can branch (e.g. skip count-up tweening, jump to end state). */
html.nma-reduced-motion .nma-anim-init { opacity: 1 !important; transform: none !important; }

/* ---------------------------------------------------------------------------
   Entrance utility: elements start hidden/offset, JS (IntersectionObserver)
   flips them to .nma-anim-in when they should appear. Falls back to visible
   if JS never runs (no-JS / error safety).
   --------------------------------------------------------------------------- */
.nma-anim-init {
    opacity: 0;
    transform: translateY(var(--nma-rise));
    transition: opacity var(--nma-t-scroll-reveal) var(--nma-ease-out),
                transform var(--nma-t-scroll-reveal) var(--nma-ease-out);
    transition-delay: calc(var(--nma-stagger-i, 0) * 60ms);
}
.nma-anim-init.nma-anim-in {
    opacity: 1;
    transform: none;
}
/* small-rise variant for table rows / list items */
.nma-anim-init--sm { transform: translateY(var(--nma-rise-sm)); }

/* ---------------------------------------------------------------------------
   Page content fade/rise (page-transition.js toggles these on .content)
   --------------------------------------------------------------------------- */
.content {
    opacity: 1;
    transform: none;
    transition: opacity var(--nma-t-page) var(--nma-ease-out),
                transform var(--nma-t-page) var(--nma-ease-out);
}
.nma-page-leaving .content {
    opacity: 0;
    transform: translateY(calc(var(--nma-rise-sm) * -1));
    transition-duration: 160ms;
    transition-timing-function: var(--nma-ease-in-out);
}
.nma-page-entering .content {
    opacity: 0;
    transform: translateY(var(--nma-rise));
}

/* ---------------------------------------------------------------------------
   Cards
   --------------------------------------------------------------------------- */
.card {
    transition: transform var(--nma-t-hover) var(--nma-ease-standard),
                box-shadow var(--nma-t-hover) var(--nma-ease-standard);
}
.card.nma-card-hoverable:hover,
a.card:hover,
.nma-hover-lift:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgba(15, 23, 42, 0.08);
}

/* ---------------------------------------------------------------------------
   Buttons — hover elevation, press scale, loading/success states
   --------------------------------------------------------------------------- */
.btn {
    transition: transform var(--nma-t-hover) var(--nma-ease-standard),
                box-shadow var(--nma-t-hover) var(--nma-ease-standard),
                filter var(--nma-t-hover) var(--nma-ease-standard);
}
.btn:not(.disabled):not(:disabled):hover {
    transform: translateY(-1px) scale(1.02);
    box-shadow: 0 6px 14px rgba(15, 23, 42, 0.12);
}
.btn:not(.disabled):not(:disabled):active {
    transform: scale(0.98);
    transition-duration: var(--nma-t-press);
    box-shadow: 0 2px 6px rgba(15, 23, 42, 0.1);
}
.btn.nma-btn-loading {
    pointer-events: none;
    position: relative;
    color: transparent !important;
}
.btn.nma-btn-loading .nma-btn-spinner {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    animation: nma-fade-in var(--nma-t-hover) var(--nma-ease-out) forwards;
}
.btn.nma-btn-loading .nma-btn-spinner::after {
    content: '';
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-right-color: transparent;
    color: rgba(255, 255, 255, 0.85);
    animation: nma-spin 0.6s linear infinite;
}
.btn-light.nma-btn-loading .nma-btn-spinner::after,
.btn-outline-secondary.nma-btn-loading .nma-btn-spinner::after {
    color: rgba(15, 23, 42, 0.65);
}
@keyframes nma-spin { to { transform: rotate(360deg); } }

.btn.nma-btn-success .nma-btn-check {
    display: inline-flex;
    animation: nma-pop-in 260ms var(--nma-ease-out);
}
@keyframes nma-pop-in {
    0% { opacity: 0; transform: scale(0.6); }
    60% { opacity: 1; transform: scale(1.08); }
    100% { opacity: 1; transform: scale(1); }
}

/* ---------------------------------------------------------------------------
   Forms — focus, validation shake, message fade, floating labels
   --------------------------------------------------------------------------- */
.form-control,
.custom-select,
.select2-selection {
    transition: border-color var(--nma-t-hover) var(--nma-ease-standard),
                box-shadow var(--nma-t-hover) var(--nma-ease-standard);
}
.form-control:focus,
.custom-select:focus,
.select2-container--focus .select2-selection {
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14);
}

.nma-shake {
    animation: nma-shake 360ms var(--nma-ease-in-out);
}
@keyframes nma-shake {
    10%, 90% { transform: translateX(-1px); }
    20%, 80% { transform: translateX(2px); }
    30%, 50%, 70% { transform: translateX(-4px); }
    40%, 60% { transform: translateX(4px); }
}

.invalid-feedback,
.help-block,
.form-text {
    transition: opacity 180ms var(--nma-ease-out);
}
.invalid-feedback.nma-anim-init,
.help-block.nma-anim-init {
    transform: none;
}

.nma-float-label {
    position: relative;
}
.nma-float-label label {
    position: absolute;
    left: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    transition: transform 160ms var(--nma-ease-standard), font-size 160ms var(--nma-ease-standard), color 160ms var(--nma-ease-standard);
    pointer-events: none;
    color: #94a3b8;
}
.nma-float-label input:focus ~ label,
.nma-float-label input:not(:placeholder-shown) ~ label {
    transform: translateY(-1.35rem) translateX(-0.1rem);
    font-size: 0.75rem;
    color: #2563eb;
}

/* Dropdowns intentionally show/hide instantly via Bootstrap's own .show class,
   no fade/scale transition — removed after it could leave the menu stuck at
   opacity:0 (looked "transparent") if the enter-class removal timing misfired. */

/* ---------------------------------------------------------------------------
   Modals — Bootstrap 4 already transitions .modal-dialog transform; we retune
   the timing/scale to spec and add an optional backdrop blur.
   --------------------------------------------------------------------------- */
.modal.fade .modal-dialog {
    transition: transform var(--nma-t-modal) var(--nma-ease-out),
                opacity var(--nma-t-modal) var(--nma-ease-out);
    transform: scale(0.96) translateY(8px);
    opacity: 0;
}
.modal.show .modal-dialog {
    transform: scale(1) translateY(0);
    opacity: 1;
}
.modal-backdrop {
    transition: opacity var(--nma-t-modal) var(--nma-ease-standard);
}
@supports (backdrop-filter: blur(2px)) {
    .modal-backdrop.show {
        backdrop-filter: blur(2px);
    }
}

/* Slide-in drawers/offcanvas panels (opt-in via .nma-drawer) */
.nma-drawer {
    transition: transform var(--nma-t-drawer) var(--nma-ease-out);
    transform: translateX(100%);
}
.nma-drawer.show { transform: translateX(0); }

/* ---------------------------------------------------------------------------
   Tooltips / popovers
   --------------------------------------------------------------------------- */
.tooltip {
    transition: opacity var(--nma-t-tooltip) var(--nma-ease-out);
}
.tooltip.show { opacity: 1; }
.bs-tooltip-top .arrow, .tooltip.bs-tooltip-auto[x-placement^="top"] {
    animation: nma-tooltip-rise var(--nma-t-tooltip) var(--nma-ease-out);
}
@keyframes nma-tooltip-rise {
    from { transform: translateY(4px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

/* ---------------------------------------------------------------------------
   Accordions (Bootstrap 4 collapse) — animate height smoothly instead of the
   default instant class toggle; collapse.js core already animates height via
   jQuery slideDown/slideUp with .collapsing, we just calm/retime it and fade
   content in after the height settles.
   --------------------------------------------------------------------------- */
.collapsing {
    transition: height 240ms var(--nma-ease-standard) !important;
}
.collapse.show > .card-body,
.collapse.show .nma-accordion-body {
    animation: nma-fade-in 200ms var(--nma-ease-out) 60ms both;
}

/* ---------------------------------------------------------------------------
   Tabs — sliding active indicator + content cross-fade
   --------------------------------------------------------------------------- */
.nav-tabs {
    position: relative;
}
.nma-tab-indicator {
    position: absolute;
    bottom: -1px;
    height: 2px;
    background: currentColor;
    color: #2563eb;
    transition: transform var(--nma-t-dropdown) var(--nma-ease-standard),
                width var(--nma-t-dropdown) var(--nma-ease-standard);
    pointer-events: none;
}
.tab-pane {
    transition: opacity 180ms var(--nma-ease-out);
}
.tab-pane:not(.active) { opacity: 0; }
.tab-pane.active.nma-tab-fade { opacity: 1; }

/* ---------------------------------------------------------------------------
   Toasts / notifications (pnotify + custom toast wrapper)
   --------------------------------------------------------------------------- */
.nma-toast {
    transform: translate(12px, -8px);
    opacity: 0;
    transition: transform var(--nma-t-toast) var(--nma-ease-out),
                opacity var(--nma-t-toast) var(--nma-ease-out);
}
.nma-toast.nma-toast-in { transform: translate(0, 0); opacity: 1; }
.nma-toast.nma-toast-out {
    transform: translateY(-6px);
    opacity: 0;
    transition-duration: 160ms;
}

.nma-badge-pulse {
    animation: nma-badge-pulse 900ms var(--nma-ease-out) 1;
}
@keyframes nma-badge-pulse {
    0% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.45); }
    70% { box-shadow: 0 0 0 8px rgba(220, 38, 38, 0); }
    100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }
}

/* ---------------------------------------------------------------------------
   Sidebar
   --------------------------------------------------------------------------- */
.nma-nav-sidebar .nav-link {
    position: relative;
    transition: color var(--nma-t-hover) var(--nma-ease-standard),
                background-color var(--nma-t-hover) var(--nma-ease-standard);
}
.nma-nav-sidebar .nav-link i,
.nma-nav-sidebar .nav-link span {
    transition: opacity var(--nma-t-hover) var(--nma-ease-standard);
}
.sidebar-xs .nma-nav-sidebar .nav-link span,
.sidebar-collapsed .nma-nav-sidebar .nav-link span {
    opacity: 0;
}
.nma-nav-sidebar .nav-item > a[data-toggle="collapse"] .caret,
.nma-nav-sidebar .nav-item > a[aria-expanded] i.caret {
    transition: transform var(--nma-t-dropdown) var(--nma-ease-standard);
}
.nma-nav-sidebar .nav-item > a[aria-expanded="true"] .caret {
    transform: rotate(90deg);
}

/* Active-item glide indicator (a thin bar that moves to the active link) */
.nma-nav-sidebar {
    position: relative;
}
.nma-nav-glide {
    position: absolute;
    left: 0;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: #2563eb;
    opacity: 0;
    transition: transform var(--nma-t-page) var(--nma-ease-out),
                height var(--nma-t-page) var(--nma-ease-out),
                opacity var(--nma-t-hover) linear;
    pointer-events: none;
}
.nma-nav-glide.nma-nav-glide-visible { opacity: 1; }

.sidebar-main {
    transition: width var(--nma-t-drawer) var(--nma-ease-out),
                margin-left var(--nma-t-drawer) var(--nma-ease-out);
}

/* ---------------------------------------------------------------------------
   Tables
   --------------------------------------------------------------------------- */
.table tbody tr {
    transition: background-color var(--nma-t-hover) var(--nma-ease-standard);
}
.table.nma-table-animated tbody tr {
    opacity: 0;
    transform: translateY(var(--nma-rise-sm));
    animation: nma-row-in 220ms var(--nma-ease-out) forwards;
    animation-delay: calc(var(--nma-row-i, 0) * 28ms);
}
@keyframes nma-row-in {
    /* transform: none (not translateY(0)) — any non-"none" transform value,
       even a zero-offset one, creates a new stacking context. With
       animation-fill-mode: forwards that would trap this row's action
       dropdown inside the row forever, so later rows paint over an open
       menu. translateY(0) and none look identical; only one is safe here. */
    to { opacity: 1; transform: none; }
}
.nma-table-fading { transition: opacity 140ms var(--nma-ease-standard); opacity: 0.35; }

/* ---------------------------------------------------------------------------
   Skeleton loading (shimmer) — never leave blank white areas
   --------------------------------------------------------------------------- */
.nma-skeleton {
    position: relative;
    overflow: hidden;
    background: #eef1f5;
    border-radius: 6px;
}
.nma-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.65), transparent);
    animation: nma-shimmer 1.3s ease-in-out infinite;
}
@keyframes nma-shimmer {
    100% { transform: translateX(100%); }
}

/* ---------------------------------------------------------------------------
   Search / filter result transitions
   --------------------------------------------------------------------------- */
.nma-filter-hidden {
    opacity: 0;
    transform: scale(0.98);
    pointer-events: none;
    position: absolute;
}
.nma-filter-item {
    transition: opacity 200ms var(--nma-ease-standard), transform 200ms var(--nma-ease-standard);
}

/* ---------------------------------------------------------------------------
   Gallery / lightbox
   --------------------------------------------------------------------------- */
.nma-gallery-thumb {
    overflow: hidden;
}
.nma-gallery-thumb img {
    transition: transform var(--nma-t-hover) var(--nma-ease-standard);
}
.nma-gallery-thumb:hover img {
    transform: scale(1.04);
}
.nma-gallery-thumb:hover {
    box-shadow: 0 8px 18px rgba(15, 23, 42, 0.14);
}
.nma-lightbox-backdrop {
    opacity: 0;
    transition: opacity var(--nma-t-modal) var(--nma-ease-standard);
}
.nma-lightbox-backdrop.show { opacity: 1; }
.nma-lightbox-img {
    opacity: 0;
    transform: scale(0.95);
    transition: opacity var(--nma-t-modal) var(--nma-ease-out),
                transform var(--nma-t-modal) var(--nma-ease-out);
}
.nma-lightbox-backdrop.show .nma-lightbox-img {
    opacity: 1;
    transform: scale(1);
}

/* ---------------------------------------------------------------------------
   Shared keyframes
   --------------------------------------------------------------------------- */
@keyframes nma-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes nma-fade-rise-in {
    from { opacity: 0; transform: translateY(var(--nma-rise)); }
    to { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   Login screen
   --------------------------------------------------------------------------- */
.nma-login-logo { animation: nma-fade-in 400ms var(--nma-ease-out) both; }
.nma-login-form { animation: nma-fade-rise-in 420ms var(--nma-ease-out) 80ms both; }
.nma-login-bg {
    background-size: 140% 140%;
    animation: nma-bg-drift 22s ease-in-out infinite alternate;
}
@keyframes nma-bg-drift {
    from { background-position: 0% 50%; }
    to { background-position: 100% 50%; }
}
