/* ========================================================================
   РЕКЛАМНЫЕ БАННЕРЫ — единый вид во всех местах площадки (задача 06.08.2026).

   Один креатив на кампанию (рекомендация 1920×1080, принимаем любую пропорцию),
   поверх — необязательные заголовок и описание. Вывод сам подгоняет картинку
   под блок и анимирует:
     .gs-bnr--zoom-in / --zoom-out  — пропорция креатива совпала с блоком: картинка
                                      видна ЦЕЛИКОМ, медленный наезд/отъезд
                                      (направление чередуется между баннерами);
     .gs-bnr--pan                   — креатив в блок не вписался: прокрутка целиком
                                      (справа налево ИЛИ снизу вверх — по факту);
     .gs-bnr--text                  — картинки нет: живой градиент под текстом.
   Класс выбирает СЕРВЕР (AdBannerWidget::animationClass) по реальным размерам
   креатива из ad_banner.image_w/image_h.

   ⚠ Фон всегда background-size: cover — тогда пустых полей не бывает ни при какой
   пропорции, а прокрутка идёт ровно по той оси, которая вылезает за блок.

   ⚠ Прокрутка ОДНА на обе оси (`background-position: 0% 0% → 100% 100%`), а не две
   раздельные. При cover переполнение всегда ровно по одной оси, по второй проценты
   схлопываются в одно значение — значит движение получается именно по нужной оси,
   и серверу не надо угадывать её заранее. Разделение на --pan-x/--pan-y ломалось на
   брейкпоинтах: у полосы листинга блок 6:1 на десктопе и 2:1 на телефоне, а класс
   один на оба (ревью 06.08).

   ⚠ Имена .gs-bnr* — НЕ «ad-banner»: точные классы .ad-banner/.banner сидят
   в косметических фильтрах адблокеров, элемент прятался бы у их пользователей.
   ======================================================================== */

/* ── СЛОТ С РОТАЦИЕЙ ────────────────────────────────────────────────────
   Место под рекламу одно, кампании сменяют друг друга по таймеру (JS вешает
   .is-on, см. layouts/main.php). Геометрию места держит ОБЁРТКА, баннеры внутри
   лежат друг на друге. Смена — растворение + микро-наплыв, чтобы движение
   читалось как «сменился баннер», а не как мигание. */
.gs-rot { position: relative; }
.gs-rot > .gs-bnr {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: scale(1.015);
    transition: opacity .65s ease, transform .65s ease;
    pointer-events: none;
}
.gs-rot > .gs-bnr.is-on {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}
/* .is-on первому баннеру проставляет СЕРВЕР — без JS слот показывает его и молчит.
   Фолбэка на :first-child нет намеренно: он перебивал бы .is-on у второго баннера
   после смены, и на экране оказывались бы два баннера сразу. */

.gs-bnr {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: 12px;
    background: linear-gradient(135deg, #16221D 0%, #0E1211 100%);
    text-decoration: none;
    isolation: isolate;
}

/* Слой картинки: отдельный элемент, а не background самой ссылки — его можно
   двигать/масштабировать, не трогая текст и плашку «Реклама». */
.gs-bnr__media {
    position: absolute;
    inset: 0;
    z-index: 0;
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    will-change: transform, background-position;
}

/* Наезд/отъезд: пропорция креатива совпала с блоком, поэтому в кадре видно всё
   изображение (в крайней точке цикла срезается ~10% — компромисс ради движения).
   12 секунд и шаг 1.10: при 16 с и 1.07 движение было почти незаметным. */
.gs-bnr--zoom-in .gs-bnr__media  { animation: gsBnrZoomIn 12s ease-in-out infinite alternate; }
.gs-bnr--zoom-out .gs-bnr__media { animation: gsBnrZoomOut 12s ease-in-out infinite alternate; }
/* Прокрутка: за цикл показывается весь баннер целиком, туда и обратно (alternate). */
.gs-bnr--pan .gs-bnr__media { background-position: 0% 0%; animation: gsBnrPan 22s ease-in-out infinite alternate; }

@keyframes gsBnrZoomIn  { from { transform: scale(1); }    to { transform: scale(1.10); } }
@keyframes gsBnrZoomOut { from { transform: scale(1.10); } to { transform: scale(1); } }
@keyframes gsBnrPan { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }

/* Баннер без картинки (только текст): фирменный градиент, который медленно течёт. */
.gs-bnr--text .gs-bnr__media {
    background: linear-gradient(125deg, #14231C 0%, #1F5B3F 35%, #16221D 65%, #0E1211 100%);
    background-size: 260% 260%;
    animation: gsBnrFlow 24s ease-in-out infinite alternate;
}
@keyframes gsBnrFlow { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }

/* Затемнение под текстом: плотнее у низа, где лежит заголовок с описанием.
   Без текста вуаль не выводится вовсе — креатив рекламодателя не притеняем. */
.gs-bnr__veil {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(180deg, rgba(14, 18, 17, .12) 0%, rgba(14, 18, 17, .48) 52%, rgba(14, 18, 17, .88) 100%);
}

.gs-bnr__body {
    position: absolute;
    z-index: 2;
    left: 14px;
    right: 14px;
    bottom: 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.gs-bnr__head {
    font-size: 17px;
    font-weight: 700;
    line-height: 1.22;
    color: #fff;
    text-shadow: 0 1px 8px rgba(8, 12, 11, .6);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* Описание — ровно две строки: столько заложено в макет любого слота. */
.gs-bnr__desc {
    font-size: 13px;
    line-height: 1.35;
    color: rgba(255, 255, 255, .86);
    text-shadow: 0 1px 6px rgba(8, 12, 11, .55);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Появление текста — класс вешает JS (layouts/main.php) при попадании баннера
   в экран. Базовое состояние ВИДИМОЕ: если JS не отработал, текст просто стоит
   на месте, а не пропадает. */
.gs-bnr.is-inview .gs-bnr__head { animation: gsBnrRise .7s .05s both; }
.gs-bnr.is-inview .gs-bnr__desc { animation: gsBnrRise .7s .22s both; }
@keyframes gsBnrRise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Плашка «Реклама · рекламодатель» — обязательна по ФЗ «О рекламе». */
.gs-bnr__mark {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 3;
    max-width: calc(100% - 16px);
    padding: 4px 8px;
    border-radius: 7px;
    background: rgba(14, 18, 17, .55);
    color: #fff;
    font-size: 11px;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Идентификатор рекламы (erid) — ВИДИМОЙ подписью на самом креативе (ст. 18.1
   ФЗ «О рекламе»): title на телефоне не открыть. Угол напротив плашки. */
.gs-bnr__erid {
    position: absolute;
    right: 6px;
    bottom: 6px;
    z-index: 3;
    max-width: calc(100% - 12px);
    padding: 2px 6px;
    border-radius: 5px;
    background: rgba(14, 18, 17, .45);
    color: rgba(255, 255, 255, .85);
    font-size: 9px;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Текст стоит внизу — если внизу же erid, приподнимаем блок, чтобы не наезжали. */
.gs-bnr--has-erid .gs-bnr__body { bottom: 26px; }

/* ── Геометрия мест показа ──────────────────────────────────────────────
   Держит её ОБЁРТКА слота (.gs-rot--*), потому что баннеры внутри лежат
   абсолютом друг на друге. Сами баннеры несут только скругление.

   Главная: карточка промо-слайдера. Ширину и высоту задаёт слайдер
   (redesign.js держит карточки в пропорции 16:9 — креатив рекомендованного
   размера влезает целиком). */
.gs-rot--home, .gs-bnr--home { border-radius: var(--radius, 16px); }
/* Мобильная карусель главной: слот .m-promo__slot уже 16:9, обёртка тянется по нему. */
.gs-rot--mhome { position: absolute; inset: 0; }
.gs-bnr--mhome { border-radius: 16px; }

/* Каталог, под фильтром: вертикальный блок колонки сайдбара. Креатив-ландшафт
   прокручивается справа налево (--pan). */
.gs-rot--catalog { margin-top: 20px; aspect-ratio: 240 / 400; }
@media (max-width: 991px) {
    /* ≤991: карточка фильтра сворачивается (new-design.css @991), а на мобиле
       сайдбар встаёт НАД списком — баннер и торчал бы из «свёрнутого» фильтра,
       и раздувал первый экран. На телефонах виджет к тому же не рендерится
       вовсе (AdBanners::isMobileUa) — показ не засчитываем. */
    .gs-rot--catalog { display: none; }
}

/* Листинг, между рядами карточек: широкая полоса. Ландшафтный креатив в неё
   не влезает по высоте → прокрутка снизу вверх (--pan). ⚠ У этого места ДВЕ
   пропорции (6:1 и 2:1 ниже), поэтому сервер здесь никогда не выбирает зум. */
.gs-rot--listing { flex: 0 0 100%; width: 100%; aspect-ratio: 1200 / 200; }
@media (max-width: 767px) {
    /* 6:1 на телефоне выродилось бы в ленту ~60px: полоса становится 2:1.
       Отдельного мобильного креатива больше НЕТ — один креатив на кампанию. */
    .gs-rot--listing { aspect-ratio: 2 / 1; }
}

/* Вид «плиткой»: баннер — такая же карточка в сетке, как объявление. Ширину
   ячейки берём с класса .advert-item (он висит на обёртке вместе с этим),
   поэтому сетка не разъедется при правках колонок. */
.gs-rot--listing-tile { align-self: stretch; background: #F2F6F8; box-shadow: 0 4px 10px 0 #2427281A; }
/* ⚠ Пол высоты — с !important и специфичностью 0-3-0, иначе плитка СХЛОПНЕТСЯ
   (ревью 04.08): все её дети вне потока, контентная высота 0, а new-design.css
   на ≤400px кроет «.advert-page .advert-item{min-height:auto !important}».
   Схлопнутый баннер = показ засчитан, а CPM списан за невидимое. */
.advert-page .advert-items .gs-rot--listing-tile { min-height: 240px !important; }
@media (max-width: 767px) {
    .advert-page .advert-items .gs-rot--listing-tile { min-height: 200px !important; }
}

/* Доступность: с prefers-reduced-motion баннер стоит неподвижно. */
@media (prefers-reduced-motion: reduce) {
    .gs-bnr__media,
    .gs-bnr.is-inview .gs-bnr__head,
    .gs-bnr.is-inview .gs-bnr__desc { animation: none !important; }
}
