/*
Theme Name: SEO Reports 2026
Theme URI: https://seo-reports.ru/blog/
Author: Evgenii Kopach
Description: Тема блога seo-reports.ru по дизайну 2026 года.
Version: 2.0.0
Requires PHP: 7.4
Text Domain: seo-reports-2026
*/

/* ===========================================================
   Токены. Спека, раздел 4.
   =========================================================== */
:root {
  --accent: #00A86B;
  --bg: #FAFAFB;          --surface: #FFFFFF;
  --ink: #0E0E12;         --ink-2: #4A4A55;       --ink-3: #8B8B95;
  --muted: #6B6B74;       --dim: #9A9AA5;         --faint: #C9CAD2;
  --line: #EEEFF3;        --line-2: #E4E5EA;
  --chip: #F5F6FA;
  --dark: #0E0E12;        --dark-2: #0A0A0D;      --dark-line: #22222C;
  --prose: #2B2B33;

  /* Финальный проход по CSS: значения, которые повторялись буквально по всему
     файлу и по смыслу обязаны меняться разом.
     --radius-pill — «таблетка» (7 мест: пилюля рубрики, бейдж «Главное»,
     счётчики, кнопки рельса, маркер callout).
     --sticky-top — отступ сверху у липких колонок (сайдбар блога, рельс
     «Поделиться», сайдбар статьи): все трое стоят под фиксированной шапкой,
     и разъехаться им нельзя. */
  --radius-pill: 999px;
  --sticky-top: 100px;

  /* Раунд правок 1 (ревью): токены для цветов, у которых их раньше не было —
     фон/заливка иконок соцсетей в футере и белый текст/лого на тёмном фоне.
     Взяты из инлайновых style источника (SiteFooter.vue), значения те же. */
  --dark-surface: #18181F;
  --dark-icon: #C9C9D4;
  --dark-fg: #FFFFFF;

  /* Задача 5 (cookie-banner.php / theme.js): токены для цветов из
     CookieConsent.vue (<style scoped>), у которых нет готового соответствия
     среди токенов выше. Значения — те же, что в источнике. */
  --dark-text-2: #D7D7DD;
  --dark-line-2: #33333E;
  --accent-hover: #059862;
  --line-hover: #DCDDE4;
  --overlay: rgba(10, 10, 13, 0.55);
  --shadow-banner: 0 24px 60px -20px rgba(0, 0, 0, 0.55);
  --shadow-modal: 0 30px 80px -20px rgba(15, 15, 30, 0.5);

  /* Задача 6 (карточки постов): токены для цветов, у которых не было готового
     соответствия. --accent-wash — фон пилюли рубрики: 15% акцента на белом,
     посчитано заранее как фолбэк для браузеров без color-mix() (см. .sr-tag).
     --shadow-card — тень карточки при наведении, тон в цвет --ink. */
  --accent-wash: #00A86B15;
  --shadow-card: 0 20px 44px -28px rgba(14, 14, 18, 0.28);

  /* Тень картинок в прозе статьи (.sr-prose img). Заметно мягче и шире
     карточной: картинка не интерактивна и не должна читаться как кнопка,
     но обязана отделяться от почти белого фона страницы — у статей блога
     много скриншотов интерфейсов со светлой подложкой. */
  --shadow-media: 0 18px 40px -20px rgba(14, 14, 18, 0.38), 0 2px 6px -2px rgba(14, 14, 18, 0.10);

  /* Подложка плашки «N статей» в герое рубрики — акцент на 8% (мокап
     rubric.jsx: `${tint}14`, 0x14 ≈ 8%). Тем же приёмом «альфа-хекс как
     фолбэк + color-mix() поверх», что и --accent-wash выше. */
  --accent-tint: #00A86B14;

  /* Задача 8 (герой блога): подсветка радиального градиента героя —
     accent на 12% (спека 7.1: radial-gradient(..., {accent}1F, transparent 60%),
     0x1F ≈ 12%), фолбэк-хекс для браузеров без color-mix() (см. .sr-tag выше). */
  --accent-glow: #00A86B1F;

  /* Раунд правок 1 (CTA-карточка, мокап components/blog.jsx): токены для
     значений мокапа, у которых нет готового соответствия среди токенов выше.
     --accent-glow-cta/--accent-shadow-cta — альфа-хеки мокапа (${tint}44 и
     ${tint}88, 0x44 ≈ 27%, 0x88 ≈ 53%) с фолбэком на color-mix(), тот же
     приём, что --accent-wash/--accent-glow. --cta-border — рамка кнопки
     «Пример отчёта» (#2A2A33 мокапа, отличается от --dark-line-2 футера/
     cookie-баннера). --cta-stat-bg — фон плашки статистики карточки
     (rgba(255,255,255,0.04) мокапа). */
  --accent-glow-cta: #00A86B44;
  --accent-shadow-cta: #00A86B88;
  --cta-border: #2A2A33;
  --cta-stat-bg: rgba(255, 255, 255, 0.04);

  /* Задача 10 (классы для контента статьи, спека 7.6): цвета callout'ов
     warn/fact — «tip» переиспользует существующий --accent/--accent-wash,
     этим двум готового соответствия нет. Спека называет только классы
     (.sr-callout--tip|warn|fact), не цвета — значения ниже собственный
     выбор в духе остальной палитры (тёплый предупреждающий/нейтральный
     информационный), тем же приёмом «--wash-хекс + color-mix() поверх»,
     что и --accent-wash выше. Стоит подтвердить у владельца перед публикацией. */
  --warn: #B45309;
  --warn-wash: #B4530926;
  --fact: #2563EB;
  --fact-wash: #2563EB26;

  --font-sans: 'Geist', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, monospace;
  --font-display: 'Lora', Georgia, serif;
  --wrap: 1200px;
  --pad: 32px;

  /* Вордмарк логотипа — как в ../seo-reports/landing/src/layouts/Base.astro. */
  --wordmark-font: 'Geist', sans-serif;
  --wordmark-weight: 700;
  --wordmark-style: normal;
  --wordmark-ls: -0.03em;
  --wordmark-size: 0.62;
}

/* --wrap/--pad (см. :root выше) — общий контейнер контентных страниц
   (.sr-container ниже, Задача 8). «Паддинги секций 32→20px» (спека,
   раздел 10, ≤640) — единая точка правки: любой раздел, использующий
   var(--pad) по горизонтали (герой, пилюли рубрик, контент+сайдбар,
   CTA-полоса), сжимается сразу, без повтора медиазапроса в каждом блоке.
   Шапка/футер сюда не входят — их 32px — буквальные значения 1:1-порта
   источника (см. комментарии над .site-header/.site-footer), не связаны
   с этим токеном. */
@media (max-width: 640px) {
  :root {
    --pad: 20px;
  }
}

/* ===========================================================
   База. Портируется из Base.astro (глобальный <style is:global>).
   =========================================================== */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 84px; }
html, body { margin: 0; padding: 0; background: var(--bg); }
body {
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  color: var(--ink);
}
img { max-width: 100%; height: auto; }

/* Акцентная кнопка-ссылка. Появляется на двух страницах-тупиках — «в рубрике
   пусто» и 404 — и в обеих ведёт читателя обратно в блог. Раньше была описана
   дважды, дословно одинаково, в двух разных секциях файла; живёт здесь, в
   базе, потому что принадлежит не странице, а теме. */
.sr-btn-accent {
  display: inline-flex;
  align-items: center;
  padding: 12px 22px;
  border-radius: 10px;
  background: var(--accent);
  color: var(--dark-fg);
  font-size: 14.5px;
  font-weight: 600;
  text-decoration: none;
  transition: background 0.15s ease;
}
.sr-btn-accent:hover {
  background: var(--accent-hover);
}

/* ===========================================================
   Chrome — логотип.
   sr_logo() (inc/template-tags.php) — порт Logo.vue. В Vue разметка несёт
   раскладку (flex/gap) и типографику вордмарка через инлайновый :style;
   PHP-версия функции (см. бриф Задачи 4) отдаёт только классы + цвет,
   поэтому раскладка и типографика вордмарка перенесены сюда, в CSS-класс.
   Значения — те же, что были в инлайн-стилях источника.
   =========================================================== */
.sr-logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.sr-logo__word {
  font-family: var(--wordmark-font, inherit);
  font-weight: var(--wordmark-weight, 600);
  font-style: var(--wordmark-style, normal);
  letter-spacing: var(--wordmark-ls, -0.02em);
  white-space: nowrap;
}
/* Кегль вордмарка = 0.62 × size (Logo.vue). Оба текущих места вызова
   (шапка — size 32, футер — size 26) захардкожены здесь явно, потому что
   sr_logo() не прокидывает size в CSS (только цвет) — иначе трогать эту
   функцию пришлось бы вопреки коду, продиктованному Шагом 3 брифа. */
.site-header .sr-logo__word {
  font-size: calc(32px * var(--wordmark-size, 0.62));
}
.site-footer .sr-logo__word {
  font-size: calc(26px * var(--wordmark-size, 0.62));
}

/* ===========================================================
   Chrome — шапка. Портируется 1:1 из
   ../seo-reports/landing/src/components/SiteHeader.vue (<style scoped>).
   Единственная содержательная правка — .site-header__toc a.is-active
   использует var(--accent) вместо захардкоженного #00a86b.

   Задача 13: hex-литералы блока (след порта из <style scoped>, значения
   не менялись) заменены на токены — #0e0e12→--ink, #eeeff3→--line,
   #4a4a55→--ink-2, #9a9aa5→--dim, white→--dark-fg. Правило
   .site-header__burger-icon[hidden] — фикс дефекта «видны обе иконки
   бургера на мобильном», тот же приём, что у .site-header__panel[hidden]
   ниже.
   =========================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(250, 250, 251, 0.8);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-header__bar {
  max-width: 1200px;
  margin: 0 auto;
  padding: 16px 32px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.site-header__nav {
  display: flex;
  gap: 32px;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-2);
}
.site-header__nav a {
  color: inherit;
  text-decoration: none;
}
.site-header__cta {
  display: flex;
  gap: 10px;
  align-items: center;
}
.site-header__login {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}
.site-header__signup {
  font-size: 14px;
  font-weight: 600;
  color: var(--dark-fg);
  background: var(--ink);
  padding: 9px 16px;
  border-radius: 8px;
  text-decoration: none;
}
/* Обёртка нужна, чтобы кнопки держались вместе: без неё space-between
   развёл бы их по разным краям шапки. */
.site-header__icons {
  display: none;
  align-items: center;
  gap: 8px;
}
.site-header__iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  background: var(--dark-fg);
  border-radius: 10px;
  cursor: pointer;
  color: var(--ink);
}
.site-header__iconbtn.is-open {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--dark-fg);
}
/* Тот же приём, что у .site-header__panel[hidden] ниже в файле (см. комментарий
   там): без явного правила для самого элемента атрибут hidden у крестика
   ничего не перебивает, и оба SVG внутри .site-header__iconbtn.site-header__burger
   (flex-контейнер) остаются видны разом. */
.site-header__burger-icon[hidden] {
  display: none;
}
.site-header__panel {
  display: none;
}
/* Расширение против источника: в Vue видимость панелей переключает
   v-show — он пишет инлайн-style, который перебивает любое правило
   класса независимо от специфичности. В теме видимость держит атрибут
   hidden (см. assets/js/theme.js), а его подразумеваемое UA-правило
   [hidden]{display:none} того же авторского происхождения, что и наши
   правила — специфичность класса .site-header__panel (в т.ч. внутри
   медиазапроса ниже) её перебивала бы. Правило с составным селектором
   .site-header__panel[hidden] специфичнее обоих и всегда выигрывает,
   пока атрибут hidden присутствует. */
.site-header__panel[hidden] {
  display: none;
}
.site-header__toc-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
  padding-bottom: 4px;
}
.site-header__toc a.is-active {
  color: var(--accent) !important;
  font-weight: 600 !important;
}
.site-header__mobile-cta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}

/* Прячем пункты в горизонтальной навигации на узких экранах.
   В гамбургер-меню (≤820px) все пункты остаются доступны. */
@media (max-width: 1079px) {
  .site-header__nav .nav-faq {
    display: none !important;
  }
}
@media (max-width: 1009px) {
  .site-header__nav .nav-how {
    display: none !important;
  }
  /* «Как работает» скрыт — поджимаем расстояние между пунктами на 10px */
  .site-header__nav {
    gap: 22px;
  }
}

@media (max-width: 820px) {
  .site-header__nav,
  .site-header__cta {
    display: none;
  }
  .site-header__icons {
    display: flex;
  }
  .site-header__panel {
    display: grid;
    gap: 6px;
    padding: 8px 32px 20px;
    border-top: 1px solid var(--line);
  }
  .site-header__panel a {
    color: var(--ink);
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    padding: 8px 0;
  }
  .site-header__toc a {
    font-size: 14.5px;
    color: var(--ink-2);
    padding: 7px 0;
  }
  .site-header__mobile .site-header__signup {
    color: var(--dark-fg);
    padding: 10px 16px;
  }
}
@media (max-width: 640px) {
  .site-header__bar {
    padding: 14px 20px;
  }
  .site-header__panel {
    padding: 8px 20px 18px;
  }
}

/* ===========================================================
   Chrome — футер. Портируется 1:1 из
   ../seo-reports/landing/src/components/SiteFooter.vue (<style scoped>).
   Единственная содержательная правка — .social-ico:hover использует
   var(--accent) вместо захардкоженного #00a86b.

   Раунд правок 1 (ревью): инлайновые style="" из <template> источника
   (не <style scoped>) в footer.php больше НЕ переносятся как голые hex —
   цвета, дублирующие токены, заменены на var(...), а для #18181F/#C9C9D4
   (своих токенов раньше не было) заведены --dark-surface/--dark-icon.
   Заливка иконок соцсетей (обычное состояние, без hover) — единственный
   случай, где инлайновый атрибут (fill="#C9C9D4" на самих <svg>) мешал
   подставить переменную естественным образом, поэтому её убрали из
   footer.php и правило добавлено здесь, ниже.

   Задача 13: оставшиеся hex-литералы блока <style scoped> заменены на
   токены — #22222c→--dark-line, #fff→--dark-fg.
   =========================================================== */
.social-ico {
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.social-ico:hover {
  background: var(--dark-line);
  border-color: var(--accent);
  transform: translateY(-2px);
}
/* Обычное (не hover) состояние иконки — раньше было инлайновым
   fill="#C9C9D4" прямо на <svg> в footer.php, теперь класс + токен. */
.social-ico svg {
  fill: var(--dark-icon);
}
/* :deep(svg) — синтаксис Vue для проникновения scoped-стилей в дочерний
   компонент; в обычном CSS это просто дочерний селектор. */
.social-ico:hover svg {
  fill: var(--dark-fg);
}

/* Верхний отступ подвала десктопный (60px) и на узких экранах выбивается
   из уменьшенных отступов секций */
@media (max-width: 820px) {
  .site-footer {
    padding-top: 40px !important;
  }
}
@media (max-width: 640px) {
  .site-footer {
    padding-top: 30px !important;
  }
  /* Боковой отступ футера на узких экранах — 20px, как у полосы шапки
     (.site-header__bar в этом же медиазапросе) и у .sr-container через
     var(--pad). В источнике он остаётся 32px на всех ширинах, из-за чего
     содержимое футера стоит на 12px правее содержимого страницы. !important
     — паддинг задан инлайном в footer.php (порт <template> источника), как и
     у остальных правил-переопределений этого блока. */
  .site-footer > div {
    padding-left: 20px !important;
    padding-right: 20px !important;
  }
}

/* В мобильной версии: логотип, описание и соцсети — на всю ширину,
   ниже «Продукт» и «Ресурсы» в две колонки */
@media (max-width: 640px) {
  .footer-top {
    grid-template-columns: 1fr 1fr !important;
    gap: 32px 24px !important;
  }
  .footer-top > :first-child {
    grid-column: 1 / -1;
  }
}

/* Когда копирайт и ссылки переносятся на вторую строку (≤770px) — центрируем */
@media (max-width: 770px) {
  .footer-bottom {
    justify-content: center !important;
    text-align: center !important;
    gap: 8px !important;
  }
  /* row-gap = отступу строк выше, чтобы при переносе «Настройка cookies»
     межстрочный интервал был одинаковым; column-gap (20px из inline) сохраняем */
  .footer-legal {
    justify-content: center !important;
    row-gap: 8px !important;
  }
}

/* ===========================================================
   Cookie-баннер и модалка настроек. Задача 5, раздел спеки 6.3.
   Портируется 1:1 из
   ../seo-reports/landing/src/components/CookieConsent.vue (<style scoped>).
   Классы свои (sr-cookie*, см. cookie-banner.php) — cc-* в источнике
   изолированы Vue-скоупингом, в глобальном CSS темы так же не защищены.
   Цвета — через переменные (см. :root выше); значения не менялись.
   =========================================================== */
.sr-cookie-banner {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 50;
  max-width: 895px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 16px 20px;
  background: var(--dark);
  color: var(--dark-text-2);
  border: 1px solid var(--dark-line);
  border-radius: 16px;
  box-shadow: var(--shadow-banner);
  font-family: var(--font-sans);
}
/* Атрибут hidden скрывает баннер до решения JS его показать; без этого
   правила display:flex выше (авторская специфичность побеждает UA-стиль
   [hidden]{display:none} независимо от порядка) держал бы баннер видимым
   всегда — тот же приём, что у .site-header__panel[hidden] выше в файле. */
.sr-cookie-banner[hidden] {
  display: none;
}
.sr-cookie-banner__text {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
}
.sr-cookie-banner__text a {
  color: var(--dark-fg);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.sr-cookie-banner__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.sr-cookie-btn {
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  padding: 10px 16px;
  border-radius: 10px;
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.sr-cookie-btn--primary {
  background: var(--accent);
  color: var(--dark-fg);
}
.sr-cookie-btn--primary:hover {
  background: var(--accent-hover);
}
.sr-cookie-btn--ghost {
  background: transparent;
  color: var(--dark-icon);
  border-color: var(--dark-line-2);
}
.sr-cookie-btn--ghost:hover {
  background: var(--dark-surface);
  color: var(--dark-fg);
}

.sr-cookie-overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: var(--overlay);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
/* Тот же приём, что у .sr-cookie-banner[hidden] выше — display:flex
   базового правила иначе держал бы оверлей поверх страницы всегда. */
.sr-cookie-overlay[hidden] {
  display: none;
}
.sr-cookie-modal {
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  background: var(--surface);
  border-radius: 18px;
  box-shadow: var(--shadow-modal);
  font-family: var(--font-sans);
  color: var(--ink);
}
.sr-cookie-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 24px 14px;
  border-bottom: 1px solid var(--line);
}
.sr-cookie-modal__title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.sr-cookie-close {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 9px;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.sr-cookie-close:hover {
  background: var(--chip);
  color: var(--ink);
}
.sr-cookie-modal__body {
  padding: 18px 24px 4px;
}
.sr-cookie-modal__intro {
  margin: 0 0 16px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-2);
}
.sr-cookie-modal__intro a {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.sr-cookie-modal__intro a:hover {
  text-decoration: underline;
}

.sr-cookie-item {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  padding: 14px 16px;
  margin-bottom: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color 0.15s;
}
.sr-cookie-item:hover {
  border-color: var(--line-hover);
}
.sr-cookie-item--locked {
  cursor: default;
  background: var(--bg);
}
/* Прячем нативный чекбокс, рисуем свой в .sr-cookie-item__box */
.sr-cookie-item input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.sr-cookie-item__box {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  border: 1.5px solid var(--faint);
  border-radius: 6px;
  background: var(--surface);
  position: relative;
  transition: background 0.15s, border-color 0.15s;
}
.sr-cookie-item input:checked + .sr-cookie-item__box {
  background: var(--accent);
  border-color: var(--accent);
}
.sr-cookie-item input:checked + .sr-cookie-item__box::after {
  content: '';
  position: absolute;
  left: 6px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid var(--surface);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.sr-cookie-item input:disabled + .sr-cookie-item__box {
  background: var(--faint);
  border-color: var(--faint);
}
.sr-cookie-item input:focus-visible + .sr-cookie-item__box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.sr-cookie-item__name {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.sr-cookie-item__desc {
  display: block;
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.5;
  margin-top: 4px;
}

.sr-cookie-modal__foot {
  padding: 14px 24px 22px;
  display: flex;
  justify-content: flex-end;
}
.sr-cookie-modal__foot .sr-cookie-btn {
  padding: 11px 24px;
}

@media (max-width: 640px) {
  .sr-cookie-banner {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    left: 10px;
    right: 10px;
    bottom: 10px;
    padding: 16px;
  }
  .sr-cookie-banner__actions {
    flex-wrap: wrap;
  }
  .sr-cookie-banner__actions .sr-cookie-btn {
    flex: 1 1 auto;
  }
}

/* ===========================================================
   Обложки постов. Спека, раздел 8. Разметку рисует sr_post_cover()
   (inc/template-tags.php, Задача 3) — там же выбор фото/генеративной ветки
   и инлайновый style (border-radius, height/aspect-ratio, background).
   CSS для этой разметки сознательно не писался в Задаче 3 и добавляется
   только теперь, вместе с карточками, которые обложку используют.
   =========================================================== */
.sr-cover {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--chip);
}
.sr-cover--photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Генеративная обложка: глиф рубрики сверху слева, узор поверх фона,
   огромная полупрозрачная буквица снизу справа — обрезается границами
   карточки за счёт overflow:hidden на .sr-cover выше. */
.sr-cover--generated {
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  padding: 16px;
}
.sr-cover--generated.sr-cover--big {
  padding: 22px;
}
.sr-cover__pattern {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.sr-cover__glyph {
  position: relative;
  z-index: 1;
  display: inline-flex;
  opacity: 0.9;
}
/* Прозрачность 0.16 — значение из спеки (раздел 8), не подбор. */
.sr-cover__letter {
  position: absolute;
  z-index: 0;
  right: 6px;
  bottom: -0.18em;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 130px;
  line-height: 1;
  color: var(--dark-fg);
  opacity: 0.16;
  pointer-events: none;
}
.sr-cover--big .sr-cover__letter {
  font-size: 180px;
}

/* ===========================================================
   Карточки постов и мета. Спека, раздел 7.1 (+ 7.2 — та же .sr-grid
   переиспользуется страницей рубрики в Задаче 9).
   =========================================================== */

/* Пилюля рубрики (тег на карточке). 11px/700, uppercase, letter-spacing .06em,
   radius 999px — точные значения из брифа Задачи 6, Шаг 4. Фон — 15% акцента:
   сперва фолбэк-переменная (заранее посчитанный цвет), затем color-mix() —
   в браузерах без её поддержки вторая строка отбрасывается как невалидная,
   и остаётся первая (обычный приём прогрессивного улучшения). */
.sr-tag {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  margin-bottom: 10px;
  padding: 5px 11px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent);
  background: var(--accent-wash);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}

/* Строка меты: дата · время чтения (template-parts/post-meta.php). */
.sr-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
}
.sr-meta__dot {
  width: 3px;
  height: 3px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--faint);
}
.sr-meta__time {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.sr-meta__icon {
  flex-shrink: 0;
}
/* Внутри карточек мета всегда прижата к низу, независимо от длины
   заголовка/анонса над ней — родитель (.sr-card__body/.sr-featured__body)
   flex-колонка, margin-top:auto толкает строку меты вниз. */
.sr-card__body .sr-meta,
.sr-featured__body .sr-meta {
  margin-top: auto;
  padding-top: 14px;
}
/* Нижняя строка обычной карточки: мета слева, «Читать статью →» справа —
   тот же приём, что и .sr-featured__foot у крупной. Отступ сверху даёт
   .sr-meta внутри (правило выше), поэтому здесь только раскладка. */
.sr-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: auto;
}
.sr-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-top: 14px;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--accent);
}

/* Общий каркас обеих карточек ленты — обычной (template-parts/card-post.php)
   и крупной «главной» (template-parts/card-featured.php). Различаются они
   только раскладкой, отступами и радиусом; фон, рамка, поведение ссылки и
   реакция на наведение у них общие — и обязаны совпадать, иначе одна карточка
   в той же ленте начнёт вести себя иначе, чем соседняя. */
.sr-card,
.sr-featured {
  background: var(--surface);
  border: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.sr-card:hover,
.sr-featured:hover {
  border-color: var(--line-2);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

/* Обычная карточка ленты (template-parts/card-post.php). */
.sr-card {
  display: flex;
  flex-direction: column;
  padding: 16px;
  border-radius: 20px;
}
.sr-card .sr-cover {
  display: block;
  width: 100%;
  margin-bottom: 16px;
}
.sr-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}
.sr-card__title {
  margin: 0 0 8px;
  font-size: 18.5px;
  line-height: 1.35;
  letter-spacing: -0.01em;
  font-weight: 600;
  color: var(--ink);
  text-wrap: pretty;
}
.sr-card__excerpt {
  margin: 0 0 14px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
}

/* Сетка обычных карточек. repeat(2,1fr)/gap:20px — спека 7.1/7.2.
   Класс подключат Задачи 8 (index.php) и 9 (category.php); адаптив (≤900 —
   одна колонка) делается уже здесь, по явному указанию брифа Задачи 6, а не
   откладывается до появления самой разметки сетки. */
.sr-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}

/* Крупная «главная» карточка первого поста (template-parts/card-featured.php).
   Сетка 1.15fr/1fr, gap:36px, radius:24px, обложка 360px — спека 7.1. */
.sr-featured {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 36px;
  padding: 24px;
  border-radius: 24px;
}
.sr-featured .sr-cover {
  display: block;
  width: 100%;
}
.sr-featured__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* Строка «★ Главное + рубрика» и строка «мета + Читать статью →» — обе из
   мокапа (blog.jsx, LayoutMagazine): без них плашка с тегом и мета с CTA
   вставали друг под другом, потому что .sr-featured__body — flex-колонка. */
.sr-featured__labels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
}
.sr-featured__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 24px;
}
/* Отступы, которыми .sr-tag и .sr-meta разделяли себя, когда были прямыми
   детьми колонки, внутри этих строк уже не нужны — расстояние держит gap.
   margin-top: auto у .sr-meta (правило «мета прижата к низу карточки») в
   строке-флексе прижал бы её к нижнему краю строки. */
.sr-featured__labels .sr-tag {
  margin-bottom: 0;
}
.sr-featured__foot .sr-meta {
  margin-top: 0;
  padding-top: 0;
}
.sr-featured__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--dark-fg);
  font-size: 12.5px;
  font-weight: 700;
}
.sr-featured__title {
  margin: 0 0 12px;
  font-size: 34px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--ink);
}
.sr-featured__excerpt {
  margin: 0 0 20px;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--muted);
}
.sr-featured__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--accent);
}

/* ≤900: сетка карточек в одну колонку, «главная» карточка складывается
   вертикально — спека, раздел 10. Обложка featured получила фиксированную
   высоту 360px инлайн-стилем из PHP (sr_post_cover); при переходе на
   одну колонку это тянет её в почти квадрат на узких экранах, поэтому
   здесь высота переопределяется на aspect-ratio — !important нужен,
   чтобы перебить inline style="height:360px" (тот же приём, что и для
   .footer-top/.footer-legal в блоке футера выше по файлу). */
@media (max-width: 900px) {
  .sr-grid {
    grid-template-columns: 1fr;
  }
  .sr-featured {
    grid-template-columns: 1fr;
    gap: 20px;
    padding: 20px;
  }
  .sr-featured .sr-cover {
    height: auto !important;
    aspect-ratio: 16 / 10;
  }
  .sr-featured__title {
    font-size: 26px;
  }
}

/* ===========================================================
   Сайдбар блога. Спека 7.1/7.5, Задача 7. Пять карточек: поиск (дополнение
   к дизайну — см. template-parts/sidebar-search.php и комментарий в
   searchform.php, поля поиска в макете не было), рубрики, популярное,
   соцсети, свежие записи. Последний блок — стандартные виджеты WordPress
   (dynamic_sidebar('sidebar-1')).
   =========================================================== */

/* Обёртка «контент + сайдбар» на страницах со списком постов (index.php —
   Задача 8, category.php — Задача 9). Класс ещё ничем не используется в этой
   задаче — тем же приёмом, что и .sr-grid в Задаче 6 («класс подключат
   будущие задачи»), брейкпоинты сайдбара готовим уже здесь, по явному
   указанию брифа Задачи 7, а не откладываем до появления самой разметки. */
/* Вертикальные отступы блока «контент + сайдбар» — 64px сверху и снизу
   (мокап blog.jsx: секция CONTENT, padding '64px 32px'; ниже сразу CTA,
   у которой своего верхнего отступа нет). Раньше воздух над лентой давал
   нижний паддинг героя и полосы пилюль — но с переездом пилюль внутрь героя
   (см. .sr-hero) лента оказалась бы прижата к его нижней границе. */
.sr-layout {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 48px;
  align-items: start;
  padding: 64px 0;
}

.sr-sidebar {
  display: flex;
  flex-direction: column;
  gap: 20px;
  position: sticky;
  top: var(--sticky-top);
}

/* Общая рамка карточки сайдбара — то самое «оформление остальных карточек»
   из спеки 7.5 (белая, radius 18px, padding 24px). Используется всеми пятью
   карточками и виджетами WordPress (.sr-widgets .widget ниже). */
/* Каркас карточки сайдбара. Виджеты из админки (.sr-widgets .widget, ниже по
   файлу) обязаны выглядеть ровно так же, как родные карточки темы, — иначе
   добавленный владельцем виджет выбьется из колонки. Поэтому общая часть
   описана здесь один раз на оба селектора, а различия виджета остались при
   нём. */
.sr-side-card,
.sr-widgets .widget {
  padding: 24px;
  border-radius: 18px;
  background: var(--surface);
  border: 1px solid var(--line);
}
.sr-side-card__title {
  margin: 0 0 16px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* Карточка поиска (template-parts/sidebar-search.php + searchform.php). */
.sr-search__form {
  margin: 0;
}
.sr-search__field {
  position: relative;
  display: block;
}
.sr-search__icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  color: var(--dim);
  pointer-events: none;
}
/* Кегль — 16px и не меньше: при меньшем iOS Safari зумит страницу по фокусу.
   Проверяется SidebarTest::testSearchInputIsNotSmallerThan16px регуляркой
   по этому правилу — при правке класса/значения синхронизировать с тестом. */
.sr-search__input {
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 16px;
  padding: 12px 14px 12px 40px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  outline: none;
  transition: border-color 0.15s ease;
}
.sr-search__input::placeholder {
  color: var(--dim);
}
.sr-search__input:focus {
  border-color: var(--accent);
}

/* Карточка «Рубрики» (template-parts/sidebar-rubrics.php). */
.sr-side-rubrics__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Строка списка — мокап (blog.jsx, BlogSidebar → Рубрики): padding 9px 10px
   при margin 0 -10px, то есть подсветка при наведении выходит за края текста
   на всю ширину карточки, а сам текст остаётся на её линии набора. */
.sr-side-rubrics__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 -10px;
  padding: 9px 10px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  transition: background 0.15s ease;
}
.sr-side-rubrics__item:hover {
  background: var(--chip);
}
.sr-side-rubrics__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Счётчик — просто цифра, без плашки: в мокапе это текст 12px/600 --dim.
   Плашка (как у пилюль рубрик героя) делала колонку заметно пестрее макета. */
.sr-side-rubrics__count {
  flex-shrink: 0;
  color: var(--dim);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Карточка «Популярное» (template-parts/sidebar-popular.php) рисуется тем же
   мини-списком с обложками, что и «Свежие записи» (.sr-mini ниже) — решение
   владельца: обложка узнаётся быстрее порядкового номера. Своё здесь только
   нижняя строка: вместо даты счётчик прочтений с иконкой глаза (11.5px,
   gap 5px — значения мокапа, components/blog.jsx).

   Раньше это была отдельная структура с крупными номерами 01–04 без обложки —
   ровно чтобы карточка не выглядела дублем «Свежих записей» по соседству. На
   главной блога соседство снято иначе: «Свежие записи» там больше не
   выводятся (sidebar.php). В сайдбаре статьи обе карточки остаются рядом,
   различаясь заголовком и нижней строкой. */
.sr-side-popular__views {
  margin-top: 4px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  color: var(--dim);
}
.sr-side-popular__views svg {
  flex-shrink: 0;
}

/* Мини-список постов: карточки «Свежие записи» и «Популярное»
   (template-parts/sidebar-fresh.php, sidebar-popular.php,
   sr_sidebar_mini_item() в inc/widgets.php). Класс .sr-mini — тот самый,
   что проверяет SidebarTest::testFreshPostsShowThumbAndDate. */
.sr-mini-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.sr-mini {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: inherit;
}
.sr-mini__cover {
  width: 64px;
  flex-shrink: 0;
}
.sr-mini__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sr-mini__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 13.5px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--ink);
}
.sr-mini:hover .sr-mini__title {
  color: var(--accent);
}
.sr-mini__date {
  margin-top: 4px;
  font-size: 12px;
  color: var(--muted);
}

/* Карточка «Мы в соцсетях» (template-parts/sidebar-social.php). Раунд правок 1
   (ревью): раньше — две голые круглые иконки без подписей, неотличимые друг
   от друга кроме формы глифа. По мокапу (components/blog.jsx) — три строки
   на плашке `--chip`: иконка, название + описание, стрелка «↗» справа.
   Значения (padding 10px 12px, radius 10px, gap 12px, шрифты названия/описания,
   цвет стрелки) — дословно из мокапа. Gap между строками (8px) мокапом не
   задан явно (в брифе приведён только `.map` без обёртки) — подобран так же,
   как gap .sr-side-popular__list выше. */
.sr-side-social__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sr-side-social__item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--chip);
  text-decoration: none;
  color: var(--ink);
  transition: background 0.15s ease;
}
.sr-side-social__item:hover {
  background: var(--line);
}
.sr-side-social__icon {
  display: inline-flex;
  flex-shrink: 0;
}
.sr-side-social__icon svg {
  fill: currentColor;
}
.sr-side-social__body {
  flex: 1 1 auto;
  min-width: 0;
}
.sr-side-social__name {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
}
.sr-side-social__desc {
  display: block;
  font-size: 11.5px;
  color: var(--ink-3);
}
.sr-side-social__arrow {
  flex-shrink: 0;
  color: var(--dim);
  font-size: 13px;
}

/* Виджеты WordPress (dynamic_sidebar('sidebar-1'), inc/widgets.php) —
   последний блок сайдбара. register_sidebar() даёт классы .widget/
   .widget-title через before_widget/before_title, само содержимое виджета —
   произвольный HTML из админки, поэтому стилизуем по стандартным тегам,
   а не по конкретной разметке виджета. */
.sr-widgets .widget {
  padding: 24px;
  border-radius: 18px;
  background: var(--surface);
  border: 1px solid var(--line);
  margin-bottom: 20px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-2);
}
.sr-widgets .widget:last-child {
  margin-bottom: 0;
}
.sr-widgets .widget-title {
  margin: 0 0 16px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.sr-widgets .widget ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sr-widgets .widget a {
  color: var(--ink-2);
  text-decoration: none;
}
.sr-widgets .widget a:hover {
  color: var(--accent);
}
.sr-widgets .widget p:last-child {
  margin-bottom: 0;
}

/* Визуально скрытая, но доступная подпись поля поиска (searchform.php).
   Стандартный приём WordPress (core/twentytwenty*). */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ≤1024: сайдбар сужается 300→260px, отступ до контента 48→32px — точные
   значения из брифа Задачи 7. ≤900: контент и сайдбар в одну колонку;
   сайдбар уходит под контент естественным порядком DOM (второй потомок
   .sr-layout), отдельный order не нужен. Липкость на мобильном отключаем —
   без второй колонки контента ей не за что «держаться». */
@media (max-width: 1024px) {
  .sr-layout {
    grid-template-columns: 1fr 260px;
    gap: 32px;
  }
}
@media (max-width: 900px) {
  .sr-layout {
    grid-template-columns: 1fr;
  }
  .sr-sidebar {
    position: static;
  }
}
/* ≤820: вертикальные отступы секций 48px (спека, раздел 10) — тот же
   брейкпоинт, на котором сжимаются герой и CTA. */
@media (max-width: 820px) {
  .sr-layout {
    padding: 48px 0;
  }
}

/* ===========================================================
   Главная блога. Спека 7.1, Задача 8: крошки, герой, пилюли рубрик,
   лента (переиспользует .sr-featured/.sr-grid/.sr-card из Задачи 6 и
   .sr-layout/.sr-sidebar из Задачи 7), пагинация, тёмная CTA-полоса.
   =========================================================== */

/* Общий центрированный контейнер контентных страниц — max-width 1200px,
   боковой паддинг 32px (→20px на ≤640 через var(--pad), см. :root выше).
   Секции (герой/пилюли/CTA) сами на всю ширину (фон во всю страницу),
   этот класс центрирует их содержимое — тот же приём full-bleed-секция +
   центрированный внутренний контейнер, что и в .site-header__bar/
   .site-footer > div (только там значения буквальные, порт источника). */
.sr-container {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* Крошки (template-parts/breadcrumbs.php, sr_breadcrumbs() в
   inc/template-tags.php). Точных значений спека не даёт (раздел 7.1
   упоминает крошки внутри описания героя, без чисел) — минимальный,
   ненавязчивый стиль по аналогии с остальной второстепенной метой темы
   (.sr-meta: 13px, --muted). */
.sr-breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 20px 0 0;
  font-size: 13px;
  color: var(--muted);
}
/* Крошки внутри героя — его первый элемент: отступ сверху даёт сама секция
   (padding героя), снизу 18px, как в мокапе (blog.jsx, строка крошек:
   marginBottom 18). Отдельным блоком ДО героя они стоят только на странице
   поста и обычной странице — там работает padding сверху из правила выше. */
.sr-hero .sr-breadcrumbs,
.sr-hero-category .sr-breadcrumbs {
  padding-top: 0;
  margin-bottom: 18px;
}
.sr-breadcrumbs__link {
  color: var(--muted);
  text-decoration: none;
}
.sr-breadcrumbs__link:hover {
  color: var(--ink);
  text-decoration: underline;
}
.sr-breadcrumbs__sep {
  color: var(--faint);
}
.sr-breadcrumbs__current {
  color: var(--ink-2);
}

/* Герой (template-parts/hero-blog.php). Спека 7.1: padding 64px 32px 36px,
   подсветка radial-gradient(ellipse 800px 360px at 50% -10%, {accent}1F,
   transparent 60%); H1 56px/1.08/-0.03em/700; лид 18px/1.55 --ink-2.

   Секция включает крошки и пилюли рубрик (мокап blog.jsx: подсветка лежит
   на всей секции — position:absolute; inset:0, — а крошки и фильтр рубрик
   её содержимое). Поэтому нижний паддинг здесь 0: его добирают .sr-hero__top
   (36px по спеке) и .sr-pills-wrap (8px сверху / 24px снизу, мокап). Нижняя
   граница — тоже из мокапа (borderBottom: 1px solid #EEEFF3), она отделяет
   градиентную полосу от ленты.

   Верхний паддинг 40px, а не 64px спеки: это ровно тот же отступ до крошек,
   что и у героя рубрики (.sr-hero-category ниже) — решение владельца, чтобы
   страница начиналась одинаково на главной блога и на рубриках. */
.sr-hero {
  padding: 40px 0 0;
  border-bottom: 1px solid var(--line);
  background: radial-gradient(ellipse 800px 360px at 50% -10%, var(--accent-glow), transparent 60%);
  background: radial-gradient(ellipse 800px 360px at 50% -10%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%);
}
/* Заголовок с лидом слева, счётчики справа — одной строкой (мокап: flex,
   justify-content: space-between, align-items: flex-end, gap 40, flex-wrap).
   Счётчики отдельным блоком под лидом (как было) читались как «перенеслись
   на вторую строку». Перенос остаётся, но только когда двум колонкам уже
   не хватает ширины. */
/* gap задан двумя значениями (row column) не для красоты: когда колонки не
   помещаются рядом и счётчики переносятся под лид — а на мобильном это
   всегда — row-gap становится их отступом СВЕРХУ, а отступом снизу работает
   padding-bottom. Пока они были разными (40 и 36/28), счётчики визуально
   сидели ниже середины своего промежутка. Держим row-gap равным
   padding-bottom здесь и в медиазапросе ≤820 ниже. */
.sr-hero__top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 36px 40px;
  padding-bottom: 36px;
}
.sr-hero__intro {
  max-width: 760px;
}
.sr-hero__title {
  margin: 0 0 16px;
  max-width: 780px;
  font-size: 56px;
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-weight: 700;
  color: var(--ink);
}
.sr-hero__accent {
  color: var(--accent);
}
.sr-hero__lead {
  margin: 0;
  max-width: 620px;
  font-size: 18px;
  line-height: 1.55;
  color: var(--ink-2);
}
/* grid repeat(3, auto) / gap 28px — мокап. Не flex: три колонки одинаковой
   природы должны переноситься все разом, а не по одной. */
.sr-hero__stats {
  display: grid;
  grid-template-columns: repeat(3, auto);
  gap: 28px;
  padding: 4px 0;
}
.sr-hero__stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sr-hero__stat-num {
  font-size: 30px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.sr-hero__stat-label {
  font-size: 12.5px;
  color: var(--ink-3);
}

/* Пилюли рубрик (template-parts/category-pills.php). Спека 7.1: 13.5px/600,
   padding 9px 16px, radius 999px, активная — --ink на белом тексте, счётчик
   постов в пилюле. По умолчанию переносятся на несколько строк (flex-wrap) —
   горизонтальный скролл спека включает точечно, только на ≤640 (раздел 10:
   «пилюли рубрик листаются горизонтальным скроллом»). Если бы скролл был
   включён всегда, на 820px пилюли вылезали бы за вьюпорт вместо переноса —
   это как раз и нашёл скриншотер (npm run shots -- blog) до этой правки. */
/* Вертикальные отступы задаёт герой, в котором пилюли лежат: у главной блога
   8px/24px (мокап blog.jsx, блок «Category filter»), у рубрики — 28px сверху
   (мокап rubric.jsx, RubricTabs marginTop). Сам блок нейтрален — иначе оба
   значения пришлось бы перебивать. */
.sr-pills-wrap {
  padding: 0;
}
.sr-hero .sr-pills-wrap {
  padding: 8px 0 24px;
}
.sr-hero-category .sr-pills-wrap {
  margin-top: 28px;
}
.sr-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* Белая пилюля с рамкой --line-2, активная — сплошная --ink (мокап blog.jsx:
   border 1px solid #E4E5EA / #0E0E12, background white / #0E0E12). Раньше
   пилюля была серой заливкой без рамки — из-за этого «плашки категорий не
   такие, как в дизайне». Счётчик — не отдельный цвет, а прозрачность поверх
   цвета текста: так он одинаково читается и на белой, и на тёмной пилюле. */
.sr-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-pill);
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--ink);
  background: var(--surface);
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.sr-pill:hover {
  background: var(--chip);
  border-color: var(--line-hover);
}
.sr-pill--on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--dark-fg);
}
.sr-pill--on:hover {
  background: var(--ink);
  border-color: var(--ink);
}
.sr-pill__count {
  font-size: 11px;
  font-weight: 700;
  opacity: 0.5;
}
.sr-pill--on .sr-pill__count {
  opacity: 0.7;
}

/* Обёртка ленты «главная карточка + сетка + пагинация» — первая колонка
   .sr-layout. Gap между блоками, а не margin — тот же приём, что и в
   остальном сайдбаре/карточках темы. min-width:0 — без него длинный
   контент (например, обложка featured) может распереть колонку grid'а
   .sr-layout шире отведённого места на узких экранах. */
.sr-blog-feed {
  display: flex;
  flex-direction: column;
  gap: 32px;
  min-width: 0;
}

/* Пагинация (template-parts/pagination.php). Спека 7.1: «Страница N из M ·
   показано X из Y» + номера страниц. */
/* Одна строка: слева «Страница N из M · показано X из Y», справа номера
   (мокап blog.jsx: flex, justify-content: space-between, align-items: center,
   gap 16, flex-wrap, marginTop 56). Раньше блок был колонкой по центру —
   сводка вставала над номерами и читалась как перенос. marginTop 56 набирается
   из gap ленты (.sr-blog-feed, 32px) и этих 24px. */
.sr-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 24px;
}
.sr-pagination__summary {
  margin: 0;
  font-size: 13.5px;
  color: var(--muted);
}
.sr-pagination__sep {
  margin: 0 6px;
  color: var(--faint);
}
.sr-pagination__pages {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-left: auto;
}
.sr-pagination__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 36px;
  padding: 0 12px;
  border-radius: 8px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border: 1px solid var(--line-2);
  background: var(--surface);
  font-variant-numeric: tabular-nums;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.sr-pagination__page:hover {
  background: var(--chip);
  color: var(--ink);
}
.sr-pagination__page--current {
  background: var(--ink);
  color: var(--dark-fg);
  border-color: var(--ink);
  cursor: default;
}
/* Стрелки — те же кнопки, только уже (в мокапе у них нет цифры, поэтому
   боковые паддинги не нужны). «Вперёд» акцентная, недоступное направление —
   приглушённая заглушка на своём месте (мокап: PageBtn primary / disabled). */
.sr-pagination__page--arrow {
  padding: 0 8px;
}
.sr-pagination__page--next {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--dark-fg);
}
.sr-pagination__page--next:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: var(--dark-fg);
}
.sr-pagination__page--off {
  opacity: 0.45;
  cursor: default;
}
.sr-pagination__ellipsis {
  padding: 0 4px;
  font-size: 13.5px;
  color: var(--faint);
}

/* ≤900: сайдбар встаёт в одну колонку сразу под пагинацией, и её отступы
   становятся видимой парой — сверху gap ленты (32px) плюс margin-top,
   снизу только gap сетки (32px). Из-за лишних 24px пагинация сидела ниже
   середины промежутка. На десктопе margin остаётся: там под ней не сайдбар,
   а нижний паддинг секции.

   Медиазапрос стоит здесь, а не рядом с остальными правилами ≤900 (блок
   сайдбара выше по файлу): при равной специфичности выигрывает последнее
   правило, а `.sr-pagination { margin-top: 24px }` объявлено ниже них. */
@media (max-width: 900px) {
  .sr-pagination {
    margin-top: 0;
  }
}

/* CTA-карточка (template-parts/cta-band.php), перед футером. Раунд правок 1:
   мокап (components/blog.jsx, секция INLINE CTA) — тёмная карточка внутри
   контейнера (не full-bleed полоса), radius 24px, радиальная подсветка в
   углу, колонка статистики справа (grid 1.4fr 1fr). Кегль заголовка
   36→30px на ≤640 — спека, раздел 10, единственное точное значение из спеки
   для этого блока; остальные размеры/расположение — дословно из мокапа. */
.sr-cta {
  padding: 0 var(--pad) 100px;
}
/* Ширина карточки — контентная ширина .sr-container, а не --wrap: боковой
   паддинг здесь снаружи (на .sr-cta), поэтому max-width: var(--wrap) давал
   карточку ровно на 2×--pad шире ленты и сайдбара над ней — она заметно
   вылезала за общую колонку страницы. У .sr-container паддинг внутри той же
   1200px-коробки, отсюда вычитание. Мокап (blog.jsx) написан так же, как
   было, — расхождение в нём самом: секция контента там maxWidth 1200 с
   padding 32, то есть 1136, а карточка CTA — 1200 без вычета. */
.sr-cta__card {
  position: relative;
  overflow: hidden;
  max-width: calc(var(--wrap) - var(--pad) * 2);
  margin: 0 auto;
  background: var(--dark);
  color: var(--dark-fg);
  border-radius: 24px;
  padding: 48px 56px;
}
.sr-cta__glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 600px 320px at 100% 0%, var(--accent-glow-cta), transparent 70%);
  background: radial-gradient(ellipse 600px 320px at 100% 0%, color-mix(in srgb, var(--accent) 27%, transparent), transparent 70%);
}
.sr-cta__grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 40px;
  align-items: center;
}
.sr-cta__eyebrow {
  margin: 0 0 14px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.sr-cta__title {
  margin: 0;
  font-size: 36px;
  line-height: 1.1;
  letter-spacing: -0.025em;
  font-weight: 700;
  color: var(--dark-fg);
}
.sr-cta__lead {
  margin: 14px 0 0;
  max-width: 540px;
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--dim);
}
.sr-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 26px;
}
.sr-cta__primary,
.sr-cta__secondary {
  display: inline-flex;
  align-items: center;
  font-size: 15px;
  font-weight: 600;
  color: var(--dark-fg);
  border-radius: 10px;
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.sr-cta__primary {
  padding: 13px 22px;
  background: var(--accent);
  box-shadow: 0 14px 30px -10px var(--accent-shadow-cta);
}
.sr-cta__primary:hover {
  background: var(--accent-hover);
}
.sr-cta__secondary {
  padding: 13px 18px;
  border: 1px solid var(--cta-border);
}
.sr-cta__secondary:hover {
  background: var(--dark-surface);
}
.sr-cta__stats {
  position: relative;
  display: grid;
  gap: 10px;
}
/* align-items: baseline — из мокапа: число и подпись сидят на одной базовой
   линии, пока подпись в одну строку. Как только она переносится (узкий экран),
   базовой становится ПЕРВАЯ строка подписи, и весь блок текста уезжает вниз
   относительно числа — на мобильном это было видно на «экономии на ручной
   сборке» и «среднем времени генерации». Переключение на center ниже, в
   медиазапросе: там, где переносов нет, поведение остаётся мокапным. */
.sr-cta__stat {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 14px 18px;
  background: var(--cta-stat-bg);
  border: 1px solid var(--dark-line);
  border-radius: 14px;
}
.sr-cta__stat-num {
  min-width: 120px;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--dark-fg);
  font-variant-numeric: tabular-nums;
}
.sr-cta__stat-label {
  font-size: 13.5px;
  color: var(--dim);
}

/* ≤900: сетка карточки 1.4fr 1fr складывается в одну колонку (задание
   правок 1) — тот же брейкпоинт, на котором сайдбар/сетка карточек ленты
   уже уходят в одну колонку (см. .sr-layout/.sr-grid выше). */
@media (max-width: 900px) {
  .sr-cta__grid {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  /* Подпись со ≤900 начинает переноситься в две строки — выравниваем по
     центру, а не по базовой линии (см. комментарий у .sr-cta__stat выше).
     Ширина колонки числа тоже лишняя: 120px рассчитаны на широкую карточку,
     на узкой они отжимают подпись почти к правому краю. */
  .sr-cta__stat {
    align-items: center;
  }
  .sr-cta__stat-num {
    min-width: 92px;
  }
}

/* ≤820: вертикальные отступы секций 48px (раздел 10). Карточка CTA —
   отступ секции снизу 100→64px, внутренний padding карточки 48/56→40/32px
   (раунд правок 1: карточка мокапа рассчитана на широкий экран, на 820px
   56px горизонтального паддинга уже заметно откусывает от grid 1.4fr 1fr). */
@media (max-width: 820px) {
  /* Верхний паддинг героя тут не трогаем: он уже 40px (см. .sr-hero выше),
     сжимать его до «48px секции» из спеки было бы наоборот увеличением.
     Нижний отступ героя набирается из двух его частей (см. .sr-hero выше):
     блока «заголовок + счётчики» и полосы пилюль. Сжимаем обе, а не
     padding-bottom самой секции — у неё он 0. */
  .sr-hero__top {
    /* row-gap = padding-bottom, см. комментарий у .sr-hero__top выше. */
    gap: 28px 40px;
    padding-bottom: 28px;
  }
  .sr-hero .sr-pills-wrap {
    padding-bottom: 32px;
  }
  .sr-cta {
    padding-bottom: 64px;
  }
  .sr-cta__card {
    padding: 40px 32px;
  }
}

/* ≤640: H1 героя 56→30px, заголовок CTA 36→30px (раздел 10). Горизонтальные
   паддинги секций уже сжались на 32→20px через var(--pad) (см. правило
   :root выше) — здесь только то, что не покрывается токеном. */
@media (max-width: 640px) {
  .sr-hero__title {
    font-size: 30px;
  }
  .sr-cta__title {
    font-size: 30px;
  }
  /* Карточка CTA на ≤640: паддинг ещё уже, скругление чуть меньше — теснее
     соответствует пропорциям мокапа при узком контейнере (раунд правок 1). */
  .sr-cta__card {
    padding: 32px 24px;
    border-radius: 20px;
  }
  /* Пагинация на узком экране — в столбик по центру: сводка «Страница N из M ·
     показано X из Y» и ряд номеров по краям одной строки читаются как
     разъехавшиеся, когда строка почти во всю ширину экрана. */
  .sr-pagination {
    flex-direction: column;
    justify-content: center;
    text-align: center;
  }
  .sr-pagination__pages {
    margin-left: 0;
    justify-content: center;
  }
  /* Раздел 10: «пилюли рубрик листаются горизонтальным скроллом» — только
     здесь, на ≤640. Скроллится содержимое .sr-pills-wrap, а не страница
     (спека, раздел 10: «Таблицы в прозе и пилюли рубрик получают
     собственные контейнеры с overflow-x: auto»). */
  .sr-pills-wrap {
    overflow-x: auto;
    scrollbar-width: none;
  }
  .sr-pills-wrap::-webkit-scrollbar {
    display: none;
  }
  .sr-pills {
    flex-wrap: nowrap;
    width: max-content;
    min-width: 100%;
  }
}

/* ≤480: H1 24px. Счётчики героя остаются в три колонки: спека (раздел 10)
   предлагала на этой ширине две, но три коротких числа с подписями
   помещаются в строку и на 360px — перенос «5 рубрик» на вторую строку
   выглядел случайным (замечание владельца). Сжимается только gap. */
@media (max-width: 480px) {
  .sr-hero__title {
    font-size: 24px;
  }
  .sr-hero__stats {
    gap: 18px;
  }
  .sr-hero__stat-num {
    font-size: 26px;
  }
}

/* ===========================================================
   Страница рубрики (Задача 9). Спека 7.2. Переиспользует .sr-container,
   .sr-layout/.sr-sidebar (Задача 7), .sr-blog-feed/.sr-grid/.sr-card
   (Задачи 6/8), .sr-pills-wrap/.sr-pill (Задача 8 — те же табы, активная
   пилюля — текущая рубрика), .sr-cta (Задача 8). Собственные новые классы —
   только герой рубрики (плитка-глиф + счётчик) и пустое состояние.
   =========================================================== */

/* Герой рубрики (template-parts/hero-category.php). Горизонтальный паддинг
   даёт вложенный .sr-container (var(--pad), тот же приём, что .sr-hero
   Задачи 8) — здесь только вертикальный, из спеки 7.2 (40px 32px 30px).
   background — инлайн-стиль из PHP (цвет темы рубрики, см. докблок файла),
   поэтому фона в правиле нет. */
.sr-hero-category {
  padding: 40px 0 30px;
  /* Нижняя граница — как у героя главной блога (мокап rubric.jsx:
     borderBottom 1px solid #EEEFF3): отделяет цветную полосу рубрики
     от ленты карточек. */
  border-bottom: 1px solid var(--line);
}
.sr-hero-category__head {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 24px;
}
/* 60×60/radius:16px/градиент 135deg — спека 7.2, дословно. Сам градиент и
   тень (цвета темы рубрики) — инлайн-стиль, см. hero-category.php. */
.sr-hero-category__tile {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  border-radius: 16px;
}
.sr-hero-category__intro {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sr-hero-category__title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}
.sr-hero-category__title {
  margin: 0;
  font-size: 44px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--ink);
}
/* Плашка «N статей» — спека 7.2. Не в цвете темы рубрики (в отличие от
   плитки-глифа выше), а в акценте бренда на его же подложке 8% — так в
   мокапе (rubric.jsx: color tint, background `${tint}14`). Была нейтральным
   серым чипом и терялась рядом с H1. */
.sr-hero-category__count {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: var(--accent-tint);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.sr-hero-category__desc {
  margin: 20px 0 0;
  max-width: 720px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* Пустое состояние рубрики без статей (template-parts/empty-rubric.php).
   Спека 7.2: «Здесь пока готовим материалы» + ссылка на весь блог, без
   пагинации. Оформлена как карточка на всю ширину контентной колонки —
   тот же язык (surface/line/radius), что и остальные карточки темы, но
   с пунктирной рамкой (--line-2) — читается как явно «пустое», а не как
   обычная карточка контента. */
.sr-empty-rubric {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 80px 32px;
  text-align: center;
  border-radius: 24px;
  border: 1px dashed var(--line-2);
  background: var(--surface);
}
.sr-empty-rubric__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--chip);
  color: var(--dim);
}
.sr-empty-rubric__title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--ink);
}
.sr-empty-rubric__lead {
  margin: 0;
  max-width: 420px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}
/* Внешний вид — общий .sr-btn-accent (секция «База»); здесь только отступ,
   которого у той же кнопки на 404 нет. */
.sr-empty-rubric__cta {
  margin-top: 8px;
}

/* ≤820: вертикальные отступы секций 48px (раздел 10) — тот же брейкпоинт,
   на котором .sr-hero/.sr-cta уже сжимаются (Задача 8). */
@media (max-width: 820px) {
  .sr-hero-category {
    padding-top: 32px;
    padding-bottom: 24px;
  }
  .sr-empty-rubric {
    padding: 56px 24px;
  }
}

/* ≤640: заголовок героя рубрики уменьшается до того же 30px, до которого
   на этой ширине сжимаются H1 героя блога и заголовок CTA (Задача 8) —
   единая точка «крупные заголовки на ≤640», а не новое число. Горизонтальные
   паддинги секций уже сжались 32→20px через var(--pad) (см. правило :root). */
@media (max-width: 640px) {
  .sr-hero-category__title {
    font-size: 30px;
  }
}

/* ≤480: тот же терминальный размер 24px, до которого на этой ширине
   доходит H1 героя блога (Задача 8) — единообразие крупных заголовков
   на самом узком брейкпоинте. */
@media (max-width: 480px) {
  .sr-hero-category__title {
    font-size: 24px;
  }
}

/* ===========================================================
   Страница поста (Задача 10). Спека 7.3. Три колонки: рельс «Поделиться»
   слева (sticky), статья по центру, липкий сайдбар справа (оглавление +
   Популярное/Свежие/Соцсети — переиспользуют sidebar-popular.php/
   sidebar-fresh.php/sidebar-social.php Задачи 7 как есть, см. sidebar.php).
   Плюс полоса прогресса чтения и блок «Читайте дальше».
   =========================================================== */

/* Полоса прогресса чтения. Спека 7.3: 3px, sticky под шапкой. Full-bleed —
   не внутри .sr-container, читается как единая полоса на всю ширину экрана.
   Правки владельца после выката: top 73 → 69px (73 в спеке — буквальное
   значение мокапа, а реальная высота шапки темы 69px, и полоса висела с
   зазором под ней) и без фона дорожки — на странице видна только заполненная
   часть, а не серая линия во всю ширину. */
.sr-progress {
  position: sticky;
  top: 69px;
  z-index: 20;
  height: 3px;
}
.sr-progress__fill {
  height: 100%;
  width: 0;
  background: var(--accent);
}

/* Заголовок + мета (single.php): H1 40px/1.12/-0.03em — спека 7.3, дословно.
   Мета — переиспользованный template-parts/post-meta.php (дата · время
   чтения), без изменений разметки/CSS того файла. */
.sr-post__head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 28px 0 32px;
}
.sr-post__title {
  margin: 0;
  max-width: 800px;
  font-size: 40px;
  line-height: 1.12;
  letter-spacing: -0.03em;
  font-weight: 700;
  color: var(--ink);
}

/* Сетка «рельс + статья + сайдбар». 44px | minmax(0, 1fr) | 288px, gap 24px.
   Спека 7.3 называет среднюю колонку как «minmax(0, 720px)», и ровно так и
   было — но в мокапе (post.jsx) 720px это max-width самой <article> внутри
   колонки 1fr, а не ширина трека. Разница видна на широком экране: с треком
   в 720px сетка суммарно уже контейнера, и лишние 36px оставались справа от
   сайдбара — тот отходил от правого края и вставал вплотную к тексту
   (24px). С 1fr колонка добирает эти 36px, сайдбар прижат к правому краю
   контейнера, а от текста его отделяют 24 + 36 = 60px, как в мокапе.
   minmax(0, …), не голый 1fr: без него широкий <pre>/<table> в прозе
   раздувает трек по min-content (см. тот же приём в медиазапросе ниже).

   Нижний паддинг — воздух под липкими колонками. Липкий элемент ездит по
   своей грид-области, а она кончается там же, где содержимое сетки: без
   паддинга рельс «Поделиться» и последняя карточка сайдбара при прокрутке
   до конца упирались прямо в линию-разделитель перед «Читайте дальше». */
.sr-post__grid {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 288px;
  gap: 24px;
  align-items: start;
  padding-bottom: 48px;
}
.sr-post__grid > .sr-prose {
  max-width: 720px;
}

/* Рельс «Поделиться» (template-parts/share-rail.php) — заменяет плагин
   uptolike (спека, раздел 11). Круглые кнопки 40px, sticky top:100px —
   спека 7.3, дословно (тот же offset, что и .sr-post__aside ниже). */
.sr-rail {
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: sticky;
  top: var(--sticky-top);
}
.sr-rail__btn {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.sr-rail__btn svg {
  fill: currentColor;
}
.sr-rail__btn:hover {
  background: var(--chip);
  border-color: var(--line-2);
  color: var(--ink);
}
/* Обратная связь «скопировано» — assets/js/theme.js навешивает класс
   на 1.8с после успешного копирования (см. share-rail.php). */
.sr-rail__copy.is-copied {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--dark-fg);
}

/* Сайдбар статьи (template-parts/toc.php + sidebar-popular/-fresh/-social.php,
   переиспользованные как есть). Тот же язык, что .sr-sidebar (Задача 7:
   flex-column/gap/sticky), но отдельный класс — тот блок «не трогай»
   по брифу Задачи 10, здесь другая композиция карточек (без поиска/рубрик). */
.sr-post__aside {
  display: flex;
  flex-direction: column;
  gap: 20px;
  position: sticky;
  top: var(--sticky-top);
}

/* Оглавление (template-parts/toc.php) — не карточка сайдбара, а голый список
   поверх фона колонки: так в мокапе (post.jsx, Toc). Надзаголовок набран как
   ярлык остальных карточек (11px/700 uppercase --ink-3), номер 01, 02…
   отдельной колонкой 24px, активный пункт помечен акцентной чертой слева.
   .is-active навешивает assets/js/theme.js по прокрутке (порог 140px, как в
   ArticlePage.vue на проде). */
.sr-toc__title {
  margin: 0 0 10px;
  padding-left: 14px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.sr-toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sr-toc__link {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 7px 0 7px 12px;
  border-left: 2px solid transparent;
  font-size: 13.5px;
  line-height: 1.4;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.sr-toc__num {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
  transition: color 0.15s ease;
}
.sr-toc__link:hover {
  color: var(--ink);
}
.sr-toc__link.is-active {
  border-left-color: var(--accent);
  color: var(--ink);
  font-weight: 600;
}
.sr-toc__link.is-active .sr-toc__num {
  color: var(--accent);
}

/* «Читайте дальше» (template-parts/related.php) — 3 карточки через YARPP
   (related_posts(), yarpp-template-thumbnail.php) либо, без плагина,
   sr_related_fallback_posts() (inc/widgets.php). Обе ветки рисуют
   .sr-card (Задача 6) — карточки не отличаются визуально от ленты. */
/* Метки статьи (template-parts/post-tags.php) — полоса пилюль между двумя
   линиями в конце <article>, мокап post.jsx. */
.sr-post-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 56px;
  padding: 24px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.sr-post-tag {
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  background: var(--chip);
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}
.sr-post-tag:hover {
  background: var(--line-2);
  color: var(--ink);
}

/* Верхняя граница секции (мокап post.jsx, <Related>: borderTop 1px solid
   #EEEFF3) — та самая линия, что логически отбивает конец статьи от блоков
   ниже. Она не зависит от меток: у поста без меток полосы .sr-post-tags нет,
   а разделитель нужен всё равно. */
.sr-related {
  padding: 64px 0;
  border-top: 1px solid var(--line);
}
.sr-related__title {
  margin: 0 0 24px;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 700;
  color: var(--ink);
}
.sr-related__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
/* Раунд правок 2 (ревью, Important 4): YARPP оборачивает вывод кастомного
   шаблона (yarpp-template-thumbnail.php) в свой div — без этого правила три
   карточки схлопываются в одну грид-колонку (единственный прямой ребёнок
   .sr-related__grid — сам этот div, а не три .sr-card). display: contents
   убирает его из раскладки, и его дети (карточки) становятся прямыми
   грид-элементами — без плагина (фолбэк рисует карточки напрямую) правило
   просто ни на что не действует.

   Селекторов два, потому что класс обёртки зависит от версии плагина:
   ожидался `yarpp yarpp-related`, а YARPP на проде (5.4.18-совместимый)
   печатает `<div class='yarpp-related'>` — одиночный класс, под `.yarpp`
   не подходящий. Правило молча не срабатывало, и «Читайте дальше» вышел
   на прод столбиком. */
.sr-related__grid > .yarpp,
.sr-related__grid > .yarpp-related {
  display: contents;
}

@media (max-width: 900px) {
  .sr-related__grid {
    grid-template-columns: 1fr;
  }
}

/* ≤820: спека, раздел 10 — «оглавление поста в кнопку в шапке; рельс
   «Поделиться» становится горизонтальной строкой под заголовком».
   Сетка схлопывается в одну колонку (порядок DOM: рельс → статья →
   сайдбар, поэтому рельс естественно оказывается прямо под заголовком,
   а карточки сайдбара — под статьёй, без явного order). Карточка
   оглавления скрыта — то же самое уже доступно кнопкой в шапке (Задача 4),
   дублировать незачем. Вертикальные отступы секций 48px — тот же брейкпоинт,
   на котором уже сжимаются .sr-hero/.sr-cta (Задача 8) и .sr-hero-category
   (Задача 9). */
@media (max-width: 820px) {
  .sr-post__head {
    padding: 24px 0;
  }
  .sr-post__grid {
    /* minmax(0, 1fr), не голый 1fr: без minmax(0, …) неявный минимальный
       размер грид-элемента равен min-content его содержимого — широкий
       <pre>/<table> внутри .sr-prose (перенос строк в них не предусмотрен,
       см. правила прозы выше) раздувает трек шире доступной ширины и тянет
       за собой .sr-rail/.sr-post__aside в этом же треке (обнаружено
       скриншотером на 390px — все три колонки уезжали на одинаковые 126px).
       Тот же приём уже применён к средней колонке десктопной сетки. */
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    /* Колонки в один столбец и без липкости — воздуха под ними нужно
       меньше, чем на десктопе (см. .sr-post__grid выше). */
    padding-bottom: 32px;
  }
  .sr-rail {
    position: static;
    flex-direction: row;
  }
  .sr-toc {
    display: none;
  }
  .sr-post__aside {
    position: static;
  }
  .sr-related {
    padding: 48px 0;
  }
}

/* ≤640/≤480: терминальные размеры H1, переиспользованные у героя блога/
   рубрики и заголовка CTA (Задача 8/9) — единая точка «крупные заголовки
   на узких экранах», не новые числа. */
@media (max-width: 640px) {
  .sr-post__title {
    font-size: 30px;
  }
}
@media (max-width: 480px) {
  .sr-post__title {
    font-size: 24px;
  }
}

/* ===========================================================
   Проза (спека 7.6). Стили для контента редактора WP — $sr_article['html']
   (single.php, sr_toc()) внутри <article id="sr-article" class="sr-prose">.
   Экранированию не подлежит (уже прошёл через apply_filters('the_content')),
   стилизуется по тегам, а не по конкретной разметке одного поста.
   =========================================================== */
.sr-prose {
  font-size: 17px;
  line-height: 1.7;
  color: var(--prose);
}
/* Верх статьи выравнивается по верху соседних колонок сетки (рельс
   «Поделиться» и сайдбар). Первый блок контента приносит свой margin-top
   (у <figure> это 32px, у h2 — 48px), и на проде статья, начинающаяся с
   картинки, стартовала на 32px ниже рельса и сайдбара. Отступ первого
   элемента сверху не нужен — его роль играет отступ шапки статьи. */
.sr-prose > *:first-child {
  margin-top: 0;
}
.sr-prose h2 {
  margin: 48px 0 18px;
  font-size: 30px;
  line-height: 1.28;
  letter-spacing: -0.01em;
  font-weight: 700;
  color: var(--ink);
}
.sr-prose h3 {
  margin: 36px 0 14px;
  font-size: 23px;
  line-height: 1.32;
  font-weight: 700;
  color: var(--ink);
}
.sr-prose h4 {
  margin: 28px 0 12px;
  font-size: 19px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--ink);
}
.sr-prose p {
  margin: 0 0 20px;
  font-size: 17px;
  line-height: 1.7;
  color: var(--prose);
}
/* Отдельного оформления у первого абзаца нет. Спека 7.3 описывала лид
   (21px/1.55/500, темнее остального текста), и он был сделан, но в реальных
   статьях первый абзац лидом чаще всего не является — это обычное начало
   текста, и увеличенный кегль читался как случайное выделение. Убрано по
   просьбе владельца; если лид понадобится, его правильнее задавать классом
   в редакторе, а не по позиции в документе. */
/* :not(.sr-checklist):not(.sr-numlist) — иначе более специфичное правило
   (класс .sr-prose + тег ul/ol, специфичность 0,1,1) перебивало бы стили
   классов редактора ниже (одиночный класс, специфичность 0,1,0), даже
   будучи объявленным раньше их в файле. */
.sr-prose ul:not(.sr-checklist):not(.sr-numlist),
.sr-prose ol:not(.sr-checklist):not(.sr-numlist) {
  margin: 0 0 20px;
  padding-left: 22px;
  font-size: 17px;
  line-height: 1.7;
  color: var(--prose);
}
.sr-prose li + li {
  margin-top: 8px;
}
/* Рамка и тень — чтобы светлый скриншот не сливался с фоном страницы
   (--bg почти белый). В мокапе (post.jsx, Figure) картинка тоже лежит в
   контейнере с рамкой 1px; здесь рамка на тон темнее (--line-2) и тень
   заметная — у статей блога много скриншотов интерфейсов с белой подложкой,
   мягкого варианта владельцу оказалось мало. */
.sr-prose img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 8px 0;
  border: 1px solid var(--line-2);
  border-radius: 18px;
  box-shadow: var(--shadow-media);
}
.sr-prose figure {
  margin: 32px 0;
}
.sr-prose figure img {
  margin: 0;
}
.sr-prose figcaption {
  margin-top: 10px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
  text-align: center;
}
/* Таблицы: скролл содержимого, а не страницы (спека, раздел 10). display:block
   на голом <table> — стандартный приём respons-таблиц без обёртки (строки/
   ячейки остаются table-row/table-cell по умолчанию, ломается только сам
   табличный алгоритм раскладки, что здесь и нужно). Блок редактора Gutenberg
   уже оборачивает таблицу в figure.wp-block-table — для него скроллится
   обёртка, а не сама таблица (иначе скролл-контейнеров было бы два вложенных). */
.sr-prose table {
  display: block;
  max-width: 100%;
  margin: 28px 0;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: 15px;
}
.sr-prose .wp-block-table {
  margin: 28px 0;
  overflow-x: auto;
}
.sr-prose .wp-block-table table {
  margin: 0;
}
.sr-prose th,
.sr-prose td {
  padding: 10px 14px;
  border: 1px solid var(--line-2);
  text-align: left;
}
.sr-prose th {
  background: var(--chip);
  font-weight: 600;
  color: var(--ink);
}
/* :not(.sr-pullquote) — та же причина, что и у ul/ol выше: без исключения
   это правило (0,1,1) перебило бы стили .sr-pullquote (0,1,0) ниже. */
.sr-prose blockquote:not(.sr-pullquote) {
  margin: 28px 0;
  padding: 2px 0 2px 20px;
  border-left: 3px solid var(--line-2);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
}
.sr-prose blockquote > *:last-child {
  margin-bottom: 0;
}
.sr-prose code {
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--chip);
  font-family: var(--font-mono);
  font-size: 0.88em;
  color: var(--ink);
}
.sr-prose pre {
  margin: 24px 0;
  padding: 18px 20px;
  border-radius: 14px;
  background: var(--ink);
  overflow-x: auto;
}
.sr-prose pre code {
  padding: 0;
  background: none;
  color: var(--dark-fg);
  font-size: 14px;
}
.sr-prose a {
  color: var(--accent);
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.sr-prose a:hover {
  text-decoration-color: var(--accent);
}

/* ≤480: единственное точное значение спеки для адаптива прозы (раздел 10):
   «h2 прозы 30→21px». */
@media (max-width: 480px) {
  .sr-prose h2 {
    font-size: 21px;
  }
}

/* ===========================================================
   Классы для редактора (спека 7.6) — их автор статьи расставляет вручную
   в блоке HTML/«Дополнительный класс CSS» админки. Разметка, на которую
   рассчитан каждый класс, задокументирована над соответствующим правилом
   и в отчёте Задачи 10 (владельцу нужно будет описать это в редакторской
   памятке). Ни один из четырёх не использует цвет-литерал вне палитры
   :root — «tip» переиспользует --accent, «warn»/«fact» — новые токены
   выше (--warn/--fact), их точные оттенки не из спеки/мокапа (см. коммент
   у :root) и стоит сверить с владельцем.
   =========================================================== */

/* .sr-callout--tip|warn|fact — <div class="sr-callout sr-callout--tip">
   <p>Текст.</p></div>. Ярлычок («Совет»/«Важно»/«Заметка») генерируется
   ::before — автору не нужно вписывать иконку/лейбл руками. */
.sr-callout {
  margin: 28px 0;
  padding: 20px 22px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--chip);
}
.sr-callout::before {
  display: inline-flex;
  align-items: center;
  margin-bottom: 10px;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sr-callout > *:last-child {
  margin-bottom: 0;
}
.sr-callout--tip {
  border-color: var(--accent);
  background: var(--accent-wash);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
}
.sr-callout--tip::before {
  content: 'Совет';
  color: var(--accent);
  background: var(--accent-wash);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}
.sr-callout--warn {
  border-color: var(--warn);
  background: var(--warn-wash);
  background: color-mix(in srgb, var(--warn) 10%, var(--surface));
}
.sr-callout--warn::before {
  content: 'Важно';
  color: var(--warn);
  background: var(--warn-wash);
  background: color-mix(in srgb, var(--warn) 15%, transparent);
}
.sr-callout--fact {
  border-color: var(--fact);
  background: var(--fact-wash);
  background: color-mix(in srgb, var(--fact) 8%, var(--surface));
}
.sr-callout--fact::before {
  content: 'Заметка';
  color: var(--fact);
  background: var(--fact-wash);
  background: color-mix(in srgb, var(--fact) 15%, transparent);
}

/* .sr-pullquote — <blockquote class="sr-pullquote"><p>Цитата.</p>
   <cite>Автор</cite></blockquote>. Lora italic 26px — спека 7.6, дословно.
   Второй десертный шрифт темы (тот, что без кириллицы, см.
   inc/enqueue.php, комментарий у sr-fonts-lora) здесь и нигде в теме
   не используется — по имени намеренно не называем его в этом файле,
   testPullquoteUsesLoraNotInstrumentSerif проверяет его отсутствие
   простым substring-поиском по всему style.css. */
.sr-pullquote {
  margin: 36px 0;
  padding: 2px 0 2px 28px;
  border-left: 3px solid var(--accent);
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 26px;
  line-height: 1.45;
  color: var(--ink);
}
.sr-pullquote > *:last-child {
  margin-bottom: 0;
}
.sr-pullquote cite {
  display: block;
  margin-top: 12px;
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}

/* .sr-checklist — <ul class="sr-checklist"><li><label><input
   type="checkbox"> Текст</label></li>…</ul>. Состояние — в localStorage
   (assets/js/theme.js, ключ по пути страницы + позиции чекбокса в
   документе), класс sr-checklist__item--done навешивает тот же скрипт. */
.sr-checklist {
  list-style: none;
  margin: 28px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.sr-checklist li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--prose);
}
.sr-checklist input[type='checkbox'] {
  flex-shrink: 0;
  width: 19px;
  height: 19px;
  margin-top: 3px;
  accent-color: var(--accent);
  cursor: pointer;
}
.sr-checklist li.sr-checklist__item--done {
  color: var(--dim);
  text-decoration: line-through;
}

/* .sr-numlist — <ol class="sr-numlist"><li>Текст</li>…</ol> (в редакторе —
   обычный нумерованный список + класс через «Дополнительный класс CSS»
   блока). Нумерация — плашками акцента (спека 7.6), через
   counter()/::before, а не наследуемые ::marker — так плашка держит
   собственные размеры/фон, что ::marker для этого не позволяет. */
.sr-numlist {
  list-style: none;
  counter-reset: sr-numlist;
  margin: 28px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.sr-numlist > li {
  counter-increment: sr-numlist;
  position: relative;
  padding-left: 44px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--prose);
}
.sr-numlist > li::before {
  content: counter(sr-numlist);
  position: absolute;
  left: 0;
  top: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--accent);
  color: var(--dark-fg);
  font-size: 13.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ===========================================================
   Обвязка: поиск, обычная страница, архив, 404 (Задача 11). Спека 7.4.
   Герои search.php/archive.php/404.php переиспользуют классы
   .sr-hero-category/__head/__title-row/__title/__count (Задача 9) без
   плитки-глифа — там нет темы конкретной рубрики, только заголовок и,
   у поиска, счётчик найденного. Контентная часть search.php/archive.php —
   тот же .sr-container/.sr-layout/.sr-blog-feed/.sr-sidebar/.sr-grid/.sr-card
   (Задачи 6–9), пустое состояние поиска — карточка .sr-empty-rubric
   (Задача 9) плюс новые классы ниже. page.php/404.php — свои узкие/
   центрированные раскладки без сайдбара (см. таблицу брифа Задачи 11 и
   докблоки page.php/404.php — у обоих нет сетки постов, которую сайдбар
   мог бы сопровождать).
   =========================================================== */

/* Пустое состояние поиска (template-parts/empty-search.php). Модификатор
   поверх карточки .sr-empty-rubric — добавляются форма нового запроса и
   ряд ссылок на рубрики, которых нет в нейтральном empty-rubric.php
   (Задача 9, переиспользуется как есть на пустой рубрике/архиве). Ссылки —
   те же .sr-pill/.sr-pill__count, что и табы под героем (Задача 8), без
   активного состояния — здесь нет «текущей» рубрики. */
.sr-empty-search__form {
  width: 100%;
  max-width: 420px;
}
.sr-empty-search__form .sr-search__form {
  margin: 0;
}
.sr-empty-search__pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

/* Обычная страница (page.php). Спека 7.4: «узкая колонка прозы по центру,
   без сайдбара». 720px — та же ширина колонки статьи, что и средний трек
   .sr-post__grid (Задача 10), не новое число. Заголовок — те же размеры,
   что и .sr-post__title (единообразие текстовых H1 темы). */
.sr-page {
  max-width: 720px;
  margin: 0 auto;
  padding: 28px 0 100px;
}
.sr-page__head {
  margin-bottom: 8px;
}
.sr-page__title {
  margin: 0;
  font-size: 40px;
  line-height: 1.12;
  letter-spacing: -0.03em;
  font-weight: 700;
  color: var(--ink);
}

/* 404 (404.php). Центрированная колонка на всю ширину .sr-container:
   форма поиска, сетка карточек рубрик, кнопка «На главную блога». */
.sr-404__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  padding: 48px 0 100px;
  text-align: center;
}
.sr-404__search {
  width: 100%;
  max-width: 480px;
}
.sr-404__search .sr-search__form {
  margin: 0;
}
.sr-404__rubrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  width: 100%;
}
/* Карточка-рубрика: плитка-глиф 36×36 (уменьшенная версия
   .sr-hero-category__tile, Задача 9) + название + счётчик, в одну строку. */
.sr-404__rubric {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface);
  text-decoration: none;
  text-align: left;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.sr-404__rubric:hover {
  border-color: var(--line-2);
  background: var(--chip);
}
.sr-404__rubric-icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
}
.sr-404__rubric-name {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sr-404__rubric-count {
  flex-shrink: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
}
/* ≤820: сетка карточек рубрик 404 — 3→2 колонки (та же логика сжатия
   сеток на этом брейкпоинте, что и .sr-related__grid, Задача 10). */
@media (max-width: 820px) {
  .sr-404__rubrics {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ≤640: заголовок узкой страницы — тот же терминальный размер 30px, что и
   H1 поста/героя (Задачи 8–10), не новое число. Карточки рубрик 404 — в
   одну колонку. */
@media (max-width: 640px) {
  .sr-page__title {
    font-size: 30px;
  }
  .sr-404__rubrics {
    grid-template-columns: 1fr;
  }
}

/* ≤480: терминальный размер 24px — тот же приём, что и везде на этой
   ширине (Задачи 8–10). */
@media (max-width: 480px) {
  .sr-page__title {
    font-size: 24px;
  }
}
