/* site.css — база единой системы оформления сайта. Канон — оформление
   главной (landing.css): токены и базовые правила скопированы оттуда без
   изменений, кроме `body` (добавлен `overflow-wrap`) и `:focus-visible`
   (заменён целиком на более сильную версию с публичных страниц). Доступность
   взята с публичных страниц (public.css), где она строже. Файл подключён
   каждой страницей сайта — см. `templates/base_site.html`. */
:root{
  --bg:#F0F2F5; --card:#FFFFFF; --line:#E3E6EB; --ink:#1B1D21; --ink-2:#5E636C; --ink-3:#9AA0AA;
  --yellow:#FFD83D; --yellow-deep:#F2C500; --red:#E0362F; --red-bg:#FDECEB; --green:#2E9E57; --green-bg:#E8F6EE;
  /* --radius-s — скругление мелких элементов (.stat, .notice, .thanks-msg
     и т.п.), НЕ радиус кнопки: у .btn ниже по файлу своё число 10px, взятое
     не отсюда. Однажды уже перепутали (взяли токен за источник истины для
     кнопки) — см. комментарий у .btn. */
  --blue:#2F6FED; --radius:14px; --radius-s:8px;
  --font:"Golos Text",system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  /* У лендинга токенов раскладки не было — .container и длинный текст
     берут их из public.css, переносим без изменений. */
  --measure:68ch; --container:1120px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
/* Было глобальным правилом в удалённом public.css (`*{transition:none!important;
   animation:none!important}`) — при переносе в канон осталась только строка
   про scroll-behavior. `.btn` (ниже) везде получил переход по transform/
   background, поэтому без возврата правила «уменьшенное движение» перестало
   что-либо гасить, кроме прокрутки. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{transition:none!important;animation:none!important}
}
/* D4-I1: перенос длинного неразрывного слова — на уровне документа, а не
   одного блока `.prose`. Страницы инструментов подставляют введённый адрес
   прямо в <h1> (до 3.25rem), и на 360 px он уводил вбок весь документ вместе с
   шапкой и формой — это WCAG 1.4.10 (Reflow). Именно `break-word`, а не
   `anywhere`: последний снижает min-content всех потомков, включая flex-блоки
   шапки и первого экрана, и рвал бы там посреди слова то, что спокойно
   переехало бы на следующую строку. У `.prose` `anywhere` остаётся. */
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased;overflow-wrap:break-word}
/* Подвал прижат к низу экрана на коротких страницах: body — колонка на всю
   высоту окна, footer{margin-top:auto} (см. раздел «Подвал»). dvh — чтобы
   на мобильных с плавающей адресной строкой не появлялась прокрутка на
   пиксель; vh строкой выше — фолбэк для браузеров без dvh. */
body{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
a{color:var(--blue);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3{margin:0;font-weight:800;letter-spacing:-.01em;line-height:1.15}
/* Канон не задавал размер h1 — на главной это не видно (там свой селектор
   `.hero h1{font-size:38px}` перекрывает канон), а на всех остальных
   страницах h1 падал на браузерные ~32px вместо прежних 52px из удалённого
   public.css. Число и мобильный шаг — оттуда же (совпадает с
   `.hero__title` в prognoz-zayavok.css, взято не случайно, а как уже
   проверенное на этой странице значение). */
h1{font-size:clamp(2rem,5vw,3.25rem)}
h2{font-size:26px;line-height:1.2}
h3{font-size:17px;font-weight:600}
p{margin:0}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
:focus-visible{outline:3px solid var(--ink);outline-offset:2px;box-shadow:0 0 0 6px var(--yellow)}
/* D2-M5: ссылка-пропуск шапки, видна только когда получает фокус с клавиатуры. */
/* Текст только для скринридера: пометка «откроется в новой вкладке» у ссылок с target=_blank. */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip-link{position:absolute;left:-9999px;top:0;z-index:100;padding:10px 16px;background:var(--bg);color:var(--ink);border:1px solid var(--ink);border-radius:6px;text-decoration:none}
.skip-link:focus{position:static;display:inline-block;margin:12px 20px;outline:3px solid var(--ink);outline-offset:2px;box-shadow:0 0 0 6px var(--yellow)}
/* Фокус после перехода по skip-link — та же обводка, что у ссылок, а не
   браузерная по умолчанию вокруг всего блока контента. Общий :focus-visible
   выше матчится и на #main (и это осознанно — сужать его до ссылок/.button
   значило бы терять обводку на остальных фокусируемых элементах), поэтому
   здесь явно гасим его box-shadow: без этого жёлтый ореол в 6px обводил бы
   весь блок контента целиком — ровно то, что запрещено строкой выше. */
#main:focus-visible{outline:3px solid var(--ink);outline-offset:4px;box-shadow:none}

/* Ниже — примитивы, из которых собираются страницы: перенесены из
   landing.css, public.css и tools.css с переименованием токенов под канон
   (--cobalt→--blue, --paper→--bg, --muted→--ink-2, --marker→--yellow).
   Источник указан в комментарии над каждой группой. */

/* === Раскладка (public.css) === */
.container{max-width:var(--container);margin:0 auto;padding:0 20px}
.section{padding:48px 20px}

/* === Ритм секций (финальное ревью, блокер 1) === */
/* У лендинга «база» ритма никогда не было — там каждый отступ прибит к
   своему блоку (`.hero h1`, `.step p` и т. п.), поэтому нули канона
   (`h1,h2,h3{margin:0}`, `p{margin:0}`) для главной верны буквально. Но
   страницы, собранные из обычных `<section class="section container">`
   (блог, инструменты, «Прогноз заявок», страницы ошибок и лидов), рассчитаны
   на отступы документа, а не на вёрстку по компонентам — без них заголовок
   слипается со следующим блоком, а абзацы друг с другом. Правила ниже
   привязаны к `.section` и на главной не работают: там этого класса нет ни
   в одном шаблоне (проверено `grep` по kabinet-direkta.html и thanks.html).
   `:where(.section)` — не опечатка и не `.section` для красоты: `:where()`
   обнуляет вес самого `.section` в специфичности, оставляя только вес тега
   (h1/h2/p и т. д.). У блога и инструментов десятки точечных классов на
   абзацах и заголовках (`.tool-card__title{margin:0}`, `.post-meta{margin:
   0 0 8px}`, `.verdict{margin-top:8px}`, `.crumbs{margin:0 0 12px}` и
   другие) — все они слабее «класс + тег», и обычный `.section h2` тихо
   перебил бы их правило снаружи, раздвинув карточки инструментов и
   превью-карточки блога, где расстояние уже держит `gap` контейнера, или
   сжав отступ под шапкой инструмента. С `:where()` вес правила ниже любого
   из них — оно применяется только там, где своего отступа ни у чего нет,
   и уступает первому же классу с margin, что и есть цель: «ритм по
   умолчанию», а не «ритм поверх». Там же, где страничный файл поверх этого
   настраивает типографику голым тегом (`.tool-page h1/h2` в tools.css, вес
   «класс + тег», выше веса `:where()`-правила), побеждает он — тоже без
   исключений и `!important`. */
:where(.section) h1{margin:0 0 20px}
:where(.section) h2{margin:0 0 16px}
:where(.section) h3{margin:0 0 8px}
:where(.section) p{margin:0 0 16px}
/* :last-child здесь — про ближайшего родителя абзаца, не про .section
   целиком (у самого `:last-child` есть вес, `:where()` его не гасит): попадает
   и в `.lead-form__note`, и в `.tool-card__teaser`, и в `.review__by` — но
   у всех у них и так `margin:0`, так что обнуление здесь не спорит с ними,
   а просто убирает лишний просвет перед padding-bottom секции у последнего
   абзаца, где своего класса с margin нет. */
:where(.section) p:last-child{margin-bottom:0}
/* Ширина абзацев и пунктов списка вне `.prose` — было в удалённом
   public.css (`p,li{max-width:var(--measure)}`), без него текст вне
   компонентов растягивался на всю ширину `.container` (1120px) вместо
   68 символов. `:not(.check)` — исключение не про специфичность (у `.check`
   своего max-width нет, обнулять нечего), а про смысл: пункты чек-листа
   (tools.css) не текстовые строки, а карточки на всю ширину `.tool-page`
   (`.check{display:flex}`), и без исключения на /tools/*/result/ они бы
   визуально сузились до 68ch посреди широкой секции. У остальных
   li-компонентов (`.pains`, `.parts`, `.steps`, `.reviews`) ширина и так
   держится грид-колонкой уже 68ch, конфликта нет. */
:where(.section) p,:where(.section) li:not(.check){max-width:var(--measure)}
/* Просвет перед лид-формой (`includes/lead_form.html`) — предыдущий абзац
   уже даёт `margin-bottom:16px` по правилу выше, этого мало, когда сама
   форма следует сразу за заголовком секции без разделяющего текста
   (страница «Спасибо» этот класс не использует — там своя вёрстка формы,
   см. lead_form_landing.html, поэтому главную и «Спасибо» это не заденет). */
:where(.section) .lead-form{margin-top:24px}
/* T6: канон снимает подчёркивание у ссылок глобально (`a{text-decoration:
   none}`) ради кнопок и навигации — внутри `.prose` оно уже возвращено, а в
   обычном абзаце секции ссылка отличалась от текста только цветом (WCAG
   1.4.1). Сужено до `p a` — кнопки внутри параграфа (см. 404.html, где
   рядом с текстовой ссылкой лежит `.btn`) и ссылки навигации/пилюль вне
   `<p>` не задеты. Два абзаца исключены явно, а не только по смыслу: `.crumbs`
   (хлебная крошка над h1 инструмента) и `.post-meta` (строка «Блог · дата ·
   тег» над постом) технически `<p>`, но по роли — навигация, а не текст, и
   попадают под тот же запрет «не задевая... навигацию». Оба — внутри
   `:where()`, чтобы вес правила остался на уровне тега, а не полез спорить
   с чужими классами. */
:where(.section p:not(.crumbs, .post-meta)) a:not(.btn){text-decoration:underline}

/* === Финальная секция с призывом (была дублирована в blog.css и
   prognoz-zayavok.css) === */
/* `.final` — общий компонент: секция «оставьте заявку» в конце поста
   блога, в конце страницы инструмента и на «Прогнозе заявок» — везде
   одна и та же роль (последний CTA перед формой), не совпадение имени.
   Правило лежало дословно одинаковым в blog.css и prognoz-zayavok.css и
   отсутствовало в tools.css, хотя `.final` есть и в tools/index.html, и в
   tools/result_base.html — третьей копией сторож классов не чинят, только
   плодят рассинхрон при следующей правке. Перенесено в канон один раз,
   вычищено из обоих страничных файлов. `.final__direct` не переехал вместе
   с ним — та строка используется только на «Прогнозе заявок», это её
   единственное место, а не общий компонент. */
.final h2{max-width:26ch}

/* === Кнопки (landing.css) === */
/* border-radius: 10px — число, а не var(--radius-s) (8px): это разные
   значения, не опечатка. Канон намеренно не унифицирует все скругления
   сайта под один токен — пересматривать дизайн ради единообразия не надо. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:0;cursor:pointer;font:inherit;font-weight:600;border-radius:10px;padding:12px 18px;transition:transform .12s ease,background .15s ease}
.btn:hover{text-decoration:none}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--yellow);color:var(--ink)}
.btn-primary:hover{background:var(--yellow-deep)}
.btn-ghost{background:var(--card);border:1px solid var(--line);color:var(--ink)}
.btn-ghost:hover{background:var(--bg)}
.btn-sm{padding:8px 14px;font-size:14px}

/* === Карточка (landing.css) === */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:32px 30px}
/* .card--warn — предупреждающая карточка на месте бутстраповского .alert
   (сам .alert снимается в задаче 5). Фон и полоска — уже заведённые токены
   --red-bg/--yellow, новых цветов под предупреждение не заводим. */
.card--warn{background:var(--red-bg);border-left:4px solid var(--yellow)}
/* Отступ карточки на самых узких экранах — свойство самого компонента, а не
   специфика лендинга (было в landing.css, ревью Task 4 попросило перенести:
   тесные поля на телефоне нужны карточке на любой странице, не только на
   главной). */
@media (max-width:560px){.card{padding:24px 18px}}

/* === Мелкие компоненты (landing.css) === */
.eyebrow{font-family:var(--mono);font-size:12px;color:var(--ink-3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:10px}
.lead{color:var(--ink-2);font-size:17px;max-width:62ch}
.chip{font-size:13px;color:var(--ink-2);background:var(--bg);border:1px solid var(--line);padding:5px 10px;border-radius:999px;white-space:nowrap}
.chip b{color:var(--green);font-weight:600}
.status{display:inline-flex;align-items:center;margin-right:8px;vertical-align:middle}
.status i{width:8px;height:8px;border-radius:50%;background:var(--green);display:block}
/* Появление метки по подсветке строки (opacity/transform/transition и
   tr.on .tag) — эффект демо-кабинета на лендинге, а не форма примитива.
   Он остался в landing.css: примитив, невидимый по умолчанию везде, кроме
   одной страницы, не отвечает своему названию. */
.tag{display:inline-block;font-size:11.5px;font-weight:600;padding:2px 7px;border-radius:6px;background:var(--red-bg);color:var(--red);margin-left:6px;white-space:nowrap}
.kv{margin-top:12px;display:grid;grid-template-columns:1fr auto;gap:6px 12px;font-size:14px}
.kv dt{color:var(--ink-2)}
.kv dd{margin:0;text-align:right;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}

/* === Шапка (landing.css) === */
/* Шапка и подвал сайта — с главной (см. комментарий вверху файла), поэтому
   их место здесь, а не в landing.css: их видят все страницы, использующие
   includes/header.html и includes/footer.html (сейчас — главная и public/
   tool-шаблоны, скоро — весь сайт). */
.top{position:sticky;top:0;z-index:20;background:var(--card);border-bottom:1px solid var(--line);height:56px;display:flex;align-items:center;padding:0 20px;gap:16px}
/* Блокер 3 финального ревью: `.top` липнет к верху на всех страницах, а
   `scroll-margin-top` был объявлен только для главной (`.shell section`
   ниже по каскаду, в landing.css) — на «Прогнозе заявок» и в конце поста
   блога переход по `#zayavka` заводил верх формы под шапку. `:target`
   матчит сам элемент с активным якорем (форма `#zayavka` из
   includes/lead_form.html, секция `#zayavka` на главной, что угодно ещё) —
   один селектор на все страницы вместо перечисления тегов и классов.
   Число то же, что у `.shell section` — конфликта нет, оба правила дают
   один отступ; `.shell section` не убираем, чтобы не трогать
   протестированную вёрстку главной без необходимости. */
:target{scroll-margin-top:80px}
/* Бренд — ссылка на "/" (ревью T3, раунд 1): логотип должен вести на главную
   с любой страницы, иначе она пропадает после перевода блога/инструментов
   на общую шапку. color:inherit — иначе базовое `a{color:var(--blue)}`
   покрасило бы имя в синий, чего в разметке-доноре (div) не было. */
.brand{display:flex;align-items:center;gap:10px;font-weight:600;color:inherit}
.brand:hover{text-decoration:none}
.brand .dot{width:28px;height:28px;border-radius:50%;object-fit:cover;flex:none}
.brand small{color:var(--ink-2);font-weight:400}
.top .spacer{flex:1}
/* Ссылка на канал — блоком (.btn-ghost), как остальные элементы шапки
   (11.09.2026). До 760px прячется: с кнопкой заявки в одну строку не влезает. */
.top-nav{display:flex;gap:14px}
@media (max-width:760px){.top-nav{display:none}}
@media (max-width:980px){
  .top .chip{display:none}
  .brand{white-space:nowrap;font-size:15px}
  .brand small{font-size:12.5px}
  .brand small::after{content:"· Яндекс Директ"}
  .brand small span{display:none}
  .top{padding:0 14px;gap:10px}
  .top .btn-primary{display:none}
  .brand small{display:inline}
}

/* === Подвал (landing.css) === */
/* Подвал — полоса на всю ширину, зеркало шапки (.top): та же подложка,
   линия и высота. margin-top:auto в flex-колонке body прижимает его к низу
   окна, когда содержимого меньше экрана; на длинной странице он просто
   идёт после содержимого. Отступ содержимого от подвала — забота страницы
   (.section, .shell), не подвала. */
.foot{margin-top:auto;background:var(--card);border-top:1px solid var(--line);min-height:56px;padding:12px 20px;color:var(--ink-3);font-size:13px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 24px}

/* === Поля формы (public.css, токены главной) === */
.lead-form{display:grid;gap:16px;max-width:520px}
.lead-form__row{display:grid;gap:6px}
.lead-form__row label{font-weight:600}
.lead-form input,.lead-form textarea{font:inherit;padding:12px 14px;border:1px solid var(--line);border-radius:6px;background:#fff;color:var(--ink)}
/* Обводка полей совпадает с общим :focus-visible (3px + жёлтый ореол);
   border-color добавлен поверх, потому что общее правило не трогает цвет
   рамки — без него в фокусе рамка поля осталась бы блёкло-серой на фоне
   яркой обводки. Конфликта между правилами нет. */
.lead-form input:focus-visible,.lead-form textarea:focus-visible{outline:3px solid var(--ink);outline-offset:2px;box-shadow:0 0 0 6px var(--yellow);border-color:var(--ink)}
.lead-form textarea{min-height:96px;resize:vertical}
.lead-form__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.lead-form__note{color:var(--ink-2);font-size:.9rem;margin:0}
.lead-form__consent{display:flex;gap:10px;align-items:flex-start;color:var(--ink-2);font-size:.9rem;font-weight:400;cursor:pointer}
.lead-form__consent input{margin:3px 0 0;width:18px;height:18px;flex:none;padding:0;accent-color:var(--yellow-deep)}
.lead-form__consent a{color:inherit;text-decoration:underline}
.cookie-bar{position:fixed;left:0;right:0;bottom:0;z-index:50;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px 16px;padding:12px 20px;background:var(--card);border-top:1px solid var(--line);color:var(--ink-2);font-size:14px}
.cookie-bar a{color:var(--ink);text-decoration:underline}
.cookie-bar[hidden]{display:none}
/* Пока полоса открыта, страница получает отступ снизу на её высоту (--cookie-bar-h ставит goals.js),
   чтобы полоса не накрывала подвал. */
.cookie-bar-open body{padding-bottom:var(--cookie-bar-h,0)}
.errorlist{color:#B42318;margin:0;padding:0;list-style:none;font-size:.9rem}

/* === Длинный текст (public.css) === */
/* D2-M6: прокрутка по горизонтали остаётся только у того, что её требует
   (код и таблицы), не у всего блока текста — иначе обводка фокуса у ссылок
   слева обрезалась бы контейнером. */
/* D3-I2: длинное неразрывное слово (URL с utm-метками — обычное дело в
   разборе кампании) без переноса раздвигало весь документ вбок — предки
   `.prose` больше не прокручиваются сами (см. правку выше). `anywhere`,
   а не `break-word`: последний не влияет на расчёт минимальной ширины и в
   grid/flex контейнерах спасает не всегда; `word-break` оставлен для
   старых браузеров без поддержки `overflow-wrap: anywhere`. */
/* Размер задан явно в пикселях, а не в rem: на корне лендинга (16px) то же
   `1.05rem`, что в public.css (корень 17px) давало почти 18px, дало бы
   16.8px — текст блога незаметно уменьшился бы. Ширину строки держит
   max-width от токена --measure, а не корневой шрифт. */
.prose{font-size:17px;max-width:var(--measure);overflow-wrap:anywhere;word-break:break-word}
/* Канон главной обнуляет отступы p/h1-h3 и подчёркивание ссылок — там
   вёрстка расставляет отступы точечно внутри каждого компонента. Длинный
   текст так не работает: без своих отступов абзацы и заголовки блога
   слипаются в простыню, а ссылки внутри текста неотличимы от обычных слов.
   `.prose` — единственное место, где канон намеренно переопределяется;
   не удалять как «дубль» базовых правил. */
.prose p{margin:0 0 1em}
.prose h1,.prose h2,.prose h3{margin:0 0 .5em}
.prose a{text-decoration:underline}
.prose h2{margin-top:1.6em}
.prose h3{font-size:1.2rem;margin-top:1.4em}
.prose img{max-width:100%;height:auto;border-radius:8px}
.prose blockquote{border-left:3px solid var(--yellow);margin:1.2em 0;padding:4px 0 4px 18px;color:var(--ink)}
.prose pre{background:#fff;border:1px solid var(--line);border-radius:8px;padding:14px;overflow-x:auto;font-size:.9rem}
.prose code{font-family:var(--mono);font-size:.92em}
/* D2-M6, дожим ревью: прокрутка на обёртке `.table-wrap` (`_wrap_tables` в
   apps/blog/markdown.py), не на самом `<table>` через display:block — тот
   в части браузеров/скринридеров убирает таблицу из дерева доступности. */
.prose .table-wrap{overflow-x:auto;margin:1.2em 0}
.prose .table-wrap table{border-collapse:collapse;margin:0;max-width:100%}
/* D3-I1: страховка для постов, сохранённых до перерисовки (`body_html` —
   кеш времени записи), и для сырого `<table>` из HTML в теле поста, который
   `_wrap_tables` не оборачивает (парковка D2-M3/D2-M4). Обёрнутые таблицы
   лежат внутри `.table-wrap`, к ним селектор `>` не применяется. */
.prose>table{display:block;overflow-x:auto;max-width:100%}
.prose th,.prose td{border:1px solid var(--line);padding:8px 10px;text-align:left}
.prose th{background:#fff}
.prose hr{border:0;border-top:1px solid var(--line);margin:2em 0}

/* === Чек-листы (tools.css, токены главной) === */
.checklist{margin:1.5rem 0 0;padding:0}
.check{display:flex;gap:1rem;align-items:flex-start;padding:.75rem 0 .75rem 1rem;border-left:4px solid var(--line);border-bottom:1px solid var(--line)}
.check-status{flex:0 0 6.5rem;font-weight:600;font-size:.9rem;padding-top:.1rem}
.check-title{font-weight:600}
.check-ok{border-left-color:var(--blue)}
.check-warn{border-left-color:var(--yellow)}
.check-fail{border-left-color:#B42318}
.check-fail .check-status{color:#B42318}
.check-info,.check-unknown{border-left-color:var(--line)}
.check-info .check-status,.check-unknown .check-status{color:var(--ink-2)}
@media (max-width:575.98px){
  .check{flex-direction:column;gap:.25rem}
  .check-status{flex-basis:auto}
}
