/* Scoped animations & motion guards */
#content-cloud .slick-spinner, .template_togglebox .slick-spinner {
  width: 40px; height: 40px;
  border: 3px solid var(--color-border-subtle);
  border-top-color: var(--brand-primary);
  border-radius: 50%;
  animation: one-spin .8s linear infinite;
}

/* Spinner sizes. one-spin is the one rotation keyframe in the theme; under
   prefers-reduced-motion every spinner becomes the one-pulse opacity cue
   (below). --sm sits inline in text and buttons and takes currentcolor. */
#content-cloud :is(.slick-spinner--sm, .slick-spinner-sm),
.template_togglebox :is(.slick-spinner--sm, .slick-spinner-sm),
.slick-dialog :is(.slick-spinner--sm, .slick-spinner-sm),
.slick-slideover :is(.slick-spinner--sm, .slick-spinner-sm) {
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  border: 2px solid color-mix(in srgb, currentcolor 25%, transparent);
  border-top-color: currentcolor;
  border-radius: 50%;
  vertical-align: -.125em;
  animation: one-spin .8s linear infinite;
}

/* Skeleton: a token surface that pulses in opacity only (no repaint of a
   moving gradient); it stops under prefers-reduced-motion. */
#content-cloud .slick-skeleton, .template_togglebox .slick-skeleton {
  min-height: 14px;
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
  animation: slick-skeleton-pulse 1.4s ease-in-out infinite;
}
#content-cloud .slick-skeleton--block, .template_togglebox .slick-skeleton--block { min-height: 64px; border-radius: var(--radius-lg); }
#content-cloud .slick-skeleton--text, .template_togglebox .slick-skeleton--text { width: 60%; }

@keyframes one-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
/* For absolutely-positioned icons that use translateY(-50%) for centering. */
@keyframes one-spin-y { from { transform: translateY(-50%) rotate(0); } to { transform: translateY(-50%) rotate(360deg); } }
@keyframes slick-skeleton-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* SSH Authentication Card animations */
@keyframes sshFadeIn {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes sshSlideDown {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Running is a steady state: the dot is static. Animation is kept for work in progress (spinners). */
#content-cloud .slick-status-running::before, .template_togglebox .slick-status-running::before { content: ""; position: absolute; width: 6px; height: 6px; background: var(--brand-primary); border-radius: 50%; left: 8px; top: 50%; transform: translateY(-50%); }
@keyframes one-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* Tag badge pop-in animation */
@keyframes slick-pop-in {
  0% { opacity: 0; transform: scale(0.8); }
  100% { opacity: 1; transform: scale(1); }
}

.tag-updated .slick-tag,
.tag-updated .tag-badge { animation: slick-pop-in 0.3s ease-out; }

/* Respect reduced motion: decorative motion stops; spinners keep a progress
   cue as an opacity pulse instead of a rotation. */
@media (prefers-reduced-motion: reduce) {
  #content-cloud .slick-skeleton,
  #content-cloud .status-icon,
  #content-cloud .ssh-auth-panel.active,
  #content-cloud .ssh-key-name-field.visible,
  .breakdown-content,
  .tag-updated .slick-tag,
  .tag-updated .tag-badge,
  .template_togglebox .slick-skeleton { animation: none !important; }

  .status-progress-bar,
  .htmx-request .htmx-indicator,
  .htmx-indicator.htmx-request,
  #content-cloud .slick-spinner,
  #content-cloud :is(.slick-spinner--sm, .slick-spinner-sm),
  .template_togglebox :is(.slick-spinner--sm, .slick-spinner-sm),
  .slick-dialog :is(.slick-spinner--sm, .slick-spinner-sm),
  .slick-slideover :is(.slick-spinner--sm, .slick-spinner-sm),
  #content-cloud .oneb-spin,
  #content-cloud .one-refresh-btn.spinning .one-refresh-icon,
  #content-cloud .search-container.searching .search-icon,
  .template_togglebox .slick-spinner { animation: one-pulse 2s ease-in-out infinite !important; }
}
