@layer components {
  .progress {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    width: 100%;
    height: 0.5rem;
    border: none;
    border-radius: 9999px;
    overflow: hidden;
    background-color: var(--secondary);
  }

  /* WebKit (Chrome, Safari, Edge) */
  .progress::-webkit-progress-bar {
    background-color: var(--secondary);
    border-radius: 9999px;
  }

  .progress::-webkit-progress-value {
    background-color: var(--primary);
    border-radius: 9999px;
    transition: width 300ms ease;
  }

  /* Firefox */
  .progress::-moz-progress-bar {
    background-color: var(--primary);
    border-radius: 9999px;
  }

  /* Indeterminate state */
  .progress:indeterminate {
    background: linear-gradient(
      90deg,
      var(--secondary) 0%,
      var(--primary) 50%,
      var(--secondary) 100%
    );
    background-size: 200% 100%;
    animation: progress-indeterminate 1.5s linear infinite;
  }

  .progress:indeterminate::-webkit-progress-bar {
    background-color: transparent;
  }

  .progress:indeterminate::-moz-progress-bar {
    background-color: transparent;
  }

  @keyframes progress-indeterminate {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
  }
}

/* Accessibility: suppress motion for users who request it (REQUIRED for all
   components — AGENTS.md "Accessibility CSS"). Near-zero duration instead of
   `none` keeps transitionend/animationend (and discrete display flips)
   firing so JS state machines that await them keep working. */
@media (prefers-reduced-motion: reduce) {
  @layer components {
    .progress,
    .progress *,
    .progress::before,
    .progress::after,
    .progress *::before,
    .progress *::after,
    .progress::backdrop {
      transition-duration: 0.01ms !important;
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
    }
  }
}
