/* Слой движения поверх готовой вёрстки. Три приёма, все из монтажа,
   а не из веб-анимации: кадр открывается шторкой, склейка уходит в чёрное,
   кадр на карточке живёт петлёй трейлера.

   Правила слоя:
   - анимируются только transform и opacity; ни одно свойство раскладки
     не меняется ни в начале, ни в конце;
   - конечное состояние каждого приёма совпадает с вёрсткой без этого файла
     пиксель в пиксель: псевдоэлемент шторки уезжает за overflow и гаснет,
     склейка стоит в opacity 0, петля в opacity 0;
   - всё, что зависит от JS, привязано к классу html.tf-js, который ставит
     строчный скрипт в <head> до первой отрисовки. Без скрипта ни шторки,
     ни склейки нет, страница сразу в конечном состоянии;
   - при prefers-reduced-motion: reduce весь файл не действует: каждый
     приём лежит внутри @media (prefers-reduced-motion: no-preference);
   - какое устройство перед нами, решает CSS (hover, pointer), скрипт
     читает результат через checkVisibility(), а не через matchMedia;
   - всё только для экрана (@media screen): на печати и в PDF страница
     в конечном состоянии, ни шторок, ни слоя склейки. */

/* ---- 1. Шторка кадра. Псевдоэлемент цвета фона лежит поверх кадра
   и уезжает вправо, когда скрипт даёт .tf-frame--open: когда видно
   не меньше трёх четвертей кадра, а для кадра выше окна - когда его верх
   поднялся выше трети экрана. Кадр открывается слева направо,
   как в ленте кадров, куда они и въезжают справа.
   Кадр .hero__frame первого экрана классом .tf-frame не является
   и шторки не получает. ---- */
@media screen and (prefers-reduced-motion:no-preference){
  html.tf-js .tf-frame::after{content:"";position:absolute;inset:0;z-index:2;background:var(--bg,#0A0A0A);pointer-events:none;transform:translateX(0);transition:transform var(--dur-reveal,600ms) var(--ease-reveal,cubic-bezier(0.3,0,0.4,1)),visibility 0s linear var(--dur-reveal,600ms)}
  html.tf-js .tf-frame--open::after{transform:translateX(100%);visibility:hidden}
  /* Возврат по истории (класс ставит строчный скрипт в <head> по типу
     навигации back_forward): кадры уже показывали, второй раз не играют */
  html.tf-back .tf-frame::after{content:none}
}
/* Горизонтальные ленты на телефоне (до 767 включительно): шторки нет, кадр
   показан сразу. Карточка за краем окна шторку не открывает: наблюдатель ждёт
   три четверти видимости, а при свайпе карточка входит в окно постепенно,
   и до открытия видна чёрным прямоугольником (замечание заказчика 15.09 про
   кадры фильма; 16.09 то же у ленты постеров главной; 18.09 - у лент
   карточек фильмов: вторая карточка «Других фильмов» на странице фильма
   и «Наших работ» на «О нас» видна на 94 px из 260 и стоит закрытой).
   Ленты: .gallery (постеры на главной, кадры на странице фильма) и карточки-
   ссылки a.films__item в .films («Другие фильмы» на страницах фильмов, «Наши
   работы» на «О нас»; в разделе «Фильмы» .films - столбец карточек-статей,
   не лента, у них шторка остаётся). На широких экранах шторка остаётся
   и открывается один раз на всю ленту (motion-layer.js). Решает
   медиазапрос, а не замер в скрипте. */
@media screen and (max-width:767px){
  html.tf-js .gallery .tf-frame::after,
  html.tf-js .films a.films__item .tf-frame::after{content:none}
}

/* ---- 2. Петля трейлера на карточке раздела «Фильмы». Элемент <video>
   стоит в разметке без <source>, адреса лежат в data-атрибутах, и пока
   скрипт не подставит их по наведению, не грузится ни байта.
   На устройствах без точного указателя элемент спрятан правилом CSS,
   скрипт видит это через checkVisibility() и адресов не подставляет.
   pointer-events:none: наведение читается с карточки, а клик по кадру
   должен доходить до картинки, иначе панель не даст заменить обложку.
   На постерах ленты главной петли нет (решение заказчика 15.09): в их
   разметке нет <video>, постер виден всегда, без перехода прозрачности. ---- */
.tf-frame__loop{display:none}
@media screen and (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  html.tf-js .tf-frame__loop{display:block;position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:cover;object-position:center;opacity:0;pointer-events:none;filter:var(--img-filter-lit,brightness(1) contrast(1.02) saturate(0.9));transition:opacity var(--dur-base,400ms) var(--ease,cubic-bezier(0.2,0,0,1))}
  html.tf-js .tf-frame--letterbox .tf-frame__loop{object-fit:contain}
  html.tf-js .tf-frame--live .tf-frame__loop{opacity:1}
}

/* ---- 3. Склейка между страницами. Слой цвета фона над всем, включая
   шапку (z 50) и окно трейлера (z 100). На новой странице он появляется
   непрозрачным и гаснет анимацией CSS, скрипту для этого работать
   не нужно. Уход в чёрное даёт класс .tf-cut--out по клику на свою
   ссылку. Без JS слоя нет вовсе. Кривая линейная (--ease-cut): наплыв
   в чёрное и из чёрного идёт ровно, как в монтаже; общая --ease в обе
   стороны давала два хлопка по 100 мс. Если переход не состоялся
   (Стоп, «Остаться» в beforeunload, обрыв сети), скрипт снимает класс
   по сторожевому таймеру. ---- */
.tf-cut{display:none}
@media screen and (prefers-reduced-motion:no-preference){
  html.tf-js .tf-cut{display:block;position:fixed;inset:0;z-index:200;background:var(--bg,#0A0A0A);opacity:0;pointer-events:none;transition:opacity var(--dur-cut,200ms) var(--ease-cut,linear);animation:tf-cut-in var(--dur-cut,200ms) var(--ease-cut,linear) backwards}
  /* animation:none: если клик пришёлся на первые 200 мс, пока идёт проявление,
     анимация перебила бы переход и уход ждал бы страховочный таймер */
  html.tf-js .tf-cut--out{opacity:1;pointer-events:auto;animation:none}
  @keyframes tf-cut-in{from{opacity:1}to{opacity:0}}
}
