/*
Theme Name: Obzoor.by Child
Description: Child-theme дизайн-системы Obzoor.by поверх News Magazine X (ADR-009).
Template: news-magazine-x
Version: 1.12.0
*/

/* =========================================================
   Токены дизайн-системы (ТЗ №2, п.0.3).
   Скопировано целиком из Design-System/tokens/{colors,spacing,typography,radius}.css —
   это единственный источник истины, руками не редактировать, обновлять
   синхронной копией при изменении исходников. base.css НЕ копируется —
   он переопределяет глобальные body/h1/a/img и конфликтует с темой.
   fonts.css не копируется — подключение Onest/PT Serif сделано через
   wp_enqueue_style в functions.php (ADR-012 / ТЗ №5 п.0), не здесь.
   ========================================================= */

:root{
  /* --- colors.css --- */
  --obz-orange:#FE5000;
  --obz-orange-press:#E04600;
  --obz-orange-tint:#FFEDE5;
  --obz-orange-tint-2:#FFD9C7;

  --obz-ink-900:#1F1F1F;
  --obz-ink-800:#2F2F2F;
  --obz-ink-600:#5A544E;
  --obz-ink-400:#8C857D;
  --obz-line:#E7E1D9;
  --obz-line-strong:#D6CEC3;
  --obz-paper:#FAF8F5;
  --obz-paper-2:#F2EDE6;
  --obz-white:#FFFFFF;
  --obz-black:#000000;

  --obz-cat-city:#1B54B8;
  --obz-cat-food:#0E7A5F;
  --obz-cat-places:#6D3BD1;
  --obz-cat-beauty:#C6187E;
  --obz-cat-other:#2F2F2F;

  --surface-page:var(--obz-paper);
  --surface-card:var(--obz-white);
  --surface-sunken:var(--obz-paper-2);
  --surface-invert:var(--obz-ink-900);
  --surface-brand:var(--obz-orange);
  --surface-brand-soft:var(--obz-orange-tint);

  --text-body:var(--obz-ink-800);
  --text-strong:var(--obz-ink-900);
  --text-meta:var(--obz-ink-600);
  --text-muted:var(--obz-ink-400);
  --text-on-brand:var(--obz-white);
  --text-on-invert:var(--obz-paper);
  --text-brand:var(--obz-orange);

  --border-default:var(--obz-line);
  --border-strong:var(--obz-line-strong);
  --border-brand:var(--obz-orange);

  --action-primary-bg:var(--obz-orange);
  --action-primary-fg:var(--obz-white);
  --action-primary-bg-press:var(--obz-orange-press);
  --action-secondary-bg:var(--obz-ink-900);
  --action-secondary-fg:var(--obz-paper);
  --action-ghost-fg:var(--obz-ink-900);

  --focus-ring:var(--obz-orange);

  --overlay-photo:linear-gradient(180deg,rgba(0,0,0,0) 34%,rgba(0,0,0,.66) 100%);

  /* --- spacing.css --- */
  --space-1:4px;  --space-2:8px;  --space-3:12px; --space-4:16px;
  --space-5:20px; --space-6:24px; --space-8:32px; --space-10:40px;
  --space-12:48px;--space-16:64px;--space-20:80px;--space-24:96px;

  --gap-grid:20px;
  --gutter-page:16px;
  --container-max:1200px;
  --container-text:680px;
  --section-y:var(--space-12);
  --tap-min:44px;

  /* --- typography.css --- */
  --font-grotesk:"Onest","Helvetica Neue",Arial,sans-serif;
  --font-serif:"PT Serif",Georgia,"Times New Roman",serif;

  --font-display:var(--font-grotesk);
  --font-body:var(--font-serif);
  --font-ui:var(--font-grotesk);

  --fw-regular:400;
  --fw-medium:500;
  --fw-semibold:600;
  --fw-bold:700;
  --fw-black:800;

  --fs-display:34px;  --lh-display:1.04; --ls-display:-.02em;
  --fs-h1:27px;       --lh-h1:1.1;       --ls-h1:-.015em;
  --fs-h2:22px;       --lh-h2:1.16;      --ls-h2:-.01em;
  --fs-h3:18px;       --lh-h3:1.24;      --ls-h3:-.005em;
  --fs-lead:19px;     --lh-lead:1.5;
  --fs-body:17px;     --lh-body:1.62;
  --fs-body-sm:15px;  --lh-body-sm:1.55;
  --fs-meta:13px;     --lh-meta:1.35;    --ls-meta:.02em;
  --fs-label:12px;    --lh-label:1.2;    --ls-label:.06em;
  --fs-numeric:40px;  --lh-numeric:1;    --ls-numeric:-.03em;

  /* --- radius.css --- */
  --radius:10px;
  --radius-sm:6px;
  --radius-pill:999px;
  --radius-round:50%;
  --shadow-none:none;
}
@media (min-width:900px){
  :root{
    --gutter-page:32px; --section-y:var(--space-20);
    --fs-display:64px; --fs-h1:42px; --fs-h2:30px; --fs-h3:21px;
    --fs-lead:22px; --lh-lead:1.5;
    --fs-body:18px;  --lh-body:1.65;
    --fs-body-sm:16px;
    --fs-numeric:56px;
  }
}

/* =========================================================
   Фаза 1 дизайн-системы (ADR-008), перенесена сюда из поля
   «Дополнительный CSS» по ADR-012 / ТЗ №5.
   Child-theme — единственный владелец визуальных стилей.
   Блок стоит ДО секций ТЗ №1–№4 намеренно: базовый слой должен
   проигрывать более специфичным правилам страницы статьи.
   Значения — только через токены, хардкода hex быть не должно.
   ========================================================= */

/* A1 — фон и базовый цвет текста.
   !important сохранён на background по тексту ТЗ №5; !important на color
   добавлен по факту проверки на живом сайте 20.08.2026 — тема выводит
   инлайн-<style> (кастомайзер, группа селекторов "body, button, input...")
   с той же специфичностью (0,0,0,1) и печатает его ПОСЛЕ нашего внешнего
   style.css, поэтому побеждает color без !important так же, как побеждал
   бы background. Тот же механизм, что и с бейджем в ТЗ №2. Долг:
   проверить, нельзя ли снять после ТЗ №7 — но не в этом ТЗ. */
body {
  background: var(--surface-page) !important;
  color: var(--text-strong) !important;
}

/* A2 — гарнитура структуры/UI. Тело статьи остаётся серифом (ТЗ №4). */
body,
h1, h2, h3,
.site-title,
.menu-item a,
[class*="newsx-cat-"],
.newsx-meta, .entry-meta, .posted-on {
  font-family: var(--font-grotesk);
}

/* A3 */
h1 { color: var(--text-strong); }

/* A4 — категорийный бейдж ВНЕ страницы статьи (лента, рубрика, главная).
   ОТКЛОНЕНИЕ ОТ ФАЗЫ 1: было сплошное оранжевое #FE5000 для всех рубрик.
   Оранжевый — цвет бренда, не цвет рубрики (ТЗ №2 п.0.1, ADR-007).
   База — нейтральный --obz-cat-other; четыре основные рубрики получают
   свой цвет из инлайн-блока в functions.php (obz_category_colors_css). */
[class*="newsx-cat-"] {
  background: var(--obz-cat-other) !important;
  color: var(--text-on-brand);
  border-radius: var(--radius) !important;
}

/* A5 — единый радиус на медиа карточек */
.newsx-grid-media,
[class*="newsx-grid-media"] { border-radius: var(--radius) !important; }

/* A6 — единый радиус на кнопках */
button,
.search-submit,
.newsx-search-submit,
input[type="submit"] { border-radius: var(--radius) !important; }

/* A7 — hover-цвет ссылок в теле статьи.
   Ограничено десктопом: на мобиле ТЗ №4 п.5 уже задал :active, а hover
   на тач-экране залипает после тапа и читается как баг. */
@media (min-width: 900px) {
  .newsx-post-content a:hover { color: var(--obz-orange) !important; }
}

/* B — тело статьи на десктопе. Не перенос правила фазы 1 (17px/1.62
   хардкодом), а закрытие дыры через токены (граница гэпа закрыта ТЗ №16,
   было 768–899px): 18px/1.65 от 900px (медиазапрос в :root). Мобильные
   17px/1.68 из ТЗ №4 живут в max-width:899px и не пересекаются. */
@media (min-width: 900px) {
  .newsx-post-content,
  .newsx-post-content p {
    font-family: var(--font-serif);
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    color: var(--text-body);
  }
}

/* ---------------------------------------------------------
   ТЗ №1 — Sticky-шапка мобильного шаблона статьи
   Referens: Design-System/templates/mobile-article/MobileArticle.dc.html (header, mode=article)
   ADR: ADR-009 (child-theme), ADR-010 (mobile-first, без backdrop-filter)
   --------------------------------------------------------- */

.obz-article-sticky-header {
  display: none; /* по умолчанию скрыт на desktop */
}

@media (max-width: 899px) {
  body.single .obz-article-sticky-header {
    display: flex;
    align-items: center;
    gap: 12px;
    position: sticky;
    top: 0;
    z-index: 20;
    height: 56px;
    padding: 0 16px;
    background: var(--obz-paper); /* сплошной цвет, БЕЗ backdrop-filter — ADR-010 п.3 */
    border-bottom: 1px solid var(--border-default);
  }
  .obz-article-sticky-header .obz-ash-logo {
    display: flex;
    align-items: center;
    height: var(--tap-min); /* WCAG-таргет 44px, визуально лого остаётся 24px */
  }
  .obz-article-sticky-header .obz-ash-logo img { display: block; height: 24px; width: auto; }
  .obz-article-sticky-header .obz-ash-divider {
    width: 1px; height: 20px; background: var(--border-default);
  }
  .obz-article-sticky-header .obz-ash-cat {
    display: flex;
    align-items: center;
    height: var(--tap-min); /* WCAG-таргет 44px */
    font-family: var(--font-grotesk);
    font-size: 14px;
    font-weight: var(--fw-bold);
    letter-spacing: -0.01em;
    text-decoration: none;
    /* ТЗ №2 п.3: цвет больше не инлайновый — наследуется каскадом от
       --obz-cat-current, заданной один раз на .obz-article-scope */
    color: var(--obz-cat-current, var(--obz-cat-other));
  }
  .obz-article-sticky-header .obz-ash-spacer { flex: 1; }
  .obz-article-sticky-header .obz-ash-search {
    width: 44px; height: 44px;
    display: grid; place-items: center;
    background: none; border: 0; cursor: pointer;
    color: var(--obz-ink-900);
  }
  /* ТЗ №20 задача 1.2 — меню «ещё рубрики», зеркало .obz-fsh-menu ленты.
     Отрицательный отступ, прижимающий последний элемент к краю, перенесён
     сюда с .obz-ash-search — теперь последний элемент это меню. */
  .obz-article-sticky-header .obz-ash-menu {
    width: 44px; height: 44px; margin-right: -10px;
    display: grid; place-items: center;
    background: none; border: 0; cursor: pointer;
    color: var(--obz-ink-900);
  }
}

/* ---------------------------------------------------------
   ТЗ №2 — Первый экран статьи: бейдж, заголовок, лид, мета, CTA
   Referens: Design-System/templates/mobile-article/MobileArticle.dc.html, строки 35-52
   --------------------------------------------------------- */

/* 1. Лид */
.obz-article-lead {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--obz-ink-800);
  margin: 0;
}

/* 2. Заголовок — отклонение от --fs-h1 осознанное, см. ADR-010 "Статус выполнения".
   !important добавлен по факту проверки на живом сайте 20.08.2026 (ADR-012 /
   ТЗ №5): тема выводит инлайн-CSS кастомайзера "h1:not(.site-title){font-size:
   28px/32px/42px}" (по брейкпоинтам) с той же специфичностью (0,1,1), печатает
   его позже наших enqueued-стилей — font-size/line-height/margin проигрывали
   без !important, хотя color совпадал случайно и не выдавал проблему раньше. */
@media (max-width: 899px) {
  .newsx-single-post-header h1 {
    font-family: var(--font-grotesk) !important;
    font-weight: var(--fw-black) !important;
    font-size: 29px !important;
    line-height: 1.08 !important;
    letter-spacing: -0.025em !important;
    color: var(--obz-ink-900) !important;
    margin: 0 !important;
    text-wrap: balance;
  }
}

/* 3. Бейдж рубрики — разметка темы (.newsx-post-categories), только стилизация */
@media (max-width: 899px) {
  .newsx-single-post-header .newsx-post-categories { margin-bottom: 0; }
  .newsx-single-post-header .newsx-post-categories a {
    display: inline-block;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    /* !important: тема генерирует инлайн-CSS вида .newsx-cat-{id} со своей
       собственной палитрой (селектор в 3 класса, специфичнее нашего) — мы
       намеренно подменяем её цветом рубрики дизайн-системы (ADR-007). */
    background: var(--obz-cat-current, var(--obz-cat-other)) !important;
    color: var(--obz-white);
    font-family: var(--font-grotesk);
    font-size: var(--fs-label);
    font-weight: var(--fw-bold);
    line-height: var(--lh-label);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    text-decoration: none;
  }
}

/* 4. Мета-строка: "12 августа · 7 минут чтения", без автора/аватара/комментариев.
   Скрытие вынесено из @media (max-width:899px) в глобальное правило —
   состав меты "дата · время чтения" не мобильное решение, а решение
   ADR-010 про CTA-слот статьи в целом, десктоп не меняет состав данных,
   только их размер. ТЗ №19 задача 2. */
.newsx-single-post-header .newsx-post-author,
.newsx-single-post-header .newsx-post-author-avatar,
.newsx-single-post-header .newsx-post-comments-number,
.newsx-single-post-header .newsx-post-time { display: none; }

@media (max-width: 899px) {
  .newsx-single-post-header .newsx-post-meta,
  .newsx-single-post-header .newsx-post-meta-inn-wrap,
  .newsx-single-post-header .newsx-post-meta-inner,
  .newsx-single-post-header .newsx-post-meta-inn-group {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-grotesk);
    font-size: var(--fs-meta);
    line-height: var(--lh-meta);
    color: var(--obz-ink-600);
  }
  .newsx-single-post-header .newsx-post-date { color: var(--obz-ink-600); }

  /* Разделитель темы (main.css ~3263) бьётся об скрытый автор — подавляем и ставим свой. */
  .newsx-single-post-header .newsx-post-meta-inn-group > *:after { content: none; }
  .newsx-single-post-header .newsx-post-reading-time:before { content: "\00b7"; margin-right: 8px; }
}

/* 5. CTA-слот под метой. .obz-article-cta — якорь для ТЗ №3, класс не переименовывать. */
.obz-article-cta { display: none; }

@media (max-width: 899px) {
  body.single .obz-article-cta {
    display: block;
    padding: 20px var(--gutter-page) 24px;
  }
  .obz-cta-tg {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--tap-min);
    height: 50px;
    border-radius: 12px; /* осознанное отклонение от --radius: 10px, см. прототип */
    background: var(--obz-orange);
    color: var(--obz-white);
    font-family: var(--font-grotesk);
    font-size: 16px;
    font-weight: var(--fw-bold);
    letter-spacing: -0.01em;
    text-decoration: none;
  }
  .obz-cta-tg:active { background: var(--obz-orange-press); }
}

/* 6. Отступы первого экрана */
@media (max-width: 899px) {
  body.single .newsx-single-post-header {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 20px var(--gutter-page) 0;
    margin-bottom: 0;
  }
}

/* Хлебные крошки — скрыты на мобиле, SEO-разметка идёт отдельно из RankMath (Schema.org) */
@media (max-width: 899px) {
  .newsx-single-post-header .newsx-breadcrumbs { display: none; }
}

/* ---------------------------------------------------------
   ТЗ №3 — Нижний sticky-CTA статьи
   Referens: Design-System/templates/mobile-article/MobileArticle.dc.html,
   строки 104-111 (фиксированный блок) — логика показа реализована через
   IntersectionObserver в assets/js/sticky-cta.js, не через onScroll
   прототипа (реализуем результат, не способ).
   --------------------------------------------------------- */

.obz-sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  padding: 10px var(--gutter-page) calc(10px + env(safe-area-inset-bottom));
  background: var(--obz-paper);
  border-top: 1px solid var(--border-default);
  transform: translateY(120%);
  opacity: 0;
  /* visibility скрывает элемент из дерева доступности и убирает его из
     табуляции, пока он не виден — без неё скринридер/Tab всё равно находят
     кнопку под экраном. Задержка на СКРЫТИЕ (transition-delay у
     .is-visible ниже — 0s, а тут 0.22s) даёт анимации доиграть, прежде чем
     элемент реально пропадёт из a11y-дерева. */
  visibility: hidden;
  pointer-events: none;
  transition: transform .22s ease, opacity .22s ease, visibility 0s linear .22s;
}
.obz-sticky-cta.is-visible {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: transform .22s ease, opacity .22s ease, visibility 0s linear 0s;
}
.obz-sticky-cta-link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 48px;
  border-radius: 12px;
  /* Тёмный secondary, не оранжевый — верхний CTA (Telegram) уже оранжевый
     primary, две одинаковые кнопки на одном экране конкурировали бы за
     внимание (осознанное решение, см. прототип). */
  background: var(--obz-ink-900);
  color: var(--obz-paper);
  font-family: var(--font-grotesk);
  font-size: 16px;
  font-weight: var(--fw-bold);
  letter-spacing: -0.01em;
  text-decoration: none;
}

@media (max-width: 899px) {
  /* Резерв под фиксированную панель внизу — на body.single, а не на
     конкретном контейнере темы (#primary/#content): их фактическая
     структура для этой темы не проверена построчно, а body.single —
     универсально верный и не требует гадать по разметке. */
  body.single { padding-bottom: 96px; }
}

@media (min-width: 900px) {
  .obz-sticky-cta { display: none; }
}

/* ---------------------------------------------------------
   ТЗ №4 — Тело статьи (.newsx-post-content), типографика чтения.
   Referens: Design-System/templates/mobile-article/MobileArticle.dc.html,
   строки 77-84 (article — абзацы, h2, blockquote).
   Десктоп этим ТЗ не трогается (ADR-010 п.1e — отдельно, последним).
   --------------------------------------------------------- */

/* п.2 — абзацы. Правило дублируется на контейнере и на p намеренно: в
   архивных статьях часть текста лежит голыми текстовыми узлами без <p>. */
@media (max-width: 899px) {
  .newsx-post-content {
    padding: 0 var(--gutter-page, 16px);
    font-family: var(--font-serif);
    font-size: 17px;
    line-height: 1.68;
    color: var(--obz-ink-800, #2F2F2F);
  }
  .newsx-post-content p {
    font-family: var(--font-serif);
    font-size: 17px;
    line-height: 1.68;
    color: var(--obz-ink-800, #2F2F2F);
    margin: 0 0 16px;
  }
  .newsx-post-content > *:last-child { margin-bottom: 0; }
}

/* п.3 — подзаголовки. h2 21px из прототипа (не токен --fs-h2: 22px) —
   осознанное отклонение, как и с h1 в ТЗ №2. h3 в прототипе нет, берём
   токен --fs-h3: 18px — в архивных статьях h3 встречается, без стиля
   оставлять нельзя. Отступ сверху у h2 больше снизу (32/12) — заголовок
   визуально принадлежит следующему блоку, не предыдущему. */
@media (max-width: 899px) {
  .newsx-post-content h2 {
    font-family: var(--font-grotesk);
    font-weight: 800;
    font-size: 21px;
    line-height: 1.22;
    letter-spacing: -0.015em;
    color: var(--obz-ink-900, #1F1F1F);
    margin: 32px 0 12px;
  }
  .newsx-post-content h3 {
    font-family: var(--font-grotesk);
    font-weight: 700;
    font-size: 18px;
    line-height: 1.24;
    color: var(--obz-ink-900, #1F1F1F);
    margin: 24px 0 8px;
  }
}

/* п.4 — цитаты. Требует ТЗ №4 п.0 (--obz-cat-current теперь на body.single,
   не на .obz-article-scope) — иначе линия падала бы на фолбэк #2F2F2F
   всегда. border:0 перед border-top обязателен — гасит собственную рамку
   темы (проверено в DevTools: тема добавляла left-border/padding). */
@media (max-width: 899px) {
  .newsx-post-content blockquote {
    margin: 24px 0;
    padding: 16px 0 0;
    border: 0;
    border-top: 2px solid var(--obz-cat-current, var(--obz-cat-other, #2F2F2F));
    background: none;
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 21px;
    line-height: 1.38;
    color: var(--obz-ink-900, #1F1F1F);
  }
  .newsx-post-content blockquote p {
    font-size: inherit;
    line-height: inherit;
    font-style: inherit;
    color: inherit;
    margin: 0;
  }
}

/* п.5 — ссылки и списки. Тёмная ссылка с оранжевым подчёркиванием (не
   сплошной оранжевый текст — в длинном тексте рябит). :active, не :hover —
   на тач-устройстве hover не существует и залипает как баг после тапа. */
@media (max-width: 899px) {
  .newsx-post-content a {
    color: var(--obz-ink-900, #1F1F1F);
    text-decoration: underline;
    text-decoration-color: var(--obz-orange, #FE5000);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
  }
  .newsx-post-content a:active { color: var(--obz-orange, #FE5000); }

  .newsx-post-content ul,
  .newsx-post-content ol {
    margin: 0 0 16px;
    padding-left: 22px;
  }
  .newsx-post-content li {
    font-family: var(--font-serif);
    font-size: 17px;
    line-height: 1.68;
    color: var(--obz-ink-800, #2F2F2F);
    margin-bottom: 8px;
  }
}

/* п.6 — гигиена архивного контента (Wayback-импорт, произвольный HTML).
   overflow-x на этих элементах локально, не на body — иначе ломается
   position: sticky шапки из ТЗ №1.

   Найдено тестовым черновиком (см. отчёт): .newsx-single-inner темы —
   display:flex с min-width:auto (дефолт flex-item) — отказывается
   сжиматься меньше min-content своего содержимого. Крупная картинка с
   width="900" (типично для архивных Wayback-статей) раздувала весь
   flex-контейнер шире вьюпорта и ломала страницу горизонтальным скроллом
   ЦЕЛИКОМ, не только сам блок с картинкой. max-width:100% на img тут не
   спасает — надёжный фикс на самом flex-контейнере. */
@media (max-width: 899px) {
  .newsx-single-inner { min-width: 0; }

  .newsx-post-content img {
    max-width: 100%;
    height: auto;
    display: block;
    border-radius: var(--radius, 10px);
    margin: 0 auto 8px;
  }
  .newsx-post-content figure { margin: 24px 0; }
  .newsx-post-content figcaption {
    font-family: var(--font-grotesk);
    font-size: 13px;
    line-height: 1.4;
    color: var(--obz-ink-600, #5A544E);
    margin-top: 8px;
  }
  .newsx-post-content iframe,
  .newsx-post-content video,
  .newsx-post-content embed { max-width: 100%; }
  .newsx-post-content .wp-video,
  .newsx-post-content .wp-block-embed__wrapper { max-width: 100%; }
  .newsx-post-content table {
    display: block;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .newsx-post-content pre { overflow-x: auto; }
}

/* ---------------------------------------------------------
   ТЗ №6 — Блок «Читать ещё»: вертикальный список на мобиле.
   Referens: Design-System/templates/mobile-article/MobileArticle.dc.html,
   секция "Читать ещё" (fон --surface-sunken, миниатюра 88px, категория
   вместо даты). Решение "список, не карусель" — ADR-010, раздел
   "Решённые открытые вопросы" п.1.
   --------------------------------------------------------- */

@media (max-width: 899px) {
  body.single .newsx-related-posts-wrap {
    margin: var(--space-10) 0 0;
    padding: var(--space-6) var(--gutter-page) var(--space-8);
    background: var(--surface-sunken);
    border-top: 1px solid var(--border-default);
  }
  .newsx-related-posts-wrap h4 {
    font-family: var(--font-grotesk);
    font-weight: var(--fw-black);
    font-size: 19px;
    line-height: 1.2;
    letter-spacing: -0.015em;
    color: var(--text-strong);
    margin: 0 0 var(--space-4);
  }
  .newsx-related-posts.obz-related-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
  }
  .obz-related-item {
    display: grid;
    grid-template-columns: 88px 1fr;
    gap: var(--space-3);
    align-items: center;
    text-decoration: none;
  }
  .obz-related-thumb {
    display: block;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius);
    overflow: hidden;
  }
  .obz-related-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    margin: 0;
  }
  .obz-related-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0; /* тот же класс проблемы, что в ТЗ №4 п.6 — без этого
                     длинный заголовок мог бы раздуть grid-колонку */
  }
  .obz-related-cat {
    font-family: var(--font-grotesk);
    font-size: 11px;
    font-weight: var(--fw-bold);
    letter-spacing: .06em;
    text-transform: uppercase;
  }
  .obz-related-title {
    font-family: var(--font-grotesk);
    font-weight: var(--fw-bold);
    font-size: 16px;
    line-height: 1.25;
    letter-spacing: -.01em;
    color: var(--text-strong);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* Десктоп: минимальное сохранение прежнего вида сетки-3 (родитель:
   .newsx-related-posts { display:grid; grid-template-columns:repeat(3,1fr) })
   с учётом новой разметки. Единственное содержательное отличие от вчерашнего
   вида — дата на карточке заменена на категорию (следствие общей разметки
   с мобильной версией, см. ТЗ №6 выше). Это НЕ десктопная адаптация
   ADR-010 п.1e — просто карточка не должна визуально сломаться. */
@media (min-width: 900px) {
  .obz-related-item {
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-decoration: none;
  }
  .obz-related-thumb {
    display: block;
    aspect-ratio: 3 / 2;
    border-radius: var(--radius, 10px);
    overflow: hidden;
  }
  .obz-related-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    margin: 0;
  }
  .obz-related-cat {
    font-family: var(--font-grotesk);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
  }
  .obz-related-title {
    font-family: var(--font-grotesk);
    font-weight: 700;
    font-size: 16px;
    line-height: 1.3;
    color: var(--obz-ink-900, #1F1F1F);
  }
}

/* ---------------------------------------------------------
   ТЗ №7 — Featured-изображение статьи. Referens:
   Design-System/templates/mobile-article/MobileArticle.dc.html, <figure>
   между CTA-блоком и телом статьи.
   Мобиль: edge-to-edge (без скругления, без гуттера) — картинка обязана
   доходить до края экрана, это отличает её от миниатюр (ТЗ №6, скруглены).
   Подпись — с гуттером, как текст тела статьи.

   ИСПРАВЛЕНО по факту живой проверки 20.08.2026 (три расхождения с текстом
   ТЗ, ни одно не было в критериях приёмки заранее):
   1) .newsx-single-wrap здесь несёт класс .newsx-container (родитель
      добавляет его при content_width:'boxed') с padding-left/right:20px —
      весь `<article>`, включая наш <figure>, живёт внутри этого паддинга.
      width:100% на img просто заполняет 100% УЖЕ суженной колонки, не
      экран — картинка не доходила до края. Фикс — стандартный приём
      "full-bleed" через 100vw/-50vw на самом <figure>, не зависящий от
      точного значения чужого паддинга.
   2) .newsx-single-post-media { margin-bottom: 20px } живёт в main.min.css
      родителя, который в <head> печатается ПОСЛЕ обеих наших style.css
      (обычная externally-enqueued таблица стилей, не кастомайзер) — при
      равной специфичности (0,1,0) побеждает по порядку, не по нам.
   3) .newsx-single-post-media img { border-radius: 3px } — на этот раз не
      main.min.css, а инлайн-блок Kirki-кастомайзера (id="kirki-inline-styles",
      печатается в <head> ещё позже main.min.css) — тот же класс проблемы,
      что с телом body/h1/бейджами в ТЗ №5, просто новый конкретный селектор.
   Оба случая (2 и 3) закрыты через !important, как и предыдущие. */

.obz-featured-media {
  margin: 0 0 var(--space-6) !important;
}
.obz-featured-media img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 899px) {
  .obz-featured-media {
    /* full-bleed: доходит до края вьюпорта независимо от паддинга любого
       предка (сейчас это 20px из .newsx-container, но приём не завязан на
       конкретное число — переживёт и будущие изменения контейнера). */
    width: 100vw;
    margin-left: calc(50% - 50vw) !important;
    margin-right: calc(50% - 50vw) !important;
  }
  .obz-featured-media img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 0 !important;
  }
  .obz-featured-caption {
    padding: var(--space-2) var(--gutter-page) 0;
    margin: 0;
    font-family: var(--font-grotesk);
    font-size: 13px;
    line-height: 1.4;
    color: var(--text-meta);
  }
}

/* Десктоп: контейнерный вид (скруглено, вписано в колонку текста).
   Принято в рамках ТЗ №19 как финальное десктопное состояние — тот же
   aspect-ratio:4/3 + object-fit:cover, что решила бы десктопная адаптация,
   начинай она с нуля. */
@media (min-width: 900px) {
  .obz-featured-media img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--radius, 10px) !important;
  }
  .obz-featured-caption {
    padding: var(--space-2) 0 0;
    margin: 0;
    font-family: var(--font-grotesk);
    font-size: 13px;
    line-height: 1.4;
    color: var(--text-meta);
  }
}

/* ---------------------------------------------------------
   ТЗ №8 — Sticky-шапка ленты/рубрики (не статьи — там ТЗ №1).
   Referens: Design-System/templates/mobile-feed/MobileFeed.dc.html, <header>.
   Тот же паттерн: сплошной фон, БЕЗ backdrop-filter (ADR-010 п.3),
   height 56px, только < 900px.
   --------------------------------------------------------- */

.obz-feed-sticky-header {
  display: none;
}

@media (max-width: 899px) {
  /* Родная шапка темы (builder) скрыта на мобиле целиком — наша заменяет её
     функционально (лого, поиск, доступ к остальным рубрикам через гамбургер).
     НЕ display:none — проверено вживую 21.08.2026: .newsx-mobile-menu-container
     (существующее меню «ещё рубрики», см. ниже) физически вложено внутрь
     .newsx-site-header (newsx-middle-section-wrap → ... → nav.newsx-mobile-menu-
     container), а display:none на предке убирает поддерево из рендера
     ПОЛНОСТЬЮ — при клике на нашу кнопку меню контейнер получал display:block,
     но schlopyvalsya в 0×0 (getBoundingClientRect всё нулевое), потому что
     сам не рендерился вообще. Заменено на visibility:hidden + height:0 +
     overflow:visible: элемент остаётся в рендер-дереве (геометрия считается),
     просто не рисуется и не занимает места, а вложенному меню и его
     потомкам явно возвращена visibility:visible — снимает видимость только
     с самой шапки. overflow:visible обязателен: overflow:hidden здесь клипует
     дочерний абсолютно спозиционированный .newsx-mobile-menu-container
     (position:absolute, а не fixed — проверено), height:0 без overflow:hidden
     сам по себе content не обрезает. */
  /* ТЗ №20 задача 1 — снято ограничение body:not(.single): разведка
     (Vyvody/2026-08-22-TZ-20-...) подтвердила, что на статье шапка темы
     тоже рендерилась (196px) поверх нашей 56px sticky-шапки — две шапки
     на первом экране статьи, чего не предполагает ни ADR-010 п.1a, ни
     прототип MobileArticle.dc.html. Меню «ещё рубрики» на статье теперь
     открывается через .obz-ash-menu в .obz-article-sticky-header
     (header.php) — тем же приёмом, что и здесь. */
  .newsx-site-header {
    visibility: hidden;
    height: 0;
    overflow: visible;
  }
  .newsx-site-header .newsx-mobile-menu-container,
  .newsx-site-header .newsx-mobile-menu-container * {
    visibility: visible;
  }

  body:not(.single) .obz-feed-sticky-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    position: sticky;
    top: 0;
    z-index: 20;
    height: 56px;
    padding: 0 var(--gutter-page);
    background: var(--obz-paper);
    border-bottom: 1px solid var(--border-default);
  }
  .obz-feed-sticky-header .obz-fsh-logo {
    display: flex;
    align-items: center;
    height: var(--tap-min);
  }
  .obz-feed-sticky-header .obz-fsh-logo img { display: block; height: 24px; width: auto; }
  .obz-feed-sticky-header .obz-fsh-spacer { flex: 1; }
  .obz-feed-sticky-header .obz-fsh-search,
  .obz-feed-sticky-header .obz-fsh-menu {
    width: 44px; height: 44px;
    display: grid; place-items: center;
    background: none; border: 0; cursor: pointer;
    color: var(--obz-ink-900);
  }
  .obz-feed-sticky-header .obz-fsh-menu { margin-right: -10px; }

  /* Сама кнопка-прокси родной темы больше не нужна визуально — её функцию
     взяла .obz-fsh-menu. Прячем именно кнопку, не весь контейнер меню:
     .newsx-mobile-menu-container должен остаться в DOM и работать по клику
     из нашей кнопки (см. functions.php). */
  .newsx-mobile-menu-toggle { display: none !important; }

  /* Гамбургер-меню: скрываем 4 пункта, дублирующих таб-бар. Селектор по
     тексту ссылки, НЕ по порядку/id — id пунктов меню не гарантированно
     стабилен между редактированиями в wp-admin (проверено на живом сайте:
     это ID пункта МЕНЮ, не ID термина рубрики, редактор может их
     перегенерировать). :has() поддерживается всеми актуальными мобильными
     браузерами (Safari iOS 16.4+, Chrome Android 105+ — див. ADR-010,
     webview-реальность соцсетей уже такого возраста). */
  .newsx-mobile-menu-container li:has(> a[href$="/city/"]),
  .newsx-mobile-menu-container li:has(> a[href$="/food/"]),
  .newsx-mobile-menu-container li:has(> a[href$="/places/"]),
  .newsx-mobile-menu-container li:has(> a[href$="/beauty/"]) {
    display: none;
  }
}

/* ТЗ №13 ч.2 — симметрия гвардов (см. ADR-010, п.1e / ТЗ №13):
   .obz-tab-bar и .obz-more-in-cat уже защищены !important-гвардом на
   min-width:900px, .obz-feed-sticky-header — нет. Без него любой
   более специфичный селектор родительской темы/плагина перебивает
   глобальный display:none выше и элемент всплывает на десктопе. */
@media (min-width: 900px) {
  .obz-feed-sticky-header { display: none !important; }
}

/* ---------------------------------------------------------
   ТЗ №9 — Нижний таб-бар ленты/рубрики.
   Referens: Design-System/templates/mobile-feed/MobileFeed.dc.html, <nav>.
   Активный таб красится через инлайн --obz-tab-color (из functions.php),
   не через классы вида .obz-tab-item.city — цвет уже вычислен на PHP-стороне
   тем же кодом, что и бейджи (obz_get_category_color единообразие).
   --------------------------------------------------------- */

.obz-tab-bar { display: none; }

@media (max-width: 899px) {
  body:not(.single) .obz-tab-bar {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    background: var(--obz-paper);
    border-top: 1px solid var(--border-default);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .obz-tab-item {
    min-height: var(--tap-min);
    height: 56px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font-family: var(--font-grotesk);
    font-size: 10px;
    font-weight: var(--fw-bold);
    letter-spacing: .01em;
    color: var(--text-meta);
    text-decoration: none;
  }
  .obz-tab-item.is-active {
    color: var(--obz-tab-color, var(--obz-orange));
  }

  /* Резерв под фиксированный таб-бар — НЕ на body.single (там свой резерв
     под sticky-CTA, ТЗ №3, другое значение 96px). Взаимоисключающие
     селекторы body.single / body:not(.single) — никогда не пересекаются. */
  body:not(.single) {
    padding-bottom: calc(56px + env(safe-area-inset-bottom));
  }
}

@media (min-width: 900px) {
  .obz-tab-bar { display: none !important; }
}

/* ---------------------------------------------------------
   ТЗ №10 ч.1 — Чипсы рубрик. Referens: MobileFeed.dc.html, [data-scroller].
   scroll-snap на чистом CSS, без swiper.js — тот же приём, что уже
   в прототипе ленты и уже принят решением ADR-010 для карусели.
   --------------------------------------------------------- */

.obz-chips { display: none; }

@media (max-width: 899px) {
  body:not(.single) .obz-chips {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-4) var(--gutter-page);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .obz-chips::-webkit-scrollbar { display: none; }
  .obz-chip {
    flex: 0 0 auto;
    scroll-snap-align: start;
    min-height: 36px;
    display: flex;
    align-items: center;
    padding: 0 14px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-strong);
    background: var(--surface-card);
    font-family: var(--font-grotesk);
    font-size: 14px;
    font-weight: var(--fw-bold);
    color: var(--obz-ink-900);
    text-decoration: none;
    white-space: nowrap;
  }
  .obz-chip.is-active {
    background: var(--obz-chip-color, var(--obz-orange));
    border-color: var(--obz-chip-color, var(--obz-orange));
    color: var(--obz-white);
  }
}

/* ТЗ №13 ч.2 — симметрия гвардов, см. комментарий у .obz-feed-sticky-header. */
@media (min-width: 900px) {
  .obz-chips { display: none !important; }
}

/* ---------------------------------------------------------
   ТЗ №10 ч.2 — «Ещё в рубрике». Только is_category(), scroll-snap.
   --------------------------------------------------------- */

.obz-more-in-cat { display: none; }

@media (max-width: 899px) {
  body.category .obz-more-in-cat {
    display: block;
    margin-top: var(--space-8);
    padding: var(--space-6) 0;
    background: var(--surface-sunken);
    border-top: 1px solid var(--border-default);
    border-bottom: 1px solid var(--border-default);
  }
  .obz-more-in-cat-head {
    padding: 0 var(--gutter-page) var(--space-4);
  }
  .obz-more-in-cat-head h2 {
    font-family: var(--font-grotesk);
    font-weight: var(--fw-black);
    font-size: 19px;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--text-strong);
    margin: 0;
  }
  .obz-more-in-cat-scroller {
    display: flex;
    gap: var(--space-3);
    padding: 0 var(--gutter-page);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .obz-more-in-cat-scroller::-webkit-scrollbar { display: none; }
  .obz-more-in-cat-item {
    flex: 0 0 156px;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    text-decoration: none;
  }
  .obz-more-in-cat-thumb {
    display: block;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius);
    overflow: hidden;
  }
  .obz-more-in-cat-thumb img {
    width: 100%; height: 100%; object-fit: cover; display: block; margin: 0;
  }
  .obz-more-in-cat-title {
    font-family: var(--font-grotesk);
    font-weight: var(--fw-bold);
    font-size: 15px;
    line-height: 1.22;
    color: var(--text-strong);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

@media (min-width: 900px) {
  .obz-more-in-cat { display: none !important; }
}

/* =========================================================
   Группа C по ADR-012 — правила неизвестного авторства, жившие в
   поле «Дополнительный CSS» до фазы 1. Каждое рассмотрено отдельно.
   ========================================================= */

/* C1 снят ТЗ №22 — «Main Menu» → «Меню» теперь значение опции
   Кастомайзера (header_pm_toggle_label), правится в интерфейсе, не
   CSS-костылём. */

/* C2 — затемнение под текстом на фото карточки.
   ADR-008 фаза 2 предписывает УБРАТЬ градиент с карточек статей — но вместе
   с переводом карточки на раздельные блоки «фото + заголовок», а это ещё не
   сделано. Пока заголовок лежит поверх фото, снимать затемнение нельзя:
   упадёт контраст белого текста на светлых снимках. Поэтому переносим, но
   переписываем через токен дизайн-системы вместо своего градиента.
   Удаляется целиком вместе с переработкой карточек. */
.newsx-grid-item .newsx-grid-over-media.newsx-full-stretch {
  background: var(--overlay-photo);
}

/* C3 — дата на карточках скрыта.
   ПОСТОЯННО по ADR-026 (23.08.2026, ТЗ №25) — продуктовое решение владельца:
   вечнозелёные подборки не должны выглядеть просроченными. Старая причина
   (кривой формат даты, открытый вопрос №2 в ТЗ №5) снята ещё в ТЗ №22 —
   правило больше не «временное ради статус-кво», как было записано здесь
   раньше.
   Селектор `.newsx-grid-item` матчит карточки ленты и рубрики (родительский
   template-parts/blog-page/post.php) и карточки Bento-сетки главной
   (obz_bento_grid_shortcode(), ТЗ №17 — та же разметка скопирована из
   живого DOM) — все три места из ADR-026 одним правилом.
   На .single не действует: там своя разметка меты (.newsx-post-date),
   класса .newsx-grid-item там нет — проверено curl по живой статье 24.08.2026
   (0 совпадений).
   ПРОВЕРЕНО 20.08.2026: класса newsx-grid-date-time нет в main.css темы (он
   приходит из PHP-разметки), но элемент реально присутствует в DOM ленты —
   правило живое, не мёртвое, переносим. */
.newsx-grid-item .newsx-grid-date-time { display: none; }

/* ТЗ №25 задача 2 — дата скрыта и в виджете «Популярные статьи»
   (newsx_featured_posts, живёт в general-right-sidebar — боковая панель
   ленты и рубрики, global_blog_sidebar_display / global_term_archive_sidebar_display
   = right). Правило C3 выше сюда не дотягивается: у виджета своя разметка
   (.newsx-featured-posts-widget, безымянный <span> с датой внутри
   .newsx-post-meta), не .newsx-grid-item. Найдено 24.08.2026 живой проверкой
   в браузере на /category/places/ — дата была видна в этом списке при уже
   скрытой дате на основных карточках. На .single не действует: сайдбар
   статьи выключен (global_blog_single_sidebar_display = none, ADR-018),
   виджет там не рендерится. */
.newsx-featured-posts-widget .newsx-post-meta > span { display: none; }

/* C4 — заголовок карточки в ленте. 18px совпал с токеном --fs-h3 точно,
   поэтому не хардкод, а токен. !important сохранён: у темы своя
   типографика из кастомайзера.
   ИСПРАВЛЕНО 20.08.2026: исходный селектор требовал предка .newsx-posts-feed
   — это верно только для страниц рубрик (виджет list-layout). На главной
   карточки рендерит другой виджет (.newsx-grid-layout.newsx-posts-widget),
   тоже с .newsx-grid-title внутри, но без .newsx-posts-feed — правило не
   срабатывало на главной. .newsx-grid-title h3 достаточно специфичен сам
   по себе, предок не нужен. */
.newsx-grid-title h3,
.newsx-grid-title h3 a {
  font-family: var(--font-grotesk) !important;
  font-size: var(--fs-h3) !important;
  line-height: var(--lh-h3);
}

/* C5 — заглушка для пустой рубрики. Нужна: 1893 архивные статьи
   распределены по рубрикам неравномерно, пустые рубрики реальны.
   Хрупкость :empty (ломается от любого пробельного узла внутри) известна и
   принимается — правило демонстрируемо работало. */
.newsx-posts-feed.newsx-list-layout:empty::after {
  content: "Мы уже готовим материалы для этой рубрики — заходите чуть позже.";
  display: block;
  padding: var(--space-10) 0;
  font-family: var(--font-grotesk);
  font-size: 16px;
  color: var(--text-meta);
}

/* C6–C8 сняты ТЗ №22 — «Previous Article»/«Next Article» теперь через
   фильтр option_newsx_options в functions.php (obz_nav_text_labels; в
   бесплатной версии темы это поле не выведено в интерфейс Кастомайзера —
   PRO). */

/* ---------------------------------------------------------
   ТЗ №11 — Шапка рубрики: бейдж + заголовок + опциональный лид.
   Referens: MobileFeed.dc.html, секция isRubric.
   Бейдж вставляется JS'ом (functions.php, obz_rubric_header_inline_script) —
   нет do_action внутри newsx_archive_page_header_markup() родительской темы.
   Лид — нативный <p>{term description}</p> темы, не наш элемент, стилизуем
   прямым селектором по месту (> p), без своего класса.
   --------------------------------------------------------- */

/* JS вставляет бейдж на любой ширине (is_category() не проверяет viewport) —
   без этого display:none он висел бы неоформленной ссылкой над h1 на
   десктопе, найдено живой проверкой 1280px 21.08.2026. */
.obz-rubric-badge { display: none; }

@media (max-width: 899px) {
  body.category .newsx-archive-page-header {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-6) var(--gutter-page) var(--space-4);
    border-bottom: 1px solid var(--border-default);
  }
  body.category .newsx-archive-page-header .newsx-breadcrumbs {
    order: -1;
    font-family: var(--font-grotesk);
    font-size: 13px;
    color: var(--text-meta);
  }
  .obz-rubric-badge {
    align-self: flex-start;
    display: inline-flex;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    background: var(--obz-rubric-color, var(--obz-cat-other));
    color: var(--obz-white);
    font-family: var(--font-grotesk);
    font-size: var(--fs-label);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    text-decoration: none;
    pointer-events: none;
  }
  body.category .newsx-archive-page-header h1 {
    font-family: var(--font-grotesk);
    font-weight: var(--fw-black);
    font-size: 32px;
    line-height: 1.05;
    letter-spacing: -0.03em;
    color: var(--text-strong);
    margin: 0;
  }
  body.category .newsx-archive-page-header > p {
    font-family: var(--font-serif);
    font-size: 18px;
    line-height: 1.5;
    color: var(--text-meta);
    margin: 0;
  }
}

/* ТЗ №13 ч.2 — симметрия гвардов, см. комментарий у .obz-feed-sticky-header. */
@media (min-width: 900px) {
  .obz-rubric-badge { display: none !important; }
}

/* ---------------------------------------------------------
   ТЗ №12 ч.1 — Пагинация ленты/рубрики на мобиле.
   Кнопки "Показать ещё" из прототипа НЕТ в реальности темы (AJAX-подгрузка
   — PRO-функция, отключена без лицензии) — стилизуем существующую
   номерную пагинацию (template-parts/blog-page/pagination.php) под тот же
   язык вместо неё. Классы подтверждены построчно 21.08.2026: .newsx-prev/
   .newsx-next (стрелки), .current (может быть и <a>, и <span> — первая/
   последняя страница рендерятся как <a class="current">, серединная как
   <span class="current">), .extend (многоточие).
   --------------------------------------------------------- */

@media (max-width: 899px) {
  body:not(.single) .newsx-blog-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-8) var(--gutter-page) var(--space-10);
    flex-wrap: wrap;
  }
  body:not(.single) .newsx-blog-pagination a,
  body:not(.single) .newsx-blog-pagination span {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 12px;
    border-radius: var(--radius);
    border: 1px solid var(--border-strong);
    background: var(--surface-card);
    font-family: var(--font-grotesk);
    font-size: 15px;
    font-weight: var(--fw-bold);
    color: var(--obz-ink-900);
    text-decoration: none;
  }
  body:not(.single) .newsx-blog-pagination .current,
  body:not(.single) .newsx-blog-pagination span.current {
    background: var(--obz-orange);
    border-color: var(--obz-orange);
    color: var(--obz-white);
  }
  body:not(.single) .newsx-blog-pagination .newsx-prev,
  body:not(.single) .newsx-blog-pagination .newsx-next {
    width: var(--tap-min);
    padding: 0;
  }
  body:not(.single) .newsx-blog-pagination .extend {
    min-width: auto;
    border: 0;
    background: none;
    color: var(--text-meta);
    padding: 0 4px;
  }
}

/* ---------------------------------------------------------
   ТЗ №12 ч.2 — Подвал сайта, сверка с дизайн-системой.
   Обнаружено 21.08.2026 (getComputedStyle на живом /): layout и цвета
   подвала уже консистентны с брендом (тёмный surface-invert, оранжевая
   кнопка "наверх" — без правок совпадает с --obz-orange), но typography
   не унаследована — заголовки виджетов рендерились Roboto 600, текст
   Open Sans. Причина: список селекторов A2 (ТЗ №5) не включал подвал.
   Точечный фикс шрифта, не расширяем это ТЗ на цвета/структуру подвала —
   там регрессий не найдено. */
.newsx-site-footer,
.newsx-site-footer h1,
.newsx-site-footer h2,
.newsx-site-footer h3,
.newsx-site-footer h4,
.newsx-site-footer a {
  font-family: var(--font-grotesk);
}

/* ---------------------------------------------------------
   ТЗ №17 — Bento-сетка главной страницы (ADR-010 п.1d).
   Секции 1/2 Кастомайзера (журнал + список, дублирующие одни и те же
   посты) скрыты вместо удаления — виджеты остаются настроены, откат
   одной правкой этого блока. Секция 3 получает [obz_bento_grid]
   (functions.php). Граница десктоп/мобайл — 900px, ADR-015. */
/* Пустые секции Кастомайзера скрываются, но ряд с Bento не скрывается
   никогда — привязка к содержимому, а не к номеру ряда. Номер ряда
   меняется при любой перестановке секций в Кастомайзере, и без этой
   защиты Bento молча исчезал бы с главной. ТЗ №18 задача 3. */
.newsx-fp-row-1:not(:has(.obz-bento-grid)),
.newsx-fp-row-2:not(:has(.obz-bento-grid)) {
  display: none;
}

@media (min-width: 900px) {
  .obz-bento-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 220px;
    gap: 16px;
  }

  /* < 5 карточек: крупная плитка не назначается в PHP (obz-bento-few) —
     равномерная раскладка без дыр, см. ТЗ №18 задача 1. */
  .obz-bento-grid.obz-bento-few {
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    grid-auto-rows: auto;
  }

  .obz-bento-grid > .obz-bento-large {
    grid-column: span 2;
    grid-row: span 2;
  }

  /* Хвостовой ряд: карточки, не заполняющие 4 колонки, растягиваются,
     чтобы ряд не обрывался пустыми ячейками. Расчёт остатка — в PHP
     (obz_bento_grid_shortcode), см. ТЗ №18 задача 2. */
  .obz-bento-grid > .obz-bento-w2 { grid-column: span 2; }
  .obz-bento-grid > .obz-bento-w4 { grid-column: span 4; }
}

@media (max-width: 899px) {
  /* Двойной класс-селектор — не эстетика, а обязательный обход конфликта:
     .newsx-magazine-layout{display:grid} тянется вместе с классом-маркером
     из main.min.css (assets/css/main.min.css), подключается ПОСЛЕ style.css
     дочерней темы и не обёрнут в media-запрос — при равной специфичности
     (один класс) он выигрывает у этого правила по порядку в каскаде.
     Обнаружено 21.08.2026 живой проверкой на 899px (сетка оставалась grid).
     .obz-bento-grid.newsx-magazine-layout — специфичность выше (2 класса). */
  .obz-bento-grid.newsx-magazine-layout {
    display: block;
  }

  /* .newsx-grid-media/.newsx-grid-over-media — .newsx-full-stretch,
     position:absolute + height:100% (main.min.css), рассчитан на высоту
     ячейки от grid-auto-rows родителя. В одноколоночной ленте (display:block)
     высоты у родителя нет — без min-height карточка схлопывалась в 0px и
     визуально пропадала (обнаружено 21.08.2026 на 375px). */
  .obz-bento-grid > .newsx-grid-item {
    position: relative;
    /* height, не min-height: .newsx-grid-media/.newsx-grid-image получают
       свою высоту через height:100% (.newsx-full-stretch, main.min.css) —
       процент от auto-высоты родителя (даже с min-height) браузер не
       резолвит, карточка схлопывалась в 0px несмотря на видимый
       min-height. Обнаружено 21.08.2026 повторно на 375px. */
    height: 260px;
    margin-bottom: 16px;
  }

  .obz-bento-grid > .newsx-grid-item:last-child {
    margin-bottom: 0;
  }
}

/* ---------------------------------------------------------
   ТЗ №19 — Десктопная адаптация статьи, первый срез (ADR-010 п.1e).
   Referens: Design-System/tokens/ (нет отдельного .dc.html для десктопа
   статьи) — значения берутся из токенов напрямую, это решение архитектора.
   --------------------------------------------------------- */

/* Задача 1 — родная шапка темы на десктопе статьи (и везде, куда она уже
   применяется вне мобиля) не входит в список A2 (ТЗ №5) — унаследовать
   гарнитуру дизайн-системы тем же приёмом, что футер (ТЗ №12 ч.2). Не
   ограничивать body.single: шапка общая для всех типов страниц, сужать
   до статьи было бы искусственно и создало бы несовпадение шапки между
   статьёй и лентой на десктопе. */
.newsx-site-header,
.newsx-site-header a,
.newsx-main-menu a {
  font-family: var(--font-grotesk);
}

/* Задача 2 — первый экран статьи на десктопе.
   Ширина текстовой колонки НЕ сужена до --container-text (680px) —
   разведка (getComputedStyle, 1280px, живая статья) показала конфликт:
   .newsx-single-inner — flex-контейнер 1240px с РЕАЛЬНЫМ сайдбаром
   (.newsx-sidebar.newsx-general-sidebar, виджет «Популярные статьи»,
   372px), а не пустая обёртка. .newsx-single-content-wrap (сама текстовая
   колонка) — 808px, не «близко» к 680px ни с каким разумным паддингом.
   max-width:680px на .newsx-single-inner сломал бы flex-раскладку с
   сайдбаром. Правило из ТЗ №19 задача 2 (сужение колонки) НЕ применено —
   зафиксировано в Vyvody/2026-08-21-TZ-19-..., решение — за архитектором.

   ОБНОВЛЕНО ТЗ №21 (22.08.2026): конфликт снят решением владельца убрать
   сайдбар со страницы статьи (Customizer: Глобальный → Боковая панель →
   «Отдельная боковая панель блога» = «Без сайдбара», newsx_options
   [global_blog_single_sidebar_display] = none — настройка НЕ глобальная,
   влияет только на одиночную статью, лента/рубрика/страницы не задеты).
   .newsx-single-inner теперь занимает контент без сайдбара (подтверждено:
   1240px, sidebar отсутствует в DOM). Правило ниже сужает саму текстовую
   колонку .newsx-single-content-wrap до --container-text (680px) — без
   него полноширинная колонка дала бы ~150 символов в строке при норме
   60-80. См. Vyvody/2026-08-22-TZ-21-Statya-Bez-Saydbara.md.

   ДОРАБОТКА (та же заливка, найдено сразу двумя проходами по живой странице):
   без сайдбара весь путь .newsx-single-wrap → .newsx-single-inner →
   .content-area.primary — вложенные flex-контейнеры, и оба .newsx-single-inner,
   и .content-area.primary были flex-item с flex-grow:0 у своего родителя,
   поэтому каждый по очереди схлопывался до content-width (680px) вместо
   заполнения 1240px — margin:auto на .newsx-single-content-wrap не мог
   центрировать: снаружи не было лишнего места. flex-grow:1 на ОБОИХ уровнях
   возвращает полную ширину, тогда margin:auto центрирует 680px-колонку верно.
   Первая правка (только .newsx-single-inner) была проверена и оказалась
   недостаточной — .content-area.primary схлопывался следующим; это вторая
   и последняя правка того же дня. */
@media (min-width: 900px) {
  body.single .newsx-single-inner,
  body.single .content-area.primary {
    flex-grow: 1;
  }
  body.single .newsx-single-content-wrap {
    max-width: var(--container-text);
    margin-left: auto;
    margin-right: auto;
  }
}

@media (min-width: 900px) {
  /* Бейдж рубрики — тот же паттерн, что мобиль (ТЗ №2 п.3). */
  .newsx-single-post-header .newsx-post-categories a {
    display: inline-block;
    padding: 5px 12px;
    border-radius: var(--radius-pill);
    background: var(--obz-cat-current, var(--obz-cat-other)) !important;
    color: var(--obz-white);
    font-family: var(--font-grotesk);
    font-size: 13px;
    font-weight: var(--fw-bold);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
  }

  /* Заголовок — используется токен --fs-h1 (42px десктопный), а не
     хардкод как на мобиле: там отклонение от токена осознанное (ТЗ №2),
     здесь прототипа с иным значением нет. !important по той же причине,
     что на мобиле — инлайн-CSS кастомайзера той же специфичности. */
  .newsx-single-post-header h1 {
    font-family: var(--font-grotesk) !important;
    font-weight: var(--fw-black) !important;
    font-size: var(--fs-h1) !important;
    line-height: var(--lh-h1) !important;
    letter-spacing: var(--ls-h1) !important;
    color: var(--obz-ink-900) !important;
    margin: 0 !important;
    text-wrap: balance;
  }

  /* Лид — токен --fs-lead десктопный (22px), переопределяет базовое
     правило строки ~264 (без @media, действует и на десктопе без этого
     override). */
  .obz-article-lead {
    font-size: var(--fs-lead);
    line-height: var(--lh-lead);
  }

  /* Мета-строка — зеркало мобильного блока ТЗ №2 п.4, font-size чуть
     крупнее (14px вместо 13px) соразмерно росту остального текста.
     Разделитель "·" тот же приём, что на мобиле. */
  .newsx-single-post-header .newsx-post-meta,
  .newsx-single-post-header .newsx-post-meta-inn-wrap,
  .newsx-single-post-header .newsx-post-meta-inner,
  .newsx-single-post-header .newsx-post-meta-inn-group {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-grotesk);
    font-size: 14px;
    line-height: 1.4;
    color: var(--obz-ink-600);
  }
  .newsx-single-post-header .newsx-post-date { color: var(--obz-ink-600); }
  .newsx-single-post-header .newsx-post-meta-inn-group > *:after { content: none; }
  .newsx-single-post-header .newsx-post-reading-time:before { content: "\00b7"; margin-right: 10px; }

  /* Отступы первого экрана — 40px сверху (var(--space-10)), не 20px
     мобильный: десктоп ADR-007 использует более щедрые отступы. */
  body.single .newsx-single-post-header {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: var(--space-10) var(--gutter-page) 0;
    margin-bottom: 0;
  }

  /* Хлебные крошки — на десктопе НЕ скрыты (решение архитектора, см. ТЗ
     №19 задача 2): дополнительная навигация вглубь категорий, не
     дублирование SEO-разметки RankMath. Родной стиль темы, без override —
     не должны визуально отличаться от крошек рубрики/ленты. */
}

/* Задача 3 — CTA-слот под лидом на десктопе. padding с боковым гуттером
   (var(--gutter-page)), а не "24px 0 0": колонка НЕ сужена (см. задачу 2
   выше), .obz-article-cta живёт на полной ширине .newsx-single-content-wrap,
   без бокового отступа кнопка прижималась бы к самому краю колонки. */
@media (min-width: 900px) {
  body.single .obz-article-cta {
    display: block;
    padding: 24px var(--gutter-page) 0;
  }
  .obz-cta-tg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: auto;
    padding: 0 24px;
    height: 48px;
    border-radius: 12px;
    background: var(--obz-orange);
    color: var(--obz-white);
    font-family: var(--font-grotesk);
    font-size: 15px;
    font-weight: var(--fw-bold);
    letter-spacing: -0.01em;
    text-decoration: none;
  }
  .obz-cta-tg:hover { background: var(--obz-orange-press); }
}

/* Задача 4 — нижний sticky-CTA: ничего не меняется, правило
   `@media (min-width:900px){.obz-sticky-cta{display:none}}` (ТЗ №3,
   строка ~444) остаётся как есть — проверено при приёмке, что этот блок
   ТЗ №19 (добавленный дальше в конце файла) не пересекается с ним по
   каскаду и не переопределяет его. */

/* Задача 5 — блок «Читать ещё»: обёртка и заголовок на десктопе.
   background:var(--surface-sunken) мобиля сознательно НЕ переносится —
   border-top вместо заливки на всю ширину (тот же приём, что другие
   десктопные секции файла, см. футер/A7). Колонка не сужена (задача 2) —
   если это решение изменится, вернуться и пересмотреть на заливку по
   образцу мобиля, не переносить молча. */
@media (min-width: 900px) {
  body.single .newsx-related-posts-wrap {
    margin: var(--space-16) 0 0;
    padding: var(--space-10) 0 var(--space-12);
    border-top: 1px solid var(--border-default);
  }
  .newsx-related-posts-wrap h4 {
    font-family: var(--font-grotesk);
    font-weight: var(--fw-black);
    font-size: var(--fs-h2);
    line-height: var(--lh-h2);
    color: var(--text-strong);
    margin: 0 0 var(--space-6);
  }
}

/* ---------------------------------------------------------
   ТЗ №20 задача 4 — «Читать ещё» не должен разваливаться при 1–2 карточках.
   Блок рассчитан родителем на 3 карточки (repeat(3,1fr)). Реальное число
   зависит от наполнения рубрики и может быть 1 или 2 — тогда фиксированная
   сетка оставляет пустые колонки. Тот же приём, что .obz-bento-few в
   ТЗ №18: auto-fit вместо жёстких колонок.
   --------------------------------------------------------- */
@media (min-width: 900px) {
  .newsx-related-posts.obz-related-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--gap-grid);
  }
}
