/* ============================================================
   A.L.E.X. — ПУЛЬС-ПОЛОСКА ПОД ШАПКОЙ (задача 1820, пункт 4;
   правило Б2-036 — то же, по которому дышит галактика первого экрана).

   ЧТО ЭТО. Полоска в два пикселя по нижнему краю шапки. По ней слева
   направо идёт мягкий блик. Скорость блика — от числа задач, которые
   цех ведёт прямо сейчас: ноль задач — почти стоит (медленный дрейф,
   а не мёртвый экран), больше задач — быстрее, с потолком.

   ПОЧЕМУ ЭТО CSS-АНИМАЦИЯ, А НЕ ХОЛСТ С requestAnimationFrame.
   Полоска висит на КАЖДОЙ из 219 страниц и живёт всё время, пока
   открыта вкладка. Холст с кадровым циклом означал бы, что на каждой
   странице сайта постоянно крутится JS — это греет батарею телефона
   ровно за декоративный блик. Здесь же скорость задана одной
   переменной --puls-sek, анимацию крутит композитор браузера на
   видеокарте, а JS просыпается раз в 45 секунд, чтобы переписать эту
   переменную. Между пробуждениями кадровой работы на процессоре нет
   вообще — отсюда и 50+ кадров, и холодная батарея.

   ДВИЖЕНИЕ — ТОЛЬКО transform. translateX композитор делает без
   пересчёта разметки и без перерисовки страницы; анимация left или
   background-position стоила бы перерисовки каждый кадр.

   «УМЕНЬШИТЬ ДВИЖЕНИЕ». При prefers-reduced-motion полоска СТАНОВИТСЯ
   СТАТИЧНОЙ — ровная тихая линия по всей ширине. Не прячем совсем:
   человек, который выключил анимации, не обязан лишаться слоя, он
   просил не двигать. Движения не остаётся никакого.
   ============================================================ */

.puls-polosa {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;          /* ложится ровно на нижнюю границу шапки */
  height: 2px;
  overflow: hidden;
  pointer-events: none;  /* полоска декоративная — клики сквозь неё */
  contain: strict;       /* её перерисовка не трогает остальную страницу */
}

/* Блик. Ширина в 38 % полосы: короткий штрих читается как «идёт
   работа», сплошная заливка читалась бы как «полоса загрузки». */
.puls-polosa i {
  position: absolute;
  top: 0;
  bottom: 0;
  left: -38%;
  width: 38%;
  background: linear-gradient(90deg,
              transparent,
              color-mix(in srgb, var(--accent) 85%, transparent),
              transparent);
  opacity: .5;
  will-change: transform;
  animation: puls-beg var(--puls-sek, 20s) linear infinite;
}

/* Крайние точки: от -38 % до 100 % ширины полосы, то есть блик
   выходит из-за левого края и уходит за правый целиком. */
@keyframes puls-beg {
  from { transform: translateX(0); }
  to   { transform: translateX(363%); }
}

/* Светлая тема: на белом фоне тот же блик виден слабее — добавляем. */
html[data-theme="light"] .puls-polosa i { opacity: .62; }

/* ТЕЛЕФОН — ЛЕГЧЕ. Полоска тоньше и бледнее: на маленьком экране
   двухпиксельная яркая линия спорит с шапкой, а не поддерживает её.
   will-change снимаем — на телефоне лишний композиторский слой
   дороже, чем выигрыш от него на такой мелкой анимации. */
@media (max-width: 640px) {
  .puls-polosa { height: 1px; }
  .puls-polosa i { opacity: .42; will-change: auto; }
}

/* УМЕНЬШИТЬ ДВИЖЕНИЕ — СТАТИКА. Ни анимации, ни трансформации. */
@media (prefers-reduced-motion: reduce) {
  .puls-polosa i {
    animation: none;
    transform: none;
    left: 0;
    width: 100%;
    opacity: .3;
    will-change: auto;
    background: linear-gradient(90deg,
                transparent,
                color-mix(in srgb, var(--accent) 55%, transparent),
                transparent);
  }
}

/* Вкладка не на экране — движение не нужно совсем: страница в фоне
   не должна тратить ни кадра. Класс вешает puls.js по visibilitychange. */
.puls-polosa.puls--spit i { animation-play-state: paused; }
