/* ===========================================================================
   MOTION SYSTEM
   ---------------------------------------------------------------------------
   Every animation here is driven by --duration-* tokens, which collapse to
   0.01ms under prefers-reduced-motion. That is not a compromise on the
   "maximum animation" brief — it is the one setting that makes rich motion
   safe to ship in a tool people are required to use at work.

   Transform and opacity only, wherever possible: those run on the compositor.
   Animating width/height/top forces layout on every frame and janks.
   =========================================================================== */

:root {
  --ease-glide:  cubic-bezier(0.22, 1, 0.36, 1);
  --ease-snap:   cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-swift:  cubic-bezier(0.4, 0, 0.2, 1);
  --ease-back:   cubic-bezier(0.68, -0.55, 0.27, 1.55);
  --stagger-step: 45ms;
}

/* ---------------------------------------------------------------------------
   1. TAB TRANSITIONS
   --------------------------------------------------------------------------- */

.tab-pane {
  animation: pane-enter var(--duration-slow) var(--ease-glide) both;
}

@keyframes pane-enter {
  from { opacity: 0; transform: translate3d(0, 14px, 0) scale(0.993); filter: blur(4px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* ---------------------------------------------------------------------------
   2. STAGGERED ENTRANCE
   Rows and cards arrive in sequence rather than all at once, which reads as
   the data assembling instead of flashing into place.
   --------------------------------------------------------------------------- */

.kpi-grid > *,
.followup-item-card,
#plantations-table-body tr,
#admin-users-table-body tr,
#admin-depts-table-body tr,
#dept-users-table-body tr,
#dept-leaderboard-tbody tr,
#tehsil-table-tbody tr {
  animation: item-rise var(--duration-normal) var(--ease-glide) both;
}

@keyframes item-rise {
  from { opacity: 0; transform: translate3d(0, 12px, 0); }
  to   { opacity: 1; transform: none; }
}

/* Cap the cascade at 14 — beyond that the last rows feel slow to arrive. */
.kpi-grid > *:nth-child(1),  tbody tr:nth-child(1),  .followup-item-card:nth-child(1)  { animation-delay: calc(var(--stagger-step) * 0); }
.kpi-grid > *:nth-child(2),  tbody tr:nth-child(2),  .followup-item-card:nth-child(2)  { animation-delay: calc(var(--stagger-step) * 1); }
.kpi-grid > *:nth-child(3),  tbody tr:nth-child(3),  .followup-item-card:nth-child(3)  { animation-delay: calc(var(--stagger-step) * 2); }
.kpi-grid > *:nth-child(4),  tbody tr:nth-child(4),  .followup-item-card:nth-child(4)  { animation-delay: calc(var(--stagger-step) * 3); }
.kpi-grid > *:nth-child(5),  tbody tr:nth-child(5),  .followup-item-card:nth-child(5)  { animation-delay: calc(var(--stagger-step) * 4); }
tbody tr:nth-child(6),  .followup-item-card:nth-child(6)  { animation-delay: calc(var(--stagger-step) * 5); }
tbody tr:nth-child(7),  .followup-item-card:nth-child(7)  { animation-delay: calc(var(--stagger-step) * 6); }
tbody tr:nth-child(8),  .followup-item-card:nth-child(8)  { animation-delay: calc(var(--stagger-step) * 7); }
tbody tr:nth-child(9),  .followup-item-card:nth-child(9)  { animation-delay: calc(var(--stagger-step) * 8); }
tbody tr:nth-child(10), .followup-item-card:nth-child(10) { animation-delay: calc(var(--stagger-step) * 9); }
tbody tr:nth-child(11), .followup-item-card:nth-child(11) { animation-delay: calc(var(--stagger-step) * 10); }
tbody tr:nth-child(12), .followup-item-card:nth-child(12) { animation-delay: calc(var(--stagger-step) * 11); }
tbody tr:nth-child(13), .followup-item-card:nth-child(13) { animation-delay: calc(var(--stagger-step) * 12); }
tbody tr:nth-child(n+14), .followup-item-card:nth-child(n+14) { animation-delay: calc(var(--stagger-step) * 13); }

/* ---------------------------------------------------------------------------
   3. HOVER PHYSICS
   --------------------------------------------------------------------------- */

.kpi-card {
  transition:
    transform var(--duration-normal) var(--ease-snap),
    box-shadow var(--duration-normal) var(--ease-out),
    background-color var(--duration-normal) var(--ease-out),
    border-color var(--duration-normal) var(--ease-out);
}
.kpi-card:hover { transform: translate3d(0, -5px, 0) scale(1.012); }
.kpi-card:active { transform: translate3d(0, -1px, 0) scale(0.998); }

.followup-item-card {
  transition:
    transform var(--duration-normal) var(--ease-glide),
    box-shadow var(--duration-normal) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}
.followup-item-card:hover {
  transform: translate3d(6px, 0, 0);
  box-shadow: var(--glass-shadow-raised);
}

.chart-card, .admin-card-section {
  transition: box-shadow var(--duration-normal) var(--ease-out),
              border-color var(--duration-normal) var(--ease-out);
}
.chart-card:hover, .admin-card-section:hover {
  box-shadow: var(--glass-shadow-raised);
  border-color: var(--glass-edge-bright);
}

/* Thumbnails lift slightly out of their cell. */
.followup-thumb, #plantations-table-body img {
  transition: transform var(--duration-normal) var(--ease-snap),
              box-shadow var(--duration-normal) var(--ease-out);
}
.followup-item-card:hover .followup-thumb,
#plantations-table-body tr:hover img {
  transform: scale(1.1) rotate(-1.5deg);
  box-shadow: 0 6px 18px rgb(2 6 23 / 0.5);
}

/* ---------------------------------------------------------------------------
   4. BUTTON FEEDBACK
   --------------------------------------------------------------------------- */

.btn, .btn-icon, .nav-item, .bottom-nav-item, .demo-user-card, .btn-close {
  transition:
    transform var(--duration-instant) var(--ease-snap),
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}

.btn:hover:not(:disabled) { transform: translate3d(0, -2px, 0); }
.btn:active:not(:disabled) { transform: translate3d(0, 1px, 0) scale(0.975); }
.btn-icon:hover { transform: translate3d(0, -2px, 0) scale(1.06); }
.btn-icon:active { transform: scale(0.92); }

/* Material-style ripple, positioned by js/motion.js from the click point. */
.ripple {
  position: absolute;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.4);
  transform: scale(0);
  animation: ripple-out 620ms var(--ease-out) forwards;
  pointer-events: none;
  z-index: 3;
}
@keyframes ripple-out {
  to { transform: scale(2.6); opacity: 0; }
}

.btn-close:hover { transform: rotate(90deg) scale(1.12); }

/* ---------------------------------------------------------------------------
   5. NAVIGATION
   --------------------------------------------------------------------------- */

.nav-item:hover { transform: translate3d(4px, 0, 0); }
.nav-item.active { transform: translate3d(2px, 0, 0); }

.nav-item.active::before {
  animation: rail-grow var(--duration-normal) var(--ease-snap) both;
}
@keyframes rail-grow {
  from { transform: translateY(-50%) scaleY(0); opacity: 0; }
  to   { transform: translateY(-50%) scaleY(1); opacity: 1; }
}

.nav-item i { transition: transform var(--duration-normal) var(--ease-snap); }
.nav-item:hover i { transform: scale(1.18) rotate(-6deg); }
.nav-item.active i { transform: scale(1.1); }

.bottom-nav-item.active i { animation: bounce-in var(--duration-normal) var(--ease-snap); }
@keyframes bounce-in {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.3) translateY(-3px); }
  100% { transform: scale(1.1); }
}

/* ---------------------------------------------------------------------------
   6. MODALS
   --------------------------------------------------------------------------- */

.modal-overlay.active { animation: overlay-fade var(--duration-fast) var(--ease-out); }
@keyframes overlay-fade { from { opacity: 0; } to { opacity: 1; } }

.modal-overlay.active .modal-container {
  animation: modal-spring var(--duration-slow) var(--ease-snap) both;
}
@keyframes modal-spring {
  0%   { opacity: 0; transform: translate3d(0, 28px, 0) scale(0.94); filter: blur(8px); }
  60%  { opacity: 1; filter: blur(0); }
  100% { opacity: 1; transform: none; }
}

/* Modal contents arrive just behind the panel itself. */
.modal-overlay.active .modal-body > * {
  animation: item-rise var(--duration-normal) var(--ease-glide) both;
  animation-delay: 110ms;
}

/* ---------------------------------------------------------------------------
   7. TOASTS
   --------------------------------------------------------------------------- */

.toast {
  animation: toast-slide var(--duration-normal) var(--ease-snap) both;
}
@keyframes toast-slide {
  from { opacity: 0; transform: translate3d(48px, 0, 0) scale(0.9); }
  to   { opacity: 1; transform: none; }
}

/* A progress bar showing the toast's remaining dwell time. */
.toast::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: 100%;
  background: currentColor;
  opacity: 0.4;
  transform-origin: left;
  animation: toast-timer 4.5s linear forwards;
}
@keyframes toast-timer { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* ---------------------------------------------------------------------------
   8. STATUS & ATTENTION
   --------------------------------------------------------------------------- */

.badge.overdue::before {
  animation: pulse-ring 2s var(--ease-in-out) infinite;
}
@keyframes pulse-ring {
  0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 rgb(239 68 68 / 0.6); }
  50%      { opacity: 0.6; box-shadow: 0 0 0 5px rgb(239 68 68 / 0); }
}

.nav-badge, .notification-count {
  animation: badge-pop var(--duration-normal) var(--ease-snap);
}
@keyframes badge-pop {
  0%   { transform: scale(0); }
  70%  { transform: scale(1.25); }
  100% { transform: scale(1); }
}

/* Overdue map pins pulse so they are findable at a glance. */
.pin-marker-body.overdue {
  animation: pin-pulse 2.2s var(--ease-in-out) infinite;
}
@keyframes pin-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgb(239 68 68 / 0.55); }
  50%      { box-shadow: 0 0 0 12px rgb(239 68 68 / 0); }
}

.leaflet-marker-icon {
  animation: pin-drop var(--duration-slow) var(--ease-snap) both;
}
@keyframes pin-drop {
  from { opacity: 0; transform: translate3d(0, -22px, 0) scale(0.7); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   9. KPI COUNT-UP
   js/motion.js animates the value; this scales the digits as they settle.
   --------------------------------------------------------------------------- */

.kpi-value { transition: transform var(--duration-fast) var(--ease-snap); }
.kpi-value.counting { transform: scale(1.04); }

/* ---------------------------------------------------------------------------
   10. LOADING
   --------------------------------------------------------------------------- */

.skeleton {
  background: linear-gradient(100deg,
    rgb(255 255 255 / 0.04) 20%,
    rgb(255 255 255 / 0.11) 50%,
    rgb(255 255 255 / 0.04) 80%);
  background-size: 220% 100%;
  animation: shimmer-sweep 1.5s linear infinite;
}
@keyframes shimmer-sweep {
  from { background-position: 220% 0; }
  to   { background-position: -220% 0; }
}

.fa-spinner { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------------------
   11. LOGIN
   --------------------------------------------------------------------------- */

.login-card {
  animation: login-arrive var(--duration-slow) var(--ease-glide) both;
}
@keyframes login-arrive {
  from { opacity: 0; transform: translate3d(0, 26px, 0) scale(0.97); filter: blur(10px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

.login-card .form-group,
.login-card .btn-login-submit,
.demo-profiles-section {
  animation: item-rise var(--duration-normal) var(--ease-glide) both;
}
.login-card .form-group:nth-of-type(1) { animation-delay: 120ms; }
.login-card .form-group:nth-of-type(2) { animation-delay: 190ms; }
.login-card .btn-login-submit          { animation-delay: 260ms; }
.demo-profiles-section                 { animation-delay: 330ms; }

.login-emblem { animation: emblem-in var(--duration-slow) var(--ease-snap) both; }
@keyframes emblem-in {
  from { opacity: 0; transform: scale(0.6) rotate(-12deg); }
  to   { opacity: 1; transform: none; }
}

.demo-user-card:hover { transform: translate3d(0, -3px, 0) scale(1.02); }
.demo-user-card:active { transform: scale(0.98); }

/* ---------------------------------------------------------------------------
   12. SCROLL REVEAL
   Applied by js/motion.js via IntersectionObserver.
   --------------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition:
    opacity var(--duration-slow) var(--ease-glide),
    transform var(--duration-slow) var(--ease-glide);
}
.reveal.revealed { opacity: 1; transform: none; }

/* ---------------------------------------------------------------------------
   13. FOCUS
   --------------------------------------------------------------------------- */

:focus-visible { animation: focus-pop var(--duration-fast) var(--ease-snap); }
@keyframes focus-pop {
  from { box-shadow: 0 0 0 0 var(--surface-base), 0 0 0 0 var(--green-400); }
}

/* ---------------------------------------------------------------------------
   14. REDUCED MOTION
   Durations are already near-zero via the tokens; these rules remove the
   keyframe animations that would otherwise still play.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .tab-pane,
  .kpi-grid > *,
  .followup-item-card,
  tbody tr,
  .modal-overlay.active .modal-container,
  .modal-overlay.active .modal-body > *,
  .toast,
  .login-card,
  .login-card .form-group,
  .login-card .btn-login-submit,
  .demo-profiles-section,
  .login-emblem,
  .leaflet-marker-icon,
  .nav-badge,
  .notification-count,
  .nav-item.active::before {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }

  /* Looping attention animations are the worst offenders — stop them dead. */
  .badge.overdue::before,
  .pin-marker-body.overdue,
  .skeleton,
  .toast::after {
    animation: none !important;
  }

  .kpi-card:hover,
  .followup-item-card:hover,
  .nav-item:hover,
  .btn:hover:not(:disabled) { transform: none !important; }

  .reveal { opacity: 1; transform: none; }
}

/* Hover-dependent motion is pointless on touch and costs battery. */
@media (hover: none) {
  .kpi-card:hover, .followup-item-card:hover, .nav-item:hover { transform: none; }
  .followup-item-card:hover .followup-thumb,
  #plantations-table-body tr:hover img { transform: none; }
}
