/* Кадр ещё грузится — рамка идёт бликом, а не стоит пустой плашкой.

   Alexa, 24.09.2026: на медленном интернете карточки должны показывать, что
   они грузятся, а не стоять пустыми. Образец — её ссылка на unlumen-ui
   shimmer-skeleton: полоса 6 % цвета текста, проход 1.6 с, ease-in-out, от
   −100 % до 200 % ширины рамки. Числа взяты оттуда как есть.

   Замер до правки (Fast 3G, 390×844): плитки первого экрана 4 с стояли
   пустыми серыми коробками, потом кадр проявлялся полосой сверху вниз и
   дорисовывался к 14-й секунде.

   Механика. Скрипт в <head> (`MEDIA_LOAD` в new-home/build.mjs) ставит на
   <html> класс `ml` и помечает картинку `is-in`, когда она пришла целиком,
   `is-out` — если не пришла. Без скрипта класса нет: картинки видны как
   раньше, блика нет. Пришедший кадр проявляется целиком, а не полосой.

   Блик живёт только в рамке, где прямо лежит ещё не пришедшая картинка.
   Рамки без картинки (карточки под NDA) его не получают; в галерее блик идёт
   только по видимому кадру, а не по всем, что стоят под ним стопкой. */

:root {
  --ml-glint: rgba(234, 234, 234, 0.06);
  --ml-sweep: 1.6s;
  --ml-fade: 0.4s;
}

html.ml :is(.hero-frag-media, .sps-media, .svs-media, .cse-media, .spv-media) img {
  transition: opacity var(--ml-fade) ease;
}
html.ml :is(.hero-frag-media, .sps-media, .svs-media, .cse-media, .spv-media) img:not(.is-in) {
  opacity: 0;
}
/* Кадр из кэша при открытии страницы не проявляется, а просто стоит. */
html.ml :is(.hero-frag-media, .sps-media, .svs-media, .cse-media, .spv-media) img.is-now {
  transition: none;
}

/* Эти три рамки не позиционированы; блику нужна система координат только
   на время загрузки, потом рамка возвращается к своей раскладке. */
html.ml :is(.svs-media, .cse-media, .spv-media):has(> img:not(.is-in, .is-out), > picture > img:not(.is-in, .is-out)) {
  position: relative;
}
html.ml :is(.hero-frag-media, .sps-media, .svs-media, .cse-media, .spv-media, .gal-frame.is-on):has(> img:not(.is-in, .is-out), > picture > img:not(.is-in, .is-out))::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg, transparent 0%, var(--ml-glint) 50%, transparent 100%);
  transform: translateX(-100%);
  animation: ml-sweep var(--ml-sweep) ease-in-out infinite;
}

@keyframes ml-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(200%); }
}

/* Без движения — ровная подсветка вместо прохода. Селектор повторён целиком:
   укороченный проигрывает по весу правилу выше. */
@media (prefers-reduced-motion: reduce) {
  html.ml :is(.hero-frag-media, .sps-media, .svs-media, .cse-media, .spv-media, .gal-frame.is-on):has(> img:not(.is-in, .is-out), > picture > img:not(.is-in, .is-out))::after {
    animation: none;
    transform: none;
    background: var(--ml-glint);
  }
  html.ml :is(.hero-frag-media, .sps-media, .svs-media, .cse-media, .spv-media) img { transition: none; }
}
