/*
 * Impact — motion layer (visual refresh).
 *
 * Adapted from the handoff's freebuff-motion.css, not copied: the handoff
 * assumes a static marketing page, while this app swaps the whole view on
 * every hash-route change. So entrance motion is keyed to the view container
 * (`#view.iom-enter`) and re-applied by motion.js after each render, and the
 * handoff's preview-only pieces (postMessage replay, hero stamp) are dropped.
 *
 * Everything here is additive and opt-out: with motion disabled — the OS
 * `prefers-reduced-motion` setting, `?motion=off`, or JS that never runs — the
 * CSS leaves every element at its final state. No opacity:0 state exists
 * outside the enabled branch.
 */

html.iom-on #view.iom-enter {
  animation: iom-view-in 240ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

/* The one place a stagger is worth it: the welcome hero. */
html.iom-on #view.iom-enter .hero > *:nth-child(1) {
  animation: iom-rise 320ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
html.iom-on #view.iom-enter .hero > *:nth-child(2) {
  animation: iom-rise 320ms cubic-bezier(0.2, 0.7, 0.2, 1) 60ms both;
}
html.iom-on #view.iom-enter .hero > *:nth-child(3) {
  animation: iom-rise 320ms cubic-bezier(0.2, 0.7, 0.2, 1) 120ms both;
}

/* Open surfaces: the account menu, the composer and any dialog. */
html.iom-on .account-menu-dropdown:not([hidden]) {
  animation: iom-pop 160ms ease-out both;
}

html.iom-on .modal:not([hidden]),
html.iom-on [role='dialog']:not([hidden]) {
  animation: iom-pop 180ms ease-out both;
}

html.iom-on .toast {
  animation: iom-toast 180ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

/* A success toast states the outcome, not just the text. */
.toast.success::before {
  content: '✓';
  margin-right: 8px;
  font-weight: 700;
  color: var(--tint-strong);
}

@keyframes iom-view-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes iom-rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes iom-pop {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes iom-toast {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Off switch, and the visitor's own preference. Both are honoured by
   motion.js before it adds `iom-on`, so no element ever flashes. */
html.iom-off #view,
html.iom-off #view *,
html.iom-off .account-menu-dropdown,
html.iom-off .modal,
html.iom-off [role='dialog'],
html.iom-off .toast {
  animation: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html.iom-on #view.iom-enter,
  html.iom-on #view.iom-enter .hero > *,
  html.iom-on .account-menu-dropdown:not([hidden]),
  html.iom-on .modal:not([hidden]),
  html.iom-on [role='dialog']:not([hidden]),
  html.iom-on .toast {
    animation: none !important;
  }
}
