/* Shared motion contract. Load tokens.css before this file. */

html {
  scroll-behavior: smooth;
}

/* Component feedback is immediate, bounded, and never delays native operation. */
:where(
  a,
  button,
  input,
  select,
  textarea,
  summary,
  [role="button"],
  [role="link"],
  [role="tab"],
  [role="switch"]
) {
  transition-property: opacity;
  transition-duration: var(--motion-fast);
  transition-timing-function: var(--ease-standard);
  transition-delay: 0s;
}

:where(.motion-transition, [data-motion-transition="standard"], [data-motion-surface]) {
  transition-property: transform, opacity;
  transition-duration: var(--motion-standard);
  transition-timing-function: var(--ease-standard);
  transition-delay: 0s;
}

:where(.motion-transition--emphasis, [data-motion-transition="emphasis"]) {
  transition-property: transform, opacity;
  transition-duration: var(--motion-emphasis);
  transition-timing-function: var(--ease-decelerate);
  transition-delay: 0s;
}

:where([data-status], [role="status"], [role="alert"], [aria-live]) {
  transition-property: opacity;
  transition-duration: var(--motion-standard);
  transition-timing-function: var(--ease-standard);
  transition-delay: 0s;
}

/* Scripted depth values remain clamped even when input values exceed the contract. */
:where(
  .motion-bounded,
  [data-motion-bounded],
  [data-motion~="parallax"],
  [data-parallax],
  [data-motion~="tracking"],
  [data-pointer-track]
) {
  --motion-x: 0px;
  --motion-y: 0px;
  --motion-angle: 0deg;

  transform:
    translate3d(
      clamp(calc(0px - var(--motion-translate-max)), var(--motion-x), var(--motion-translate-max)),
      clamp(calc(0px - var(--motion-translate-max)), var(--motion-y), var(--motion-translate-max)),
      0
    )
    rotate(
      clamp(calc(0deg - var(--motion-rotate-max)), var(--motion-angle), var(--motion-rotate-max))
    );
  transition-property: transform, opacity;
  transition-duration: var(--motion-standard);
  transition-timing-function: var(--ease-standard);
  transition-delay: 0s;
}

/* Fine-pointer attraction has its own stricter four-pixel envelope. */
:where(.motion-attract, [data-motion-attract], [data-motion~="attract"]) {
  --motion-attract-x: 0px;
  --motion-attract-y: 0px;

  transform: translate3d(
    clamp(calc(0px - var(--motion-attract-max)), var(--motion-attract-x), var(--motion-attract-max)),
    clamp(calc(0px - var(--motion-attract-max)), var(--motion-attract-y), var(--motion-attract-max)),
    0
  );
  transition-property: transform, opacity;
  transition-duration: var(--motion-fast);
  transition-timing-function: var(--ease-standard);
  transition-delay: 0s;
}

@media (hover: hover) and (pointer: fine) {
  :where(.motion-attract, [data-motion-attract], [data-motion~="attract"]):hover {
    --motion-attract-y: calc(0px - var(--motion-attract-max));
  }

  :where(.motion-attract, [data-motion-attract], [data-motion~="attract"]):active {
    --motion-attract-x: 0px;
    --motion-attract-y: 0px;
  }
}

/*
 * The sole automatic reveal is opt-in and decorative-only. Requiring aria-hidden
 * keeps content and controls available before this sequence completes or if it fails.
 */
:where(.motion-reveal[aria-hidden="true"], [data-motion-reveal][aria-hidden="true"]) {
  opacity: 1;
  transform: none;
}

.motion-ready
  :where(.motion-reveal[aria-hidden="true"], [data-motion-reveal][aria-hidden="true"])
  [data-motion-reveal-part],
.motion-ready
  :where(.motion-reveal[aria-hidden="true"], [data-motion-reveal][aria-hidden="true"])[data-motion-state="pending"] {
  opacity: 0;
  transform: translate3d(0, var(--motion-translate-max), 0);
}

.motion-ready
  :where(.motion-reveal[aria-hidden="true"], [data-motion-reveal][aria-hidden="true"])
  [data-motion-reveal-part][data-motion-state="revealed"],
.motion-ready
  :where(.motion-reveal[aria-hidden="true"], [data-motion-reveal][aria-hidden="true"])[data-motion-state="revealed"] {
  animation-name: hdwa-reveal-once;
  animation-duration: var(--motion-reveal);
  animation-timing-function: var(--ease-decelerate);
  animation-delay: 0s;
  animation-iteration-count: 1;
  animation-fill-mode: both;
}

@keyframes hdwa-reveal-once {
  from {
    opacity: 0;
    transform: translate3d(0, var(--motion-translate-max), 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  html,
  :where([data-scroll-container], .scroll-region) {
    scroll-behavior: auto !important;
  }

  /* Neutralize motion declared by shared, route, and third-party style layers. */
  *,
  *::before,
  *::after {
    animation-name: none !important;
    animation-delay: 0s !important;
    animation-duration: 0s !important;
    animation-iteration-count: 1 !important;
    transition-delay: 0s !important;
    transition-duration: 0s !important;
    scroll-behavior: auto !important;
  }

  /* Parallax and pointer tracking return to their static resting composition. */
  :where(
    .motion-bounded,
    [data-motion-bounded],
    .motion-parallax,
    .parallax,
    [data-motion~="parallax"],
    [data-parallax],
    .motion-tracking,
    .pointer-tracking,
    [data-motion~="tracking"],
    [data-pointer-track],
    .motion-attract,
    [data-motion-attract],
    [data-motion~="attract"]
  ) {
    animation: none !important;
    transition-property: none !important;
    transform: none !important;
    will-change: auto !important;
  }

  /* Automatic reveals resolve immediately to their visible resting state. */
  :where(
    .motion-reveal,
    .reveal,
    [data-motion-reveal],
    [data-motion~="reveal"],
    [data-reveal],
    [data-motion-reveal-part]
  ) {
    animation: none !important;
    transition-property: none !important;
    opacity: 1 !important;
    transform: none !important;
    visibility: visible !important;
  }

  /* Ambient loops and pulses stop rather than freezing mid-transform. */
  :where(
    .motion-loop,
    .is-looping,
    [data-motion-loop],
    [data-motion~="loop"],
    [data-motion~="pulse"]
  ) {
    animation: none !important;
    transition-property: none !important;
    transform: none !important;
    will-change: auto !important;
  }

  /* Shimmer overlays are removed while their static fallback surface remains. */
  :where(
    .motion-shimmer,
    .shimmer,
    [data-shimmer],
    [data-motion~="shimmer"]
  ) {
    animation: none !important;
    background-image: none !important;
    transform: none !important;
  }

  :where(
    .motion-shimmer,
    .shimmer,
    [data-shimmer],
    [data-motion~="shimmer"]
  )::before,
  :where(
    .motion-shimmer,
    .shimmer,
    [data-shimmer],
    [data-motion~="shimmer"]
  )::after {
    animation: none !important;
    opacity: 0 !important;
    transform: none !important;
  }

  /* Ripples and celebrations are decorative and disappear without gating results. */
  :where(
    .motion-ripple,
    .ripple,
    [data-ripple],
    [data-motion~="ripple"],
    .motion-celebration,
    .celebration,
    .confetti,
    [data-celebration],
    [data-motion~="celebration"]
  ) {
    display: none !important;
    animation: none !important;
    transform: none !important;
  }

  /* Retain only a short, nonspatial status fade. */
  :where([data-status], [role="status"], [role="alert"], [aria-live]) {
    animation: none !important;
    transition-property: opacity !important;
    transition-duration: var(--motion-reduced) !important;
    transition-timing-function: linear !important;
    transition-delay: 0s !important;
    transform: none !important;
  }
}
