/*
  animations.css - Micro-animation layer for CHMSU Pulse
  ─────────────────────────────────────────────────────
  Rules:
  • Durations: 150ms–300ms  |  Easing: ease-out / cubic-bezier only
  • CSS transitions + @keyframes only — no external libraries
  • No looping animations on static/non-interactive elements
  • Zero layout, color, or functionality changes — motion only
  • Everything inside @media (prefers-reduced-motion: reduce) is
    stripped to instant / no-op so the master kill-switch below works.

  Import order: load AFTER base.css, admin.css / student.css.
*/

/* ══════════════════════════════════════════════════════════════
   0. REDUCED-MOTION KILL-SWITCH
   Disables every transition and animation in this file for users
   who have enabled "Reduce motion" in their OS accessibility settings.
   ══════════════════════════════════════════════════════════════ */
@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;
  }

  /* Ensure scroll-triggered elements that start hidden become visible */
  .animate-in,
  .animate-slide-left,
  .animate-slide-right,
  .animate-scale {
    opacity:   1 !important;
    transform: none !important;
  }
}


/* ══════════════════════════════════════════════════════════════
   1. BUTTON MICRO-INTERACTIONS
   • Hover  → lift (-2px) + shadow bloom  (already in base.css;
     we layer a scale(1.02) on top so it's consistent everywhere)
   • Active → scale down (0.95) for tactile press feedback
   ══════════════════════════════════════════════════════════════ */

/* Generic lift on hover for every .btn variant */
.btn {
  transition:
    background      var(--duration-fast) var(--ease-out),
    border-color    var(--duration-fast) var(--ease-out),
    box-shadow      var(--duration-base) var(--ease-out),
    color           var(--duration-fast) var(--ease-out),
    transform       var(--duration-fast) var(--ease-out),
    opacity         var(--duration-fast) var(--ease-out);
  will-change: transform;
}

.btn:hover:not(:disabled) {
  transform: translateY(-2px) scale(1.02);
}

/* Press feedback — scale down a touch */
.btn:active:not(:disabled) {
  transform: translateY(0) scale(0.95);
  transition-duration: 100ms;
}

/* Disabled state: no transform */
.btn:disabled {
  transform: none !important;
  cursor: not-allowed;
  opacity: 0.55;
}

/* Land-page button variants get the same treatment */
.land-btn-primary,
.land-btn-ghost,
.land-btn-outline,
.land-btn-ghost-light,
.btn-white,
.btn-banner {
  transition:
    background   150ms var(--ease-out),
    border-color 150ms var(--ease-out),
    box-shadow   200ms var(--ease-out),
    color        150ms var(--ease-out),
    transform    150ms var(--ease-out);
  will-change: transform;
}

.land-btn-primary:hover,
.land-btn-ghost:hover,
.land-btn-outline:hover,
.land-btn-ghost-light:hover,
.btn-white:hover,
.btn-banner:hover {
  transform: translateY(-2px) scale(1.02);
}

.land-btn-primary:active,
.land-btn-ghost:active,
.land-btn-outline:active,
.land-btn-ghost-light:active,
.btn-white:active,
.btn-banner:active {
  transform: translateY(0) scale(0.95);
  transition-duration: 100ms;
}


/* ══════════════════════════════════════════════════════════════
   2. NAV LINK SLIDING UNDERLINE
   The student portal and landing page already have ::after
   underlines — we just tighten the easing here so it's consistent.
   Admin sidebar links get a left-edge indicator slide.
   ══════════════════════════════════════════════════════════════ */

/* Student top-nav & landing nav — sliding bottom underline */
.student-nav-links a::after,
.land-nav-links a::after {
  transition:
    width  220ms cubic-bezier(0.16, 1, 0.3, 1),
    left   220ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity 150ms ease-out;
}

/* Admin sidebar — icon + text nudge on hover */
.sidebar-link {
  transition:
    background  var(--duration-fast) var(--ease-out),
    color       var(--duration-fast) var(--ease-out),
    padding-left var(--duration-base) cubic-bezier(0.16, 1, 0.3, 1);
}

.sidebar-link:hover {
  padding-left: calc(0.75rem + 3px);
}

.sidebar-link.active {
  padding-left: 0.75rem; /* active links don't nudge */
}

/* Active indicator bar slide-in */
.sidebar-link.active::before {
  transition:
    height    200ms cubic-bezier(0.34, 1.56, 0.64, 1),
    opacity   150ms ease-out;
}


/* ══════════════════════════════════════════════════════════════
   3. FORM INPUT FOCUS GLOW
   A soft green glow grows from nothing on focus — replaces the
   hard outline with a breathing ring.
   ══════════════════════════════════════════════════════════════ */

.form-group input,
.form-group select,
.form-group textarea {
  transition:
    border-color  200ms var(--ease-out),
    box-shadow    200ms var(--ease-out),
    background    200ms var(--ease-out),
    transform     150ms var(--ease-out);
}

/* Slight inset scale on focus — feels tactile */
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  border-color: var(--brand);
  background:   var(--brand-light);
  box-shadow:
    0 0 0 0px   rgba(22, 163, 74, 0),       /* start collapsed */
    0 0 0 4px   rgba(22, 163, 74, 0.12);    /* expand to glow ring */
  transform: scaleY(1.005);                 /* micro-height bump */
}

/* Inline data-table selects (status dropdowns) */
.data-table select:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.12);
  outline: none;
  transition: border-color 150ms ease-out, box-shadow 150ms ease-out;
}


/* ══════════════════════════════════════════════════════════════
   4. CARD LIFT ON HOVER
   Cards rise 3-4 px with a deeper shadow — communicates
   interactivity without layout shift.
   ══════════════════════════════════════════════════════════════ */

.card {
  transition:
    box-shadow var(--duration-base) var(--ease-out),
    transform  var(--duration-base) var(--ease-out);
  will-change: transform;
}

.card:hover {
  box-shadow: var(--sh3);
  transform:  translateY(-3px);
}

/* Stat cards */
.stat-card,
.student-stat {
  transition:
    box-shadow    200ms cubic-bezier(0.16, 1, 0.3, 1),
    transform     200ms cubic-bezier(0.16, 1, 0.3, 1),
    border-color  200ms ease-out;
  will-change: transform;
}

.stat-card:hover,
.student-stat:hover {
  transform:  translateY(-3px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10);
}

/* Office cards */
.office-card {
  transition:
    box-shadow var(--duration-base) var(--ease-out),
    transform  var(--duration-base) var(--ease-out);
  will-change: transform;
}

.office-card:hover {
  box-shadow: var(--sh3);
  transform:  translateY(-3px);
}

/* Report cards — lateral slide accent already exists; add depth */
.report-card {
  transition:
    box-shadow  200ms var(--ease-out),
    transform   200ms var(--ease-out),
    border-color 200ms ease-out;
  will-change: transform;
}

.report-card:hover {
  box-shadow: var(--sh2);
  transform:  translateX(3px) translateY(-1px);
}

/* Action cards (quick-actions grid) */
.action-card {
  transition:
    box-shadow   200ms var(--ease-out),
    transform    200ms var(--ease-out),
    border-color 200ms ease-out;
  will-change: transform;
}

.action-card:hover {
  box-shadow: var(--sh3);
  transform:  translateY(-3px);
}

/* Section cards — subtle shadow deepen only */
.section-card {
  transition: box-shadow 200ms var(--ease-out);
}

.section-card:hover {
  box-shadow: var(--sh2);
}

/* Office list items */
.office-item {
  transition: background var(--duration-fast) var(--ease-out);
}

/* Table rows */
.data-table tbody tr {
  transition: background var(--duration-fast) var(--ease-out);
}


/* ══════════════════════════════════════════════════════════════
   5. MODAL OPEN / CLOSE
   The confirm modal in base.css uses confirm-pop-in @keyframes.
   We extend it: overlay fades in, modal scales up; on close the
   .modal-closing class triggers the out animation.
   ══════════════════════════════════════════════════════════════ */

/* Overlay backdrop fade */
.confirm-modal-overlay {
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
  /* display toggled by JS — open class drives opacity */
}

.confirm-modal-overlay.open {
  opacity: 1;
}

/* Modal panel — richer spring entrance */
.confirm-modal {
  animation: modal-scale-in 260ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
  transform-origin: center bottom;
}

@keyframes modal-scale-in {
  from {
    opacity:   0;
    transform: scale(0.85) translateY(16px);
  }
  to {
    opacity:   1;
    transform: scale(1) translateY(0);
  }
}

/* Close / exit — JS adds .modal-closing to the overlay */
.confirm-modal-overlay.modal-closing {
  opacity: 0;
  transition: opacity 180ms var(--ease-out);
}

.confirm-modal-overlay.modal-closing .confirm-modal {
  animation: modal-scale-out 180ms var(--ease-out) both;
}

@keyframes modal-scale-out {
  from {
    opacity:   1;
    transform: scale(1) translateY(0);
  }
  to {
    opacity:   0;
    transform: scale(0.9) translateY(8px);
  }
}

/* Lightbox — already has transitions; strengthen consistency */
.lightbox-overlay {
  transition: opacity 220ms var(--ease-out);
}

.lightbox-img {
  transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
}

.lightbox-overlay.lb-open .lightbox-img {
  animation: lightbox-img-in 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes lightbox-img-in {
  from {
    opacity:   0;
    transform: scale(0.88);
  }
  to {
    opacity:   1;
    transform: scale(1);
  }
}


/* ══════════════════════════════════════════════════════════════
   6. PAGE / SECTION FADE-IN ON LOAD
   Main content areas fade up once — not a loop.
   ══════════════════════════════════════════════════════════════ */

/* Admin main content area */
.main-content {
  animation: page-fade-up 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes page-fade-up {
  from {
    opacity:   0;
    transform: translateY(10px);
  }
  to {
    opacity:   1;
    transform: translateY(0);
  }
}

/* Student body */
.student-body {
  animation: page-fade-up 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Auth form panel — already has slide-in; keep it consistent */
.auth-form-panel {
  animation: auth-form-slide-in 300ms cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
}

/* Page-header title stagger */
.page-header h2 {
  animation: page-fade-up 280ms cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
}

.page-header p {
  animation: page-fade-up 280ms cubic-bezier(0.16, 1, 0.3, 1) 0.10s both;
}


/* ══════════════════════════════════════════════════════════════
   7. ERROR FIELD SHAKE
   Applied by JS when a field contains a validation error.
   A fast horizontal shake draws attention without looping.
   ══════════════════════════════════════════════════════════════ */

@keyframes field-shake {
  0%   { transform: translateX(0); }
  15%  { transform: translateX(-6px); }
  30%  { transform: translateX(5px); }
  45%  { transform: translateX(-4px); }
  60%  { transform: translateX(3px); }
  75%  { transform: translateX(-2px); }
  90%  { transform: translateX(1px); }
  100% { transform: translateX(0); }
}

/* The .field-error class is added/removed by JS */
.field-error {
  animation: field-shake 320ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

/* Red glow ring on error inputs */
.form-group input.input-error,
.form-group select.input-error,
.form-group textarea.input-error {
  border-color: #ef4444 !important;
  box-shadow:   0 0 0 4px rgba(239, 68, 68, 0.12) !important;
  transition:   border-color 150ms ease-out, box-shadow 150ms ease-out !important;
}

/* Alert banners — shake on appear */
.alert-error {
  animation: field-shake 320ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}


/* ══════════════════════════════════════════════════════════════
   8. SUCCESS STATE BOUNCE / COLOR FLASH
   Applied by JS after a successful action.
   A single-shot scale pop signals positive feedback.
   ══════════════════════════════════════════════════════════════ */

@keyframes success-bounce {
  0%   { transform: scale(1); }
  30%  { transform: scale(1.06); }
  55%  { transform: scale(0.97); }
  75%  { transform: scale(1.02); }
  100% { transform: scale(1); }
}

@keyframes success-flash {
  0%   { box-shadow: 0 0 0 0   rgba(22, 163, 74, 0);    }
  30%  { box-shadow: 0 0 0 6px rgba(22, 163, 74, 0.25); }
  100% { box-shadow: 0 0 0 0   rgba(22, 163, 74, 0);    }
}

/* JS adds .success-pop to the element after a successful save/submit */
.success-pop {
  animation:
    success-bounce 350ms cubic-bezier(0.34, 1.56, 0.64, 1) both,
    success-flash  350ms ease-out both;
}

/* Alert success banners get the pop-in treatment */
.alert-success {
  animation: success-bounce 300ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}


/* ══════════════════════════════════════════════════════════════
   9. TOAST NOTIFICATION SLIDE-IN / SLIDE-OUT
   Toasts already exist; add the enter/exit animations.
   ══════════════════════════════════════════════════════════════ */

.toast {
  animation: toast-slide-in 260ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes toast-slide-in {
  from {
    opacity:   0;
    transform: translateX(100%) scale(0.92);
  }
  to {
    opacity:   1;
    transform: translateX(0) scale(1);
  }
}

.toast.toast-exit {
  animation: toast-slide-out 260ms var(--ease-out) both;
}

@keyframes toast-slide-out {
  from {
    opacity:   1;
    transform: translateX(0) scale(1);
  }
  to {
    opacity:   0;
    transform: translateX(30px) scale(0.9);
  }
}


/* ══════════════════════════════════════════════════════════════
   10. BADGE & NOTIFICATION COUNT PULSE
   A single-shot scale-pop when a badge number changes.
   ══════════════════════════════════════════════════════════════ */

/* Notification count badges in nav */
.student-nav-links a span[style*="background:#dc2626"],
.nav-drawer-links a span[style*="background:#dc2626"] {
  transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
  display: inline-flex;
  will-change: transform;
}

/* Admin badge in sidebar */
.admin-badge {
  transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
  will-change: transform;
}


/* ══════════════════════════════════════════════════════════════
   11. AVATAR UPLOAD PREVIEW / FILE UPLOAD ZONE
   ══════════════════════════════════════════════════════════════ */

.file-upload-box,
.photo-upload-zone {
  transition:
    border-color 150ms var(--ease-out),
    background   150ms var(--ease-out),
    transform    150ms var(--ease-out);
}

.file-upload-box:hover,
.photo-upload-zone:hover {
  transform: scale(1.005);
}

/* Image preview pop-in */
.photo-preview-wrap img,
#edit-preview-img,
#office-photo-preview-img {
  animation: img-pop-in 280ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes img-pop-in {
  from {
    opacity:   0;
    transform: scale(0.85);
  }
  to {
    opacity:   1;
    transform: scale(1);
  }
}


/* ══════════════════════════════════════════════════════════════
   12. BACK-TO-TOP BUTTON
   Smooth appearance / disappearance.
   ══════════════════════════════════════════════════════════════ */

.back-to-top {
  transition:
    opacity    200ms var(--ease-out),
    transform  200ms cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 200ms var(--ease-out);
}

.back-to-top.visible {
  animation: back-to-top-pop 280ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes back-to-top-pop {
  from {
    opacity:   0;
    transform: scale(0.7) translateY(12px);
  }
  to {
    opacity:   1;
    transform: scale(1) translateY(0);
  }
}

.back-to-top:hover {
  transform: translateY(-2px) scale(1.1);
  box-shadow: 0 6px 20px rgba(22, 163, 74, 0.35);
}

.back-to-top:active {
  transform: scale(0.93);
  transition-duration: 100ms;
}


/* ══════════════════════════════════════════════════════════════
   13. ROLE SELECTOR BUTTONS (register/profile)
   ══════════════════════════════════════════════════════════════ */

.role-btn {
  transition:
    border-color 150ms var(--ease-out),
    background   150ms var(--ease-out),
    box-shadow   200ms var(--ease-out),
    transform    150ms var(--ease-out);
  will-change: transform;
}

.role-btn:hover {
  transform: translateY(-2px);
}

.role-btn:active {
  transform: scale(0.97);
  transition-duration: 100ms;
}

.role-btn.role-active {
  transform: none; /* no lift on selected — it's already "pressed" */
}


/* ══════════════════════════════════════════════════════════════
   14. SIDEBAR MOBILE SLIDE
   The sidebar already has a transform transition in admin.css.
   This file tightens the easing curve.
   ══════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  .sidebar {
    transition: left 280ms cubic-bezier(0.16, 1, 0.3, 1);
  }
}


/* ══════════════════════════════════════════════════════════════
   15. TIMELINE DOTS — entrance pop when visible
   ══════════════════════════════════════════════════════════════ */

.timeline-dot {
  transition:
    background    200ms var(--ease-out),
    border-color  200ms var(--ease-out),
    transform     200ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.timeline-dot.done,
.timeline-dot.active {
  animation: dot-pop-in 300ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes dot-pop-in {
  from {
    transform: scale(0);
    opacity:   0;
  }
  to {
    transform: scale(1);
    opacity:   1;
  }
}


/* ══════════════════════════════════════════════════════════════
   16. STAR RATING HOVER (report-detail page)
   ══════════════════════════════════════════════════════════════ */

.star-rating span {
  transition:
    color     150ms var(--ease-out),
    transform 150ms cubic-bezier(0.34, 1.56, 0.64, 1);
  display: inline-block;
  will-change: transform;
}

.star-rating span:hover {
  transform: scale(1.25);
}


/* ══════════════════════════════════════════════════════════════
   17. AVATAR UPLOAD CIRCLE (profile page)
   ══════════════════════════════════════════════════════════════ */

.avatar-upload-circle,
.profile-avatar {
  transition:
    box-shadow 200ms var(--ease-out),
    transform  200ms cubic-bezier(0.16, 1, 0.3, 1);
}

.avatar-upload-circle:hover,
a:hover > .profile-avatar {
  transform: scale(1.04);
  box-shadow: 0 0 0 4px rgba(22, 163, 74, 0.18);
}
