/* ==========================================================================
   motion.css — движение интерфейса
   Подключать ПОСЛЕ tokens.css.
   Правила: анимируем только transform и opacity (исключения помечены),
   входы — ease-out, длительности 150–250 мс, уважение prefers-reduced-motion.
   ========================================================================== */

:root {
  /* Длительности */
  --dur-instant: 100ms;  /* смена цвета при hover, тап-фидбек */
  --dur-fast:    150ms;  /* нажатие, тултип, мелкие переключатели */
  --dur-base:    200ms;  /* поповер, дропдаун, тост, смена вкладки */
  --dur-slow:    250ms;  /* модалка, шторка — верхняя граница для UI */
  --dur-exit:    150ms;  /* выход всегда короче входа */
  --dur-chart:   600ms;  /* прорисовка графика при первом показе */
  --dur-count:   800ms;  /* count-up KPI (JS читает это значение) */
  --stagger:     30ms;   /* шаг каскада для списков/карточек; максимум ~8 элементов */

  /* Кривые */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);    /* вход, ответ на действие — по умолчанию */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);   /* перемещение уже видимого элемента */
  --ease-in:     cubic-bezier(0.4, 0, 1, 1);        /* только короткий выход, не для входа */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);    /* шторки и bottom sheet */
  /* Пружина (затухание ≈0.72, перелёт ≈4%): для жестов и «приземления» после драга.
     linear() — Chrome 113+, Safari 17.2+, Firefox 112+; в старых браузерах — fallback ниже. */
  --ease-spring: var(--ease-out);
  --dur-spring:  450ms;

  /* Амплитуды — обнуляются при reduced motion */
  --motion-distance: 8px;   /* сдвиг при появлении */
  --motion-scale:    0.96;  /* стартовый масштаб поповеров/модалок (никогда не 0) */
  --press-scale:     0.97;  /* нажатие кнопки */
}

@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --ease-spring: linear(0, 0.0388, 0.1334, 0.2576, 0.392, 0.5232, 0.643, 0.7466,
      0.8323, 0.9, 0.9513, 0.9881, 1.0129, 1.0281, 1.0359, 1.0384, 1.0372, 1.0338,
      1.0291, 1.024, 1.0189, 1.0142, 1.0102, 1.0068, 1.0041, 1.0021, 1.0006, 0.9996,
      0.999, 0.9986, 0.9985, 0.9986, 1);
  }
}

/* ---------- 1. Нажатие: всё, что кликается ---------- */
.pressable {
  transition: transform var(--dur-fast) var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.pressable:active:not(:disabled, [aria-disabled="true"]) {
  transform: scale(var(--press-scale));
}

/* Смена цвета при наведении — коротко и только на устройствах с hover */
.hoverable {
  transition:
    background-color var(--dur-instant) var(--ease-out),
    color var(--dur-instant) var(--ease-out),
    border-color var(--dur-instant) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .hoverable:hover { background-color: var(--surface-3); }
}

/* ---------- 2. Появления (keyframes — для элементов, которые монтируются) ---------- */
@keyframes fade-in   { from { opacity: 0; } }
@keyframes fade-up   { from { opacity: 0; transform: translateY(var(--motion-distance)); } }
@keyframes fade-down { from { opacity: 0; transform: translateY(calc(var(--motion-distance) * -1)); } }
@keyframes scale-in  { from { opacity: 0; transform: scale(var(--motion-scale)); } }
@keyframes fade-out  { to   { opacity: 0; } }
@keyframes scale-out { to   { opacity: 0; transform: scale(var(--motion-scale)); } }

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

/* Каскад: style="--i: 0..7" на дочерних элементах. Не больше 8 шагов —
   дальше задержка начинает раздражать; элементы после 8-го появляются вместе с 8-м. */
.stagger > * {
  animation: fade-up var(--dur-base) var(--ease-out) both;
  animation-delay: calc(min(var(--i, 0), 7) * var(--stagger));
}

/* ---------- 3. Поповеры, дропдауны, тултипы ---------- */
/* Растут ОТ точки привязки. Положение триггера задавайте через --origin
   (top left / top right / bottom center …). */
.popover {
  transform-origin: var(--origin, top center);
  animation: scale-in var(--dur-base) var(--ease-out) both;
}
.popover[data-state="closed"] {
  animation: scale-out var(--dur-exit) var(--ease-out) both;
}

/* Тултип: первый — с задержкой и анимацией; соседние, пока группа «тёплая», — мгновенно */
.tooltip {
  transform-origin: var(--origin, bottom center);
  animation: scale-in var(--dur-fast) var(--ease-out) both;
}
.tooltip[data-instant] { animation: none; }

/* ---------- 4. Модалка ---------- */
.overlay {
  position: fixed; inset: 0;
  background: var(--surface-overlay);
  z-index: var(--z-overlay);
  animation: fade-in var(--dur-slow) var(--ease-out) both;
}
.overlay[data-state="closed"] { animation: fade-out var(--dur-exit) var(--ease-out) both; }

.modal {
  z-index: var(--z-modal);
  transform-origin: center;
  animation: scale-in var(--dur-slow) var(--ease-out) both;
}
.modal[data-state="closed"] { animation: scale-out var(--dur-exit) var(--ease-out) both; }

/* ---------- 5. Шторки (drawer справа) и bottom sheet ---------- */
/* Переход через transition, а не keyframes: transition прерываемый —
   если пользователь закрыл шторку на середине открытия, она поедет обратно с текущей точки. */
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  z-index: var(--z-modal);
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-drawer);
  will-change: transform;
}
.drawer[data-state="open"] { transform: translateX(0); }

.sheet {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--z-modal);
  transform: translateY(100%);
  transition: transform var(--dur-slow) var(--ease-drawer);
  padding-bottom: env(safe-area-inset-bottom);
  overscroll-behavior: contain;
  will-change: transform;
}
.sheet[data-state="open"] { transform: translateY(0); }
/* Во время драга пальцем — без transition, после отпускания — пружина */
.sheet[data-dragging] { transition: none; }
.sheet[data-settling] { transition: transform var(--dur-spring) var(--ease-spring); }

/* ---------- 6. Тосты ---------- */
.toast {
  animation: fade-up var(--dur-base) var(--ease-out) both;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
.toast[data-state="closed"] { animation: fade-out var(--dur-exit) var(--ease-out) both; }

/* ---------- 7. Загрузка ---------- */
/* Скелетон: блик едет через transform, а не через background-position */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--skeleton);
  border-radius: var(--radius-sm);
  color: transparent;
  user-select: none;
}
.skeleton::after {
  content: "";
  position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent);
  animation: skeleton-shine 1.4s ease-in-out infinite;
}
@keyframes skeleton-shine { to { transform: translateX(100%); } }

/* Спиннер для кнопки в состоянии loading (16px, цвет = currentColor) */
.spinner {
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  flex: none;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Показывать индикатор загрузки только если ждём дольше ~300 мс,
   иначе он мелькнёт и создаст ощущение тормозов */
.delayed-appear { animation: fade-in var(--dur-base) var(--ease-out) 300ms both; }

/* ---------- 8. Графики: прорисовка при первом появлении ---------- */
/* Линия: <path pathLength="1" class="chart-draw">. Исключение из правила transform/opacity —
   stroke-dashoffset одной линии дёшев и не вызывает перекладку страницы. */
.chart-draw {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: chart-draw var(--dur-chart) var(--ease-out) forwards;
}
@keyframes chart-draw { to { stroke-dashoffset: 0; } }

/* Столбцы растут от базовой линии */
.chart-bar {
  transform-box: fill-box;
  transform-origin: bottom;
  animation: bar-grow var(--dur-chart) var(--ease-out) both;
  animation-delay: calc(min(var(--i, 0), 11) * 20ms);
}
.chart-bar--horizontal { transform-origin: left; animation-name: bar-grow-x; }
@keyframes bar-grow   { from { transform: scaleY(0); } }
@keyframes bar-grow-x { from { transform: scaleX(0); } }

/* Заливка области под линией — проявляется после линии */
.chart-area { animation: fade-in var(--dur-chart) var(--ease-out) 150ms both; }

/* Точки/маркеры — после прорисовки */
.chart-dot {
  transform-box: fill-box;
  transform-origin: center;
  animation: scale-in var(--dur-base) var(--ease-out) calc(var(--dur-chart) - 100ms) both;
}

/* Сегмент кольцевой диаграммы — та же техника, что и линия */
.chart-arc { stroke-dasharray: 1; stroke-dashoffset: 1; animation: chart-draw var(--dur-chart) var(--ease-out) forwards; }

/* ---------- 9. Смена значения (цифра обновилась по данным) ---------- */
/* Короткая подсветка фоном, не мигание текстом */
@keyframes value-flash {
  from { background-color: var(--accent-soft); }
  to   { background-color: transparent; }
}
.value-updated { animation: value-flash 900ms var(--ease-out); border-radius: var(--radius-xs); }

/* ---------- 10. Уменьшенное движение ---------- */
/* Не выключаем всё подряд: убираем перемещение и масштаб, оставляем мягкое
   появление прозрачностью — оно не вызывает укачивания и сохраняет смысл. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-distance: 0px;
    --motion-scale: 1;
    --press-scale: 1;
    --stagger: 0ms;
    --dur-chart: 0ms;
    --dur-count: 0ms;
  }
  .drawer, .sheet, .sheet[data-settling] {
    transition: opacity var(--dur-base) var(--ease-out);
  }
  .drawer:not([data-state="open"]),
  .sheet:not([data-state="open"]) { opacity: 0; pointer-events: none; }
  .skeleton::after { animation: none; display: none; }
  .spinner { animation-duration: 1.6s; } /* вращение — индикатор, не украшение: замедляем, не убираем */
  .chart-draw, .chart-arc { animation: none; stroke-dashoffset: 0; }
  .chart-bar, .chart-dot { animation: none; }
  .value-updated { animation: none; }
  html { scroll-behavior: auto; }
}
