/**
 * animations.css — keyframes + small motion utility classes.
 * Orchestrated, purposeful motion only — see design principles in Phase 1.
 */

@keyframes shimmer {
  100% { transform: translateX(100%); }
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

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

@keyframes pulse-ring {
  0%   { box-shadow: 0 0 0 0 rgba(124, 58, 237, 0.35); }
  100% { box-shadow: 0 0 0 8px rgba(124, 58, 237, 0); }
}

@keyframes caret-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.anim-fade-in { animation: fade-in var(--duration-base) var(--ease-out) both; }
.anim-rise-in { animation: rise-in var(--duration-slow) var(--ease-out) both; }
.anim-scale-in { animation: scale-in var(--duration-base) var(--ease-out) both; }

/* Stagger helper: add to children of a container, combine with inline
   `style="--stagger: 2"` for list reveals (dashboard cards, search results) */
.anim-stagger { animation: rise-in var(--duration-slow) var(--ease-out) both; animation-delay: calc(var(--stagger, 0) * 40ms); }

/* Typing-reveal caret used while a generated "response" streams in */
.typing-caret {
  display: inline-block;
  width: 2px; height: 1em;
  background: currentColor;
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: caret-blink 1s step-end infinite;
}

.is-thinking .tool-card__icon,
.is-thinking .dock-shell {
  animation: pulse-ring 1.6s ease-out infinite;
}
