/* Publicly — Animation Library
   All keyframes and animation utility classes.
   Import after tokens.css. */

/* ═══════════════════════════════════════════════════
   KEYFRAMES
═══════════════════════════════════════════════════ */

/* Entrance */
@keyframes pub-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes pub-fade-in-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pub-fade-in-down {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: translateY(0); }
}

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

/* Continuous */
@keyframes pub-float {
  0%, 100% { transform: translateY(0px); }
  50%       { transform: translateY(-8px); }
}

@keyframes pub-float-slow {
  0%, 100% { transform: translateY(0px) rotate(0deg); }
  33%       { transform: translateY(-6px) rotate(1deg); }
  66%       { transform: translateY(-3px) rotate(-1deg); }
}

@keyframes pub-pulse-soft {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.55; }
}

@keyframes pub-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Loading / skeleton */
@keyframes pub-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position:  400px 0; }
}

/* Progress */
@keyframes pub-progress {
  from { width: 0%; }
  to   { width: var(--pub-progress-target, 100%); }
}

@keyframes pub-progress-indeterminate {
  0%   { transform: translateX(-100%) scaleX(0.3); }
  40%  { transform: translateX(0%)    scaleX(0.6); }
  100% { transform: translateX(100%)  scaleX(0.3); }
}

/* Crawl dot — file appearing in index */
@keyframes pub-dot-appear {
  0%   { opacity: 0; transform: scale(0) rotate(-15deg); }
  60%  { opacity: 1; transform: scale(1.2) rotate(3deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

/* Serve redirect — document flying to user */
@keyframes pub-serve-fly {
  0%   { opacity: 1; transform: translateX(0) translateY(0) scale(1); }
  40%  { opacity: 1; transform: translateX(40px) translateY(-20px) scale(0.9); }
  70%  { opacity: 0.6; transform: translateX(100px) translateY(-10px) scale(0.7); }
  100% { opacity: 0; transform: translateX(150px) translateY(0) scale(0.5); }
}

@keyframes pub-serve-arrive {
  0%   { opacity: 0; transform: translateX(-30px) scale(0.8); }
  100% { opacity: 1; transform: translateX(0) scale(1); }
}

/* Arrow flow (for the serve illustration line) */
@keyframes pub-arrow-flow {
  0%   { stroke-dashoffset: 120; opacity: 0.3; }
  50%  { opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 0.3; }
}

/* Success / bounce-in */
@keyframes pub-bounce-in {
  0%   { opacity: 0; transform: scale(0.3); }
  50%  { opacity: 1; transform: scale(1.08); }
  70%  { transform: scale(0.97); }
  100% { transform: scale(1); }
}

@keyframes pub-check-draw {
  from { stroke-dashoffset: 30; }
  to   { stroke-dashoffset: 0; }
}

/* Stale / warning pulse */
@keyframes pub-stale-pulse {
  0%, 100% { background-color: var(--pub-warning); opacity: 0.8; }
  50%       { background-color: var(--pub-warning); opacity: 0.4; }
}

/* Slide in from right (toast / notification) */
@keyframes pub-slide-in-right {
  from { opacity: 0; transform: translateX(100%); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes pub-slide-out-right {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(100%); }
}


/* ═══════════════════════════════════════════════════
   UTILITY CLASSES
═══════════════════════════════════════════════════ */

/* Entrance (use on mount) */
.pub-anim-fade-in    { animation: pub-fade-in    var(--pub-duration-slow) var(--pub-ease) both; }
.pub-anim-fade-in-up { animation: pub-fade-in-up var(--pub-duration-slow) var(--pub-ease) both; }
.pub-anim-scale-in   { animation: pub-scale-in   var(--pub-duration-slow) var(--pub-ease) both; }

/* Staggered entrance — add delay via style="--pub-delay: Xms" */
.pub-anim-stagger { animation-delay: var(--pub-delay, 0ms); }

/* Continuous */
.pub-anim-float      { animation: pub-float      3.5s ease-in-out infinite; }
.pub-anim-float-slow { animation: pub-float-slow 5s   ease-in-out infinite; }
.pub-anim-pulse-soft { animation: pub-pulse-soft 2s   ease-in-out infinite; }
.pub-anim-spin       { animation: pub-spin       1s   linear infinite; }

/* Loading skeleton */
.pub-skeleton {
  background: linear-gradient(
    90deg,
    var(--pub-slate-100) 25%,
    var(--pub-slate-200) 50%,
    var(--pub-slate-100) 75%
  );
  background-size: 800px 100%;
  animation: pub-shimmer 1.4s ease-in-out infinite;
  border-radius: var(--pub-radius-sm);
}

/* Progress bar */
.pub-progress-bar {
  height: 4px;
  border-radius: var(--pub-radius-full);
  background: var(--pub-blue-100);
  overflow: hidden;
}
.pub-progress-bar__fill {
  height: 100%;
  background: var(--pub-primary);
  border-radius: var(--pub-radius-full);
  animation: pub-progress var(--pub-duration-slower) var(--pub-ease) forwards;
}
.pub-progress-bar--indeterminate .pub-progress-bar__fill {
  width: 40%;
  animation: pub-progress-indeterminate 1.4s ease-in-out infinite;
}

/* Success */
.pub-anim-bounce-in { animation: pub-bounce-in 0.5s var(--pub-ease) both; }

/* Toast */
.pub-toast-enter { animation: pub-slide-in-right  300ms var(--pub-ease) both; }
.pub-toast-exit  { animation: pub-slide-out-right 200ms var(--pub-ease) both; }

/* Stale badge */
.pub-badge-stale {
  animation: pub-stale-pulse 2.5s ease-in-out infinite;
  border-radius: var(--pub-radius-full);
  display: inline-block;
  width: 8px; height: 8px;
}

/* Crawl dot */
.pub-crawl-dot {
  animation: pub-dot-appear 0.35s var(--pub-ease) both;
}
