/* ════════════════════════════════════════════════════════════════════════════
   design.css — зона Агента 5, сквозная дизайн-полировка (№106)

   Каскад: site.css (база, заморожен) → ЭТОТ ФАЙЛ (сквозное) → money.css /
   trust.css (страничное сильнее сквозного). Ничего не переопределяю «на всякий
   случай»: каждое правило чинит конкретный замеренный дефект и ссылается на
   закон паспорта, который сейчас нарушается. Замеры — 04_DOCS/E-дизайн-ревью.md,
   проверка до/после — 04_DOCS/E-tools/pair.py.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 1. Закон близости: заголовок принадлежит своему содержимому ──────────────
   Было: в band-soft заголовок стоял вплотную к ЧУЖОМУ предыдущему блоку (0 px)
   и на 26 px отрывался от своего (site.css:436 `.band-soft .b-h{margin-top:0}`
   перебивал общее правило при равной специфичности). Замер на 4 заголовках
   /uslugi/master-klassi-i-vistupleniya: до 0 / после 26 — инверсия.
   Паспорт §4.2: «между смысловыми полосами воздуха больше, чем внутри любой».
   Воздух не добавляется, а перераспределяется: сверху больше, снизу меньше.

   ОБНОВЛЕНО 30.07 (задача владельца «то отступов практически нет, то они
   большие»): конкретные значения этого пункта переехали в раздел «ШКАЛА РИТМА»
   в конце файла — там они приведены к единой шкале вместе со стыками полос.
   Лид-абзац под заголовком остаётся частью заголовочной группы (site.css:437). */

/* ── 2. Чип-регалии перестают спорить с призывом ──────────────────────────────
   Первый экран главной: 11 фиолетовых объектов при законе §8.1 «≤3 пятна».
   Три чипа стоят ВЫШЕ заголовка и первыми ловят глаз, хотя это метаданные,
   а не действие. Заливку не трогаю — §2.3 разрешает чипам violet-ghost 10%;
   гасится только насыщенный текст, который и делает чип пятном.
   Контраст #14161C на #EFEDFC ≈ 16:1 — выше порога AAA (§2.6). */
.chip{ color: var(--ink) }

/* ── 2б. Вес заголовков: «всё жирное = ничто не главное» ──────────────────────
   Решение владельца 30.07 (малый ход, без ревизии паспорта Д-02/§3.1):
   H2-band 800 → 750, b-sub 750 → 700. Цифры фактов, H1 и CTA-t остаются 800 —
   их вес и есть иерархия: на полосе крупная цифра должна быть тяжелее
   заголовка, иначе теряется. Кегли не трогаю, меняется только насыщенность:
   заголовок перестаёт спорить с цифрой и с призывом. */
.band .b-h{ font-weight: 750 }
.b-sub{ font-weight: 700 }

/* ── 3. Двухуровневый пункт списка (главный приём КП) ─────────────────────────
   Стиль готов заранее: проявится там, где исполнители дадут тезис тегом <b>.
   Пока разметки нет — правило ничего не меняет. Паспорт §3.3: полужирный
   в тексте 600–650, не 800. */
.tick li > b,
.tick li > strong{ display: block; font-weight: 650; color: var(--ink); margin-bottom: 3px }
.tick li:has(> b), .tick li:has(> strong){ line-height: 1.55 }

/* ── 4. Дно страницы перестаёт быть болотом ───────────────────────────────────
   Блок доверия давал две band-mist подряд: логотипы 619 px + FAQ 1 063 px =
   1 682 px без единой смены фона, на каждой контентной странице. §8.3 —
   «две полосы одного фона подряд» в жёстких запретах, §4.2 закрепляет FAQ
   за мглой лишь как назначение полосы. Коллизия решена в пользу запрета. */
.band-mist + .band-mist{ background: var(--paper) }
.band-mist + .band-mist .faq{ border-top: 1px solid var(--line); padding-top: 4px }

/* ── 5. Оффер-карточка во всю ширину смысла ───────────────────────────────────
   `.price` был 760 px при контейнере 1 140 — самый важный блок страницы был
   самым узким, справа 380 px пустоты. В КП панель «ИТОГО» занимает всю ширину
   колонки — потому и читается как счёт. */
.price{ max-width: 980px }
.price-row dd{ font-size: 16.5px }
/* ВАЖНО: только от 561px. Без медиазапроса это правило встало бы ПОСЛЕ
   site.css:646 `@media(max-width:560px){.price-row{grid-template-columns:1fr}}`
   и отменило бы его — колонка 220px + gap не влезала в 350px экрана и давала
   горизонтальный вынос на 5px. Поймано замером scrollWidth на 390. */
@media(min-width: 561px){
  .price-row{ grid-template-columns: 220px 1fr; padding: 13px 0 }
}

/* ── 11. Сетка не заканчивается рядом из одного элемента ──────────────────────
   14 случаев на 68 страницах, из них 9 — ровно «4 карточки в 3 колонки»:
   `.feat` раскрывается auto-fit в 3 дорожки при контейнере 1 140 (на 4 нужно
   1 204), и четвёртая карточка висит одна. Число элементов известно браузеру —
   правило декларативное; без поддержки :has() просто не применится.

   ВАЖНО — только от 861px (брейкпоинт паспорта §4.1, где сетки и так падают
   в 2 колонки). Без медиазапроса эти правила стоят ПОСЛЕ мобильных
   медиазапросов site.css и замораживают десктопную раскладку на телефоне:
   замер дал горизонтальный вынос до 521px на /privacy. */
@media(min-width: 861px){
  .feat:has(> :nth-child(4):last-child),
  .svc:has(> :nth-child(4):last-child),
  .cards:has(> :nth-child(4):last-child){ grid-template-columns: repeat(2, 1fr) }
  .feat:has(> :nth-child(10):last-child){ grid-template-columns: repeat(2, 1fr) }
  .fp-grid:has(> :nth-child(5):last-child),
  .fp-grid:has(> :nth-child(9):last-child){ grid-template-columns: repeat(3, 1fr) }
  .svc:has(> :nth-child(7):last-child){ grid-template-columns: repeat(4, 1fr) }
}
/* 13 элементов (/rekviziti) не раскладываются без сироты ни при 2, ни при 3,
   ни при 4 колонках — 13 простое. Служебная страница, принято как есть. */


/* ════════════════════════════════════════════════════════════════════════════
   ЗАХОД 2 — мобильный путь, длина строки, микромоторика
   Мобильный трафик у Дмитрия главный: с выступлений заходят по QR со сцены.
   Поэтому мобильные правки идут первыми и мерятся путём «попал → понял →
   написал», а не общим видом (E-tools/mobile.py).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 7а. Крошки не съедают первый экран ──────────────────────────────────────
   Замер 390px: на /uslugi/master-klassi-i-vistupleniya крошки занимали 101 px
   в три строки, причём второй уровень — служебный титул родителя «Выберите
   формат — от часовой консультации до…». До H1 было 186 px.
   Прячем ТОЛЬКО визуально промежуточные уровни: JSON-LD BreadcrumbList в
   <head> не трогается, микроразметка для поиска остаётся полной (§5.2). */
@media(max-width: 720px){
  .crumbs > a:not(:first-child){ display: none }
  .crumbs > .sep ~ .sep{ display: none }
  .crumbs a, .crumbs .here{ padding: 11px 0 }        /* тач-таргет 22 → 44 (§5) */
  .crumbs{ padding-top: 6px; padding-bottom: 0 }
}

/* ── 7б. Кнопки героя: равная ширина ─────────────────────────────────────────
   Было 195 px и 166 px друг под другом — рваный левый блок, вторая кнопка
   читается как сломанная. Вес действий различают заливка и рамка, а не
   ширина (§5.1), поэтому обе на всю ширину — это нормальный мобильный ход. */
@media(max-width: 560px){
  .phero-cta, .hero-cta{ display: grid; gap: 12px }
  .phero-cta .btn, .hero-cta .btn{ width: 100%; justify-content: center }
}

/* ── 7в. Тач-таргеты меню и подвала ──────────────────────────────────────────
   Замер: 48 ссылок в drawer по 38 px и 28 ссылок подвала по 17 px при законе
   §5 «≥44×44». Drawer — главное меню на телефоне, по нему и промахиваются. */
@media(max-width: 1040px){
  .dr-sub{ padding-top: 11px; padding-bottom: 11px }
  .dr-top{ padding-top: 13px; padding-bottom: 13px }
}
@media(max-width: 720px){
  .ftr a{ padding: 13px 0 }
  /* Находка Агента 3, проверенная замером и оказавшаяся серьёзнее: внизу
     мобильной страницы ДВЕ фиксированные панели — таб-бар (58 px, запас под
     него в подвале был) и кнопка WhatsApp, которая не круглая, а во всю
     ширину: x 16…374, y 722…774. Она физически накрывала последнюю строку
     подвала — копирайт и ссылки «связаться» / «кабинет участника» не
     читались и не нажимались. Запас до таб-бара был 11 px, до FAB —
     отрицательный. Даём запас под обе панели. */
  .ftr{ padding-bottom: 124px }
}
/* Мелочь, но она стоит заявок: чекбокс согласия в форме был 17×17.
   Клик работает по всему <label> (так свёрстано), поэтому катастрофы нет —
   но сам квадратик мельче нормы, и палец целится именно в него.
   Чекбокс до 20, зона label до 44 по высоте. */
.lf-agree{ padding: 6px 0 }
.lf-agree input{ width: 20px; height: 20px; margin-top: 1px }
/* Кнопки шапки и drawer: 40 и 39 px — дотягиваем до 44 (§5). */
.s-btn{ min-width: 44px; min-height: 44px }
.drawer-x{ min-width: 44px; min-height: 44px }
.hdr-in .logo{ padding: 7px 0 }
/* Теги-фильтры лент («Я рекомендую», блог): 41 px — два пикселя до нормы.
   Заодно радиус 99 → 999 по канону Д-12 (визуально то же, но канон один). */
.fp-tag{ padding: 10px 16px; border-radius: 999px }
/* Кнопка формы «Отправить заявку» была 43 px — на пиксель ниже закона §5.
   ВАЖНО, как это чинить: правка `padding` у `.btn` перебивает `.btn-lg`
   (site.css:177) и `.hdr-cta` (:469) — у них та же специфичность, а мой файл
   ниже, поэтому крупная и компактная кнопки схлопнулись бы в один размер.
   `min-height` поднимает только тех, кто реально ниже нормы, и не трогает
   внутренние отступы модификаторов. */
.btn{ min-height: 44px }

/* ── 10. Длина строки в ЗНАКАХ, а не в «ch» ──────────────────────────────────
   Правило `.faq-a{max-width:74ch}` в site.css:372 уже стояло — и всё равно
   замер давал 82 знака в строке. Причина не в вёрстке: `ch` = ширина знака
   «0», а кириллица в среднем уже, поэтому в 74ch помещается ~82 буквы.
   Закон §3.3 говорит про ЗНАКИ (60–76) — пересчитываю единицу. */
.faq .faq-a{ max-width: 66ch }

/* ── 9. Микромоторика: один язык движения ────────────────────────────────────
   Было: подъём карточек −2 px (site.css:216, :245) и −3 px (:331) вперемешку,
   у .feat-i −2 px; кривая перехода — дефолтный `ease`. Паспорт §7.2.2: −3 px;
   §7.1: `ease` → cubic-bezier(.2,0,0,1) «при доводке» — вводим сейчас. */
:root{ --ease-ui: cubic-bezier(.2, 0, 0, 1) }
.svc-card, .ct, .feat-i, .case, .rev{ transition: transform .2s var(--ease-ui),
  box-shadow .2s var(--ease-ui), border-color .15s var(--ease-ui) }
.svc-card:hover, .ct:hover, .feat-i:hover{ transform: translateY(-3px) }
.btn{ transition: background .15s var(--ease-ui), color .15s var(--ease-ui),
  border-color .15s var(--ease-ui), transform .12s var(--ease-ui) }

/* Запрет §7.2.2 «scale запрещён (желейность)» нарушался в галерее
   (site.css:535). И отдельно §8.3: «движение рядом с доказательством» —
   логотипы клиентов это доказательство, им положен цвет на hover (§5.10),
   но не подъём. Гасим оба движения, цветовой hover остаётся. */
.gal a:hover img{ transform: none }
.logos img{ transition: filter .2s var(--ease-ui), opacity .2s var(--ease-ui) }
.logos img:hover{ transform: none }

/* Радиусы к канону Д-12 (20 / 16 / 12 / 999): было 14 у логотипов,
   10 у шапки и верхних пунктов drawer, 8 у подменю drawer. */
.logos img{ border-radius: 16px }
.dr-sub{ border-radius: 12px }
.dr-top, .s-btn, .hdr-cta{ border-radius: 12px }

/* ── 8. Кегли: одна роль — один размер ───────────────────────────────────────
   Замер дал 17 кеглей на страницу, но это не хаос: ярусы заголовков и тела
   собраны верно. Настоящих совпадений ролей два, их и свожу.

   А. «Заголовок карточки/пункта» жил в четырёх значениях в диапазоне 2 px:
      .svc-t 19 · .feat-t 18.5 · .step-t 17.5 · FAQ summary 17. Разница
      в полпикселя не читается как иерархия — читается как небрежность.
      Оставляю два: 19 — крупная карточка, 17 — компактный пункт.
   Б. «Мета/подпись» — 14.5 / 14 / 13.5. Паспорт §3.2 задаёт для подписей
      диапазон 13–14.5, поэтому свожу к двум краям: 14.5 — подпись, несущая
      смысл (описание карточки, подпись цифры), 13.5 — служебная мета.

   15.5 (текст внутри карточки) НЕ трогаю: он уже единый у четырёх
   компонентов и осмысленно отличается от 16.5 body. Кегли заголовочного
   яруса (54/38/34) — закон паспорта, не касаюсь. Итого 17 → 13 кеглей. */
.feat-t{ font-size: 19px }
.tl .step-t{ font-size: 17px }   /* именно .tl .step-t — в site.css:354 селектор из двух классов */
.svc-d, .svc-go, .proof{ font-size: 14.5px }

/* Уважение к prefers-reduced-motion (§7.2.5): подъёмов нет вовсе. */
@media(prefers-reduced-motion: reduce){
  .svc-card:hover, .ct:hover, .feat-i:hover{ transform: none }
}


/* ════════════════════════════════════════════════════════════════════════════
   ШКАЛА РИТМА (задача владельца 30.07: «то отступов практически нет,
   то они большие» — разделы /uslugi/… и /treningi/…)

   ЗАМЕР ДО (E-tools/rhythm.py, 16 страниц, 176 стыков полос + 320 внутренних):
     между полосами (pb+pt):  116 ×3 · 128 ×17 · 140 ×13 · 144 ×67 · 168 ×76
     внутри полос:            10 ×56 · 14 ×13 · 20 ×132 · 26 ×22 · 56 ×42
   Пять номиналов там и пять здесь, и ни один не назначен — все получились
   сложением паддингов соседних полос (84/60/44) и разных margin-правил.
   Отсюда и ощущение рваности: 10 px рядом с 168 px без внятных ступеней.

   ШКАЛА — четыре номинала, все из шкалы паспорта §4.2 (4/8/12/16/24/32/48/64/80):
     12 px  — внутри группы: абзац → абзац
     16 px  — заголовок → его содержимое (закон близости: меньше, чем между группами)
     48 px  — между смысловыми группами внутри полосы
    144 px  — между полосами (сумма pb + pt на стыке)
   Соотношение 12 : 48 : 144 = 1 : 4 : 12 — ступени различимы глазом, и
   закон §4.2 «между полосами воздуха больше, чем внутри любой» выполняется
   с запасом. Единственное сознательное исключение — стык двух band-soft
   (120 px): паспорт §4.2 требует, чтобы склеенные лёгкие полосы стояли
   теснее, и это правило сильнее единообразия.

   Мобильные значения масштабируются тем же clamp-приёмом, что в базе,
   иначе сквозной файл сломал бы мобильную шкалу (протокол: повторять
   брейкпоинты базы). На 390 px: стык 76 px, между группами 32 px.
   ════════════════════════════════════════════════════════════════════════════ */

/* — внутри полос — */
.band-soft > .wrap > * + *{ margin-top: clamp(32px, 3.4vw, 48px) }
.band-soft > .wrap > * + .b-h{ margin-top: clamp(32px, 3.4vw, 48px) }
.band-soft > .wrap > .b-h + *:not(p){ margin-top: 16px }
.band > .wrap > .b-h + *:not(p){ margin-top: 16px }
.band-soft p + p{ margin-top: 12px }
.band .b-h, .b-h{ margin-bottom: 16px }

/* — стыки полос: приводим все к 144 px (на 390 px — 76 px) —
   «сильная + сильная» давала 168: у второй уменьшаем верхний паддинг.
   `.band:not(.band-soft):not(.band-tight)` — именно так, потому что в разметке
   у полос класс `band` плюс модификатор, и без :not() правило задело бы
   склеенные band-soft, где по §4.2 нужно теснее. */
.band:not(.band-soft):not(.band-tight) + .band:not(.band-soft):not(.band-tight){
  padding-top: clamp(32px, 4.2vw, 60px);
}
/* «служебная вставка + сильная полоса» давала 128 — добираем нижним паддингом */
.band-tight{ padding-bottom: clamp(32px, 4.2vw, 60px) }
/* герой + первая полоса давал 116/140 — выравниваем на 144 */
.phero + .band{ padding-top: clamp(32px, 6vw, 88px) }

/* Запись без текста (перенос с Тильды: там она тоже пустая). Обычные отступы
   давали под заголовком четверть экрана белизны — страница читалась как
   сломанная, хотя она просто короткая. Правило здесь, а не в site.css:
   `.phero + .band` выше по специфичности и перебивало бы его. */
.phero + .band-pusto{ padding-top: 22px }
.band-pusto{ padding-bottom: 22px }
.band-pusto .post-nav{ display: none }
.band-pusto .post-back{ margin-top: 0 }

/* ═══════════════ Анимации: выбор владельца 09.08 (приёмы 2,3,5,6,7,9) ═══════════════
   Полосы .band уже появляются наблюдателем в site.js — это не трогаем.
   Здесь — движение ВНУТРИ полос: карточки, шаги, чипы, фото, кнопка.

   Класс .vidno вешает обработчик прокрутки (static/anim.js), а не наблюдатель:
   IntersectionObserver и CSS animation-timeline браузер придерживает в фоновой
   и скрытой вкладке — проверено 09.08 на демо, анимаций там просто не видно.
   Обработчик прокрутки срабатывает везде и стоит доли миллисекунды. */

/* 2. Карточки услуг — лесенкой, а не хором */
.js-anim .svc-card{opacity:0;transform:translateY(20px);
  transition:opacity .65s cubic-bezier(.16,1,.3,1), transform .65s cubic-bezier(.16,1,.3,1)}
.js-anim .svc-card.vidno{opacity:1;transform:none}
.js-anim .svc-card:nth-child(2){transition-delay:.09s}
.js-anim .svc-card:nth-child(3){transition-delay:.18s}
.js-anim .svc-card:nth-child(4){transition-delay:.27s}
.js-anim .svc-card:nth-child(5){transition-delay:.36s}
.js-anim .svc-card:nth-child(6){transition-delay:.45s}

/* 3. Факты первого экрана. Намеренно НЕ счётчик: крутящиеся цифры читаются
   как приём маркетолога и вызывают вопрос «а это правда?» */
.js-anim .hero .chip{opacity:0;transform:translateY(14px) scale(.96);
  transition:opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1)}
.js-anim .hero .chip.vidno{opacity:1;transform:none}
.js-anim .hero .chip:nth-child(2){transition-delay:.1s}
.js-anim .hero .chip:nth-child(3){transition-delay:.2s}

/* 5. Полоса прочитанного — под шапкой, ширину ведёт обработчик */
.chital{position:fixed;left:0;top:var(--hdr-h,64px);height:3px;width:100%;z-index:40;
  pointer-events:none;background:transparent}
.chital i{display:block;height:100%;width:var(--p,0%);
  background:linear-gradient(90deg,var(--violet),#7C6BEA);transition:width .08s linear}

/* 6. Фото — мягкое приближение, без параллакса */
.js-anim .hero img,.js-anim .about-foto img{transform:scale(1.05);opacity:.85;
  transition:transform 1.05s cubic-bezier(.16,1,.3,1), opacity .8s}
.js-anim .hero img.vidno,.js-anim .about-foto img.vidno{transform:none;opacity:1}

/* 7. Кнопка — отклик на действие. Не эффект, а ощущение качества */
.btn{transition:transform .18s cubic-bezier(.16,1,.3,1), box-shadow .18s, background .18s, color .18s}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0)}

/* 9. Три шага — по очереди, линия под ними дорастает */
.js-anim .tl .step{opacity:0;transform:translateY(18px);
  transition:opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1)}
.js-anim .tl .step.vidno{opacity:1;transform:none}
.js-anim .tl .step:nth-child(2){transition-delay:.12s}
.js-anim .tl .step:nth-child(3){transition-delay:.24s}
.shagi-liniya{height:2px;background:var(--line);border-radius:2px;margin-top:14px;overflow:hidden}
.shagi-liniya i{display:block;height:100%;width:var(--shagi,0%);background:var(--violet);
  transition:width .35s cubic-bezier(.16,1,.3,1)}

/* «меньше движения» в системе — показываем всё сразу */
@media (prefers-reduced-motion:reduce){
  .js-anim .svc-card,.js-anim .hero .chip,.js-anim .tl .step,
  .js-anim .hero img,.js-anim .about-foto img{opacity:1;transform:none;transition:none}
  .chital i,.shagi-liniya i{transition:none}
}

/* Цитата в записи (заявка №7): слова клиента или выдержка — это доказательство,
   а не украшение, поэтому отличается от абзаца, но без кавычек-картинок и курсива
   во всю ширину: читать длинный курсив тяжело. */
.post-quote{margin:18px 0;padding:2px 0 2px 18px;border-left:3px solid var(--violet,#5B4CE0);
  color:var(--muted,#5C6373);font-size:1.02em;line-height:1.6}
.post-quote b{color:var(--ink,#14161C)}

/* «### » — подзаголовок поменьше (доработка №7, 11.08). Ступень между
   b-sub и жирным началом абзаца: в длинных записях одного уровня не хватало. */
.post-body .b-sub3{font-size:17.5px;font-weight:700;letter-spacing:-.01em;
  margin:18px 0 6px;color:var(--ink,#14161C)}


/* ── Липкая кнопка на телефоне ведёт в форму заявки, а не в WhatsApp ──────
   Решение владельца 07.09: заявка с сайта попадает в кабинет и в карточку
   человека, переписка в мессенджере — никуда. Зелёный цвет был цветом
   WhatsApp и обещал уход в мессенджер; кнопка стала фирменной.
   Геометрия остаётся в site.css (.wa-fab) — он заморожен, здесь только вид. */
.wa-fab.zv-fab{background:var(--violet,#5B4CE0);
  box-shadow:0 10px 30px rgba(91,76,224,.34)}
.wa-fab.zv-fab:hover,.wa-fab.zv-fab:active{background:var(--violet-d,#4A3CC4)}
