/* ════════════════════════════════════════════════════════════════
   PULSAR-RH · Motion system
   ════════════════════════════════════════════════════════════════
   Philosophy: ambient · gentle · ease-in-out · low-frequency.
   Movement is the SIGNAL that something is alive, not a request
   for attention. Default duration is SECONDS, not milliseconds.
   ══════════════════════════════════════════════════════════════ */

:root {
  /* ─── Easing curves ────────────────────────────────────────── */
  --ease-soft:    cubic-bezier(.22, 1, .36, 1);  /* easing único da família */     /* sharp-then-soft, no overshoot — for entrances */
  --ease-ambient: cubic-bezier(.22, 1, .36, 1);     /* material standard — for hover, micro UI */
  --ease-pulse:   cubic-bezier(.25, .1, .25, 1);   /* gentle in-out — for breathing/looping */
  --ease-linear:  linear;                           /* skeletons only */

  /* ─── Durations — name by VIBE, not number ─────────────────── */
  --motion-instant: 120ms;   /* hover state changes */
  --motion-quick:   200ms;   /* button, tab, badge */
  --motion-glide:   200ms;   /* card hover lift, page transitions */
  --motion-reveal:  320ms;  /* = anim-fade-up do Finance */   /* entrance from off-state */
  --motion-breathe: 2400ms;  /* ambient pulse */
  --motion-ekg:     3000ms;  /* signature pulse-line draw */
  --motion-halo:    4000ms;  /* radial halo expansion */
  --motion-stage:   6000ms;  /* carousel auto-advance */
}

/* ════════════════════════════════════════════════════════════════
   KEYFRAMES · all named with `pulsar-` to avoid collision
   ══════════════════════════════════════════════════════════════ */

/* 1 · EKG pulse-line — gentler draw + bottom-opacity floor */
@keyframes pulsar-ekg-draw {
  0%   { stroke-dashoffset: var(--ekg-len, 240); opacity: .35; }
  60%  { stroke-dashoffset: 0; opacity: .85; }
  100% { stroke-dashoffset: var(--ekg-len, 240); opacity: .35; }
}

/* 2 · Logo breathe — tighter opacity range, soft glow always on */
@keyframes pulsar-breathe {
  0%, 100% { opacity: .94; filter: drop-shadow(0 0 4px rgba(112,72,232,.15)); }
  50%      { opacity: 1;   filter: drop-shadow(0 0 8px rgba(112,72,232,.25)); }
}

/* 3 · Radial halo — softer expand, shorter fade-out tail */
@keyframes pulsar-ring-expand {
  0%   { transform: translate(-50%, -50%) scale(.5); opacity: .7; }
  100% { transform: translate(-50%, -50%) scale(1.45); opacity: 0; }
}

/* 4 · Typing dots — opacity-only, no Y translate */
@keyframes pulsar-dot-pulse {
  0%, 80%, 100% { opacity: .35; }
  40%           { opacity: 1; }
}

/* 5 · Skeleton shimmer — diagonal sweep */
@keyframes pulsar-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}

/* 6 · Entrance: fade + 8px lift (cards, KPIs) */
@keyframes pulsar-fade-up {
  0%   { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* 7 · Entrance: fade only — for layered text */
@keyframes pulsar-fade-in {
  from { opacity: 0; } to { opacity: 1; }
}

/* 8 · KPI count-up — driven by JS but easing curve hint */
@keyframes pulsar-count {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0);   }
}

/* 9 · Toast slide-in from right */
@keyframes pulsar-toast-in {
  0%   { transform: translateX(120%); opacity: 0; }
  100% { transform: translateX(0);    opacity: 1; }
}
@keyframes pulsar-toast-out {
  0%   { transform: translateX(0);    opacity: 1; }
  100% { transform: translateX(120%); opacity: 0; }
}

/* 10 · Progress bar fill */
@keyframes pulsar-fill {
  0% { width: 0%; }
  100% { width: var(--fill, 100%); }
}

/* 11 · Carousel slide swap (X-axis, slight Y to feel weightless) */
@keyframes pulsar-slide-in {
  0%   { opacity: 0; transform: translate(8px, 4px); }
  100% { opacity: 1; transform: translate(0, 0); }
}
@keyframes pulsar-slide-out {
  0%   { opacity: 1; transform: translate(0, 0); }
  100% { opacity: 0; transform: translate(-8px, -4px); }
}

/* 12 · Soft halo — gentler scale + opacity range */
@keyframes pulsar-halo-orbit {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: .92; }
  50%      { transform: translate(-50%, -50%) scale(1.06); opacity: .78; }
}

/* 13 · Sparkline draw — stroke-dasharray reveal once */
@keyframes pulsar-spark-draw {
  0%   { stroke-dashoffset: var(--spark-len, 500); }
  100% { stroke-dashoffset: 0; }
}

/* 14 · Avatar status dot pulse — softer ping */
@keyframes pulsar-status-ping {
  0%   { box-shadow: 0 0 0 0   rgba(8,193,106,.40); }
  100% { box-shadow: 0 0 0 6px rgba(8,193,106,0);    }
}

/* ════════════════════════════════════════════════════════════════
   UTILITY CLASSES · drop on any element
   ══════════════════════════════════════════════════════════════ */

/* Looping ambients are always-on (they don't gate visibility). */
.motion-breathe   { animation: pulsar-breathe var(--motion-breathe) var(--ease-pulse) infinite; }
.motion-status   { animation: pulsar-status-ping 1.8s var(--ease-ambient) infinite; }

/* One-shot entrances opt-in via .go modifier so the at-rest state is
   the FINAL state (good for static thumbnails + initial render).
   To trigger on mount, add .go via JS in a useEffect/onload. */
.motion-fade-in.go   { animation: pulsar-fade-in var(--motion-reveal)  var(--ease-soft) both; }
.motion-fade-up.go   { animation: pulsar-fade-up var(--motion-reveal)  var(--ease-soft) both; }
.motion-slide-in.go  { animation: pulsar-slide-in var(--motion-glide)  var(--ease-soft) both; }
.motion-toast        { animation: pulsar-toast-in var(--motion-glide)  var(--ease-soft) both; }

/* Stagger helper — children of .stagger-up.go fade-up in cascade.
   Default state is VISIBLE so static captures + initial SSR render the
   final layout. Add .go (via JS on mount, or .replay on a click) to
   trigger the entrance. */
.stagger-up.go > *,
.stagger-up.replay > * {
  animation: pulsar-fade-up var(--motion-reveal) var(--ease-soft) both;
}
.stagger-up.go > *:nth-child(1), .stagger-up.replay > *:nth-child(1) { animation-delay: 0ms; }
.stagger-up.go > *:nth-child(2), .stagger-up.replay > *:nth-child(2) { animation-delay: 80ms; }
.stagger-up.go > *:nth-child(3), .stagger-up.replay > *:nth-child(3) { animation-delay: 160ms; }
.stagger-up.go > *:nth-child(4), .stagger-up.replay > *:nth-child(4) { animation-delay: 240ms; }
.stagger-up.go > *:nth-child(5), .stagger-up.replay > *:nth-child(5) { animation-delay: 320ms; }
.stagger-up.go > *:nth-child(6), .stagger-up.replay > *:nth-child(6) { animation-delay: 400ms; }
.stagger-up.go > *:nth-child(7), .stagger-up.replay > *:nth-child(7) { animation-delay: 480ms; }
.stagger-up.go > *:nth-child(8), .stagger-up.replay > *:nth-child(8) { animation-delay: 560ms; }

/* Skeleton — pulse-shimmer placeholder for loading rows */
.skel {
  background: linear-gradient(
    100deg,
    var(--surface-2)   0%,
    var(--surface-3)  40%,
    var(--surface-2)  60%,
    var(--surface-2) 100%
  );
  background-size: 200% 100%;
  animation: pulsar-shimmer 1.6s var(--ease-linear) infinite;
  border-radius: 6px;
}

/* Hover transitions — apply to interactive elements for free polish */
.motion-hover-lift  { transition: transform var(--motion-quick) var(--ease-ambient),
                                  box-shadow var(--motion-quick) var(--ease-ambient),
                                  border-color var(--motion-quick) var(--ease-ambient); }
.motion-hover-lift:hover { transform: translateY(-2px); }

.motion-hover-glow  { transition: box-shadow var(--motion-glide) var(--ease-ambient); }
.motion-hover-glow:hover { box-shadow: 0 0 0 1px var(--pulsar-primary), 0 8px 24px rgba(112,72,232,.25); }

/* ════════════════════════════════════════════════════════════════
   REDUCED MOTION — RESPECT system preference
   ══════════════════════════════════════════════════════════════ */
@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;
  }
}
