.cs-spinner {
  inline-size: 14px;
  block-size: 14px;
  border-radius: 50%;
  border: 2px solid color-mix(in oklab, var(--ds-on-cta-soft) 30%, transparent);
  border-block-start-color: var(--ds-on-cta-soft);
  flex-shrink: 0;
}

.cs-btn__spinner {
  display: none;
  border-color: color-mix(in oklab, currentColor 35%, transparent);
  border-block-start-color: currentColor;
}

.cs-btn.is-loading { position: relative; pointer-events: none; }
.cs-btn.is-loading .cs-btn__label { visibility: hidden; }

/* inset and margin, never transform: cs-spin writes transform, and a translate here would make it slide. */
.cs-btn.is-loading .cs-btn__spinner {
  display: block;
  position: absolute;
  inset: 0;
  margin: auto;
}

.ds-loader {
  --loader-dot: 6px;
  --loader-hop: 4px;

  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-2);
  color: var(--ds-text-muted);
  font-size: var(--ds-font-size-sm);
}

.ds-loader--lg {
  --loader-dot: 8px;
  --loader-hop: 6px;

  font-size: var(--ds-font-size-base);
}

/* The box keeps room for the hop, so nothing around it moves. */
.ds-loader__dots {
  display: inline-flex;
  align-items: flex-end;
  gap: calc(var(--loader-dot) / 2);
  block-size: calc(var(--loader-dot) + var(--loader-hop));
}

.ds-loader__dots i {
  inline-size: var(--loader-dot);
  block-size: var(--loader-dot);
  border-radius: var(--ds-radius-full);
  background: color-mix(in oklab, var(--ds-on-cta-soft) 45%, transparent);
}
.ds-loader__dots i:nth-child(2) { background: color-mix(in oklab, var(--ds-on-cta-soft) 70%, transparent); }
.ds-loader__dots i:nth-child(3) { background: var(--ds-on-cta-soft); }

@media (prefers-reduced-motion: no-preference) {
  .cs-spinner { animation: cs-spin 0.7s linear infinite; }

  .ds-loader__dots i { animation: ds-loader-hop 900ms ease-in-out infinite; animation-delay: 0ms; }
  .ds-loader__dots i:nth-child(2) { animation-delay: 120ms; }
  .ds-loader__dots i:nth-child(3) { animation-delay: 240ms; }

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

  @keyframes ds-loader-hop {
    0%, 60%, 100% { translate: 0 0; }
    30% { translate: 0 calc(var(--loader-hop) * -1); }
  }
}
