/* ============================================================
   AD-KIT · рекламные модули портала DERBYLY  (SOR-680, Pixel)
   ------------------------------------------------------------
   ЭТО СЛОЙ НОВЫХ ПРАВИЛ ПОВЕРХ ТЕМЫ. Подключать ПОСЛЕ
   fonts.css → tokens.css → global.css → home.css → ui-kit.css →
   templates.css → media.css → cookie.css.  Тогда правила этого
   файла перекрывают прежнюю реализацию слотов 1:1.

   Что здесь есть (и чего нет):
   + токены размеров/ритма/состояний слотов (--ad-*),
   + каркас слота с ЖЁСТКО ЗАРЕЗЕРВИРОВАННОЙ высотой (CLS = 0),
   + мульти-слайдер N креативов + счётчик/точки + метка «Реклама»,
   + стопка 2–4 баннеров 300×600 + правила вертикального ритма,
   + in-article 728×90, bottom 970×250,
   + mobile sticky 320×100 / 320×50 + правила против контента и cookie,
   + состояния: filled / empty / error (+ 1 партнёр, N партнёров),
   + тёмная тема (overlay) — портал её ещё не включает, слоты готовы.

   НЕ здесь: PHP-рендер слота (inc/structure.php), ротация-таймер
   (assets/sp.js), трекинг клика (mu-plugin derbyly-affiliate.php).
   Точки подключения перечислены в README.md этого каталога.
   ============================================================ */

/* ---------- 1. ТОКЕНЫ КИТА (расширение :root темы) ---------- */
:root {
  /* размеры креативов: рекламодатель присылает ровно эти */
  --ad-top-w: 970px;   --ad-top-h: 250px;   /* leaderboard */
  --ad-inline-w: 728px; --ad-inline-h: 90px; /* in-article */
  --ad-side-w: var(--w-ad); /* 300px */ --ad-side-h: 600px; /* half-page */
  --ad-sticky-w: 320px; --ad-sticky-h: 100px; --ad-sticky-h-sm: 50px;

  /* геометрия каркаса */
  --ad-pad:    var(--sp-3);   /* 12px — поле рамки вокруг креатива */
  --ad-pad-sm: var(--sp-2);   /* 8px  — то же на ≤760px */
  --ad-radius: var(--r-lg);   /* 16px */
  --ad-box-radius: var(--r-sm); /* 8px — внутреннее окно креатива */
  --ad-frame: calc(var(--bw-strong) * 2); /* 4px — рамка слота по кругу */
  /* внешние габариты слота = окно креатива + поле рамки + сама рамка:
     только так окно получает РОВНО 970/728/300/320 px и
     пропорция креатива не «съедается» на пару процентов */
  --ad-outer-top:    calc(var(--ad-top-w) + var(--ad-pad) * 2 + var(--ad-frame));
  --ad-outer-inline: calc(var(--ad-inline-w) + var(--ad-pad) * 2 + var(--ad-frame));
  --ad-outer-side:   calc(var(--ad-side-w) + var(--ad-pad) * 2 + var(--ad-frame));
  --ad-dot: 8px;
  --ad-min-h-sm: 100px;       /* минимальная высота слота на мобиле */
  --ad-side-max: 4;           /* максимум баннеров в стопке (правило ритма R3) */

  /* вертикальный ритм */
  --ad-stack-gap:    var(--sp-block); /* 24px — шаг между баннерами стопки */
  --ad-stack-gap-sm: var(--sp-4);     /* 16px — то же на ≤1000px */
  --ad-stack-top:    var(--sp-6);     /* 24px — от блока контента до стопки */
  --ad-header-h: 72px;                /* липкая шапка портала (для sticky-сдвига) */
  --ad-head-top: calc(var(--ad-header-h) + var(--sp-5));

  /* поверхности и линии состояний */
  --ad-surface:        var(--surface-soft);  /* пусто / ошибка */
  --ad-surface-filled: var(--surface);       /* есть креатив */
  --ad-line:           var(--line-strong);
  --ad-label-bg:       var(--surface-page);  /* фон, на котором лежит верхняя
                                                рамка слота (метка «Реклама») */
  --ad-err:            var(--warning);
  --ad-z-sticky: 25;                         /* ниже cookie-баннера (30) */
}

/* ---------- 1b. ТЁМНАЯ ТЕМА (overlay-предложение) ----------
   Портал сегодня тёмной темы не имеет (нет ни prefers-color-scheme,
   ни data-theme в теме). Этот блок — заготовка: когда тема включит
   свой тёмный контур, слоты заработают без правок. В демо-прототипе
   overlay применяется к странице целиком, чтобы проверить контраст. */
:root[data-theme="dark"] {
  --ed-white: #0b0d0f; --ed-light: #15181c; --ed-paper: #15181c;
  --surface-page: var(--ed-white); --surface-soft: var(--ed-light);
  --surface: var(--ed-paper); --surface-muted: #22262b;
  --ink-900: #ffffff; --ink-700: rgba(255, 255, 255, .82);
  --ink-500: rgba(255, 255, 255, .68); --ink-400: rgba(255, 255, 255, .55);
  --line: #2c3238; --line-strong: #3a4148; --line-dark: rgba(255, 255, 255, .14);
  --text: var(--ink-900); --text-secondary: var(--ink-700); --text-muted: var(--ink-500);
  --focus: var(--energy);
  --ad-surface: #15181c; --ad-surface-filled: #15181c;
  --ad-line: #3a4148; --ad-label-bg: #0b0d0f; --ad-err: #f0a33a;
  --sh-1: 0 1px 2px rgba(0, 0, 0, .5);
  --sh-2: 0 2px 10px rgba(0, 0, 0, .6);
  --sh-3: 0 10px 30px rgba(0, 0, 0, .7);
}

/* ---------- 2. КАРКАС СЛОТА ----------
   Высота слота задана ДО загрузки креатива:
   [ рамка 2px + поле --ad-pad ] + окно креатива с aspect-ratio.
   Ни один внешний размер не зависит от того, загрузилась картинка
   или нет → сдвига вёрстки (CLS) при ротации/ошибке нет. */
.ad-slot {
  position: relative;
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  padding: var(--ad-pad);
  border: var(--bw-strong) dashed var(--ad-line);
  border-radius: var(--ad-radius);
  background: var(--ad-surface);
}

/* окно креатива: единый носитель пропорции — и для слайдера, и для фоллбэка
   (поэтому пустой слот занимает РОВНО ту же высоту, что и заполненный) */
.ad-box--top,
.ad-box--inline,
.ad-box--side,
.ad-box--sticky {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: var(--ad-box-radius);
}
.ad-box--top    { aspect-ratio: 970 / 250; max-width: var(--ad-top-w); margin-inline: auto; }
.ad-box--inline { aspect-ratio: 728 / 90;  max-width: var(--ad-inline-w); margin-inline: auto; }
.ad-box--side   { aspect-ratio: 300 / 600; max-width: var(--ad-side-w); margin-inline: auto; }
.ad-box--sticky { aspect-ratio: 320 / 100; margin-inline: auto; }

/* метки на верхней рамке: «Реклама» слева, счётчик «1/N» справа */
.ad-label,
.ad-count {
  position: absolute; top: calc(-1 * var(--sp-2)); z-index: 3;
  background: var(--ad-label-bg);
  padding: 0 var(--sp-2);
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--text-muted); white-space: nowrap; line-height: 1.4;
}
.ad-label { left: var(--sp-4); }
.ad-count { right: var(--sp-4); font-variant-numeric: tabular-nums; }

/* ---------- 3. СЛАЙДЕР N КРЕАТИВОВ ---------- */
.ad-slider { position: relative; min-height: 0; }
.ad-slide {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-base);
}
.ad-slide.is-on { opacity: 1; visibility: visible; position: relative; }
.ad-slide img {
  display: block; width: 100%; height: 100%;
  object-fit: contain; border-radius: var(--ad-box-radius);
}

/* точки индикации: лежат в поле рамки, креатив НЕ перекрывают */
.ad-dots {
  position: absolute; left: 50%; z-index: 3;
  bottom: calc((var(--ad-pad) - var(--ad-dot)) / 2);
  transform: translateX(-50%);
  display: flex; gap: var(--sp-2);
}
.ad-dot {
  position: relative;
  width: var(--ad-dot); height: var(--ad-dot);
  padding: 0; border: 0; border-radius: var(--r-full);
  background: var(--ad-line); cursor: pointer;
}
.ad-dot::after { content: ""; position: absolute; inset: -11px; } /* хит-зона ≥24px */
.ad-dot.is-on { background: var(--energy-dk); }
.ad-dot:focus-visible { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }

/* ---------- 4. РАЗМЕЩЕНИЕ МОДУЛЕЙ В СЕТКЕ ПОРТАЛА ---------- */
.ad-top,
.ad-bottom {
  width: 100%;
  max-width: var(--ad-outer-top);
  margin-inline: auto;
}
.ad-top    { margin: 0 auto var(--sp-section); }   /* 56px — как было в теме */
.ad-bottom { margin: var(--sp-section) auto 0; }
.ad-in-article {
  width: 100%;
  max-width: var(--ad-outer-inline);
  margin: var(--sp-6) auto;                        /* 24px сверху и снизу */
}
.ad-slot.ad-sidebar {
  width: 100%;
  max-width: var(--ad-outer-side);
  margin: 0 auto;
}

/* ---------- 5. СТОПКА САЙДБАРА (2–4 × 300×600) ----------
   R1: от контента до стопки — --ad-stack-top (24px).
   R2: между баннерами — --ad-stack-gap (24 / 16px).
   R3: максимум 4 баннера; сервер отдаёт не больше.
   R4: sticky включается ТОЛЬКО если стопка целиком влезает в экран
       (класс .is-sticky ставит sp.js: height ≤ 100vh − шапка − 24px).
   R5: ≤1000px стопка уходит под контент (портал уже так делает),
       ≤760px слот скрыт — мобильную монетизацию несут top/in-article/sticky. */
.ad-stack {
  display: grid;
  gap: var(--ad-stack-gap);
  justify-items: center;
  width: 100%;
  max-width: var(--ad-outer-side);
  margin: var(--ad-stack-top) auto 0;
}
/* Боковая колонка в рубриках исторически 300px. Выводим слот наружу на 28px,
   чтобы внутренний бокс 300×600 не ужимался из-за рамки и padding слота. */
.ad-stack .ad-slot.ad-sidebar {
  width: calc(100% + var(--ad-outer-side) - var(--ad-side-w));
  max-width: var(--ad-outer-side);
}
.ad-stack .ad-box--side { flex: 0 0 var(--ad-side-w); width: var(--ad-side-w); }
.ad-stack.is-sticky {
  position: sticky;
  top: var(--ad-head-top);
  align-self: start;
}

/* ---------- 6. MOBILE STICKY 320×100 / 320×50 ----------
   Бар живёт вне потока (fixed) — контент под ним не «уезжает».
   Место под бар резервирует body.ad-sticky-open (padding-bottom):
   padding-bottom документа не сдвигает контент, только высоту скролла.
   Пока открыт cookie-баннер — бар НЕ показывается (не перекрываем его). */
.ad-sticky {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--ad-z-sticky);
  display: none;
  justify-content: center; align-items: center;
  padding: var(--sp-3) var(--sp-3) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: var(--bw) solid var(--ad-line);
  box-shadow: 0 -8px 24px rgba(11, 13, 15, .18);
  --ad-label-bg: var(--surface);
}
.ad-sticky.is-live { display: flex; }
.ad-sticky .ad-slot {
  padding: 0; border-style: solid;
  max-width: min(calc(var(--ad-sticky-w) + var(--ad-frame)), calc(100% - 32px));
  background: var(--surface);
}
.ad-sticky .ad-slider,
.ad-sticky .ad-fallback { border-radius: var(--ad-box-radius); }
.ad-sticky.is-compact .ad-box--sticky { aspect-ratio: 320 / 50; }

.ad-sticky-close {
  position: absolute; top: 4px; right: 4px;
  width: 24px; height: 24px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--on-dark-14); border-radius: var(--r-sm);
  background: rgba(11, 13, 15, .72); color: #fff;
  font-size: var(--fs-sm); line-height: 1; cursor: pointer;
}
.ad-sticky-close:hover { background: rgba(11, 13, 15, .9); }
.ad-sticky-close:focus-visible { outline: var(--focus-width) solid var(--energy); outline-offset: 2px; }

/* резерв под бар: padding в конце документа контент не двигает */
.ad-sticky-open { padding-bottom: calc(var(--ad-sticky-h) + var(--sp-6)); }
.ad-sticky-open.is-ad-compact { padding-bottom: calc(var(--ad-sticky-h-sm) + var(--sp-6)); }
/* cookie-баннер важнее: пока согласие не дано, бар молчит.
   Класс ставится на <body> (в проде) или на общий контейнер (в ките) —
   правило одинаково работает, потому что не привязано к body. */
.cookie-open .ad-sticky { display: none; }

/* ---------- 7. СОСТОЯНИЯ ----------
   filled — креатив(ы) на месте;  empty — продано 0;  error — креатив(ы) не пришли.
   Все три занимают ОДНУ И ТУ ЖЕ высоту: сетка без «дыр» и без скачков. */
.ad-slot[data-state="filled"] { border-style: solid; background: var(--ad-surface-filled); }
.ad-slot[data-state="empty"]  { border-style: dashed; background: var(--ad-surface); }
.ad-slot[data-state="error"]  { border-style: dashed; border-color: var(--ad-err); background: var(--ad-surface); }

.ad-fallback {
  /* фоллбэк — это ТО ЖЕ окно слота (класс ad-box--* даёт ему aspect-ratio),
     поэтому высота слота не зависит от того, продано место или нет.
     В потоке — не absolute: иначе окно не задаёт высоту слота. */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-2);
  text-align: center;
  background: var(--ad-surface);
}
.ad-body {
  font-size: var(--fs-sm); color: var(--text-muted);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
}
.ad-slot[data-state="error"] .ad-body { color: var(--ad-err); }
.ad-link {
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  color: var(--energy-text); white-space: nowrap;
  transition: color var(--t-fast);
}
.ad-link:hover { color: var(--text); }
:root[data-theme="dark"] .ad-link { color: var(--energy); }
.ad-actions { display: flex; align-items: center; gap: var(--sp-4); }

/* ---------- 8. МОБИЛЬНЫЕ ПРАВИЛА (≤760px) ----------
   Слоты не «тощие»: окно креатива не ниже --ad-min-h-sm, картинка
   ужимается по contain (пропорция креатива не искажается).
   Сайдбар-стопку на телефоне не показываем — это решение по UX
   (флаг для утверждения борда, см. README §8). */
@media (max-width: 760px) {
  .ad-slot { padding: var(--ad-pad-sm); }
  .ad-dots { bottom: calc((var(--ad-pad-sm) - var(--ad-dot)) / 2); }
  .ad-box--top, .ad-box--inline { min-height: var(--ad-min-h-sm); }
  .ad-slot.ad-sidebar,
  .ad-stack { display: none; }
  .ad-top    { margin: 0 auto var(--sp-section-sm, var(--sp-8)); }
  .ad-in-article { margin: var(--sp-5) auto; }
}
@media (max-width: 1000px) {
  .ad-stack { gap: var(--ad-stack-gap-sm); }
  .ad-stack.is-sticky { position: static; } /* R4: сдвиг по вертикали отключён */
}

/* ---------- 9. ДОСТУПНОСТЬ И МОТИВ ---------- */
@media (prefers-reduced-motion: reduce) {
  .ad-slide { transition: none; }
}

/* на телефоне поле рамки меньше — пересчитываем и внешние габариты */
@media (max-width: 760px) {
  :root {
    --ad-outer-top:    calc(var(--ad-top-w) + var(--ad-pad-sm) * 2 + var(--ad-frame));
    --ad-outer-inline: calc(var(--ad-inline-w) + var(--ad-pad-sm) * 2 + var(--ad-frame));
    --ad-outer-side:   calc(var(--ad-side-w) + var(--ad-pad-sm) * 2 + var(--ad-frame));
  }
}
