@scope (progress-ui) {
  :where(:scope) {
    /* -- Tokens -- */
    --progress-track-default:    var(--a-bg-muted);
    --progress-fill-default:     var(--a-accent);
    --progress-height-default:   0.375rem;
    --progress-radius-default:   var(--a-radius-full);
    --progress-duration-default: var(--a-duration);
    --progress-easing-default:   var(--a-easing);

    /* -- Indeterminate motion -- */
    --progress-shimmer-duration-default: 1.5s;
    --progress-shimmer-easing-default:   ease-in-out;
    --progress-spin-duration-default:    0.6s;
    --progress-spin-easing-default:      linear;
  }

  :scope {
    /* -- Base -- */
    box-sizing: border-box;
    display: block;
    width: 100%;
  }

  /* ── Bar variant ── */

  [slot="track"] {
    width: 100%;
    height: var(--progress-height, var(--progress-height-default));
    border-radius: var(--progress-radius, var(--progress-radius-default));
    background: var(--progress-track, var(--progress-track-default));
    overflow: hidden;
  }

  [slot="fill"] {
    height: 100%;
    border-radius: var(--progress-radius, var(--progress-radius-default));
    background: var(--progress-fill, var(--progress-fill-default));
    transition: width var(--progress-duration, var(--progress-duration-default)) var(--progress-easing, var(--progress-easing-default));

    /* Enter animation: paint the fill at 0 on first frame, then transition
       to the inline width set by JS — so a freshly-mounted determinate bar
       animates 0 → value rather than snapping in (or, in some cascades,
       briefly painting at the indeterminate width:100% before settling). */
    @starting-style {
      width: 0;
    }
  }

  /* Indeterminate bar shimmer */
  :scope[value^="-"] [slot="fill"],
  :scope:not([value]) [slot="fill"] {
    width: 100% !important;
    background: linear-gradient(
      90deg,
      var(--progress-track, var(--progress-track-default)) 0%,
      var(--progress-fill, var(--progress-fill-default)) 50%,
      var(--progress-track, var(--progress-track-default)) 100%
    );
    background-size: 200% 100%;
    animation: progress-shimmer var(--progress-shimmer-duration, var(--progress-shimmer-duration-default)) var(--progress-shimmer-easing, var(--progress-shimmer-easing-default)) infinite;
  }

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

  /* ── Spinner variant ── */

  :scope[variant="spinner"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5em;
    height: 1.5em;
  }

  :scope[variant="spinner"] [slot="track"] { display: none; }

  :scope[variant="spinner"]::after {
    content: "";
    box-sizing: border-box;
    display: block;
    width: 100%;
    height: 100%;
    border: 2px solid var(--progress-fill, var(--progress-fill-default));
    border-top-color: transparent;
    border-radius: var(--progress-radius, var(--progress-radius-default));
    animation: progress-spin var(--progress-spin-duration, var(--progress-spin-duration-default)) var(--progress-spin-easing, var(--progress-spin-easing-default)) infinite;
  }

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