/* ==========================================================================
   animations.css — движение интерфейса.
   Ориентир по длительности: 180–400 мс. Никакого bounce, вращений
   и постоянного движения. Всё выключается при prefers-reduced-motion.
   ========================================================================== */

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes rise-in-sm {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes slide-in-right {
  from { opacity: 0; transform: translateX(14px); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes panel-in {
  from { transform: translateX(100%); }
  to   { transform: translateX(0); }
}

@keyframes dropdown-in {
  from { opacity: 0; transform: translateY(-5px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes toast-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(24px); }
}

@keyframes shimmer {
  100% { transform: translateX(100%); }
}

@keyframes grow-x {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes grow-y {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}

@keyframes ring-draw {
  from { stroke-dashoffset: var(--dash-total, 400); }
  to   { stroke-dashoffset: var(--dash-offset, 0); }
}

/* ==========================================================================
   Появление контента страницы
   ========================================================================== */

.page-enter { animation: rise-in var(--dur-slow) var(--ease-soft) both; }

/* Каскадное появление — задержка задаётся инлайн через --i */
.reveal {
  animation: rise-in var(--dur-slow) var(--ease-soft) both;
  animation-delay: calc(var(--i, 0) * 45ms);
}

.reveal--fast {
  animation: rise-in-sm var(--dur-base) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 28ms);
}

.fade-enter { animation: fade-in var(--dur-base) var(--ease-out) both; }

/* ==========================================================================
   Раскрытие / сворачивание
   ========================================================================== */

.collapse {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--t-slow);
}

.collapse > * { overflow: hidden; min-height: 0; }
.collapse.is-open { grid-template-rows: 1fr; }

.rotate-on-open { transition: transform var(--t-base); }
[aria-expanded='true'] > .rotate-on-open { transform: rotate(180deg); }

/* ==========================================================================
   Мягкое обновление данных вместо мигания скелетом
   ========================================================================== */

.is-refreshing {
  opacity: 0.55;
  transition: opacity var(--t-fast);
  pointer-events: none;
}

/* ==========================================================================
   Отключение движения
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .media--zoom:hover img { transform: none; }
}
