/* ═══════════════════════════════════════════════════════
   GLOBAL ANIMATIONS — Indo Cahaya Express
   Berlaku untuk semua halaman: home, admin, auth, dll.
═══════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────
   1. KEYFRAME DEFINITIONS
───────────────────────────────────────────── */

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(32px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInLeft {
  from { opacity: 0; transform: translateX(-28px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes fadeInRight {
  from { opacity: 0; transform: translateX(28px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes slideDown {
  from { opacity: 0; transform: translateY(-20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes scaleIn {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50%       { transform: scale(1.05); }
}
@keyframes bounce {
  0%, 20%, 53%, 80%, 100% { transform: translate3d(0, 0, 0); }
  40%, 43%                { transform: translate3d(0, -28px, 0); }
  70%                     { transform: translate3d(0, -14px, 0); }
  90%                     { transform: translate3d(0, -4px, 0); }
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25%       { transform: translateX(-6px); }
  75%       { transform: translateX(6px); }
}
@keyframes shimmer {
  from { background-position: -1000px 0; }
  to   { background-position:  1000px 0; }
}
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes ripple {
  from { transform: scale(0); opacity: 1; }
  to   { transform: scale(4); opacity: 0; }
}
@keyframes slideInRight {
  from { opacity: 0; transform: translateX(60px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes slideOutRight {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(60px); }
}


/* ─────────────────────────────────────────────
   2. SCROLL REVEAL SYSTEM
   Tambahkan class .reveal / .reveal-left / .reveal-right
   ke elemen HTML. JS di bawah otomatis menambahkan
   .is-visible saat elemen masuk viewport.
───────────────────────────────────────────── */

.reveal,
.reveal-left,
.reveal-right {
  opacity: 0;
  transition:
    opacity  0.65s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.65s cubic-bezier(0.4, 0, 0.2, 1);
}
.reveal       { transform: translateY(28px); }
.reveal-left  { transform: translateX(-28px); }
.reveal-right { transform: translateX(28px); }

.reveal.is-visible,
.reveal-left.is-visible,
.reveal-right.is-visible {
  opacity: 1;
  transform: translate(0);
}

/* Stagger helpers */
.reveal-d1 { transition-delay: 0.10s; }
.reveal-d2 { transition-delay: 0.20s; }
.reveal-d3 { transition-delay: 0.30s; }
.reveal-d4 { transition-delay: 0.40s; }
.reveal-d5 { transition-delay: 0.50s; }
.reveal-d6 { transition-delay: 0.60s; }


/* ─────────────────────────────────────────────
   3. HERO SECTION — page-load animations
───────────────────────────────────────────── */

.hero-eyebrow {
  animation: fadeInLeft 0.7s cubic-bezier(0.4, 0, 0.2, 1) both;
  animation-delay: 0.1s;
}
.hero-title {
  animation: fadeInUp 0.8s cubic-bezier(0.4, 0, 0.2, 1) both;
  animation-delay: 0.25s;
}
.hero-desc {
  animation: fadeInUp 0.8s cubic-bezier(0.4, 0, 0.2, 1) both;
  animation-delay: 0.4s;
}
.hero-cta-row {
  animation: fadeInUp 0.8s cubic-bezier(0.4, 0, 0.2, 1) both;
  animation-delay: 0.55s;
}
.track-panel {
  animation: fadeInRight 0.9s cubic-bezier(0.4, 0, 0.2, 1) both;
  animation-delay: 0.3s;
}


/* ─────────────────────────────────────────────
   4. STATS BAR
───────────────────────────────────────────── */

.stat-cell {
  animation: fadeInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}
.stat-cell:nth-child(1) { animation-delay: 0.10s; }
.stat-cell:nth-child(2) { animation-delay: 0.20s; }
.stat-cell:nth-child(3) { animation-delay: 0.30s; }
.stat-cell:nth-child(4) { animation-delay: 0.40s; }


/* ─────────────────────────────────────────────
   5. HOME PAGE — HOVER & MICRO-INTERACTIONS
───────────────────────────────────────────── */

/* Bento cards */
.bento-card {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.3s;
}

/* Route cards */
.route-card {
  transition: border-color 0.3s, box-shadow 0.3s;
}

/* Why-us items */
.why-item {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.3s, border-color 0.3s;
}

/* Testimonial cards */
.testi-card {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.3s, border-color 0.3s;
}


/* ─────────────────────────────────────────────
   6. BUTTONS
───────────────────────────────────────────── */

.btn,
.btn-cta-primary,
.btn-cta-outline,
.btn-book,
.btn-login,
.btn-primary,
.btn-secondary,
.btn-green,
.btn-navy,
.btn-red {
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}


/* ─────────────────────────────────────────────
   7. FORM ELEMENTS
───────────────────────────────────────────── */

input, select, textarea {
  transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow   0.2s cubic-bezier(0.4, 0, 0.2, 1),
              background   0.2s;
}

/* Shake on validation error */
.form-group.has-error {
  animation: shake 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}


/* ─────────────────────────────────────────────
   8. TOAST / FLASH NOTIFICATIONS
───────────────────────────────────────────── */

.toast       { animation: slideInRight 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.toast.hiding { animation: slideOutRight 0.35s ease forwards; }

/* Flash notif (dipakai di admin pages) */
.flash-notif { animation: slideInRight 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both; }


/* ─────────────────────────────────────────────
   9. MODAL & DROPDOWN
───────────────────────────────────────────── */

.modal-overlay.open .modal-box { animation: scaleIn 0.28s cubic-bezier(0.34, 1.56, 0.64, 1) both; }

.modal-backdrop { animation: fadeIn 0.25s ease both; }

.dropdown-menu,
.dd-panel.is-open {
  animation: slideDown 0.22s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  transform-origin: top right;
}


/* ─────────────────────────────────────────────
   10. ADMIN / DASHBOARD CARDS
   (dipakai di halaman admin, stats, reports)
───────────────────────────────────────────── */

.stat-card {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.3s, border-color 0.3s;
}

/* Staggered entrance for stat cards in admin */
.stats-grid .stat-card {
  animation: fadeInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}
.stats-grid .stat-card:nth-child(1) { animation-delay: 0.05s; }
.stats-grid .stat-card:nth-child(2) { animation-delay: 0.15s; }
.stats-grid .stat-card:nth-child(3) { animation-delay: 0.25s; }
.stats-grid .stat-card:nth-child(4) { animation-delay: 0.35s; }

/* Table rows */
.dash-table tbody tr {
  animation: fadeIn 0.3s ease both;
}
.dash-table tbody tr:nth-child(1)  { animation-delay: 0.04s; }
.dash-table tbody tr:nth-child(2)  { animation-delay: 0.08s; }
.dash-table tbody tr:nth-child(3)  { animation-delay: 0.12s; }
.dash-table tbody tr:nth-child(4)  { animation-delay: 0.16s; }
.dash-table tbody tr:nth-child(5)  { animation-delay: 0.20s; }
.dash-table tbody tr:nth-child(6)  { animation-delay: 0.24s; }
.dash-table tbody tr:nth-child(7)  { animation-delay: 0.28s; }
.dash-table tbody tr:nth-child(8)  { animation-delay: 0.32s; }


/* ─────────────────────────────────────────────
   11. ALERTS
───────────────────────────────────────────── */

.alert           { animation: slideDown 0.4s cubic-bezier(0.4, 0, 0.2, 1) both; }
.alert-success   { animation: slideDown 0.4s cubic-bezier(0.4, 0, 0.2, 1) both; }
.alert-error     { animation: shake    0.45s cubic-bezier(0.4, 0, 0.2, 1) both; }


/* ─────────────────────────────────────────────
   12. UTILITY CLASSES
───────────────────────────────────────────── */

/* Loading skeleton */
.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 800px 100%;
  animation: shimmer 1.8s infinite;
}

/* Spinner */
.loading-spinner {
  display: inline-block;
  width: 20px; height: 20px;
  border: 2.5px solid rgba(13, 46, 122, 0.15);
  border-top-color: #0D2E7A;
  border-radius: 50%;
  animation: spin 0.85s linear infinite;
}

/* Ripple (add class to buttons) */
.ripple-effect          { position: relative; overflow: hidden; }
.ripple-effect::after   {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 0; height: 0;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  animation: ripple 0.55s ease-out;
}

/* Period badge pulse */
.period-badge { animation: pulse 3s ease-in-out infinite; }

/* Disabled / loading state */
.is-loading {
  opacity: 0.6;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

/* Image fade-in on load */
img.img-loading { opacity: 0; transition: opacity 0.35s ease; }
img.img-loaded  { opacity: 1; }

/* Progress bar */
.progress-bar-fill {
  transition: width 0.65s cubic-bezier(0.4, 0, 0.2, 1);
}


/* ─────────────────────────────────────────────
   13. RESPONSIVE — reduce motion
───────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration:   0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration:  0.01ms !important;
  }
}

@media (max-width: 768px) {
  .hero-eyebrow,
  .hero-title,
  .hero-desc,
  .hero-cta-row,
  .track-panel {
    animation-duration: 0.5s;
  }
}


/* ─────────────────────────────────────────────
   14. SCROLL REVEAL — JS snippet
   Paste ini di layout utama (layouts/app.blade.php)
   di dalam <script> tag sebelum </body>:

   document.addEventListener('DOMContentLoaded', () => {
     const els = document.querySelectorAll('.reveal, .reveal-left, .reveal-right');
     if (!els.length) return;
     const io = new IntersectionObserver((entries) => {
       entries.forEach(e => {
         if (e.isIntersecting) {
           e.target.classList.add('is-visible');
           io.unobserve(e.target);
         }
       });
     }, { threshold: 0.12 });
     els.forEach(el => io.observe(el));
   });
───────────────────────────────────────────── */
