/* ==========================================================================
   Animations — DBBackup landing page
   ========================================================================== */

/* --------------------------------------------------------------------------
   Border Beam
   A thin light line (green → cyan comet) chasing around an element's border.

   How it works:
   1. @property registers --beam-angle as a real <angle>, so @keyframes can
      interpolate it smoothly (plain custom properties can't animate).
   2. A ::before overlay paints a conic-gradient starting from that angle:
      mostly transparent, with a short tail ramping into a bright head.
   3. Two stacked masks composited with `exclude` punch out the center,
      leaving only a 2px ring — so the gradient reads as a border, not a fill.

   Apply `.border-beam` to any element with border-radius; the ring inherits it.
   -------------------------------------------------------------------------- */

@property --beam-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.border-beam {
  position: relative;
  isolation: isolate;
}

.border-beam::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  padding: 2px; /* beam thickness */
  background: conic-gradient(
    from var(--beam-angle),
    transparent 0%,
    transparent 72%,
    color-mix(in srgb, var(--accent-secondary) 40%, transparent) 82%,
    var(--accent-secondary) 92%,
    var(--accent-primary) 99%,
    transparent 100%
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: beam-rotate 4s linear infinite;
  pointer-events: none;
}

/* Soft glow that follows the beam's overall presence (cheap approximation:
   a faint static halo so the beam doesn't float on pure darkness). */
.border-beam::after {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  box-shadow: 0 0 24px color-mix(in srgb, var(--accent-primary) 18%, transparent);
  pointer-events: none;
}

@keyframes beam-rotate {
  to {
    --beam-angle: 360deg;
  }
}

/* --------------------------------------------------------------------------
   Hero pipeline: pulse of light traveling database → cloud
   -------------------------------------------------------------------------- */

.pipeline-line {
  position: relative;
  overflow: hidden;
}

.pipeline-line::after {
  content: "";
  position: absolute;
  top: 50%;
  left: -64px;
  width: 64px;
  height: 2px;
  transform: translateY(-50%);
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent-primary), var(--accent-secondary));
  box-shadow: 0 0 12px var(--accent-primary);
  animation: pipeline-flow 2.6s ease-in-out infinite;
}

@keyframes pipeline-flow {
  0%   { left: -64px; opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { left: 100%; opacity: 0; }
}

/* Cloud "receives" the pulse: lock glows in sync with the flow cycle */
.pipeline-cloud svg {
  animation: cloud-receive 2.6s ease-in-out infinite;
}

@keyframes cloud-receive {
  0%, 80%, 100% { filter: drop-shadow(0 0 0 transparent); }
  90% { filter: drop-shadow(0 0 10px color-mix(in srgb, var(--accent-secondary) 60%, transparent)); }
}

/* --------------------------------------------------------------------------
   Hero entrance: staggered fade-up on load
   -------------------------------------------------------------------------- */

.fade-up {
  opacity: 0;
  transform: translateY(14px);
  animation: fade-up 0.7s ease-out forwards;
}

.fade-up.delay-1 { animation-delay: 0.12s; }
.fade-up.delay-2 { animation-delay: 0.24s; }
.fade-up.delay-3 { animation-delay: 0.36s; }
.fade-up.delay-4 { animation-delay: 0.48s; }

@keyframes fade-up {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --------------------------------------------------------------------------
   Feature icon micro-animations
   -------------------------------------------------------------------------- */

.icon-anim-pulse {
  animation: icon-pulse 3s ease-in-out infinite;
}

@keyframes icon-pulse {
  0%, 100% { filter: drop-shadow(0 0 0 transparent); }
  50% { filter: drop-shadow(0 0 8px color-mix(in srgb, var(--accent-primary) 50%, transparent)); }
}

.icon-anim-spin {
  animation: icon-spin 9s linear infinite;
  transform-origin: center;
}

@keyframes icon-spin {
  to { transform: rotate(360deg); }
}

.icon-anim-float {
  animation: icon-float 3.6s ease-in-out infinite;
}

@keyframes icon-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

/* --------------------------------------------------------------------------
   Status dot: subtle "alive" blink on the Success indicator
   -------------------------------------------------------------------------- */

.status-dot {
  animation: status-blink 2.4s ease-in-out infinite;
}

@keyframes status-blink {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-primary) 45%, transparent); }
  50% { box-shadow: 0 0 0 5px transparent; }
}

/* --------------------------------------------------------------------------
   Toasts: slide in from the right, fade out upward on dismiss
   -------------------------------------------------------------------------- */

.toast {
  animation: toast-in 0.25s ease-out;
}

.toast.leaving {
  animation: toast-out 0.3s ease-in forwards;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateX(16px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes toast-out {
  to {
    opacity: 0;
    transform: translateY(-6px);
  }
}

/* --------------------------------------------------------------------------
   Settings: modal entrance + inline "Saved" flash on toggles
   -------------------------------------------------------------------------- */

.modal {
  animation: modal-in 0.2s ease-out;
}

@keyframes modal-in {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.saved-flash {
  animation: saved-fade 1.7s ease forwards;
}

@keyframes saved-fade {
  0% { opacity: 0; }
  15% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; }
}

/* --------------------------------------------------------------------------
   Accessibility: kill all decorative motion for users who ask for it
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .border-beam::before,
  .pipeline-line::after,
  .pipeline-cloud svg,
  .fade-up,
  .icon-anim-pulse,
  .icon-anim-spin,
  .icon-anim-float,
  .status-dot,
  .toast,
  .toast.leaving,
  .modal {
    animation: none;
  }

  .saved-flash {
    animation: saved-fade 1.7s step-end forwards;
  }

  .fade-up {
    opacity: 1;
    transform: none;
  }
}
