/* ==========================================================================
   БЕСШОВНЫЙ ПЕРЕХОД «Разводящая объекты» → «Страница объекта»
   (Figma: section 78:14274 «АНИМАТИКА: Бесшовный переход с разводящей на
   страницу кейса», кадры 78:14275 / 78:14313 / 78:14371).

   Механика по трём кадрам макета:
     1. Кадр 1 — разводящая: шапка (96) + крошки (55), ниже картинка активного
        объекта 1900×929, слева панель «Фильтр объектов», справа внизу стрелки.
     2. Кадр 2 — панель, стрелки, шапка и крошки ушли; картинка доросла до
        1900×1070, то есть съела полосу шапки и крошек сверху.
     3. Кадр 3 — сверху въехали overlay-шапка и светлые крошки (уже с третьим
        пунктом — названием объекта), снизу проявились заголовок с фактами
        и промо категории оборудования.

   Делается на Cross-Document View Transitions: обе страницы остаются обычными
   серверными документами со своими URL и мета — переход рисует браузер поверх
   штатной навигации. Браузеры без поддержки (сейчас Firefox) молча делают
   обычный переход: и @view-transition, и view-transition-name, и ::view-
   transition-* им неизвестны и отбрасываются. Запасной ветки не требуется.

   Подключается только на objects.php и case-object.php — то есть переход
   работает лишь между ними. Навигация на прочие страницы (они правило не
   объявляют) идёт как раньше: для межстраничного перехода оба документа
   обязаны включить его у себя.

   ВАЖНО: правило @view-transition продублировано инлайном в <head> обеих
   страниц, и убирать его оттуда нельзя. Проверено на живых страницах: когда
   опт-ин лежал только здесь — в последнем из девяти внешних стилей — уходящая
   страница снимок делала (событие pageswap приходило с viewTransition), а
   входящий документ переход не подхватывал, и он молча отменялся. Переход
   заработал ровно после того, как правило появилось в <head> до <link>'ов.
   Здесь оно оставлено, чтобы файл был самодостаточным.

   В Битрикс/WP переезжает как есть: файл в шаблон, классы не меняются.
   ========================================================================== */

@view-transition {
  navigation: auto;
}

:root {
  /* Общая длительность = ход картинки. Уходящее укладывается в первую треть,
     въезжающее стартует с задержкой, когда картинка уже пошла вверх. */
  --vt-duration: 620ms;
  --vt-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- Кадры ---------------------------------------------------------------- */

@keyframes vt-fade-out {
  to { opacity: 0; }
}

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

/* Шапка и крошки разводящей уходят вверх за край экрана (кадр 1 → 2) */
@keyframes vt-slide-up-out {
  to {
    opacity: 0;
    transform: translateY(-100%);
  }
}

/* Шапка и крошки кейса въезжают сверху (кадр 2 → 3) */
@keyframes vt-slide-down-in {
  from {
    opacity: 0;
    transform: translateY(-100%);
  }
}

/* Панель «Фильтр объектов» сходит влево, к своему краю */
@keyframes vt-slide-left-out {
  to {
    opacity: 0;
    transform: translateX(-24px);
  }
}

/* Заголовок и промо кейса проявляются снизу */
@keyframes vt-rise-in {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
}

/* --- Имена групп ----------------------------------------------------------
   Именованный элемент вынимается из общего снимка страницы и едет отдельной
   группой. Имя, встречающееся на обеих страницах (object-image), даёт морфинг
   старого бокса в новый; имя, которое есть только на одной, — чистый уход или
   чистое появление.

   Всё это только с 1024: ниже разводящая — статичная сетка карточек, общей
   картинки нет и морфить нечего. Там остаётся штатный кроссфейд документов.  */

@media (min-width: 768px) {

  /* Единственный общий элемент: картинка объекта. Скругление и обрезку задаём
     самому именованному элементу — снимок группы не наследует overflow предка,
     и без этого на время перехода у картинки были бы прямые углы. */
  .objects-page .object-list__bgs,
  .case-page .case-hero__bg {
    overflow: hidden;
    border-radius: 10px;
    view-transition-name: object-image;
  }

  /* Уходит (разводящая) */
  .objects-page .header       { view-transition-name: list-header; }
  .objects-page .crumbs       { view-transition-name: list-crumbs; }
  .objects-page .object-list__veil {
    overflow: hidden;
    border-radius: 10px;
    view-transition-name: list-veil;
  }
  .objects-page .object-list__panel { view-transition-name: list-panel; }
  .objects-page .object-list__nav   { view-transition-name: list-nav; }

  /* Появляется (кейс) */
  .case-page .header          { view-transition-name: case-header; }
  .case-page .case-crumbs     { view-transition-name: case-crumbs; }
  .case-page .case-hero__veil {
    overflow: hidden;
    border-radius: 10px;
    view-transition-name: case-veil;
  }
  .case-page .case-hero__text { view-transition-name: case-text; }
  .case-page .case-promo      { view-transition-name: case-promo; }
}

/* --- Картинка: морфинг бокса ----------------------------------------------
   Старый бокс — остаток экрана под шапкой и крошками, новый — почти весь
   экран: картинка растёт вверх, боковые и нижний края стоят на месте.

   object-fit: cover на снимках обязателен. По умолчанию снимок растягивается
   под меняющийся бокс (fill) — картинка на ходу «плыла» бы по вертикали.
   С cover оба слоя кадрируются ровно так же, как настоящая картинка сцены. */

::view-transition-group(object-image) {
  animation-duration: var(--vt-duration);
  animation-timing-function: var(--vt-ease);
}

::view-transition-old(object-image),
::view-transition-new(object-image) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  animation-duration: var(--vt-duration);
  animation-timing-function: var(--vt-ease);
}

/* --- Уход элементов разводящей (кадр 1 → 2) ------------------------------- */

::view-transition-old(list-header),
::view-transition-old(list-crumbs) {
  animation: vt-slide-up-out 320ms var(--vt-ease) both;
}

::view-transition-old(list-panel) {
  animation: vt-slide-left-out 280ms var(--vt-ease) both;
}

::view-transition-old(list-veil),
::view-transition-old(list-nav) {
  animation: vt-fade-out 220ms var(--vt-ease) both;
}

/* --- Появление элементов кейса (кадр 2 → 3) -------------------------------
   Задержка + fill both: пока картинка идёт вверх, входящие слои держат своё
   стартовое состояние. Без both они моргнули бы в полную непрозрачность
   до начала собственной анимации. */

::view-transition-new(case-veil) {
  animation: vt-fade-in 360ms var(--vt-ease) 220ms both;
}

::view-transition-new(case-header),
::view-transition-new(case-crumbs) {
  animation: vt-slide-down-in 340ms var(--vt-ease) 280ms both;
}

::view-transition-new(case-text),
::view-transition-new(case-promo) {
  animation: vt-rise-in 380ms var(--vt-ease) 320ms both;
}

/* --- Остальная страница: кроссфейда нет, и это главное для плавности --------
   Всё неименованное едет одной группой root. По умолчанию она кроссфейдится —
   а это два слоя размером с окно, которые смешиваются каждый кадр. Оказалось,
   что именно они и делали переход дёрганым.

   Замер на кадре 1920×1080 (счётчик кадров между viewTransition.ready и
   .finished, без троттлинга процессора):
     • с кроссфейдом root ......... 22 fps, худший кадр 133 мс;
     • без него ................... 46 fps, худший кадр 27 мс.
   Для сравнения: отключение JS блоков давало 29 fps, отключение морфинга
   картинки — 31 fps. То есть дело было не в скриптах и не в самой анимации.

   Платы за это нет: в кадре всё видимое уже разобрано на именованные группы
   (картинка, вуаль, панель, стрелки, шапка, крошки), а на root остаётся полоска
   фона страницы по краям да то, что ниже сгиба. Поэтому старый снимок просто
   убираем, а новый показываем сразу, без анимации.

   Убирать заодно и вуали смысла нет: проверено, это всего +4 fps, зато градиент
   начинает возникать рывком вместо плавного проявления.

   Только с 1024. Ниже имён групп нет вовсе, и кроссфейд root там — это и есть
   весь переход: сняли бы его — получили бы резкую подмену страницы. На узком
   экране он и стоит дёшево, слои размером с телефон. */

@media (min-width: 768px) {
  ::view-transition-old(root) {
    display: none;
  }

  ::view-transition-new(root) {
    animation: none;
  }
}

/* --- Уважение к системной настройке --------------------------------------
   Переход схлопывается в мгновенную смену кадра: движение убрано, навигация
   при этом обычная и работает как всегда. */

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
  }
}
