@charset "UTF-8";
/* ============================================================================
   promo.html — стили промо-страницы (17.09.2026, редакция «интерактив»).

   Откуда взято:
     * цвета, отступы, радиусы, тени, кегли, тап-таргеты — только из
       tokens.css (брендбук v1.0). Своих hex-значений здесь нет ни одного:
       искать цвет в этом файле бессмысленно, он всегда var(--...).
     * правила брендбука: бирюза #0EA5A0 только заливками и графикой, текст и
       кнопки — brand-700; тап-таргет не меньше 44px; статус всегда подписан
       словом, а не цветом; карточки в потоке разделяются границей, а не тенью
       (§7.3).

   ОДИН ЗАЛИТЫЙ PRIMARY НА ЭКРАН (§3.7). Залитые кнопки стоят в трёх местах:
   первый экран, результат калькулятора, отправка формы. Это три РАЗНЫХ
   экрана. Исключение одно и оно управляемое: панель выбранной задачи
   разворачивается прямо под кнопкой первого экрана, и пока она открыта,
   кнопка первого экрана гасится в контурную (класс .btn-quiet, его ставит
   скрипт страницы). Двух залитых кнопок рядом не бывает ни в одном состоянии.

   ЧЕМ НА ЭТОЙ СТРАНИЦЕ ЯВЛЯЕТСЯ --color-brand-500 (#0EA5A0) - ОТВЕТ:
   ЗАЛИВКОЙ, И НИЧЕМ БОЛЬШЕ. Брендбук §3.4 отдаёт бирюзу заливкам и графике,
   а текст и кнопки - brand-700. Здесь ни одного сплошного бирюзового пятна нет:
   заливка главной кнопки это brand-700 (её назначение прямо записано в
   tokens.css), наведение и нажатие - brand-800/900, акценты на тёмном -
   brand-400 (его же отдаёт тёмная тема для фокусного кольца). Поэтому
   brand-500 на этой странице не используется НИ РАЗУ, и это решение, а не
   забытая строка: первое же сплошное бирюзовое пятно на светлом фоне
   (плашка, диаграмма, залитый бейдж) берётся отсюда, а не из brand-700,
   которым набраны подписи.

   ПОЧЕМУ СВОЙ ФАЙЛ, А НЕ content.css. Страница живёт на отдельном поддомене и
   продаёт услугу человека, а не сервис: у неё свой первый экран, свой подвал и
   своя форма. Общий content.css тянет за собой каркас сайта lis post, который
   здесь не нужен. Общими остаются tokens.css (токены) и cookie_banner.css
   (общий баннер cookie) — их подключает сама страница.

   ШРИФТЫ: @font-face ниже ПЕРЕОБЪЯВЛЕНЫ относительным путём ("fonts/...").
   Причина ровно одна: tokens.css объявляет те же гарнитуры абсолютным путём
   ("/static/fonts/..."), и при открытии файла прямо с диска (file://) шрифты
   не находились бы, и страница показалась бы системным Segoe UI. Объявление
   идёт ПОСЛЕ tokens.css, поэтому выигрывает оно; относительный путь работает и
   с диска, и с сервера (при отдаче страницы каталог /fonts/ отдаёт корневой
   StaticFiles приложения). Файлы шрифтов те же самые, лицензии OFL лежат рядом
   с ними (static/fonts/LICENSE-*.txt) — требование лицензии выполнено.
   Семья 'RubSymbol' (знак ₽) переобъявлена НИЖЕ и по той же самой причине:
   в tokens.css она объявлена только абсолютным путём, и при открытии с диска
   её запросы уходили в никуда (замер: два FAILED на file:///E:/static/fonts/).
   ========================================================================= */

@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/inter-cyrillic-400-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/inter-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/inter-cyrillic-500-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/inter-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/inter-cyrillic-600-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/inter-latin-600-normal.woff2') format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/inter-cyrillic-700-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/inter-latin-700-normal.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/jetbrains-mono-cyrillic-400-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/jetbrains-mono-cyrillic-500-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/jetbrains-mono-cyrillic-600-normal.woff2') format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/jetbrains-mono-latin-600-normal.woff2') format('woff2')}

/* ЗНАК РУБЛЯ (U+20BD) — семья 'RubSymbol'. Ровно та же причина, что у гарнитур
   выше: tokens.css объявляет её абсолютным путём ("/static/fonts/rub-*.woff2"),
   и при открытии страницы с диска (file://) браузер шлёт два запроса в никуда —
   за ₽400 и ₽600 (замер: FAILED file:///E:/static/fonts/rub-400-normal.woff2 и
   .../rub-600-normal.woff2). Файлы лежат рядом со страницей, поэтому путь
   относительный, как у Inter и JetBrains Mono выше: работает и с диска, и с
   сервера. Объявление идёт ПОСЛЕ tokens.css, поэтому выигрывает оно, а
   unicode-range U+20BD оставляет весь остальной текст остальным семьям.
   Начертание самого знака от этого меняется на канон брендбука §4.7 (полный
   JetBrains Mono), то есть ровно на то, что отдаёт сервер. */
@font-face{font-family:'RubSymbol';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/rub-400-normal.woff2') format('woff2');unicode-range:U+20BD}
@font-face{font-family:'RubSymbol';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/rub-500-normal.woff2') format('woff2');unicode-range:U+20BD}
@font-face{font-family:'RubSymbol';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/rub-600-normal.woff2') format('woff2');unicode-range:U+20BD}
@font-face{font-family:'RubSymbol';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/rub-700-normal.woff2') format('woff2');unicode-range:U+20BD}

/* ---------------------------------------------------------------------------
   Основа
   --------------------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
/* ЦЕНА ЧЕСТНОСТИ ЧИТАЕТСЯ КАК ОБЫЧНЫЙ ТЕКСТ. Семь оговорок — те самые, ради
   которых страница и написана честно, — были набраны самым мелким кеглем
   страницы (--text-sm, 13px, интерлиньяж 20.8) и читались хуже всего
   остального текста. Подняты до кегля основного текста (--text-body, 15px,
   интерлиньяж 24): .hero-honest и .hero-note (первый экран), .price-note
   (оговорка под ценами), .ask5-sub, .form-promise (обещание в форме),
   .foot-line (подвал), .caveats-sub («Чего калькулятор не учитывает»).
   Список закрытый: остальные правила по-прежнему берут --text-sm, и это
   осознанно — подписи и ремарки не несут обещаний. */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--color-bg);color:var(--color-text);
  font-family:var(--font-sans);font-size:var(--text-body-lg);line-height:var(--leading-body)}
img,svg{max-width:100%}
h1,h2,h3,h4{margin:0;font-weight:700;line-height:var(--leading-heading);letter-spacing:var(--tracking-heading)}
p{margin:0}
ul,ol{margin:0;padding:0}
ul{list-style:none}
a{color:var(--color-text-link)}
/* ВИДИМЫЙ ФОКУС. Кольцо рисует tokens.css (`:focus-visible{outline:none;
   box-shadow:var(--focus-ring-strong)}`), и здесь ОБВОДКА НЕ ЗАДАЁТСЯ:
   правило из этого файла стоит ниже по порядку и при равной специфичности
   побеждает, поэтому кольца рисовались ДВА - своё светлое из tokens.css и
   тёмная обводка отсюда (замер: outline 2px + box-shadow 2px). Остаётся одно
   кольцо, а форма угла берётся отсюда.
   САМО КОЛЬЦО НА ТЁМНОМ СВЕТЛОЕ ТОЛЬКО ТАМ, ГДЕ СЕКЦИЯ ОБЪЯВИЛА СЕБЯ ТЁМНОЙ:
   brand-700 на навy даёт 3.36:1, а на залитой кнопке того же цвета - 1:1.
   Поэтому у .hero и .foot стоит data-theme="dark". */
a:focus-visible,button:focus-visible,summary:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible{border-radius:var(--radius-xs)}

.wrap{width:100%;max-width:var(--container);margin:0 auto;padding:0 var(--space-4)}
.wrap-narrow{max-width:var(--container-narrow)}
/* Иконки Lucide (брендбук §6.3): контур, без заливки, обводка наследует цвет
   текста. Толщина 2 при 24px и 2.5 при 20px и меньше — иначе тонко. */
.ic,.ic-24{fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;vertical-align:middle}
.ic{width:20px;height:20px;flex:0 0 auto;color:currentColor}
.ic-24{width:24px;height:24px;flex:0 0 auto}

/* Секции: ритм из шкалы — 48px на мобильном, 64px на десктопе */
.sect{padding:var(--space-12) 0}
.sect-alt{background:var(--color-bg-subtle);border-block:1px solid var(--color-border)}
.sect-head{max-width:var(--container-narrow);margin:0 0 var(--space-8)}
.sect-h{font-size:var(--text-h2)}
.sect-sub{margin-top:var(--space-3);color:var(--color-text-secondary)}

/* ---------------------------------------------------------------------------
   Кнопки (§8.1). Высота 48px: минимум для тапа 44px.
   --------------------------------------------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  min-height:48px;padding:0 var(--space-5);border:1px solid transparent;border-radius:var(--radius-md);
  font-family:inherit;font-size:var(--text-body);font-weight:600;text-decoration:none;
  cursor:pointer;transition:background-color var(--transition-color),color var(--transition-color),border-color var(--transition-color)}
.btn-primary{background:var(--color-brand-700);color:var(--color-text-on-brand)}
.btn-primary:hover{background:var(--color-brand-800)}
.btn-primary:active{background:var(--color-brand-900)}
.btn-ghost{background:transparent;color:var(--color-brand-700);border-color:var(--color-brand-200)}
.btn-ghost:hover{background:var(--color-brand-50);color:var(--color-brand-800);border-color:var(--color-brand-300)}
/* Тихое состояние главной кнопки первого экрана: включается, пока открыта
   панель задачи, чтобы на экране не оказалось двух залитых кнопок. */
.btn-quiet{background:transparent;color:var(--color-brand-700);border-color:var(--color-brand-200)}
.btn-quiet:hover{background:var(--color-brand-50);color:var(--color-brand-800);border-color:var(--color-brand-300)}
.btn[disabled],.btn[aria-disabled="true"]{background:var(--color-gray-100);color:var(--color-gray-500);cursor:not-allowed}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}html{scroll-behavior:auto}}

/* ---------------------------------------------------------------------------
   Шапка страницы: знак слева, меню по разделам, кнопка справа
   --------------------------------------------------------------------------- */
/* Владелец: «вверху должно быть меню, и знак должен быть там, где ему положено
   быть». До этого знак стоял в ПРАВОЙ колонке первого экрана, рядом с оффером,
   и страница читалась как резюме с фотографией. Первый экран стал
   одноколоночным, знак переехал в шапку.

   Почему база — узкая шапка. Полное меню из пяти пунктов плюс кнопка
   занимает около 850px: на планшете (768) оно не поместилось бы и полезло бы
   под знак. Поэтому до 1024 в шапке знак и кнопка-раскрывашка, а меню живёт в
   панели под шапкой; с 1024 панель становится обычной строкой меню.

   Кнопка шапки КОНТУРНАЯ. На первом экране залитая кнопка уже есть (главное
   действие экрана), а брендбук разрешает одну заливку на экран (§3.7). */
.topbar{position:sticky;top:0;z-index:var(--z-sticky);background:var(--color-bg);
  border-bottom:1px solid var(--color-border)}
.topbar-in{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) 0}
/* ЗНАК И НАЗВАНИЕ - ОДНА ССЫЛКА. Схема взята с lis post (.brand): знак слева,
   справа от него название. Слоган стоит рядом со ссылкой (см. .tb-lockup), а не
   внутри неё: пояснение не должно быть кликабельным и не должно подчёркиваться.
   Высота знака живёт в переменной --tb-logo-h: от неё же считается отступ
   слогана, чтобы слоган встал ровно под названием, а не под знаком. */
.tb-lockup{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;
  --tb-logo-h:36px;--tb-logo-gap:var(--space-2)}
.tb-brand{display:inline-flex;align-items:center;gap:var(--tb-logo-gap);
  min-height:var(--tap-target-min);flex-shrink:0;text-decoration:none}
/* Знак lis lab в шапке - ИКОНОЧНАЯ версия файла (lis-lab-icon.svg), а не
   основной знак. Брендбук §5.7 запрещает основной знак ниже 48 px: на мелком
   кегле он рассыпается на два пятна. Для интерфейса ниже 48 px у знака есть
   иконочная версия (её полоса 16-47 px), и здесь берётся именно она.
   Высота 36 px на телефоне и 40 px с 1024 (см. медиазапрос ниже): 40 px -
   верхняя часть полосы иконочной версии, знак читается чисто. Потолок ширины
   остался от прежней редакции и ничего не ломает: иконочная версия квадратная. */
.tb-logo{display:block;height:var(--tb-logo-h);width:auto;max-width:200px}
.tb-burger{display:inline-flex;align-items:center;justify-content:center;
  width:var(--tap-target-min);height:var(--tap-target-min);margin-left:auto;padding:0;
  background:none;border:1px solid var(--color-border-strong);border-radius:var(--radius-sm);
  color:var(--color-text);cursor:pointer;flex-shrink:0}
.tb-burger .ic{stroke-width:2.5}
.tb-burger:hover{border-color:var(--color-brand-700);color:var(--color-brand-700)}
/* Раскрывашка. Лежит ПОД шапкой, а не поверх неё: открытая панель не
   перекрывает знак и кнопку, а контент страницы уходит вниз по клику на пункт. */
.tb-menu{display:none;position:absolute;top:100%;left:var(--space-4);right:var(--space-4);
  flex-direction:column;align-items:stretch;gap:var(--space-1);padding:var(--space-2);
  background:var(--color-bg);border:1px solid var(--color-border);
  border-radius:var(--radius-md);box-shadow:var(--shadow-md);z-index:var(--z-dropdown)}
.tb-menu.open{display:flex}
.tb-nav{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-1)}
.tb-link{display:inline-flex;align-items:center;min-height:var(--tap-target-min);
  padding:var(--space-3) var(--space-4);border-radius:var(--radius-sm);
  color:var(--color-text);font-size:var(--text-body-lg);font-weight:500;text-decoration:none}
.tb-link:hover{background:var(--color-bg-hover)}
.tb-cta{margin-top:var(--space-1);width:100%;font-size:var(--text-body)}
/* НАЗВАНИЕ И СЛОГАН. Та же схема, что на lis post: название крупно, строка-
   пояснение мелким серым под ним, обе строки справа от знака. Раньше слоган
   стоял под знаком и был набран крупнее него, поэтому блок читался разваленным.
   С 1024 строк становится две (название и слоган), до 1024 остаётся один знак:
   в узкой шапке рядом стоит кнопка меню, и место важнее подписи. */
.tb-name{display:none;font-size:var(--text-h4);font-weight:700;letter-spacing:-.3px;
  color:var(--color-text);white-space:nowrap}
.tb-slogan{display:none;margin-left:calc(var(--tb-logo-h) + var(--tb-logo-gap));
  font-size:var(--text-xs);color:var(--color-text-secondary);white-space:nowrap;
  max-width:240px;overflow:hidden;text-overflow:ellipsis}
/* ТЕЛЕФОН В ШАПКЕ. Один контактный элемент рядом с кнопкой: цифрами, а не
   словом «ТЕЛЕФОН» (разбор 11 площадок: цифрами номер показан у семи из
   одиннадцати, капс-ярлыка нет ни у одной). Тап-таргет 44 px, как у пунктов
   меню. Пока номера нет, элемент скрыт атрибутом hidden и в шапке стоят
   только меню и кнопка. */
.tb-phone{display:inline-flex;align-items:center;gap:var(--space-2);
  min-height:var(--tap-target-min);padding:var(--space-3) var(--space-4);
  border-radius:var(--radius-sm);color:var(--color-text);font-size:var(--text-body-lg);
  font-weight:500;text-decoration:none;white-space:nowrap}
.tb-phone:hover{background:var(--color-bg-hover)}
.tb-phone .ic{color:var(--color-gray-500)}
.tb-phone:hover .ic{color:var(--color-brand-700)}
/* Переход по пункту меню не заводит заголовок под залипшую шапку. */
section[id]{scroll-margin-top:var(--space-20)}

/* ---------------------------------------------------------------------------
   1. Первый экран: оффер и выбор задачи
   --------------------------------------------------------------------------- */
/* Первый экран — СПЛОШНАЯ тёмная поверхность. Процентная заливка градиента
   («тёмное до 62% высоты») держалась ровно до первой правки текста: блок
   подрос, светлая половина началась посреди подсказок, и бирюзовые строки
   оказались бирюзовыми по белому. Полоса с тремя строками вынесена в свою
   секцию (.facts-band), поэтому тёмное кончается там, где кончается текст. */
.hero{padding:var(--space-12) 0 var(--space-16);
  background:var(--color-navy-900)}
/* Цвет задаётся НА СЕКЦИИ и наследуется. Перечислять здесь p и span нельзя:
   такое правило бьёт по вложенным элементам сильнее, чем собственные классы
   подсказок (.hero-honest, .tp-head), и они теряют свой цвет. */
.hero{color:var(--color-navy-text)}
/* Поправка к тёмной теме. Вместе с data-theme="dark" приходит не только
   светлое фокусное кольцо, но и токен --color-text-on-brand: в тёмной теме он
   тёмный (подпись для СВЕТЛОЙ заливки). Заливка главной кнопки на этой
   странице тёмная (brand-700), поэтому подпись на ней обязана остаться белой,
   и здесь токен возвращается к своему светлому значению. Без этой строки текст
   на залитой кнопке первого экрана и в подвале стал бы тёмным по тёмному. */
.hero,.foot,.midcta{--color-text-on-brand:var(--color-gray-0)}
/* Первый экран ОДНОКОЛОНОЧНЫЙ. Раньше на 1024 и шире здесь стояла раскладка
   «текст 1.55fr + знак 1fr», и знак оказывался справа от оффера. Правой
   колонки больше нет вовсе: знак ушёл в шапку.

   ЧТО ИЗМЕНИЛОСЬ 17.09. Пока знак стоял в правой колонке, текст был ограничен
   820px - и это было оправдано: место справа занимал знак. После переезда
   знака в шапку ширина 820px осталась, а заполнять её стало нечем: контейнер
   на десктопе 1160px, и правые 340px первого экрана стояли пустыми на всю его
   высоту. Жалоба владельца была именно про это: «куча свободного места».
   Теперь текстовая колонка занимает контейнер целиком, а её содержимое
   разложено построчно (.hero-in, ниже), поэтому пустой половины нет ни на одной
   высоте. Левая граница текста по-прежнему на одной вертикали с остальными
   разделами страницы (.wrap), и ни один элемент разметки не переставлен. */
.hero-grid{display:grid;gap:var(--space-10);align-items:start}
.hero-grid>div{max-width:820px}
.hero-h1{font-size:clamp(1.75rem,1.15rem + 2.6vw,var(--text-display));letter-spacing:var(--tracking-display);color:var(--color-navy-text);text-wrap:balance}
.hero-lead{margin-top:var(--space-5);color:var(--color-navy-muted);max-width:62ch}
.hero-ask{margin-top:var(--space-8);font-weight:600;font-size:var(--text-h4);color:var(--color-navy-text)}

/* Чипы задач. Это кнопки, а не ссылки: клик ничего не открывает, он
   разворачивает панель ниже и переносит задачу в заявку. */
.chips-grid{margin-top:var(--space-4);display:flex;flex-wrap:wrap;gap:var(--space-2)}
.chipbtn{display:inline-flex;align-items:center;min-height:44px;padding:0 var(--space-4);
  background:var(--color-navy-800);color:var(--color-navy-text);
  border:1px solid var(--color-navy-line-2);border-radius:var(--radius-full);
  font-family:inherit;font-size:var(--text-body);text-align:left;cursor:pointer;
  transition:background-color var(--transition-color),border-color var(--transition-color),color var(--transition-color)}
.chipbtn:hover{border-color:var(--color-brand-400);color:var(--color-brand-300)}
.chipbtn[aria-pressed="true"]{background:var(--color-brand-400);border-color:var(--color-brand-400);color:var(--color-navy-900);font-weight:600}
.chipbtn[aria-pressed="true"]:hover{color:var(--color-navy-900)}

/* Панель выбранной задачи. Разворачивается там же, где чипы: человек не
   ищет форму по странице. Внутри ЧЕРНОВИК (в форму ничего не отправляется),
   поэтому ни согласия, ни кнопки «отправить» здесь нет. */
.task-panel{margin-top:var(--space-5);padding:var(--space-5);border-radius:var(--radius-lg);
  background:var(--color-navy-800);border:1px solid var(--color-brand-600)}
.tp-head{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);
  font-weight:600;letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--color-brand-300)}
.tp-task{margin-top:var(--space-3);font-size:var(--text-h4);font-weight:600;color:var(--color-navy-text)}
.tp-lbl{display:block;margin-top:var(--space-4);font-size:var(--text-sm);color:var(--color-navy-muted)}
.tp-draft{margin-top:var(--space-2);width:100%;min-height:88px;padding:var(--space-3);
  font-family:inherit;font-size:var(--text-body);line-height:var(--leading-body);
  color:var(--color-text);background:var(--color-bg-raised);border:1px solid var(--color-border-strong);
  border-radius:var(--radius-sm);resize:vertical}
.tp-actions{margin-top:var(--space-4);display:flex;flex-wrap:wrap;gap:var(--space-3)}
/* На тёмной панели контурная кнопка должна быть светлой: brand-700 на навy
   даёт слишком мало контраста. */
.task-panel .btn-ghost{color:var(--color-navy-text);border-color:var(--color-navy-line-2)}
.task-panel .btn-ghost:hover{background:var(--color-navy-700);color:var(--color-navy-text);border-color:var(--color-brand-400)}

/* КНОПКИ НА ТЕЛЕФОНЕ ВО ВСЮ ШИРИНУ. Первый экран стал короче (чипы и оговорки
   уехали вниз), и замер заполнения по полосам показал: последние три полосы
   экрана были свободны справа на 45% - под кнопками, каждая из которых шире
   половины строки не становится. Растянутые кнопки закрывают эти полосы
   целиком, а на телефоне это ещё и привычнее: главное действие экрана на всю
   ширину, палец попадает без прицела. С 768 кнопки снова в строку, с 1024
   раскладку задаёт первый экран. */
.hero-cta{margin-top:var(--space-6);display:flex;flex-direction:column;
  align-items:stretch;gap:var(--space-3)}
.hero-cta .btn-ghost{color:var(--color-navy-text);border-color:var(--color-navy-line-2)}
.hero-cta .btn-ghost:hover{background:var(--color-navy-800);color:var(--color-brand-300);border-color:var(--color-brand-400)}
.hero-honest{margin-top:var(--space-4);display:flex;gap:var(--space-2);font-size:var(--text-body);
  color:var(--color-brand-300);max-width:62ch}
.hero-note{margin-top:var(--space-3);font-size:var(--text-body);color:var(--color-navy-muted);max-width:62ch}

/* Раскладка первого экрана на десктопе: одна колонка контейнера, внутри неё
    раскладка. Заголовок, вопрос и чипы идут во всю ширину, остальное - в две
   колонки. Порядок элементов в разметке НЕ менялся ни на одном: места в раскладке
    заданы явно, поэтому правка текста из админки ничего не сдвигает и в
   освободившуюся строку ничего не уезжает. На телефоне и планшете колонок нет:
   там та же разметка идёт в один столбец, как и раньше. */
@media (min-width:1024px){
  .hero-grid>div{max-width:none}
  /* row-gap 20px вместо 24: оговорки выросли до 15px, первый экран стал выше и
     внизу слева оголилась пустота. Заполнение первого экрана текстом поднято с
     42,9% до 50,2% (порог 45) именно этим шагом вместе с обменом колонок ниже.
     grid-auto-flow:dense нужен ровно для этого обмена: обе оговорки расставлены
     по колонкам явно, а строку им выбирает раскладка. Без dense она ставит их
     друг под друга (курсор не возвращается назад), и пустое место возвращается
     с другой стороны. */
  .hero-in{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);
    column-gap:var(--space-16);row-gap:var(--space-5);align-items:start;
    grid-auto-flow:dense}
  .hero-in>*{margin-top:0}
  /* Место в раскладке задано ЯВНО, потому что порядок в разметке другой: панель
     задачи стоит между чипами и кнопками (так человек не ищет форму по
     странице), а кнопки на десктопе уходят в правую колонку, к подзаголовку.
     Автоматическая расстановка поставила бы кнопки ПОД чипы, в пустую строку
     во всю ширину, - то есть вернула бы ту самую пустую полосу.
     Панель задачи идёт последней и позиции не имеет: она встаёт в первую
     свободную строку. Пока панель скрыта (по умолчанию), строки под неё нет
     вовсе, и лишнего зазора между чипами и мелкой строкой не появляется. */
  .hero-in>.hero-h1{grid-column:1/-1;grid-row:1}
  /* Подзаголовок шире 62ch на десктопе: колонка под него отдана широкая, и
     при 62ch справа от него оставалась бы пустая полоса - ровно то, на что
     была жалоба. 72ch по-прежнему внутри читаемого диапазона (45-75). */
  .hero-in>.hero-lead{grid-column:1;grid-row:2;max-width:72ch}
  /* Кнопки встают справа от подзаголовка и растянуты по своей колонке: две
     кнопки друг под другом занимают её целиком, поэтому рядом с подзаголовком
     не остаётся пустого места на всю его высоту.
     19.09 чипы, панель задачи и две оговорки уехали из первого экрана в
     отдельный блок ниже (решение владельца: «они душат оффер»), поэтому мест
      в раскладке стало три: заголовок, подзаголовок и кнопки. Правила для уехавших
     элементов убраны вместе с ними: держать в файле селекторы, которым нечего
     выбирать, значит показывать следующему читателю несуществующую вёрстку. */
  .hero-in>.hero-cta{grid-column:2;grid-row:2;align-self:start;
    flex-direction:column;align-items:stretch}
}

/* ---------------------------------------------------------------------------
   2. Цифры о себе
   --------------------------------------------------------------------------- */
/* Строка цифр идёт сразу под первым экраном: разбор 14 площадок показал, что
   такая строка есть у девяти из них и почти всегда стоит вторым-третьим
   блоком. Человек, впервые попавший на страницу, первым делом хочет понять,
   с кем он разговаривает.
   Числа набраны моноширинным (как .f3-v и .res-v на этой же странице): это
   значения, а не текст, и они не должны ехать при правке цифры владельцем.
   Заглушка ЦИФРА набрана тем же кеглем и цветом, что настоящее число: место
   под цифру видно заранее, и подстановка ничего не сдвинет.
   ПОКА ЦИФР НЕТ, СТРОКИ НЕ ВИДНО ВООБЩЕ: каждый <li> в разметке помечен
   hidden, а скрипт страницы снимает его, когда из админки приедет число.
   Скрыты все три - секция не должна занимать место пустой полосой с
   отступами (это читается как сбой вёрстки), и правило ниже убирает её само.
   Тот же приём, что у .foot-group в подвале. */
.stats-band:not(:has(li:not([hidden]))){display:none}
.stats3{display:grid;gap:var(--space-4)}
.stat-v{display:block;font-family:var(--font-mono);font-weight:600;
  font-size:var(--text-h2);color:var(--color-brand-700);
  font-variant-numeric:tabular-nums}
.stat-t{margin-top:var(--space-1);display:block;font-size:var(--text-body);
  color:var(--color-text-secondary)}

/* ---------------------------------------------------------------------------
   3. Чипы боли и две оговорки
   --------------------------------------------------------------------------- */
/* Блок переехал с тёмного первого экрана (решение владельца 19.09: «чипы
   душат оффер»). Разметка внутри не тронута ни на знак, поэтому классы у
   элементов прежние (.chipbtn, .task-panel, .hero-honest, .hero-note), а
   цвета тёмной темы на светлом фоне не читались бы: чипы стали бы стеной
   тёмных пилюль, подсказка про ИИ - почти невидимой (brand-300 по белому).
   Здесь только ЦВЕТА, и все они из tokens.css. */
/* Вопрос над чипами был набран цветом тёмной темы (--color-navy-text, почти
   белый): на белом фоне он читался как призрак - проверено снимком. Здесь он
   берёт обычный цвет текста. */
.pains .hero-ask{color:var(--color-text)}
.pains .chipbtn{background:var(--color-bg-raised);color:var(--color-text);
  border-color:var(--color-border-strong)}
.pains .chipbtn:hover{border-color:var(--color-brand-700);color:var(--color-brand-700)}
.pains .chipbtn[aria-pressed="true"]{background:var(--color-brand-50);
  border-color:var(--color-brand-300);color:var(--color-brand-800);font-weight:600}
.pains .chipbtn[aria-pressed="true"]:hover{color:var(--color-brand-800)}
.pains .task-panel{background:var(--color-bg-subtle);border-color:var(--color-border-strong)}
.pains .tp-head{color:var(--color-brand-700)}
.pains .tp-task{color:var(--color-text)}
.pains .tp-lbl{color:var(--color-text-secondary)}
.pains .task-panel .btn-ghost{color:var(--color-brand-700);
  border-color:var(--color-brand-200)}
.pains .task-panel .btn-ghost:hover{background:var(--color-brand-50);
  color:var(--color-brand-800);border-color:var(--color-brand-300)}
/* Две оговорки закрывают блок: короткая про ИИ и длинная про срок ответа.
   На тёмном фоне они были разного цвета, здесь различие осталось, но
   контрастным: бирюза текстом (brand-700) и серый пояснительный. */
.pains .hero-honest{color:var(--color-brand-700)}
.pains .hero-note{color:var(--color-text-secondary)}
.pains .chips-grid{margin-top:var(--space-5)}

/* ---------------------------------------------------------------------------
   4. Кому подхожу и кому не подхожу
   --------------------------------------------------------------------------- */
/* Блок есть у zinin-shturbin, Verano и Fernside: он экономит разговор обеим
   сторонам. Две колонки - два ответа, а не «плюсы и минусы»: слева то, с чем
   работа идёт, справа прямой отказ. Заголовок каждой колонки подписан словом
   и знаком (галочка и крест), поэтому цвет нигде не единственный носитель
   смысла. */
.fit-grid{display:grid;gap:var(--space-5)}
.fit-col{padding:var(--space-5);background:var(--color-bg-raised);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-lg)}
.fit-ch{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-h4)}
.fit-ch .ic{flex:0 0 auto;color:var(--color-text-secondary)}
.fit-list{margin-top:var(--space-4);display:grid;gap:var(--space-3)}
.fit-list li{display:flex;gap:var(--space-3);font-size:var(--text-body);
  color:var(--color-text-secondary)}
.fit-list li::before{content:"";flex:0 0 auto;width:6px;height:6px;margin-top:9px;
  border-radius:var(--radius-full);background:var(--color-gray-400)}
.fit-yes li::before{background:var(--color-brand-700)}

/* Полоса под первым экраном: «как было и как стало». Светлая. Цены здесь нет:
   суммы на странице не показываются ни цифрой, ни вилкой - только условие
   «фиксируется в договоре». Значения набраны mono: это цифры, а не текст.
   Три условия («на каких условиях») из полосы уехали отдельным разделом ниже,
   к вилке по работам: обещания без цены не читаются, а цена стоит выше. */
.facts-band{padding:var(--space-8) 0 var(--space-10);background:var(--color-bg);
  border-bottom:1px solid var(--color-border)}
.facts3{display:grid;gap:var(--space-3)}
.facts3 li{display:grid;gap:var(--space-1);padding:var(--space-4);
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong);border-radius:var(--radius-md)}
.f3-v{font-family:var(--font-mono);font-weight:600;font-size:var(--text-h4);color:var(--color-brand-700)}
.f3-t{font-size:var(--text-sm);color:var(--color-text-secondary)}
/* 05.10.2026. Списки .facts3 в разделе про сайты («На какой системе делать сайт»,
   «Сайты, которые я делал»). Стоят в обычном разделе, а не в .cond, и своего
   верхнего отступа не имели — прилипали к абзацу-подводке. Правило узкое: только
   список, идущий сразу за подводкой. */
.price-note + .facts3{margin-top:var(--space-6)}

/* Полоса «что → было → стало». Широкая: строка идёт на всю ширину контейнера
   тремя колонками - что за процесс, как было, как стало. Стрелка между
   «было» и «стало» нарисована иконкой Lucide, а не текстом: из редактора она
   не правится и в озвучку скринридера не попадает (aria-hidden), потому что
   смысл несут сами слова.
   `white-space:nowrap` у «стало» не даёт короткому значению разорваться на
   две строки: «3 минуты» должно читаться одной строкой. */
.delta-band{padding:var(--space-10) 0 var(--space-12)}
.db-head{margin-bottom:var(--space-6)}
.db-row{display:grid;gap:var(--space-1);padding:var(--space-4) 0;
  border-top:1px solid var(--color-border)}
.db-row:last-child{border-bottom:1px solid var(--color-border)}
.db-w{font-weight:600}
/* На телефоне «было» и «стало» стоят в две строки, а стрелка открывает
   вторую: «полтора часа вручную» над «→ 3 минуты». Переносом по ширине
   (flex-wrap) стрелка осталась бы висеть в конце первой строки, а значение
   уезжало бы на следующую - у каждой строки по-разному. Здесь это раскладка, и
   вид одинаков во всех четырёх строках. */
.db-pair{display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:var(--space-2);row-gap:var(--space-1);align-items:baseline}
.db-was{grid-column:1/-1;color:var(--color-text-secondary)}
.db-arr{grid-row:2;grid-column:1;width:16px;height:16px;align-self:center;color:var(--color-gray-500)}
.db-now{grid-row:2;grid-column:2;justify-self:start;
  font-family:var(--font-mono);font-size:var(--text-h4);font-weight:600;
  font-variant-numeric:tabular-nums;color:var(--color-brand-700);white-space:nowrap}
/* Условия закрывают полосу снизу. Это тот же список .facts3, что раньше стоял
   отдельной секцией под первым экраном: смысл и вид не менялись, добавилась
   только отбивка с линией - иначе три карточки читались бы как продолжение
   таблицы результатов, а это другая мысль. */
.db-cond{margin-top:var(--space-10);font-size:var(--text-h4);font-weight:600}
.delta-band .facts3{margin-top:var(--space-8);padding-top:var(--space-8);
  border-top:1px solid var(--color-border)}
/* МОНОШРИФТ ТОЛЬКО ДЛЯ ЧИСЕЛ. Моноширинный набран там, где значение это
   цифра: «3 минуты», «15 минут», «40-60 минут». Слова без единой цифры
   («каждый день», «Фиксируется в договоре», «До основной работы») моноширинным
   быть не должны: это фраза, а не число, и в моно она читается как машинный
   вывод.
   Класс ставится на СТРОКУ (.db-pair и li условий), а не на само значение:
   в тех же классах .db-now и .f3-v стоят и настоящие числа, и модификатор на
   значении переключал бы правило вместе с ними. Отсюда потомок в селекторе. */
.no-mono .db-now,.no-mono .f3-v{font-family:var(--font-sans)}

/* ---------------------------------------------------------------------------
   7. На каких условиях
   --------------------------------------------------------------------------- */
/* Заголовок и три карточки переехали из полосы отдельным разделом: стоять
   рядом с вилкой по работам они обязаны потому, что это снятие возражений про
   цену, риск и срок, а возражение без цены не читается. Блоки редактора и
   разметка те же (promo_db_cond и promo_f3_*), изменилась только обёртка:
   заголовок был h4 внутри полосы, стал заголовком раздела. */
.cond .db-cond{margin-top:0;font-size:var(--text-h2)}
.cond .facts3{margin-top:var(--space-8)}

/* ---------------------------------------------------------------------------
   2. Калькулятор «сколько уходит впустую»
   --------------------------------------------------------------------------- */
.calc{display:grid;gap:var(--space-6)}
.calc-grid{display:grid;gap:var(--space-5)}
.slider{padding:var(--space-4);background:var(--color-bg-raised);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-md);display:grid;gap:var(--space-2)}
/* Поле, которого человек не касался, помечено data-set="0": в расчёт оно не
   идёт, и подсказка говорит об этом прямо. Число справа при этом пустое. */
.slider[data-set="0"]{border-style:dashed}
.sl-h{font-weight:600}
.sl-row{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap}
/* Цвет ползунка задан явно. Без этого Chrome отдаёт ползунку свой цвет
   (замер: rgb(16,16,16) - ни один токен брендбука), и он же уезжает в
   рамку дорожки: значение бралось из палитры браузера, а не из tokens.css.
   accent-color ниже остаётся: он красит заполненную часть дорожки и бегунок. */
.sl-range{flex:1 1 160px;min-width:120px;height:44px;margin:0;color:var(--color-text);
  accent-color:var(--color-brand-700);cursor:pointer}
.sl-num{width:104px;min-height:44px;padding:0 var(--space-3);font-family:var(--font-mono);
  font-size:var(--text-body);color:var(--color-text);background:var(--color-bg-input);
  border:1px solid var(--color-border-control);border-radius:var(--radius-sm);
  transition:border-color var(--transition-color),background-color var(--transition-color)}
.sl-num:hover{border-color:var(--color-gray-500)}
.sl-num:focus{border-color:var(--color-border-focus);background:var(--color-bg-raised)}
.sl-num::placeholder{font-family:var(--font-sans);color:var(--color-text-secondary)}
.sl-hint{font-size:var(--text-sm);color:var(--color-text-secondary)}

.calc-out{padding:var(--space-5);border-radius:var(--radius-lg);
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong)}
/* ПУСТОЕ СОСТОЯНИЕ НЕ ОСТАВЛЯЕТ ДЫРУ. С 768 калькулятор это две колонки:
   слева вывод, справа оговорки. Пока ползунки не тронуты, вывод это одна
   короткая плашка (замер 19.09 на 1440: 90 px против 413 px у оговорок), и
   под ней стояла пустая полоса на треть экрана - ровно то состояние, в
   которое попадает каждый первый. В пустом состоянии карточка вывода
   растягивается на высоту строки, а плашка встаёт по её середине; как только
   расчёт появился, правило перестаёт действовать само. */
.calc-out:has(> .calc-empty:not([hidden])){align-self:stretch;display:flex;
  flex-direction:column;justify-content:center}
.calc-empty{display:flex;gap:var(--space-3);align-items:flex-start;color:var(--color-text-secondary)}
.calc-empty .ic-24{color:var(--color-gray-500)}
.calc-empty-t{font-size:var(--text-body)}
/* ИТОГ ОДНОЙ ЦИФРОЙ. Раньше три равнозначных числа стояли в ряд, и глаз не
   знал, за что зацепиться. Теперь главная цифра одна и она крупнее прочих
   втрое: деньги за год. Кегль растёт вместе с экраном (clamp), но потолок -
   --text-display: крупнее заголовка страницы итог быть не должен. */
.res-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--space-3)}
.res-big{font-family:var(--font-mono);font-weight:600;
  font-size:clamp(2rem,1.35rem + 2.4vw,var(--text-display));line-height:1.05;
  color:var(--color-brand-700);font-variant-numeric:tabular-nums}
.res-big-t{font-size:var(--text-body);color:var(--color-text-secondary)}
.res-2{margin-top:var(--space-5);display:grid;gap:var(--space-4)}
.res-2 li{display:grid;gap:var(--space-1)}
.res-v{font-family:var(--font-mono);font-weight:600;font-size:var(--text-h3);color:var(--color-brand-700);
  font-variant-numeric:tabular-nums}
.res-t{font-size:var(--text-sm);color:var(--color-text-secondary)}
/* СРАВНЕНИЕ «СЕЙЧАС / ПОСЛЕ». Полоса это не украшение и не график: она
   показывает, какую часть часов снимает автоматизация, на одной шкале с тем,
   что есть сейчас. Верхняя полоса всегда во всю ширину, нижняя - доля от неё.
   Ширина нижней меняется переходом: ползунок ведут рукой, и полоса, дёргаясь
   на каждый пиксель, читалась бы как рывок. Числа при этом меняются сразу. */
.cmp{margin-top:var(--space-6);padding-top:var(--space-5);border-top:1px solid var(--color-border)}
.cmp-h{font-weight:600}
.cmp-row{display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:var(--space-1) var(--space-3);margin-top:var(--space-4)}
.cmp-l{grid-column:1;grid-row:1;font-size:var(--text-sm);color:var(--color-text-secondary)}
.cmp-v{grid-column:2;grid-row:1;justify-self:end;
  font-family:var(--font-mono);font-weight:600;font-size:var(--text-h4);
  color:var(--color-brand-700);font-variant-numeric:tabular-nums}
.cmp-track{grid-column:1/-1;grid-row:2;display:block;height:10px;
  border-radius:var(--radius-full);background:var(--color-gray-100);overflow:hidden}
.cmp-fill{display:block;height:100%;width:100%;border-radius:var(--radius-full);
  background:var(--color-gray-400);transition:width .35s ease-out}
.cmp-fill-after{background:var(--color-brand-700)}
.cmp-note{margin-top:var(--space-3);font-size:var(--text-sm);color:var(--color-text-secondary)}
/* Строка с формулой: цифру нельзя оспорить, потому что видно, откуда она. */
.formula{margin-top:var(--space-5);padding:var(--space-3);border-radius:var(--radius-sm);
  background:var(--color-gray-50);border:1px solid var(--color-border);
  font-family:var(--font-mono);font-size:var(--text-sm);color:var(--color-gray-700);
  word-break:break-word}
.fl-lbl{font-family:var(--font-sans);font-weight:600;color:var(--color-text)}
.noact{margin-top:var(--space-5);padding-top:var(--space-4);border-top:1px solid var(--color-border)}
.noact-h{font-size:var(--text-h4)}
.noact-p{margin-top:var(--space-2);font-size:var(--text-body);color:var(--color-text-secondary)}
.noact-p .res-v{font-size:var(--text-h4)}
.noact-t{font-size:var(--text-body)}
.calc-cta{margin-top:var(--space-5)}
.caveats{margin-top:var(--space-6);padding:var(--space-5);border-radius:var(--radius-lg);
  background:var(--color-warning-soft);border:1px solid var(--color-warning-line)}
.caveats-h{font-weight:600;color:var(--color-warning-ink)}
.caveats-sub{margin-top:var(--space-3);font-size:var(--text-body);color:var(--color-warning-ink)}
.caveats-list{margin-top:var(--space-3);display:grid;gap:var(--space-2)}
.caveats-list li{display:flex;gap:var(--space-3);font-size:var(--text-body);color:var(--color-text-secondary)}
.caveats-list .ic{margin-top:3px;color:var(--color-warning-ink)}

/* ---------------------------------------------------------------------------
   10. Промежуточный призыв
   --------------------------------------------------------------------------- */
/* Тёмная полоса между калькулятором и порядком работ: человек только что
   увидел цену своей рутины, и предложение разбора стоит вплотную к этому
   расчёту, а не через три раздела. Тёмная, чтобы не читаться ещё одной
   светлой секцией в ряду. data-theme="dark" у полосы в разметке обязателен
   по той же причине, что у первого экрана и подвала: иначе фокусное кольцо
   берётся из светлой темы и на навy почти не видно. */
.midcta{background:var(--color-navy-900);color:var(--color-navy-text);
  padding:var(--space-10) 0;border-block:1px solid var(--color-navy-line)}
.midcta-in{display:grid;gap:var(--space-5);align-items:center}
.midcta-h{font-size:var(--text-h3);color:var(--color-navy-text)}
.midcta-p{margin-top:var(--space-2);color:var(--color-navy-muted);max-width:62ch}

/* ---------------------------------------------------------------------------
   3. Табы «что можно автоматизировать»
   --------------------------------------------------------------------------- */
/* ВКЛАДКИ ПЕРЕНОСЯТСЯ, А НЕ УЕЗЖАЮТ ЗА КРАЙ. Замер 19.09 на 390: полоса
   вкладок была 1033 px при видимых 358, то есть 65% разделов стояли за правым
   краем без единого признака, что они есть. Прокрутка тут не годится: её
   нечем показать, кроме градиента и стрелки, а стрелку пришлось бы гасить
   скриптом на конце прокрутки. Перенос в две строки показывает ВСЕ разделы
   сразу и работает без скрипта. Ни одна кнопка от переноса не меняется:
   ширина у неё по содержимому, высота та же. */
.tablist{display:flex;flex-wrap:wrap;gap:var(--space-2);padding-bottom:var(--space-2)}
.tab-btn{display:inline-flex;align-items:center;white-space:nowrap;min-height:44px;
  padding:0 var(--space-4);background:var(--color-bg-raised);color:var(--color-text-secondary);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-full);
  font-family:inherit;font-size:var(--text-body);font-weight:600;cursor:pointer;
  transition:background-color var(--transition-color),color var(--transition-color),border-color var(--transition-color)}
.tab-btn:hover{border-color:var(--color-brand-300);color:var(--color-brand-800)}
.tab-btn[aria-selected="true"]{background:var(--color-brand-50);border-color:var(--color-brand-300);color:var(--color-brand-800)}
.tabpanel{margin-top:var(--space-6);display:grid;gap:var(--space-5)}
.tcard{padding:var(--space-5);background:var(--color-bg-raised);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-lg);display:grid;gap:var(--space-3)}
.tc-h{font-size:var(--text-h4)}
.tc-p{color:var(--color-text-secondary)}
.tc-p:first-of-type{color:var(--color-text)}
.tc-r,.tc-t{display:flex;gap:var(--space-3);font-size:var(--text-body);color:var(--color-text-secondary)}
.tc-r .ic{margin-top:3px;color:var(--color-brand-700)}
.tc-t .ic{margin-top:3px;color:var(--color-gray-500)}
.tabs-cta{margin-top:var(--space-2)}

/* ---------------------------------------------------------------------------
   3б. Сайты и продвижение: свой раздел, а не шестая вкладка
   --------------------------------------------------------------------------- */
/* Раскладка карточек ровно та же, что у панели вкладок (.tabpanel): тот же
    шаг раскладки и то же место для кнопки. Блок обязан не выпадать из ритма
   страницы, поэтому он и собран из тех же классов .tcard/.tc-h/.tc-p/.tc-r,
   а сюда вынесено только то, что относится к раскладке. */
.site-grid{margin-top:var(--space-6);display:grid;gap:var(--space-5)}

/* ---------------------------------------------------------------------------
   4. Кейсы: одна цифра на входе, раскрытие по клику. Нативный <details>:
   раскрывается без JS и работает с клавиатуры.
   --------------------------------------------------------------------------- */
.casecard{margin-top:var(--space-5);background:var(--color-bg-raised);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-lg);overflow:hidden}
.cc-sum{display:grid;gap:var(--space-2);padding:var(--space-5);cursor:pointer;list-style:none;
  min-height:var(--tap-target-min);position:relative}
.cc-sum::-webkit-details-marker{display:none}
.cc-sum:hover .case-h{color:var(--color-brand-700)}
.case-scope{font-size:var(--text-xs);font-weight:600;letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--color-gray-600)}
.case-h{font-size:var(--text-h3)}
.cc-big{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--space-3);margin-top:var(--space-2)}
.cc-v{font-family:var(--font-mono);font-weight:600;font-size:var(--text-h2);color:var(--color-brand-700);
  font-variant-numeric:tabular-nums}
.cc-vt{font-size:var(--text-body);color:var(--color-text-secondary)}
.cc-more{position:absolute;top:var(--space-5);right:var(--space-5);color:var(--color-brand-700);
  transition:transform var(--transition-color)}
.casecard[open] .cc-more{transform:rotate(180deg)}
.cc-body{padding:0 var(--space-5) var(--space-5);display:grid;gap:var(--space-5);
  border-top:1px solid var(--color-border);padding-top:var(--space-5)}
.cc-row{display:grid;gap:var(--space-2)}
.cc-k{font-size:var(--text-xs);font-weight:600;letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--color-gray-600)}
.cc-v2{color:var(--color-text-secondary)}
.cc-cta{margin-top:var(--space-1)}

/* СВОЙ ПРОДУКТ. Маленький блок НИЖЕ кейсов, и карточкой кейса он не
   притворяется намеренно: у него нет ни раскрытия по клику, ни цифры
   «было-стало». Именно поэтому владелец и вынес его из кейсов: стоя вторым
   кейсом, он читался как работа для заказчика и обесценивал соседей. */
.ownprod{margin-top:var(--space-6);padding:var(--space-5);display:grid;gap:var(--space-3);
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong);
  border-radius:var(--radius-lg)}
.ownprod-p{color:var(--color-text-secondary);max-width:var(--container-narrow)}

/* ---------------------------------------------------------------------------
   4б. Как идёт работа: четыре шага по порядку
   --------------------------------------------------------------------------- */
/* Раздел отвечает на вопрос «что будет после того, как я напишу». Стоит между
   кейсами и форматами: форматы отвечают «в каком виде», этот блок — «в каком
   порядке». Номер шага рисует счётчик CSS, а не текст: номер в разметке
   сбивал бы нумерацию при правке из редактора. */
.steps4{margin-top:var(--space-6);display:grid;gap:var(--space-3);counter-reset:step;
  list-style:none}
.steps4 li{counter-increment:step;display:grid;gap:var(--space-1);padding:var(--space-4);
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong);
  border-radius:var(--radius-md)}
.steps4 li::before{content:counter(step);font-family:var(--font-mono);font-weight:600;
  font-size:var(--text-sm);color:var(--color-brand-700)}
.st-h{font-size:var(--text-h4)}
.st-p{font-size:var(--text-body);color:var(--color-text-secondary)}
/* СРОК ПРИВЯЗАН К ШАГУ. Разбор площадок: сроки жили отдельно от порядка
   работ, и человек не мог понять, сколько ждать на каждом шаге. Строка стоит
   под описанием шага, отделена линией и читается как ремарка, а не как ещё
   один абзац. Значение набрано как в вилке по работам: сроки владелец ещё не
   называл, на их месте стоит слово СРОК. */
.st-term{margin-top:var(--space-4);padding-top:var(--space-3);display:flex;
  flex-wrap:wrap;gap:var(--space-1) var(--space-3);align-items:baseline;
  border-top:1px solid var(--color-border)}
/* ПОКА СРОКА НЕТ, СТРОКИ НЕ ВИДНО: <p class="st-term"> помечен в разметке
   hidden, и скрипт страницы снимает его, когда из админки приедет срок. */
.st-term[hidden]{display:none}
/* Подпись «Срок» набрана строчными, а не капсом, как подписи в карточках
   форматов: рядом с ней встанет срок владельца, набранный капсом-заглушкой
   СРОК только до заполнения, а два капса подряд читались бы как «СРОК СРОК». */
.st-tk{font-size:var(--text-xs);font-weight:600;color:var(--color-text-secondary)}
.st-m{font-size:var(--text-body);color:var(--color-text)}

/* ---------------------------------------------------------------------------
   5. Форматы работы: три карточки «что это, цена, срок»
   --------------------------------------------------------------------------- */
.fmt-grid{margin-top:var(--space-6);display:grid;gap:var(--space-5)}
.fmt-card{padding:var(--space-5);background:var(--color-bg-raised);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-lg);display:grid;gap:var(--space-3)}
.fc-h{display:flex;align-items:center;gap:var(--space-3);font-size:var(--text-h4)}
.fc-h .ic-24{color:var(--color-brand-700)}
.fc-p{color:var(--color-text-secondary)}
.fc-row{display:grid;gap:var(--space-1);padding-top:var(--space-3);border-top:1px solid var(--color-border)}
.fc-k,.fc-tk{font-size:var(--text-xs);font-weight:600;letter-spacing:var(--tracking-caps);
  text-transform:uppercase;color:var(--color-gray-600)}
.fc-price,.fc-term{font-size:var(--text-body);color:var(--color-text)}
.fmt-note{margin-top:var(--space-6);color:var(--color-text-secondary);max-width:var(--container-narrow)}

/* ВИЛКА ПО РАБОТАМ. Все суммы и все сроки страницы стоят одним списком здесь:
   ни в карточках форматов, ни в форме заявки, ни в новых блоках чисел нет.
   Значение набрано mono (это число), название работы обычным текстом, срок
   обычным текстом и без mono: срок это слово или фраза («4 недели»), а
   моноширинный на словах на этой странице снят отдельным правилом (.no-mono).
   Список разделён линиями, а не тенями: §7.3 брендбука. */
.price-h{margin-top:var(--space-10);font-size:var(--text-h3)}
.price-list{margin-top:var(--space-4);border-top:1px solid var(--color-border)}
.price-list li{display:grid;gap:var(--space-1);padding:var(--space-4) 0;
  border-bottom:1px solid var(--color-border)}
.pr-n{font-weight:600}
.pr-v{font-family:var(--font-mono);font-weight:600;font-size:var(--text-h4);
  color:var(--color-brand-700);font-variant-numeric:tabular-nums}
.pr-t{color:var(--color-text)}
.price-note{margin-top:var(--space-4);font-size:var(--text-body);
  color:var(--color-text-secondary);max-width:var(--container-narrow)}

/* ---------------------------------------------------------------------------
   Вопросы-возражения. Нативный <details>: раскрывается без JS.
   --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   15. Кто я
   --------------------------------------------------------------------------- */
/* Разбор 14 площадок: лицо и короткое описание исполнителя есть у шести.
   Здесь оно стоит после доказательств и цены, перед вопросами: человек уже
   видел цифры и порядок сумм, теперь видит, кому пишет.

   РАМКА ПОД ФОТОГРАФИЮ. Фотографии у владельца пока нет, и чужая не
   подставлена: в рамке стоит слово ФОТО. Рамка задаёт размер и пропорции
   (квадрат) заранее, поэтому настоящая фотография встанет на это место без
   переверстки. Пунктирная граница говорит то же самое глазами: здесь будет
   картинка.

   ПОКА ФОТОГРАФИИ НЕТ, РАМКИ НЕ ВИДНО. Пунктирный квадрат со словом ФОТО
   видит каждый посетитель, и это читается как черновик, а текст рядом
   закончен и без квадрата. Поэтому рамка помечена в разметке hidden: скрипт
   страницы снимает его, как только владелец впишет подпись из админки. Пока
   рамки нет, .about-grid не резервирует под неё колонку 280px (правило в
   медиазапросе 768px ниже) - иначе текст уехал бы вправо от пустого места. */
.about-grid{display:grid;gap:var(--space-6)}
.about-photo{margin:0;display:flex;align-items:center;justify-content:center;
  width:100%;max-width:280px;aspect-ratio:1/1;border-radius:var(--radius-lg);
  background:var(--color-bg-subtle);border:1px dashed var(--color-border-strong)}
.about-photo[hidden]{display:none}
.about-ph{font-family:var(--font-mono);font-size:var(--text-sm);font-weight:600;
  letter-spacing:var(--tracking-caps);color:var(--color-text-secondary)}
.about-name{margin-top:var(--space-3);font-size:var(--text-h4);font-weight:600}
.about-p{margin-top:var(--space-3);color:var(--color-text-secondary);max-width:62ch}

.faq{margin-top:var(--space-6);display:grid;gap:var(--space-2)}
.faq-item{background:var(--color-bg-raised);border:1px solid var(--color-border-strong);border-radius:var(--radius-md)}
.faq-q{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-5);
  cursor:pointer;list-style:none;min-height:var(--tap-target-min)}
.faq-q::-webkit-details-marker{display:none}
.faq-q h3{font-size:var(--text-h4);font-weight:600;flex:1 1 auto}
.faq-q .ic{color:var(--color-brand-700);transition:transform var(--transition-color)}
.faq-item[open] .faq-q .ic{transform:rotate(180deg)}
.faq-q:hover h3{color:var(--color-brand-700)}
.faq-a{padding:0 var(--space-5) var(--space-5);color:var(--color-text-secondary)}

/* Пять вопросов подрядчику. Красный флаг помечен и цветом, и словом
   «Красный флаг»: цвет не может быть единственным носителем смысла. */
/* ШИРИНА СТРОКИ В ВОЗРАЖЕНИЯХ. Замер 19.09: строка ответа была 1110 px, а
   строка красного флага 1070 px при норме 45-75 знаков. Подзаголовок раздела
   (.sect-sub) ограничен 720 px честно, а список и ответы шли во всю ширину
   контейнера 1160 px, то есть в строке набиралось до 130 знаков. Ограничение
   то же, что у подзаголовка: строки встают в ту же вертикаль, что заголовок. */
.faq{max-width:var(--container-narrow)}
.ask5{margin-top:var(--space-8);padding:var(--space-5);border-radius:var(--radius-lg);
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong);
  max-width:var(--container-narrow)}
.ask5-h{font-size:var(--text-h3)}
.ask5-sub{margin-top:var(--space-2);font-size:var(--text-body);color:var(--color-text-secondary)}
.ask5-list{margin-top:var(--space-5);display:grid;gap:var(--space-4)}
.ask5-list li{display:grid;gap:var(--space-2);padding-top:var(--space-4);border-top:1px solid var(--color-border)}
.ask5-q{font-weight:600}
.ask5-f{display:flex;gap:var(--space-3);font-size:var(--text-body);color:var(--color-text-secondary)}
.ask5-f .ic{margin-top:3px;color:var(--color-warning-ink)}
.ask5-note{margin-top:var(--space-5);padding-top:var(--space-4);border-top:1px solid var(--color-border);
  font-size:var(--text-body);color:var(--color-brand-800)}

/* ---------------------------------------------------------------------------
   Форма заявки
   --------------------------------------------------------------------------- */
.form-wrap{max-width:var(--container-narrow)}
.form{margin-top:var(--space-6);display:grid;gap:var(--space-4)}
.field{display:grid;gap:var(--space-2)}
.field label,.field .fl-need,.chan legend{font-weight:600}
.field .opt{font-weight:400;color:var(--color-text-secondary)}
.field input,.field textarea,.field select{width:100%;min-height:var(--control-height-lg);
  padding:var(--space-3);font-family:inherit;font-size:var(--text-body-lg);color:var(--color-text);
  background:var(--color-bg-input);border:1px solid var(--color-border-control);
  border-radius:var(--radius-sm);
  transition:border-color var(--transition-color),background-color var(--transition-color)}
.field select{cursor:pointer}
.field textarea{min-height:132px;resize:vertical;line-height:var(--leading-body)}
.field input:hover,.field textarea:hover,.field select:hover{border-color:var(--color-gray-500)}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--color-border-focus);background:var(--color-bg-raised)}
.field input::placeholder,.field textarea::placeholder{color:var(--color-text-secondary)}
.field.bad input,.field.bad textarea{border-color:var(--color-danger-ink);background:var(--color-bg-raised)}
.fe-name,.fe-company,.fe-email,.fe-task,.fe-consent{font-size:var(--text-sm);color:var(--color-danger-ink)}
/* Канал ответа. Это выбор, а не согласие: галочки по умолчанию пустые,
   а канал отмечен один (почта) — так человек видит, куда придёт ответ. */
.chan{margin:0;padding:0;border:0;display:flex;flex-wrap:wrap;gap:var(--space-3);align-items:center}
.chan legend{padding:0;margin-bottom:var(--space-2);float:left;width:100%}
.chan-opt{display:inline-flex;align-items:center;gap:var(--space-2);min-height:44px;
  padding:0 var(--space-4);border:1px solid var(--color-border-strong);border-radius:var(--radius-full);
  background:var(--color-bg-raised);font-size:var(--text-body);cursor:pointer}
.chan-opt:hover{border-color:var(--color-brand-300)}
/* РАДИОКНОПКА И ЧЕКБОКС НАРИСОВАНЫ САМИ. Браузерная отрисовка берёт рамку из
   своей палитры (замер: rgb(118,118,118)) и ни на color, ни на border-color не
   реагирует вовсе: пиксельный замер подтвердил, что рамка остаётся прежней.
   Поэтому appearance снят, а рамка, заливка и размер взяты из токенов.
   Галочка и точка нарисованы ФОНОМ, а не псевдоэлементом: псевдоэлементы на
   <input> браузер не рисует (это уже было замерено раньше, см. .consent).
   Галочка - контур Lucide из того же набора, что и остальные иконки страницы,
   вшитый в стиль строкой data:, то есть без единого запроса наружу. */
.chan-opt input,.consent input{appearance:none;-webkit-appearance:none;
  width:18px;height:18px;margin:0;color:var(--color-text);cursor:pointer;
  background-color:var(--color-bg-raised);background-repeat:no-repeat;
  background-position:center;border:1px solid var(--color-border-control);
  border-radius:var(--radius-full)}
.chan-opt input:checked,.consent input:checked{
  background-color:var(--color-brand-700);border-color:var(--color-brand-700)}
.chan-opt input:checked{background-image:radial-gradient(circle,var(--color-gray-0) 0 3px,transparent 3.5px)}
/* Ловушка для ботов (honeypot): человек её не видит и не может на неё встать.
   Вместо капчи — см. _promo_legal_draft_20260917/lead-flow.md. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* Строка согласия — это <label> (§8.2 и §9.2 брендбука): сам квадрат галочки
   остаётся 18px, а зона нажатия задана обёрткой и выходит не меньше 44px по
   высоте и во всю ширину строки. Псевдоэлементом зону нажатия тут расширить
   НЕЛЬЗЯ: ::before/::after у <input> браузер не рисует, и галочка осталась бы
   18 пикселей (замерено). Ссылка внутри подписи нажатие не переключает. */
.consent{display:flex;gap:var(--space-3);align-items:flex-start;min-height:var(--tap-target-min)}
.consent input{flex:0 0 auto;margin:3px 0 0;border-radius:var(--radius-xs)}
.consent input:checked{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");background-size:12px 12px}
.consent span{font-size:var(--text-body);color:var(--color-text-secondary)}
.consent a,.consent-note a{color:var(--color-text-link)}
.consent-note{margin-top:var(--space-2);font-size:var(--text-sm);color:var(--color-text-secondary)}
/* Две оговорки согласия разведены по абзацам (см. promo.html): пока они шли
   одной строкой-потоком, нижнее поле нажатия ссылки на почту перехватывала
   ссылка на политику - замер попаданием давал 20px вместо 44px. Зазор 16px
   больше нижнего поля ссылки (14px), поэтому абзац ниже не заходит на него. */
.consent-note + .consent-note{margin-top:var(--space-4)}
/* Пометка «задача подставлена из выбора выше»: она сообщает, ОТКУДА взялся
   текст, чтобы подстановка не выглядела как чужая правка. */
.prefill-note{margin-top:var(--space-2);font-size:var(--text-sm);color:var(--color-info-ink)}
.form-actions{margin-top:var(--space-2);display:flex;flex-wrap:wrap;gap:var(--space-4);align-items:center}
.form-promise{font-size:var(--text-body);color:var(--color-text-secondary);max-width:440px}
/* Бюджетный ориентир в заявке. Сумм здесь нет намеренно: вилка и сроки стоят
   одним местом в разделе «Форматы работы», и вторая их копия в форме рано или
   поздно разошлась бы с первой. Строка называет место, а не число. */
.form-budget{margin-top:var(--space-2);font-size:var(--text-sm);color:var(--color-text-secondary)}
/* ССЫЛКА НА «ФОРМАТЫ РАБОТЫ» СТОИТ НА СВОЕЙ СТРОКЕ. Пока она шла строчной
   посреди абзаца, следующая за ней строка текста (.fb-2) накрывала её нижний
   padding: замер попаданием на 390x844 давал 32px нажатия при поле 44px.
   Блочный элемент заканчивается до начала следующей строки, поэтому нижнее
   поле нажатия больше ничем не перехватывается. width:fit-content - чтобы
   нажималась сама ссылка, а не полоса во всю ширину формы. */
.form-budget .fb-link{color:var(--color-text-link);display:block;width:fit-content}
/* ТАП-ТАРГЕТ 44px У ССЫЛОК В ФОРМЕ. Это то место, где человек как раз и
   нажимает, а ссылки здесь строчные: их высота равнялась высоте строки текста
   (замер на 390x844: 16 / 16 / 16 / 43 px при норме 44). Вертикальные padding
   у СТРОЧНОГО (display:inline) элемента не участвуют в расчёте высоты строки —
   вёрстка не сдвигается ни на пиксель, — но входят в область нажатия, и
   браузер по ним попадает. Поэтому здесь padding, а не inline-block с
   min-height: последний раздул бы строку абзаца и сломал ритм формы.
   28px даёт ровно 44px при кегле 13px (16 + 14 + 14). */
.fb-link,.fcn-mail,.fcn-pol,.fc-link{padding-block:14px}
.notice{margin-top:var(--space-4);padding:var(--space-4);border-radius:var(--radius-md);
  border:1px solid var(--color-border-strong);background:var(--color-bg-subtle);
  display:flex;gap:var(--space-3);color:var(--color-text-secondary);font-size:var(--text-body)}
.notice .ic{margin-top:2px;color:var(--color-warning-ink)}
.notice-ok{border-color:var(--color-success-ink);background:var(--color-success-soft)}
.notice-ok .ic{color:var(--color-success-ink)}
.notice.flash{border-color:var(--color-warning-ink);box-shadow:var(--shadow-md)}

/* ---------------------------------------------------------------------------
   Подвал
   --------------------------------------------------------------------------- */
.foot{background:var(--color-navy-900);color:var(--color-navy-text);
  padding:var(--space-10) 0 var(--space-8);margin-top:var(--space-12)}
.foot-grid{display:grid;gap:var(--space-6)}
.foot-name{font-weight:700;font-size:var(--text-h4)}
.foot-line{margin-top:var(--space-2);color:var(--color-navy-muted);font-size:var(--text-body)}
/* КТО ОТВЕЧАЕТ ПО ДОГОВОРУ. Имя и статус стоят под описанием направления:
   название говорит, чем занимается направление, имя - с кем человек имеет
   дело. Статус набран тише имени: он поясняет, а не называет. */
.foot-author{margin-top:var(--space-4);display:flex;flex-direction:column;gap:var(--space-1)}
.foot-author-n{font-weight:600}
.foot-status{font-size:var(--text-sm);color:var(--color-navy-muted)}
/* СВЯЗАТЬСЯ. Контакты сгруппированы, а не вывалены одной строкой: сначала
   телефон и почта, ниже отдельной группой мессенджеры. Группа это список
   ссылок в столбик - на узком экране они идут друг под другом, с 768 в
   строку. Тап-таргет тот же, что везде: 44 px. */
.foot-ch{font-size:var(--text-h4);font-weight:700}
.foot-group{margin-top:var(--space-3);display:flex;flex-wrap:wrap;
  gap:var(--space-2) var(--space-5)}
.foot-group-msg{margin-top:var(--space-4)}
/* Группа, в которой ВСЕ пункты скрыты (ни одного адреса каналов у владельца
   ещё нет), не занимает места вовсе: пустая полоса в подвале читается как
   сбой вёрстки. Как только владелец впишет адрес и снимет hidden, группа
   появляется сама - правил для этого не нужно. Тот же приём, что у пустого
   состояния калькулятора (:has выше). */
.foot-group:not(:has(a:not([hidden]))){display:none}
/* ВНИМАНИЕ НА :not([hidden]). Скрытый контакт (номера и адресов каналов у
   владельца пока нет) обязан исчезнуть, а не занять место пустой строкой.
   Правило [hidden]{display:none} стоит в конце файла, но селектор
   «.foot-group a» специфичнее него (класс + тег против одного атрибута), и без
   этого :not скрытый пункт рисовался бы наравне с остальными - проверено
   глазами на снимке: в подвале стояли три пустых «ССЫЛКА». */
.foot-group a:not([hidden]){display:inline-flex;align-items:center;gap:var(--space-2);
  min-height:var(--tap-target-min);color:var(--color-navy-text);
  text-decoration:none;font-size:var(--text-body)}
.foot-group a:hover{text-decoration:underline;text-underline-offset:3px}
.foot-group .ic{color:var(--color-brand-400)}
/* ФИРМЕННЫЕ ЗНАКИ СЕРВИСОВ. Официальные файлы из брендбуков Telegram и MAX
    (см. комментарий в разметке), каждый одноцветный и в тон подвалу -
   цвет зашит в файл, потому что картинка не наследует цвет строки.
   Квадрат 20x20 и object-fit:contain: пропорции знака не меняются ни на одном
   размере. Картинка, а не CSS-маска: маска со страницы, открытой с диска, в
   Chromium не грузится вовсе (net::ERR_FAILED на file://). */
.brand-ic{display:block;flex:0 0 auto;width:20px;height:20px;object-fit:contain}
.foot-links{margin-top:var(--space-4);display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-5)}
.foot-links a{display:inline-flex;align-items:center;gap:var(--space-2);min-height:var(--tap-target-min);
  color:var(--color-navy-text);text-decoration:none;font-size:var(--text-body)}
.foot-links a:hover{text-decoration:underline;text-underline-offset:3px}
.foot-links .ic{color:var(--color-brand-400)}
/* ТОЧКА НЕ ОТРЫВАЕТСЯ ОТ ФРАЗЫ. Строка собрана из ссылки на политику и
   следующего за ней года, который начинается с точки («. 2026.»). Между ними
   стоял зазор flex-раскладки (4 px), и строка читалась как «...данных . 2026.»
   с точкой в воздухе. Зазор убран: точка прижимается к слову, как в обычном
   тексте. Ссылке «Cookie», которую дописывает общий баннер, отступ оставлен
   отдельно: без него она приклеилась бы к году. */
.foot .copy{margin-top:var(--space-8);padding-top:var(--space-5);border-top:1px solid var(--color-navy-line);
  display:flex;flex-wrap:wrap;align-items:center;gap:0;
  color:var(--color-navy-muted);font-size:var(--text-sm)}
.foot .copy a{color:var(--color-navy-text);display:inline-flex;align-items:center;
  min-height:var(--tap-target-min)}
.foot .cb-foot-link{display:inline-flex;align-items:center;min-height:var(--tap-target-min);
  margin-left:var(--space-4)}

/* ---------------------------------------------------------------------------
   Планшет и десктоп. Брейкпоинты брендбука: 768 и 1024.
   --------------------------------------------------------------------------- */
@media (min-width:768px){
  .wrap{padding:0 var(--space-6)}
  /* Кнопки первого экрана с планшета снова стоят в строку: узкая колонка
     телефона кончилась, и растягивать их на всю ширину больше не нужно. */
  .hero-cta{flex-direction:row;flex-wrap:wrap}
  /* ШАПКА НЕ ДОЛЖНА БЫТЬ НИЖЕ НА ДЕСКТОПЕ, ЧЕМ НА ТЕЛЕФОНЕ. Замер 19.09: на
     1440 шапка была 48 px, на 390 - 68 px. Причина в порядке правил, а не в
     значениях: `.topbar-in{padding:var(--space-3) 0}` и `.wrap{padding:0
     var(--space-6)}` имеют одинаковую специфичность (0,2,0), и правило из
     этого медиазапроса стоит НИЖЕ по файлу, поэтому вертикальные отступы
     шапки обнулялись. Пара классов `.wrap.topbar-in` даёт специфичность
     (0,2,0) против (0,1,0) у `.wrap`: этого достаточно, чтобы вернуть шапке
     её собственные отступы и не трогать отступы остальных секций. */
  .wrap.topbar-in{padding:var(--space-3) var(--space-6)}
  .sect{padding:var(--space-16) 0}
  .hero{padding:var(--space-20) 0 var(--space-16)}
  .facts3{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-4)}
  .stats3{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-6)}
  .fit-grid{grid-template-columns:1fr 1fr;gap:var(--space-5)}
  .midcta-in{grid-template-columns:minmax(0,1fr) auto}
  .about-grid{grid-template-columns:280px minmax(0,1fr);gap:var(--space-10);
    align-items:start}
  /* Рамки под фотографию нет (см. .about-photo[hidden]) - колонка 280px под
     неё не резервируется, текст занимает всю ширину. Как только владелец
     впишет подпись и скрипт снимет hidden, правило перестаёт действовать само:
     правок вёрстки не нужно. Тот же приём, что у .foot-group в подвале. */
  .about-grid:not(:has(.about-photo:not([hidden]))){grid-template-columns:minmax(0,1fr)}
  /* Строка «что → было → стало» с планшета идёт таблицей: колонки у всех
     строк одной ширины, поэтому «было» и «стало» стоят друг под другом от
     строки к строке. `display:contents` распускает обёртку .db-pair, и её
     содержимое встаёт прямо в колонки строки. Три правила ниже снимают
     места, которые обёртка задавала детям на телефоне: без них «было»
     растянулось бы на все четыре колонки строки. */
  .db-row{grid-template-columns:minmax(0,1fr) minmax(0,1.5fr) 24px minmax(0,1.1fr);
    align-items:baseline;column-gap:var(--space-4);padding:var(--space-5) 0}
  .db-pair{display:contents}
  .db-was{grid-column:auto}
  .db-arr{grid-row:auto;grid-column:auto;width:20px;height:20px;align-self:center}
  .db-now{grid-row:auto;grid-column:auto;justify-self:stretch}
  .calc-grid{grid-template-columns:1fr 1fr;gap:var(--space-5)}
  .calc{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:start}
  .calc-grid{grid-column:1/-1}
  .res-2{grid-template-columns:1fr 1fr;gap:var(--space-5);
    padding-top:var(--space-5);border-top:1px solid var(--color-border)}
  .tabpanel{grid-template-columns:1fr 1fr;gap:var(--space-5)}
  .tabpanel .tabs-cta{grid-column:1/-1}
  /* Раздел «Сайты и продвижение» идёт тем же шагом, что панель вкладок. */
  .site-grid{grid-template-columns:1fr 1fr}
  .site-grid .tabs-cta{grid-column:1/-1}
  /* Вилка: работа, сумма, срок. Срок стоит третьей колонкой и не липнет к
     сумме: у него своя вертикаль во всех восьми строках. */
  .price-list li{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) minmax(0,.9fr);
    column-gap:var(--space-4);align-items:baseline}
  /* СРОКА НЕТ - КОЛОНКИ НЕТ. Пока владелец не назвал срок, .pr-t скрыт (см.
     разметку), и третья колонка не резервируется: таблица из двух колонок -
     работа и цена - выглядит законченной, а не наполовину заполненной.
     Строка появляется сама, как только из админки приедет срок: скрипт
     страницы снимает hidden, и правило перестаёт совпадать. */
  .price-list li:has(> .pr-t[hidden]){grid-template-columns:minmax(0,1.5fr) minmax(0,1fr)}
  /* СУММЫ НЕТ - КОЛОНКИ ПОД НЕЁ НЕТ. У строки «Анализ цен конкурентов» сумма
     ещё не названа владельцем: в разметке стоит слово-заглушка ЦЕНА, скрытое
     атрибутом hidden. Без этого правила справа от названия оставалась бы
     пустая половина строки, и список читался бы как недозаполненный. Сумма
     приедет из админки - скрипт страницы снимет hidden, и правило перестанет
     совпадать. */
  .price-list li:has(> .pr-v[hidden]){grid-template-columns:minmax(0,1fr)}
  .fmt-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  /* Шаги в две колонки: в четыре узкие колонки строка шага ломается на шесть
     строк и правило «не длиннее пяти строк» перестаёт выполняться. */
  .steps4{grid-template-columns:1fr 1fr;gap:var(--space-4)}
  .cc-body{gap:var(--space-6)}
  .foot-grid{grid-template-columns:2fr 1fr;align-items:start}
}
@media (min-width:1024px){
  /* Шапка: раскрывашка уступает место строке меню. */
  .tb-burger{display:none}
  .tb-menu{display:flex;position:static;flex:1;min-width:0;flex-direction:row;
    align-items:center;gap:var(--space-4);padding:0;background:none;border:0;box-shadow:none}
  /* ЗАЗОР МЕЖДУ ПУНКТАМИ МЕНЮ. Было 8 px (боковые отступы самих пунктов),
     стало 20 px ровно: отступы пунктов убраны до нуля, а расстояние задаёт
     gap строки меню. Так зазор одинаков и для рамок пунктов, и для самих
     слов, и его видно одним числом, а не суммой padding и gap. */
  .tb-nav{flex:1;flex-direction:row;align-items:center;justify-content:center;
    gap:var(--space-5);flex-wrap:nowrap}
  .tb-link{padding:0;font-size:var(--text-body);
    color:var(--color-text-secondary);white-space:nowrap}
  .tb-link:hover{color:var(--color-text)}
  /* Телефон на широком экране: та же строка, что меню, но тише его по цвету.
     Пять пунктов меню, телефон и кнопка на 1024 переносились бы на вторую
     строку, поэтому телефон держится одной строкой и не растягивает шапку. */
  .tb-menu{gap:var(--space-3)}
  .tb-phone{padding:0 var(--space-2);font-size:var(--text-sm);
    color:var(--color-text-secondary)}
  .tb-phone:hover{background:transparent;color:var(--color-text)}
  /* С 1024 знак крупнее (40 px - верхняя часть полосы иконочной версии, до
     основного знака в 48 px не дотягивает намеренно: в шапке нужен знак, а не
     логотип во всю высоту), рядом со знаком встают название и слоган. */
  .tb-lockup{--tb-logo-h:40px;--tb-logo-gap:var(--space-3)}
  .tb-name{display:block}
  .tb-slogan{display:block}
  /* КНОПКА ПРИЖАТА ВПРАВО САМОЙ РАСКЛАДКОЙ, а не отступом. Прежде её отодвигал
     margin-left:auto, который на 1440 превращался в 252 px пустоты перед ней -
     одна большая дыра посреди шапки. Теперь свободное место забирает строка
     меню (flex:1) и раздаёт его по краям: пункты стоят по центру своей полосы,
     а кнопка упирается в правый край. */
  .tb-cta{margin-top:0;width:auto;padding:0 var(--space-4)}
  /* ШАПКА СТАЛА ВЫШЕ. Знак 40 px и две строки подписи дают 88 px, а якорь
     отступал на 80: заголовок раздела уезжал под залипшую шапку на 8 px.
     Отступ считается от той же высоты шапки, что видна на этой ширине. */
  section[id]{scroll-margin-top:calc(var(--space-20) + var(--space-2))}
  .calc-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .tabpanel{grid-template-columns:repeat(3,minmax(0,1fr))}
  .site-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .cc-body{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .cc-body .cc-row:nth-child(1),.cc-body .cc-row:nth-child(3){grid-column:1}
  .cc-body .cc-row:nth-child(2),.cc-body .cc-row:nth-child(4){grid-column:2}
  .cc-body .cc-row:nth-child(1){grid-row:1}
  .cc-body .cc-row:nth-child(2){grid-row:1}
  .cc-body .cc-row:nth-child(3){grid-row:2}
  .cc-body .cc-row:nth-child(4){grid-row:2}
  .cc-body .cc-cta{grid-column:1/-1}
}
/* ШИРОКИЙ ЭКРАН: в шапке после разбора площадок остались только меню, телефон
   и кнопка, и место в строке освободилось. Сжаты ровно отступы самой шапки:
   у телефона - боковой padding (8 -> 4 px), у кнопки - её собственный padding
   (16 -> 12). У пунктов меню отступов нет с 19.09: расстояние между ними
   задаёт gap строки меню (20 px), и здесь его трогать нечего. Ни кегль, ни
   разметка не тронуты. */
@media (min-width:1440px){
  .tb-phone{padding:0 var(--space-1)}
  .tb-cta{padding:0 var(--space-3)}
}
@media (max-width:400px){
  .sl-num{width:100%}
}

/* ---------------------------------------------------------------------------
   ВАЖНО: это правило обязано стоять В КОНЦЕ файла.

   `hidden` в разметке должно побеждать любой display, заданный классом
   (.notice{display:flex}, .btn{display:inline-flex}, .tabpanel{display:grid}):
   при равной специфичности решает порядок, и правило, стоящее выше,
   проигрывает. На этом уже один раз вылезла ВИДИМАЯ плашка «заявка
   отправлена», которой положено быть скрытой до подключения приёма заявок.
   Браузерная проверка этого не увидела: атрибут hidden в DOM был на месте, а
   элемент всё равно рисовался. Увидел глазами.
   --------------------------------------------------------------------------- */
[hidden]{display:none}

/* ---------------------------------------------------------------------------
   8. Подбор под задачу и бюджет (05.10.2026)
   Шесть шагов, в конце результат. Сделано на тех же переменных, что и остальная
   страница: новых цветов и размеров не вводится (§3 и §7 брендбука).
   --------------------------------------------------------------------------- */
.quiz{margin-top:var(--space-8);display:grid;gap:var(--space-8)}
/* Счётчик шага: тем же моношрифтом, что подписи в результате, — он читается
   как служебная строка, а не как часть вопроса. */
.qz-prog{margin:0;font-family:var(--font-mono);font-size:var(--text-sm);
  letter-spacing:.04em;text-transform:uppercase;color:var(--color-text-secondary)}
.qz-step{display:grid;gap:var(--space-4)}
.qz-q{display:flex;gap:var(--space-3);align-items:baseline;margin:0;
  font-size:var(--text-h4);font-weight:600}
.qz-n{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:28px;height:28px;border-radius:var(--radius-full,50%);
  background:var(--color-brand-700);color:#fff;font-size:var(--text-sm);font-weight:600}
.qz-opts{display:grid;gap:var(--space-2)}
.qz-opt{display:flex;align-items:center;min-height:var(--tap-target-min);
  padding:var(--space-3) var(--space-4);text-align:left;cursor:pointer;
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong);
  border-radius:var(--radius-md);color:var(--color-text-primary);
  font:inherit;font-size:var(--text-body)}
.qz-opt:hover{border-color:var(--color-brand-700)}
.qz-opt[aria-pressed="true"]{border-color:var(--color-brand-700);
  background:var(--color-brand-50,var(--color-bg-raised));font-weight:600}
.qz-next{margin:0}
.qz-out{display:grid;gap:var(--space-3);padding:var(--space-6);
  background:var(--color-bg-raised);border:1px solid var(--color-border-strong);
  border-radius:var(--radius-md)}
.qz-out-h{margin:0;font-family:var(--font-mono);font-size:var(--text-sm);
  letter-spacing:.04em;text-transform:uppercase;color:var(--color-text-secondary)}
.qz-out-name{margin:0;font-size:var(--text-h3);font-weight:600}
.qz-out-why{margin:0;color:var(--color-text-secondary)}
.qz-out-facts{display:grid;gap:var(--space-2);margin:0;padding:0;list-style:none}
.qz-out-facts li{display:grid;grid-template-columns:auto 1fr;gap:var(--space-3);
  align-items:baseline}
.qz-fv{font-family:var(--font-mono);font-weight:600;color:var(--color-brand-700)}
.qz-out-note{margin:0;font-size:var(--text-sm);color:var(--color-text-secondary)}
.qz-out-act{display:flex;flex-wrap:wrap;gap:var(--space-3);align-items:center}

@media (min-width:768px){
  .qz-opts{grid-template-columns:1fr 1fr}
  .qz-budget{grid-template-columns:repeat(4,1fr)}
}

/* МОЯ ПОЛОМКА 05.10.2026, найдена владельцем: «не работает и занимает кучу места».
   У элементов подбора задано своё display (grid), а авторский стиль СИЛЬНЕЕ
   браузерного, которым работает атрибут hidden. Поэтому все шесть шагов и все три
   ветки второго шага показывались разом: нажатие переключало hidden, а стиль его
   игнорировал. Три строки ниже возвращают hidden его силу.

   ПРАВИЛО НА БУДУЩЕЕ: если элементу, который прячется атрибутом hidden, задан
   свой display, рядом обязана стоять такая строка. Иначе он не спрячется. */
.qz-step[hidden],.qz-opts[hidden],.qz-out[hidden]{display:none}
