/* Relay build, pre-rendered once from the approved vector animation. Shared
   bitmap frames avoid per-frame SVG painting; no runtime animation script.
   Adapters preserve each host's dimensions, visibility and progress state. */
:root {
  --ri-relay-art: url('/images/loaders/relay-build.webp?v=20261008-relay-smooth-v2');
  --ri-relay-art-large: url('/images/loaders/relay-build-large.webp?v=20261008-relay-smooth-v2');
}

.ri-loader {
  display: inline-block;
  width: var(--ri-loader-size, 20px);
  height: var(--ri-loader-size, 20px);
  flex-shrink: 0;
  vertical-align: middle;
}

:is(.ri-loader, .spinner, .btn-spinner, .animate-spin,
  .accuracy-tooltip-spinner, .ao-drift-loading-spinner, .asme-spinner,
  .asme-spinner-sm, .bio-cg-compare-runs-spinner, .cat-lpi-loading-spinner,
  .dashboard-contributor-spinner, .delete-overlay-spinner, .dw-save-spinner-ring,
  .frp-spinner, .inline-spinner, .mini-spinner, .owned-shoe-eff-spinner,
  .proc-spinner, .report-payment-spinner, .run-btn-spinner, .shoe-cutout-spinner,
  .shoe-focus-confidence-spinner, .strava-row-saving-spinner, .strava-sync-spinner,
  .stryd-processing-spinner, .proc-logo-spinner-wrap, .shoes-logo-spinner-wrap,
  .sync-proc-logo),
[data-tone="busy"] :is(.gp-status-icon, .sp-status-icon, .ah-status-icon),
.run-loading::before,
.ri-btn[aria-busy="true"] .ri-btn-icon::before,
.ri-btn[aria-busy="true"]:not(:has(.ri-btn-icon))::after {
  background: transparent var(--ri-relay-art) center / contain no-repeat !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  filter: none !important;
  animation: none !important;
  -webkit-mask: none !important;
  mask: none !important;
  min-width: 16px;
  min-height: 16px;
}

/* Text loaders need a readable mark after the artwork's internal padding.
   This also overrides the legacy 20px inline style rebuilt by stream requests.
   Keep the 96px asset: it covers these 32px markers at 3x pixel density. */
#driftInspectorLoading .ri-loader,
:is(.inline-spinner, .bio-cg-compare-runs-spinner,
  .cat-lpi-loading-spinner, .shoe-focus-confidence-spinner) {
  width: 32px !important;
  height: 32px !important;
  min-width: 32px;
  min-height: 32px;
  flex-shrink: 0;
  vertical-align: middle;
}

/* Only the large loading marks need the larger decoded image. */
:is(.proc-logo-spinner-wrap, .shoes-logo-spinner-wrap, .sync-proc-logo) {
  background-image: var(--ri-relay-art-large) !important;
}

/* Old SVG tracks, ripple rings and membership lockups are decorative children.
   The label and the determinate progress bar live outside these wrappers. */
:is(.animate-spin, .strava-sync-spinner, .proc-logo-spinner-wrap,
  .shoes-logo-spinner-wrap, .sync-proc-logo) > *,
[data-tone="busy"] :is(.gp-status-icon, .sp-status-icon, .ah-status-icon) > * {
  visibility: hidden !important;
  animation: none !important;
}

/* Image documents do not consistently inherit live motion preference changes.
   Switch the URL in the host document so the fallback is reliable in Safari too. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --ri-relay-art: url('/images/loaders/relay-mark.svg?v=20261008-relay-v1');
    --ri-relay-art-large: var(--ri-relay-art);
  }
}
