/* ═══════════════════════════════════════════════════════════════════════════
   blog.css — ОБЩИЙ шаблон блога Цех360 (класс .p-blog на обёртке рядом с
   .p-cand на <body>)

   Потребители: /blog (список), /blog/<slug> (шаблон статьи — единый на все
   будущие SEO-материалы, не переписывается под каждую новую публикацию).

   Источник дизайна — утверждённые макеты ceh360-blog-final-v3.html и
   ceh360-blog-tablica-ucheta-proizvodstva-excel-v3.html: композиция и
   визуальный язык перенесены как есть, а не переосмыслены. Отличия от
   макетов — только там, где этого требует интеграция в существующий сайт:

     1. Токены макета (--bg/--ink/--muted/--orange/...) заменены на --c-*
        из candidate.css — те же значения, тот же источник правды, что и у
        остальных «новых» страниц (industry-page.css, feature-page.css).
     2. Точки перелома макета (760/960/1180) приведены к общей лестнице
        1180/900/640/480 — той же, что у candidate.css/feature-page.css/
        industry-page.css. Совпадающих правил не было ни у одной пары
        (760 vs 640, 960 vs 900, 1180 совпадала случайно) — с той стороны
        полосы, что была шире у макета, кегль/сетка держатся на одну ступень
        дольше.
     3. Классы нарисованного интерфейса из макета (.app/.app-top/.app-body/
        .kpi/.stock-list/.chart/.donut/.money/.plan-list/.route-line/
        .mini-table) переименованы с префиксом .b- и живут ТОЛЬКО здесь:
        .app-top/.app-layout/.stock-list уже заняты в product-ui.css другой,
        куда более крупной структурой (полный кабинет с сайдбаром) —
        совпадение имён при разных структурах молча даёт мусорную вёрстку
        ровно там, где два файла встречаются на одной странице.
     4. Собственных точек `:root` здесь нет — как и в industry-page.css,
        см. предупреждение в шапке candidate.css: блок токенов страницы
        затеняет .p-cand по ближайшему предку, а не наоборот.

   ПОРЯДОК ПОДКЛЮЧЕНИЯ:
       fonts → tsekh360 → landing → candidate → product-ui → blog

   Шапка, подвал, кнопки, контейнер, метка раздела, крошки (внутри страницы
   компонент свой — crumbs здесь не входит в candidate.css) и FAQ-аккордеон
   (нативные <details>/<summary>, тот же приём, что на всех отраслевых и
   функциональных страницах) — общие. Здесь — только то, чего нет нигде
   больше: список статей, карточка статьи, hero и layout статьи, sticky TOC,
   карточка скачивания и полосы нарисованного превью.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Кнопки ────────────────────────────────────────────────────────────────
   .btn/.btn-orange/.btn-outline существуют только под .p-feat в
   feature-page.css — блог не несёт .p-feat на обёртке (свой .p-blog, тот же
   приём, что industry-page.css под .p-ind), поэтому без своей копии здесь
   каждая кнопка на обеих страницах блога рендерилась бы без стиля вовсе:
   без фона, без паддинга, голая ссылка. Значения — 1:1 с feature-page.css,
   а не переосмыслены. */
.p-blog .btn{
  height:50px; line-height:1; padding:0 19px; border-radius:var(--c-r-control);
  border:1px solid #d9d2ca; background:var(--c-bg); color:var(--c-ink);
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-size:16px; font-weight:600; cursor:pointer; transition:.18s ease;
  white-space:nowrap;
}
.p-blog .btn:hover{ transform:translateY(-1px) }
.p-blog .btn-orange{ background:var(--c-accent); border-color:var(--c-accent); color:#fff }
.p-blog .btn-outline{ background:var(--c-bg) }

/* ── Крошки (свой компонент: у candidate.css такого нет) ─────────────────── */
/* --c-muted (6.52:1), не --c-muted-2 (2.85:1 замерено) — тот же выбор, что
   .p-feat .crumbs в feature-page.css уже делает для ссылок; последний пункт
   (текущая страница) — --c-ink, тоже по тому же образцу. --c-muted-2
   оставлен только разделителю «→», это декоративный символ, не текст. */
.p-blog .crumbs{ display:flex; align-items:center; gap:9px; color:var(--c-muted); font-size:14px; margin-bottom:24px; flex-wrap:wrap }
.p-blog .crumbs a{ color:var(--c-muted) }
.p-blog .crumbs a:hover{ color:var(--c-accent) }
.p-blog .crumbs span:last-child{ color:var(--c-ink); font-weight:500 }
.p-blog .crumbs span.sep{ color:var(--c-muted-2) }

/* ── Общий фон блога: мягкий, а не белый — макет и задание сходятся ───────
   На нём карточки статей и превью — белые, границы — var(--c-line),
   тяжёлых теней нет намеренно (пункт 4 задания). */
/* --c-sidebar-fs/--c-sidebar-lh — общий источник кегля для пунктов
   «Содержания» (.toc a) и заголовков «Похожих статей» (.related-list b):
   раньше .toc a вообще не задавал line-height сам, 22.4px (14×1.6)
   приходил случайным наследованием от body{line-height:1.6} —
   совпадение, не источник правды. Оба правила теперь читают явно
   отсюда; поменять масштаб — один раз здесь, оба блока не разъедутся. */
.p-blog{ background:var(--c-bg); --c-sidebar-fs:14px; --c-sidebar-lh:1.6 }
.p-blog .container{ width:var(--c-container); max-width:none; margin:0 auto; padding:0 }

/* ══ /blog: список статей ═══════════════════════════════════════════════ */
.p-blog .blog-hero{ padding:54px 0 36px }
.p-blog .blog-hero .h1{ font-size:var(--c-fs-h1); line-height:var(--c-lh-h1); letter-spacing:var(--c-ls-h1); font-weight:var(--c-fw-head); margin:0 }
.p-blog .blog-hero .lead{ font-size:19px; line-height:1.58; color:var(--c-muted); max-width:920px; margin:16px 0 0 }

.p-blog .filters{ display:flex; gap:10px; flex-wrap:wrap; margin-top:34px }
.p-blog .filter{ border:1px solid var(--c-line); background:var(--c-bg); border-radius:var(--c-r-control); padding:11px 16px; font-size:14px; color:#5f5954; cursor:pointer }
.p-blog .filter.active{ background:var(--c-accent); border-color:var(--c-accent); color:#fff }

.p-blog .featured{ display:grid; grid-template-columns:.9fr 1.1fr; gap:0; border:1px solid var(--c-line); border-radius:22px; overflow:hidden; background:var(--c-bg) }
.p-blog .featured > *{ min-width:0 }
.p-blog .featured-copy{ padding:34px; display:flex; flex-direction:column; min-height:400px }
.p-blog .featured-copy h2{ font-size:32px; line-height:1.08; letter-spacing:-.03em; font-weight:var(--c-fw-head); margin:18px 0 0; max-width:590px }
.p-blog .featured-copy p{ color:var(--c-muted); font-size:16px; margin:18px 0 0; max-width:520px }
.p-blog .featured-copy .btn{ margin-top:auto; align-self:flex-start }
.p-blog .featured-visual{ background:var(--c-soft); padding:26px; display:flex; align-items:center; justify-content:center }

.p-blog .article-grid{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; margin-top:24px }
.p-blog .article-card{ border:1px solid var(--c-line); border-radius:18px; overflow:hidden; background:var(--c-bg); display:flex; flex-direction:column }
.p-blog .article-card:hover{ border-color:#d8cfc5 }
/* overflow:hidden — обязательный предохранитель: renderPreview() отдаёт
   один и тот же виджет и в featured (auto-height, помещается) и сюда
   (фиксированная высота слота). Диагностика: .article-visual раньше был
   overflow:visible, и превью 'orders' (410–474px по факту) вылезало за
   185px слота на 225–289px и наплывало на подложку карточки — граница
   .article-card-body прозрачна (rgba(0,0,0,0)), поэтому вылезший виджет
   был виден сквозь неё вокруг текста заголовка и категории, хотя сам
   текст (глифы) при точечном hit-test оставался «сверху».

   align-items:flex-start — умолчание на случай, если .article-visual--fits
   ещё не проставлен (до отработки JS ниже) или JS отключён: широкие виджеты
   («orders», «route-items», «compare», «workload» — все на основе .b-app,
   замерено 315–472px при области слота 189px после вычета padding) обрезаются
   по нижней границе, верх виден с тем же padding:18px, что и у слота — это и
   задумано, чинили в прошлом заходе именно обрубленный верх.

   .article-visual--fits переключает на center — но только для виджетов,
   которые физически помещаются в слот (короткие: b-money 104px, b-plan
   142px, b-stock 115px, b-kpis 88px, b-chart 118px при той же области
   189px), иначе выбор через flex-start вешал их у верхнего края с пустым
   полем внизу в половину слота. Класс проставляется не по списку типов, а
   по факту рендера — см. landing.js, блок «Article preview vertical fit»:
   scrollHeight виджета сравнивается с реальной высотой слота на текущей
   ширине. Без JS все виджеты остаются top-aligned — то, что уже было
   проверено и работает, не регрессия. */
.p-blog .article-visual{ padding:18px; background:var(--c-soft); height:225px; overflow:hidden; display:flex; align-items:flex-start }
.p-blog .article-visual.article-visual--fits{ align-items:center }
.p-blog .article-card-body{ padding:20px; display:flex; flex-direction:column; flex:1 }
.p-blog .article-card h3{ margin-top:12px; font-size:20px; line-height:1.2; letter-spacing:-.02em; font-weight:var(--c-fw-head) }
.p-blog .article-card p{ font-size:14px; color:var(--c-muted); margin:12px 0 0 }

/* Категория + время + дата — единый вид на карточке, hero-превью и списке */
/* --c-accent-ink, не --c-accent: сам акцент текстом на мягком фоне даёт
   3.31:1 (замерено) — ниже порога 4.5. Тот же приём и то же готовое
   значение, что candidate.css уже документирует для акцента-как-текста
   (5.77:1 на --c-accent-soft) — здесь 5.94 на --c-soft, 6.41 на белом. */
.p-blog .b-eyebrow{ display:inline-flex; align-items:center; gap:9px; color:var(--c-accent-ink); font-size:12px; font-weight:650; letter-spacing:.14em; text-transform:uppercase }
.p-blog .b-eyebrow:before{ content:""; width:7px; height:7px; border-radius:50%; background:currentColor; flex:none }
/* --c-muted, не --c-muted-2 (3.08:1 замерено на 12px — ниже порога 4.5). */
.p-blog .b-meta{ display:flex; gap:10px; flex-wrap:wrap; color:var(--c-muted); font-size:12px; margin-top:auto; padding-top:18px }
.p-blog .b-meta span+span:before{ content:"•"; margin-right:10px }
.p-blog .featured-copy .b-meta,.p-blog .article-hero .b-meta{ padding-top:0; margin-top:20px }

.p-blog .blog-cta{ padding:96px 0 }
.p-blog .blog-cta .box{ border:1px solid var(--c-line); border-radius:22px; background:var(--c-soft); padding:32px; display:grid; grid-template-columns:1fr auto; gap:32px; align-items:center }
.p-blog .blog-cta .box > *{ min-width:0 }
.p-blog .blog-cta .copy{ max-width:760px }
/* Было --c-fs-h4 (21px) — тот же токен, что держит заголовок карточки и
   плашки связи (см. комментарий у --c-fs-card в candidate.css), мельче
   типовых заголовков завершающих блоков сайта. Эталон — .p-feat
   .final-cta h2 в feature-page.css: var(--c-fs-h2), тот же компонент
   используют industry-page.css/dlya-* страницы (своего .final-cta там
   нет — общий класс на странице, несущей оба класса .p-feat и .p-ind). */
.p-blog .blog-cta .copy h2{ font-size:var(--c-fs-h2); line-height:var(--c-lh-h2); letter-spacing:var(--c-ls-h2); font-weight:var(--c-fw-head); margin:18px 0 0 }
.p-blog .blog-cta .copy p{ margin:14px 0 0; color:var(--c-muted); font-size:17px }
.p-blog .blog-cta .actions{ display:flex; gap:12px; flex-wrap:wrap }

/* ── Мелкие превью-виджеты для карточек и hero: .b-* — только здесь ─────── */
.p-blog .b-kpis{ display:grid; grid-template-columns:repeat(3,1fr); gap:9px; width:100% }
.p-blog .b-kpis > *{ min-width:0 }
.p-blog .b-kpi{ border:1px solid var(--c-line); background:var(--c-bg); border-radius:12px; padding:12px }
.p-blog .b-kpi span{ display:block; font-size:10px; color:var(--c-muted-2) }
.p-blog .b-kpi b{ display:block; font-size:17px; margin-top:3px }

.p-blog .b-stock{ width:100%; border:1px solid var(--c-line); border-radius:12px; overflow:hidden; background:var(--c-bg) }
.p-blog .b-stock-row{ display:grid; grid-template-columns:1fr 70px; gap:12px; padding:10px 12px; border-bottom:1px solid var(--c-line); font-size:11px }
.p-blog .b-stock-row > *{ min-width:0 }
.p-blog .b-stock-row:last-child{ border-bottom:0 }

.p-blog .b-chart{ width:100%; height:120px; border:1px solid var(--c-line); border-radius:12px; background:var(--c-bg); padding:14px; display:flex; align-items:flex-end; gap:8px }
.p-blog .b-chart i{ flex:1; background:linear-gradient(180deg,var(--c-accent-2),var(--c-accent)); border-radius:6px 6px 2px 2px; min-width:8px }

.p-blog .b-money{ width:100%; display:grid; grid-template-columns:110px 1fr; gap:16px; align-items:center }
.p-blog .b-money > *{ min-width:0 }
.p-blog .b-donut{ width:104px; height:104px; border-radius:50%; background:conic-gradient(var(--c-accent) 0 48%,#ff9b70 48% 80%,#ffd2bf 80% 95%,#ece6e0 95%); position:relative }
.p-blog .b-donut:after{ content:"2 480 ₽"; position:absolute; inset:17px; border-radius:50%; background:var(--c-bg); display:grid; place-items:center; font-size:12px; font-weight:650 }
.p-blog .b-legend{ display:grid; gap:7px; font-size:10px }
.p-blog .b-legend span{ display:flex; justify-content:space-between; gap:10px }

.p-blog .b-plan{ width:100%; border:1px solid var(--c-line); border-radius:12px; background:var(--c-bg); padding:12px; display:grid; gap:10px }
.p-blog .b-plan-item{ display:grid; grid-template-columns:22px 1fr 20px; gap:9px; align-items:center; font-size:11px }
.p-blog .b-plan-item > *{ min-width:0 }
.p-blog .b-plan-item i{ width:22px; height:22px; border-radius:50%; background:var(--c-soft); display:grid; place-items:center; font-style:normal; color:var(--c-muted-2) }
.p-blog .b-check{ color:var(--c-green); font-weight:700 }

/* Заказ-в-цехе превью для featured/hero: тот же язык, что product-ui.css,
   но со своими компактными классами — .app-* уже заняты полным кабинетом. */
.p-blog .b-app{ background:var(--c-bg); border:1px solid var(--c-line); border-radius:18px; overflow:hidden; box-shadow:var(--c-shadow) }
.p-blog .b-app-top{ height:42px; padding:0 15px; display:flex; align-items:center; gap:7px; border-bottom:1px solid var(--c-line) }
.p-blog .b-dot{ width:8px; height:8px; border-radius:50%; background:#d6cec7 }
.p-blog .b-app-top small{ margin-left:auto; color:var(--c-muted-2) }
.p-blog .b-app-body{ padding:18px }
.p-blog .b-ui-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:15px; padding-bottom:14px; border-bottom:1px solid var(--c-line) }
.p-blog .b-ui-head small{ color:var(--c-muted-2) }
.p-blog .b-ui-head h3{ font-size:22px; line-height:1.08; letter-spacing:-.03em; font-weight:var(--c-fw-head); margin:4px 0 0 }
.p-blog .b-route{ display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:7px; margin:14px 0 }
.p-blog .b-route-step{ border:1px solid var(--c-line); border-radius:10px; padding:9px 7px; background:var(--c-bg); min-width:0 }
.p-blog .b-route-step small{ display:block; font-size:9px; color:var(--c-muted-2) }
.p-blog .b-route-step b{ display:block; font-size:11px; margin-top:3px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.p-blog .b-route-step em{ display:block; font-style:normal; font-size:9px; margin-top:6px; color:var(--c-muted-2) }
.p-blog .b-route-step.done em{ color:var(--c-green-ink) }
.p-blog .b-route-step.work em{ color:var(--c-accent-ink) }
.p-blog .b-mini-table{ margin-top:10px; border:1px solid var(--c-line); border-radius:13px; overflow:hidden }
.p-blog .b-mini-row{ display:grid; grid-template-columns:34px minmax(0,1fr) 96px; gap:10px; align-items:center; padding:10px 12px; border-bottom:1px solid var(--c-line); font-size:11px }
.p-blog .b-mini-row:last-child{ border-bottom:0 }
.p-blog .b-num{ width:26px; height:26px; border-radius:8px; background:var(--c-soft); display:grid; place-items:center; color:var(--c-muted-2); font-size:10px }

/* ══ /blog/<slug>: статья ═══════════════════════════════════════════════
   scroll-margin-top:90px — тот же отступ, что уже используют якоря сайта
   (#vnedrenie, .st-shot-sec, .st-sec--lead в landing.css): реальная высота
   шапки — 70px (.nav-inner в landing.css), а не 76px, как в макете статьи —
   90px даёт запас в 20px на обеих ширинах, отдельного мобильного значения
   не нужно (высота шапки не меняется по брейкпоинтам). */
.p-blog .article-content [id]{ scroll-margin-top:90px }
.p-blog .article-content section{ scroll-margin-top:90px }

/* Белый, не var(--c-soft): требование было именно про белый, а не про
   «любой не-белый токен» — предыдущая правка перепутала знак. .p-blog
   (обёртка) сама несёт var(--c-soft), поэтому явный var(--c-bg) здесь
   обязателен — без него hero унаследовал бы серый от обёртки, а не стал
   бы белым. Отбивки от .article-main не нужно: оба белые, граница не
   рисуется по замыслу — страница читается одним полотном. /blog
   (список) это правило не задевает: .blog-hero своего override не
   имеет и как был на var(--c-soft) от обёртки — так и остался. */
.p-blog .article-hero{ padding:44px 0 40px; background:var(--c-bg) }
/* align-items:start (пункт 11 старого задания) решал пустую зону ПОД
   панелью, но не решал случай, где панель заметно КОРОЧЕ левой
   колонки — на 1440/1280 разница доходила до 283.8px (замер:
   .article-copy 610px против .hero-sheet 326px на статье со скачиванием;
   у остальных пяти статей без карточки скачивания расхождение 20–111px).
   Замер решает: >150px — панель растягивается и её собственные строки
   раздвигаются, чтобы кончиться там же, где копия слева (см. :has() ниже,
   единственный потребитель — статья с .download-panel); ≤150px —
   простого вертикального центрирования достаточно, растягивать нечего. */
/* row-gap:0, не 44px: .download-panel — теперь отдельный grid-item (был
   вложен в .article-copy), а не часть обычного блочного потока. Зазор
   между meta и панелью держит её собственный margin-top:22px — тот же,
   что был при вложенности, — а не сумма margin + межстрочный gap грида. */
.p-blog .article-hero-grid{ display:grid; grid-template-columns:.9fr 1.1fr; gap:0 44px; align-items:center }
/* Тот же дефект и то же лечение, что у .article-layout выше: без
   min-width:0 колонка не сжимается ниже intrinsic-ширины текста внутри —
   на 390px .article-copy держал 432px. */
.p-blog .article-hero-grid > *{ min-width:0 }
.p-blog .article-copy .b-eyebrow{ margin-bottom:0 }
.p-blog .article-copy h1{ font-size:44px; line-height:1.03; letter-spacing:-.03em; font-weight:var(--c-fw-head); margin:16px 0 0 }
.p-blog .article-copy .lead{ font-size:18px; line-height:1.58; color:var(--c-muted); max-width:650px; margin:16px 0 0 }
/* Порядок в разметке — copy, hero-sheet, download-panel (в этом порядке
   и требуется на мобильном: текст → интерфейс → плашка). На десктопе
   .download-panel явно ставится под .article-copy в ту же колонку —
   auto-flow сам туда бы не попал (после hero-sheet во 2-й колонке
   auto-placement продолжил бы со 2-й же), а .hero-sheet растягивается
   на обе строки (1/span 2), чтобы при :has() ниже стретчиться на высоту
   copy+панель вместе, а не только на высоту copy одной. Сброс на
   мобильном — в брейкпоинте 900px. */
.p-blog .article-copy{ grid-column:1; grid-row:1 }
.p-blog .hero-sheet{ grid-column:2; grid-row:1 / span 2; padding:18px; border-radius:22px; background:var(--c-soft) }
.p-blog .download-panel{ grid-column:1; grid-row:2 }
/* Ветка >150px: панель тянется на всю высоту объединённой строки (copy +
   .download-panel в 1-й колонке), сама карточка и таблица внутри неё
   растут вместе с ней (flex:1 по цепочке), а существующие четыре строки
   (не выдуманные новые) раздвигаются justify-content:space-between —
   интерфейс кончается там же, где копия с плашкой, без добавления
   данных, которых не было в макете. */
.p-blog .article-hero-grid:has(.download-panel){ align-items:stretch }
.p-blog .article-hero-grid:has(.download-panel) .hero-sheet{ display:flex; flex-direction:column }
.p-blog .article-hero-grid:has(.download-panel) .sheet-card{ display:flex; flex-direction:column; flex:1 }
.p-blog .article-hero-grid:has(.download-panel) .sheet-table{ flex:1; display:flex; flex-direction:column; justify-content:space-between }
.p-blog .sheet-card{ background:var(--c-bg); border:1px solid var(--c-line); border-radius:18px; overflow:hidden; box-shadow:var(--c-shadow) }
.p-blog .sheet-top{ height:43px; border-bottom:1px solid var(--c-line); display:flex; align-items:center; gap:7px; padding:0 15px }
.p-blog .sheet-top b{ margin-left:8px; font-size:12px }
.p-blog .sheet-top small{ margin-left:auto; color:var(--c-muted-2) }
.p-blog .sheet-tabs{ display:flex; gap:7px; padding:13px 14px 0; overflow-x:auto; scrollbar-width:none }
.p-blog .sheet-tabs::-webkit-scrollbar{ display:none }
.p-blog .sheet-tab{ padding:7px 10px; border:1px solid var(--c-line); border-radius:9px 9px 0 0; font-size:10px; background:var(--c-soft); color:var(--c-muted); white-space:nowrap }
.p-blog .sheet-tab.active{ background:var(--c-accent); color:#fff; border-color:var(--c-accent) }
.p-blog .sheet-table{ padding:14px }
.p-blog .sheet-row{ display:grid; grid-template-columns:70px 1.5fr 72px 74px 96px; gap:8px; align-items:center; padding:10px 8px; border-bottom:1px solid var(--c-line); font-size:10px }
.p-blog .sheet-row.header{ font-weight:700; color:var(--c-muted); background:var(--c-soft); border-radius:8px }
.p-blog .sheet-row:last-child{ border-bottom:0 }
.p-blog .sheet-row span,.p-blog .sheet-row b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.p-blog .b-status{ display:inline-flex; justify-content:center; border-radius:999px; padding:5px 8px; font-size:9px; background:var(--c-accent-soft); color:var(--c-accent-ink) }
.p-blog .b-status.green{ background:var(--c-green-soft); color:var(--c-green-ink) }

/* .chip — статусная плашка внутри .b-app/.b-mini-row (заказ «в работе»,
   операция «готово»). Была в мокапе (.chip/.chip.orange/.chip.green) и уже
   использовалась в build-blog.js (превью featured-карточки на /blog) без
   единого объявления в blog.css — рендерилась текстом без заливки.
   --c-accent-ink, не --c-accent: тот же 3.31:1 замер, что у b-eyebrow. */
.p-blog .chip{ display:inline-flex; align-items:center; padding:6px 10px; border-radius:999px; font-size:11px; font-weight:650; white-space:nowrap }
.p-blog .chip.orange{ background:var(--c-accent-soft); color:var(--c-accent-ink) }
.p-blog .chip.green{ background:var(--c-green-soft); color:var(--c-green-ink) }
.p-blog .chip.red{ background:var(--c-red-soft); color:var(--c-red-ink) }

/* Было border:var(--c-accent-border) + background:var(--c-accent-soft) —
   розовая заливка поверх белого hero и рядом с оранжевой кнопкой давала
   три фона в одном месте и перетягивала внимание с заголовка статьи.
   Белый + var(--c-line) — та же пара, что у всех прочих карточек блога
   (.article-card, .b-app, .sheet-card); радиус 18px — туда же, вместо
   собственного 16px. Акцент остаётся только на кнопке «Скачать XLSX»
   (.btn-orange, ниже) — заголовок, описание и «↓» в кнопке не тронуты. */
.p-blog .download-panel{ margin-top:22px; border:1px solid var(--c-line); background:var(--c-bg); border-radius:18px; padding:18px; display:grid; grid-template-columns:1fr auto; gap:20px; align-items:center }
.p-blog .download-panel > *{ min-width:0 }
.p-blog .download-panel strong{ display:block; font-size:18px }
.p-blog .download-panel p{ margin:5px 0 0; color:var(--c-muted); font-size:14px }
.p-blog .btn.download:before{ content:"↓"; font-size:18px; margin-right:8px }

.p-blog .article-main{ padding-top:0; background:var(--c-bg) }
/* Шапка и .container уже выровнены (оба — width:var(--c-container),
   #nav .wrap приведён к тому же значению в candidate.css). Несовпадение
   было не в контейнере, а внутри грида: первая колонка была жёстко
   ограничена 820px, а контейнер на 1260px (1440-экран) — 56px между
   колонками уходили в никуда, и сайдбар заканчивался на 56px раньше
   кнопки в шапке. Тот же 1fr для растущей колонки уже используется на
   соседнем брейкпоинте ниже (900–1180px) — здесь тот же приём. */
.p-blog .article-layout{ display:grid; grid-template-columns:minmax(0,1fr) 320px; gap:64px; align-items:start }
/* Без min-width:0 грид-элемент не сжимается уже своего min-content —
   .article-content держал 554px на 390px-экране (offending width found by
   getBoundingClientRect() sweep), хотя .article-layout уже был в одну
   колонку: 1fr сам по себе не сжимает трек ниже intrinsic-ширины контента. */
.p-blog .article-layout > *{ min-width:0 }
.p-blog .article-content{ font-size:18px; line-height:1.72 }
/* landing.css держит голое правило section{padding:var(--space-24) 0}
   для секций лендинга верхнего уровня (herо, features…) — оно бьёт по
   тегу без класса и попадает в том числе на H2-подсекции статьи внутри
   .article-content, добавляя 64–96px padding сверх собственных 52px
   margin-top ниже. На мобильном это давало 186px пустоты между
   последним абзацем и следующим заголовком — читалось как «пропавший
   визуал». .blog-hero/.article-hero/.article-main уже глушат то же
   правило своим padding явно (см. ниже) — здесь было пропущено. */
.p-blog .article-content section{ margin-top:52px; padding:0 }
.p-blog .article-content section:first-child{ margin-top:0 }
.p-blog .article-content h2{ font-size:32px; line-height:1.1; letter-spacing:-.03em; font-weight:var(--c-fw-head); margin:0 0 16px }
.p-blog .article-content h3{ font-size:23px; line-height:1.18; font-weight:var(--c-fw-head); margin:28px 0 12px }
.p-blog .article-content p{ color:#4e4945; margin:0 0 18px }
.p-blog .article-content ul,.p-blog .article-content ol{ margin:0 0 24px; padding-left:24px; color:#4e4945 }
.p-blog .article-content li{ margin:8px 0 }
.p-blog .article-content a.inline-link{ color:var(--c-accent); text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:3px }

.p-blog .quote{ border:1px solid var(--c-line); border-radius:16px; padding:22px 24px; margin:30px 0; background:var(--c-bg); font-size:19px; line-height:1.5 }
.p-blog .quote:before{ content:"“"; color:var(--c-accent); font-size:42px; line-height:1; display:block; margin-bottom:4px }
.p-blog .quick-answer{ background:var(--c-soft); border-radius:18px; padding:24px; margin-bottom:34px }
.p-blog .quick-answer h2{ font-size:23px; margin-bottom:10px }
.p-blog .quick-answer p:last-child{ margin-bottom:0 }

.p-blog .number-list{ display:grid; gap:12px; margin:24px 0 30px }
.p-blog .number-item{ display:grid; grid-template-columns:34px minmax(0,1fr); gap:12px; align-items:start }
.p-blog .number-item i{ width:32px; height:32px; border-radius:50%; background:var(--c-accent-soft); color:var(--c-accent-ink); font-style:normal; display:grid; place-items:center; font-size:12px; font-weight:650 }
.p-blog .number-item p{ margin:4px 0 0 }
.p-blog .formula-grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; margin:24px 0 }
.p-blog .formula-card{ border:1px solid var(--c-line); border-radius:14px; padding:18px; background:var(--c-bg) }
.p-blog .formula-card b{ display:block }
.p-blog .formula-card code{ display:block; margin-top:8px; padding:10px; border-radius:9px; background:var(--c-soft); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; white-space:normal }
.p-blog .check-list{ display:grid; gap:10px; margin:20px 0 }
.p-blog .check{ display:grid; grid-template-columns:24px minmax(0,1fr); gap:10px }
.p-blog .check i{ width:22px; height:22px; border-radius:50%; background:var(--c-green-soft); color:var(--c-green-ink); display:grid; place-items:center; font-style:normal; font-size:12px; font-weight:700 }

.p-blog .preview-box{ border:1px solid var(--c-line); border-radius:18px; background:var(--c-soft-2); padding:18px; margin:26px 0 34px }
.p-blog .preview-title{ display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:12px }
.p-blog .preview-title small{ color:var(--c-muted) }
.p-blog .preview-table{ border:1px solid var(--c-line); border-radius:13px; background:var(--c-bg); overflow-x:auto }
.p-blog .preview-row{ display:grid; grid-template-columns:90px 1.2fr 92px 90px 110px; gap:8px; padding:10px 12px; border-bottom:1px solid var(--c-line); font-size:11px; align-items:center }
.p-blog .preview-row:last-child{ border-bottom:0 }
.p-blog .preview-row.head{ background:var(--c-soft); font-weight:700; color:var(--c-muted) }

.p-blog .sidebar{ position:sticky; top:100px; display:grid; gap:16px; align-self:start }
.p-blog .side-card{ border:1px solid var(--c-line); border-radius:17px; padding:22px; background:var(--c-bg) }
.p-blog .side-card h3{ font-size:18px; margin:0 0 12px }
.p-blog .side-card p{ font-size:14px; color:var(--c-muted) }
.p-blog .side-card .btn{ width:100%; margin-top:12px }
.p-blog .toc{ display:grid; gap:10px }
.p-blog .toc a{ font-size:var(--c-sidebar-fs); line-height:var(--c-sidebar-lh); color:#68615b; padding-left:14px; position:relative; display:block }
.p-blog .toc a:before{ content:""; width:6px; height:6px; border-radius:50%; background:#ddd3cb; position:absolute; left:0; top:8px }
.p-blog .toc a.active:before{ background:var(--c-accent) }
.p-blog .side-download{ background:var(--c-accent-soft); border-color:var(--c-accent-border) }
.p-blog .side-download .btn{ background:var(--c-accent); border-color:var(--c-accent); color:#fff }
.p-blog .related-mini{ display:grid; gap:12px }
.p-blog .related-mini a{ display:grid; grid-template-columns:72px 1fr; gap:10px; align-items:center }
.p-blog .related-mini a > *{ min-width:0 }
.p-blog .b-thumb{ height:58px; border-radius:10px; background:var(--c-soft); border:1px solid var(--c-line); display:grid; place-items:center; font-size:10px; color:var(--c-muted) }
.p-blog .related-mini b{ font-size:13px; line-height:1.25; font-weight:600 }

/* «Похожие статьи»: только заголовки, без .b-thumb — квадрат с категорией
   обрезал текст в узкой колонке сайдбара и дублировал смысл заголовка.
   Линия — только МЕЖДУ строками (border-bottom, снят у :last-child) — ни
   сверху, ни снизу списка. Строка целиком кликабельна: <a> остаётся
   display:block на всю ширину, паддинг держит и кликабельную область, и
   равные отступы сверху/снизу. */
.p-blog .related-list{ display:block }
.p-blog .related-list a{ display:block; padding:15px 0; border-bottom:1px solid var(--c-line) }
.p-blog .related-list a:last-child{ border-bottom:none }
/* font-weight:600 сохранён — заголовки «Похожих статей» ссылки, им
   уместно быть плотнее пунктов оглавления (тот же аргумент, что и в
   задании). font-size/line-height теперь общий источник с .toc a
   (--c-sidebar-fs/--c-sidebar-lh) — были свои 13px/1.35. */
.p-blog .related-list b{ display:block; font-size:var(--c-sidebar-fs); line-height:var(--c-sidebar-lh); font-weight:600 }

.p-blog .faq{ display:grid; gap:0; border-top:1px solid var(--c-line); margin-top:20px }
.p-blog .faq details{ border-bottom:1px solid var(--c-line); padding:16px 0 }
.p-blog .faq summary{ cursor:pointer; font-weight:600 }
.p-blog .faq p{ font-size:16px; margin:12px 0 0 }
.p-blog .author{ margin-top:46px; display:grid; grid-template-columns:58px 1fr; gap:14px; align-items:center }
.p-blog .author > *{ min-width:0 }
.p-blog .avatar{ width:58px; height:58px; border-radius:50%; background:var(--c-bg); border:1px solid var(--c-line); display:grid; place-items:center }
.p-blog .avatar img{ width:30px; height:30px }
.p-blog .author b{ display:block }
.p-blog .author span{ display:block; color:var(--c-muted); font-size:13px }

/* Финальный CTA статьи: своя секция, всю ширину контейнера, ПОСЛЕ грида со
   sidebar — sidebar заканчивается выше него (пункт 18 задания: фон секции
   белый, плашка CTA — мягкая, а не наоборот). */
.p-blog .article-end{ padding:48px 0 96px; background:var(--c-bg); margin-top:72px }
.p-blog .article-end .box{ border:1px solid var(--c-line); border-radius:22px; background:var(--c-soft); padding:34px; display:grid; grid-template-columns:1fr auto; gap:32px; align-items:center }
.p-blog .article-end .box > *{ min-width:0 }
/* Тот же перевод на var(--c-fs-h2), см. комментарий у .blog-cta .copy h2 —
   один эталон (.p-feat .final-cta h2), два места вывода того же CTA
   (список статей и низ статьи). */
.p-blog .article-end h2{ font-size:var(--c-fs-h2); line-height:var(--c-lh-h2); letter-spacing:var(--c-ls-h2); font-weight:var(--c-fw-head); margin:18px 0 0; max-width:760px }
.p-blog .article-end p{ margin:14px 0 0; color:var(--c-muted); font-size:17px; max-width:720px }
.p-blog .article-end .actions{ display:flex; gap:12px; flex-wrap:wrap }

.p-blog .mobile-toc{ display:none }

/* ═══ ЛЕСТНИЦА 1180 / 900 / 640 / 480 ═════════════════════════════════════ */
@media (max-width:1180px){
  .p-blog .article-layout{ grid-template-columns:minmax(0,1fr) 300px; gap:36px }
}
@media (max-width:900px){
  .p-blog .featured,.p-blog .blog-cta .box,.p-blog .article-hero-grid,.p-blog .article-layout,.p-blog .article-end .box{ grid-template-columns:1fr }
  /* Сброс явного grid-column/grid-row с десктопа (article-hero-grid — 2
     колонки, .hero-sheet растянут на 2 строки) — без этого в 1-колоночном
     гриде .hero-sheet искал бы несуществующую 2-ю колонку implicit-треком
     и уезжал вбок. auto возвращает порядок к разметке: copy → hero-sheet
     → download-panel — «текст, интерфейс, плашка», как и требуется на
     мобильном. */
  .p-blog .article-copy,.p-blog .hero-sheet,.p-blog .download-panel{ grid-column:auto; grid-row:auto }
  /* row-gap грида — 0 (см. .article-hero-grid выше): при column-gap-only
     сборке .download-panel держит зазор до предыдущего блока собственным
     margin-top (22px здесь, 16px/12px на более узких ступенях ниже) —
     так его не удваивает grid-gap. .hero-sheet тем же margin-top не был
     заведён вовсе: в 2-колоночной десктопной раскладке он не нужен
     (colonки рядом, не друг под другом), а при схлопывании в 1 колонку
     здесь текст «1 сентября 2026 · 7 минут чтения» вплотную упирался в
     интерфейс под ним. Значение — не с потолка, а то же самое 22px,
     которым .download-panel уже держит идентичный переход (текст → блок
     под ним) на этой же ступени; шаг вниз повторяет его же 16px/12px. */
  .p-blog .hero-sheet{ margin-top:22px }
  .p-blog .article-grid{ grid-template-columns:repeat(2,minmax(0,1fr)) }
  .p-blog .featured-copy{ min-height:auto }
  .p-blog .featured-copy .btn{ margin-top:26px }
  .p-blog .featured-visual{ min-height:320px }
  .p-blog .sidebar{ position:static; grid-template-columns:1fr 1fr }
  .p-blog .side-card.toc-card{ display:none }  /* содержание — только сверху статьи на этой ширине, см. .mobile-toc */
  .p-blog .hero-sheet{ padding:14px }
  /* Содержание переезжает в начало статьи начиная с этой же ширины — иначе
     в промежутке между 900 и 640 у статьи нет содержания вовсе (sidebar уже
     скрыт выше, .mobile-toc раньше показывался только на ≤640). */
  .p-blog .mobile-toc{ display:block; margin:0 0 28px }
}
@media (max-width:640px){
  .p-blog .blog-hero{ padding:38px 0 26px }
  .p-blog .filters{ overflow-x:auto; flex-wrap:nowrap; padding-bottom:6px; scrollbar-width:none }
  .p-blog .filters::-webkit-scrollbar{ display:none }
  .p-blog .filter{ white-space:nowrap }
  .p-blog .article-grid{ grid-template-columns:1fr }
  .p-blog .featured-copy,.p-blog .blog-cta .box{ padding:22px }
  .p-blog .featured-visual{ padding:16px; min-height:auto }
  .p-blog .blog-cta .actions{ display:grid }
  .p-blog .blog-cta .actions .btn{ width:100% }
  /* ── ПОЛОСА COOKIE: важный блок первого экрана (копия + карточка
     скачивания) целиком выше порога — тот же приём компактизации
     типографики в мобильной зоне, что и на отраслевых страницах, не
     сокращение текста. Замерено ДО правки: низ download-panel 813px на
     390×844 при пороге 704 — полоса cookie (её верх реально на 705.75px)
     закрывала кнопку «Скачать XLSX». Лид держал 7 строк при 18px/1.58,
     панель скачивания — 214px с внутренними отступами 18px. */
  .p-blog .article-hero{ padding:26px 0 }
  .p-blog .article-copy h1{ font-size:30px }
  .p-blog .article-copy .lead{ font-size:15px; line-height:1.5; margin-top:12px }
  .p-blog .article-copy .b-meta{ margin-top:14px }
  .p-blog .hero-sheet{ margin-top:16px }
  /* .sheet-row на десктопе — 5-колоночный grid 70px 1.5fr 72px 74px 96px
     (сумма фиксированных 312px). На этой ширине строка сама уже 308px —
     фиксированные колонки уже не помещаются, и гибкая 1.5fr получает
     0px: название изделия не обрезается многоточием, а пропадает целиком,
     на всех строках .sheet-table, на всех статьях блога (общий шаблон,
     см. build-blog.js). На 1024px та же колонка честно получает 91px
     и обрезается многоточием — это не задето, там реальный запас есть.

     Чиним перестройкой строки в две визуальные полосы вместо сжатия
     колонок: заказ+изделие сверху (изделие — самое важное, ему нужна
     вся ширина), срок снизу вместе с ним, статус — узкая пилюля справа
     на обе строки. «Готов.» (процент) убран целиком — он дублирует
     смысл статуса («В производстве»/«Новый»), а не несёт новой
     информации; шапку (.header, те же 5 колонок с подписями) на этой
     ширине тоже прячем — короткие ярлыки-подписи страдали бы тем же
     переполнением, а данные под ними самоописательны (дата читается
     как дата и без подписи «Срок»). Горизонтальный скролл внутри
     виджета не заводим — просили не добавлять. */
  .p-blog .sheet-row.header{ display:none }
  .p-blog .sheet-row{ grid-template-columns:52px 1fr auto; grid-template-rows:auto auto; row-gap:3px }
  .p-blog .sheet-row > *:nth-child(1){ grid-column:1; grid-row:1 }
  .p-blog .sheet-row > *:nth-child(2){ grid-column:2; grid-row:1 }
  .p-blog .sheet-row > *:nth-child(3){ grid-column:1 / span 2; grid-row:2; color:var(--c-muted) }
  .p-blog .sheet-row > *:nth-child(4){ display:none }
  .p-blog .sheet-row > *:nth-child(5){ grid-column:3; grid-row:1 / span 2; align-self:center }
  .p-blog .download-panel{ margin-top:16px; padding:14px; gap:12px }
  .p-blog .download-panel strong{ font-size:16px }
  .p-blog .download-panel p{ font-size:13px }
  .p-blog .article-content{ font-size:17px }
  .p-blog .article-content h2{ font-size:27px }
  .p-blog .article-content section{ margin-top:40px }
  .p-blog .sidebar{ grid-template-columns:1fr }
  .p-blog .formula-grid{ grid-template-columns:1fr }
  .p-blog .download-panel{ grid-template-columns:1fr }
  .p-blog .download-panel .btn{ width:100% }
  .p-blog .article-end{ padding-bottom:72px }
  .p-blog .article-end .box{ padding:22px }
  .p-blog .article-end .actions{ display:grid }
  .p-blog .article-end .actions .btn{ width:100% }
  /* Ширина всей страницы не сжимается: у таблиц свой горизонтальный скролл
     внутри preview-table/sheet-table, а не у документа (пункт 33 задания). */
  .p-blog .preview-table{ overflow-x:auto }
  .p-blog .preview-row{ min-width:460px }
  .p-blog .sheet-tabs{ overflow-x:auto }
  .p-blog .b-money{ grid-template-columns:1fr; justify-items:center; text-align:center }
  .p-blog .b-legend{ width:100% }
}
@media (max-width:480px){
  /* Тот же запас, до́лжный на 375×812, требует ещё немного высоты — низ
     download-panel был на 667.97px при пороге 672, запас всего 4px против
     нужных 20px. Досжато типографикой, не текстом. */
  .p-blog .article-hero{ padding:18px 0 }
  .p-blog .article-copy .b-eyebrow{ margin-bottom:0 }
  .p-blog .article-copy h1{ font-size:27px; margin-top:10px }
  .p-blog .hero-sheet{ margin-top:12px }
  .p-blog .download-panel{ margin-top:12px }
}
