@import url("fonts.css");

/* ==========================================================================
   ДЕНТАЛ МЕД — вариант 1 «Ателье улыбки»
   Палитра: тёплый беж / графит / золото. Антиква + гротеск.
   ========================================================================== */

:root{
  --c-light:#EAE8E8;
  --c-light-2:#F4F2F0;
  --c-paper:#FBFAF9;
  --c-dark:#14151D;
  --c-dark-2:#1D1E28;
  --c-gold:#B38C61;          /* акцент на ТЁМНОМ фоне и крупная декоративная графика */
  --c-gold-ink:#7E5A38;      /* тот же акцент для ТЕКСТА и иконок на СВЕТЛОМ фоне: AA >= 4.8:1 */
  --c-gold-btn:#8F6B41;      /* заливка кнопки: белый текст на ней даёт 4.83:1 */
  --c-gold-soft:#DAC8B7;
  --grad-gold:linear-gradient(270deg,#b38b61,#dac8b7);
  --c-dark-10:rgba(20,21,29,.10);
  /* прозрачности подняты до порогов WCAG AA (4.5:1) на всех фонах палитры */
  --c-dark-40:rgba(20,21,29,.64);
  --c-dark-60:rgba(20,21,29,.74);
  --c-light-40:rgba(234,232,232,.60);
  --c-light-60:rgba(234,232,232,.78);
  --fill-initial:#CDCDCD;

  --ease-menu:cubic-bezier(.6,.14,0,1);
  --ease-out-quint:cubic-bezier(.22,1,.36,1);
  --slide-ease:cubic-bezier(.24,.43,.15,.97);
  --default-ease:ease-in-out;

  /* ЕДИНАЯ СЕТКА КОНТЕНТА (LAYOUT-STANDARDS §1.А)
     Один max-width на весь сайт + плавный vw-отступ. Ступенчатых контейнеров нет.
     1440px — верх диапазона «портфолио/галереи» (§2): сайт медийный, полноэкранный.
     Формула width:min(1440px,92vw) монотонна — ширина контента НИКОГДА не убывает
     с ростом вьюпорта (модель padding+cap давала провал 1313 -> 1296 между 1440 и 1636,
     из-за чего на 1536 шапка не помещалась в строку).
       360:331  390:359  414:381  768:707  820:754  844:777  1024:942  1180:1086
       1280:1178  1440:1325  1536:1413  1568+:1440 (поля растут)  1920:1440  2560:1440
     --grid-inset — фактический отступ от края экрана до колонки контента; им же
     выравниваются full-bleed-секции (пиннированный каталог, лента, подписи медиа). */
  --grid-max:1440px;
  --grid-fluid:92vw;
  --grid-inset:max(4vw,calc((100vw - var(--grid-max)) / 2));
  --grid-measure:80ch;

  --header-h:76px;
  --gut:var(--grid-inset);
  --serif:"Playfair Display",Georgia,"Times New Roman",serif;
  --sans:"Manrope","Helvetica Neue",Arial,sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0;background:var(--c-light);color:var(--c-dark);
  font-family:var(--sans);font-size:17px;line-height:1.55;font-weight:400;
  -webkit-font-smoothing:antialiased;overflow-x:clip;
}
body.is-locked{overflow:hidden}
img,video,svg{display:block;max-width:100%}
img{height:auto}
a{color:inherit;text-decoration:none}
button,input,textarea,select{font:inherit;color:inherit}
button{background:transparent;border:0;padding:0;cursor:pointer;text-align:inherit}
h1,h2,h3,h4,h5{margin:0;font-weight:400;font-family:var(--serif);letter-spacing:-.01em}
p{margin:0 0 1em}
ul{margin:0;padding:0;list-style:none}
figure{margin:0}
dl,dd{margin:0}
::selection{background:var(--c-gold);color:#fff}

section{scroll-margin-top:calc(var(--header-h) + 24px)}
h1,h2,h3,[id]{scroll-margin-top:calc(var(--header-h) + 24px)}

/* Типографические классы --------------------------------------------------- */
.t-display{font-family:var(--serif);font-size:clamp(44px,8.4vw,148px);line-height:.94;letter-spacing:-.02em}
.t-h1{font-family:var(--serif);font-size:clamp(38px,6.2vw,104px);line-height:1;letter-spacing:-.02em}
.t-h2{font-family:var(--serif);font-size:clamp(30px,4.2vw,68px);line-height:1.05;letter-spacing:-.015em}
.t-h3{font-family:var(--serif);font-size:clamp(24px,2.5vw,40px);line-height:1.12}
.t-h4{font-family:var(--serif);font-size:clamp(20px,1.7vw,27px);line-height:1.2}
.it{font-style:italic}
.lead{font-size:clamp(17px,1.35vw,22px);line-height:1.5;color:var(--c-dark-60);max-width:62ch}
.label{font-family:var(--sans);font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--c-gold-ink)}
.small{font-size:14px;line-height:1.5;color:var(--c-dark-60)}
.xsmall{font-size:12.5px;line-height:1.5;color:var(--c-dark-40)}
.gold{color:var(--c-gold-ink)}
.dark .gold,[data-theme="dark"] .gold{color:var(--c-gold-soft)}

.wrap{width:min(var(--grid-max),var(--grid-fluid));max-width:min(var(--grid-max),var(--grid-fluid));
  margin-inline:auto;padding-inline:0;box-sizing:border-box}
/* measure: заголовки балансируем, длинные абзацы не растягиваем (LAYOUT-STANDARDS §5).
   Исключены заголовки, которые режет SplitType (split-title, cat__name, pre-cta__big):
   там перенос строк должен оставаться детерминированным. */
.t-h2,.t-h3,.t-h4{text-wrap:balance}
p,.lead,.small,.xsmall{text-wrap:pretty}
.sec p:not([class]):not([style*="max-width"]){max-width:var(--grid-measure)}

/* ★ РАЗРЕЗАННЫЙ ТЕКСТ: СЛОВО — НЕРАЗРЫВНЫЙ АТОМ ============================
   SplitType заворачивает КАЖДОЕ слово в <div class="word" style="display:inline-block">
   и каждый символ в такой же inline-block. inline-block — это БЛОЧНЫЙ КОНТЕЙНЕР,
   поэтому он НАСЛЕДУЕТ text-wrap:balance/pretty от заголовка и абзаца — и движок
   начинает «балансировать» САМО СЛОВО из атомарных символов. В WebKit это давало
   ровно то, что на скриншоте владельца: «Наша» -> «Наш» + «а» на следующей строке,
   «диагностика,» -> запятая отдельной строкой, точка после курсива — отдельной строкой.
   Лечим на уровне вёрстки, а не подгонкой ширин:
     1) на всех разрезаемых узлах режим переноса возвращаем в обычный;
     2) слову запрещаем ломаться внутри себя вовсе (white-space:nowrap);
     3) знак препинания, приклеенный из соседнего узла (main.js §4a), не наследует курсив.
   Ни один движок после этого не может разорвать слово — это не эвристика, а запрет. */
[data-rv="lines"],[data-rv="chars"],[data-fill],.split-title,.cat__name,.ln,.line-mask{
  text-wrap:wrap;text-wrap-mode:wrap;text-wrap-style:auto}
/* ПОРЯДОК ЗДЕСЬ КРИТИЧЕН. white-space — это СОКРАЩЕНИЕ для
   white-space-collapse + text-wrap-mode. Любое «text-wrap: wrap» или
   «text-wrap-mode: wrap», написанное ПОСЛЕ white-space:nowrap, отменяет ровно ту
   часть, ради которой правило существует: computed white-space снова становится
   normal, и запрет переноса внутри слова бесшумно исчезает.
   Поэтому на обёртках слов гасим ТОЛЬКО стиль переноса (балансировку),
   а режим переноса задаём последним — через сам white-space. */
.word,.w{display:inline-block;text-wrap-style:auto;white-space:nowrap}
.char{display:inline-block;text-wrap-style:auto;white-space:pre}
.char.is-glued{font-style:normal}
/* Связка «однобуквенный союз + следующее слово» (main.js §4a): обычный
   строчный контейнер, внутри которого перенос запрещён. Пара ведёт себя как
   одно слово, но каждое слово внутри сохраняет свою анимацию. */
.tie{white-space:nowrap}
/* Слово не должно и переносом-дефисом разъезжаться на разрезанных заголовках */
[data-rv="lines"],[data-rv="chars"],[data-fill]{hyphens:manual;-webkit-hyphens:manual}

/* ЗАГОЛОВОК В ДВЕ ОСМЫСЛЕННЫЕ СТРОКИ (LAYOUT-STANDARDS §7, 3-line-guard).
   «Технологии, ради которых | к нам едут через город» — разрыв по границе
   смысловых частей, а не «Технологии, ради / которых к нам / едут через город».
   Числа не на глаз: в Playfair Display строка «Технологии, ради которых» имеет
   ширину 12,20em, вторая (курсив) — 10,03em, а 1ch = 0,60em. Кап 21ch = 12,60em:
   первая часть влезает (12,20), а следующее слово «к» (+0,75em) уже нет —
   перенос ГАРАНТИРОВАННО падает в нужное место, а не «как получится». */
.h-2line{max-width:21ch}
/* На 360–420 px нижняя ступень clamp у .t-h2 (30px) шире, чем 12,20em помещается
   в колонку 331–386 px, — только здесь кегль опускаем, иначе строк три. */
@media (max-width:420px){
  .h-2line.t-h2{font-size:clamp(23px,6.6vw,27px);line-height:1.08}
}
.sec{padding-block:clamp(72px,9vw,150px);position:relative}
.dark{background:var(--c-dark);color:var(--c-light)}
.dark .lead,.dark .small,[data-theme="dark"] .lead,[data-theme="dark"] .small{color:var(--c-light-60)}
.dark .xsmall,[data-theme="dark"] .xsmall{color:rgba(234,232,232,.7)}
.dark .label,[data-theme="dark"] .label{color:var(--c-gold-soft)}
[data-theme="dark"] .t-h2,[data-theme="dark"] .t-h3,[data-theme="dark"] .t-h4{color:inherit}

/* Кнопки -------------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:14px;white-space:nowrap;max-width:100%;
  padding:14px 22px;border-radius:999px;border:1px solid var(--c-dark);
  background:var(--c-dark);color:var(--c-light);
  font-size:14.5px;font-weight:600;letter-spacing:.005em;cursor:pointer;
  transition:background-color .3s var(--default-ease),color .3s var(--default-ease),border-color .3s var(--default-ease);
}
.btn .ic{width:20px;height:20px;flex:none;transition:transform .45s var(--ease-out-quint)}
.btn:hover{background:transparent;color:var(--c-dark)}
.btn:hover .ic{transform:rotate(180deg)}
.btn-ghost{background:transparent;color:var(--c-dark)}
.btn-ghost:hover{background:var(--c-dark);color:var(--c-light)}
.btn-gold{background:var(--c-gold-btn);border-color:var(--c-gold-btn);color:#fff}
.btn-gold:hover{background:transparent;color:var(--c-gold-ink);border-color:var(--c-gold-ink)}
.dark .btn{background:var(--c-light);border-color:var(--c-light);color:var(--c-dark)}
.dark .btn:hover{background:transparent;color:var(--c-light)}
.dark .btn-gold{background:var(--c-gold-btn);border-color:var(--c-gold-btn);color:#fff}
.dark .btn-gold:hover{background:transparent;color:var(--c-gold-soft);border-color:var(--c-gold-soft)}
.btn-lg{padding:18px 30px;font-size:16px}

.link-arrow{display:inline-flex;align-items:center;gap:9px;font-size:15px;font-weight:600;
  border-bottom:1px solid currentColor;padding-bottom:2px;transition:opacity .3s}
.link-arrow .ic{width:14px;height:14px;transition:transform .3s var(--default-ease)}
.link-arrow:hover .ic{transform:translate(3px,-3px)}

section:has(.decor){overflow:hidden}

/* скип-ссылка: была уведена за экран без возврата по фокусу — клавиатурный
   пользователь не мог перепрыгнуть навигацию (WCAG 2.4.1) */
.skip{position:absolute;left:-9999px;top:0;z-index:400;padding:12px 20px}
.skip:focus{left:var(--grid-inset);top:10px;padding:12px 20px;border-radius:999px;
  background:var(--c-dark);color:var(--c-light);font-size:14px;font-weight:600;
  outline:2px solid var(--c-gold);outline-offset:2px}

/* ШАПКА ==================================================================== */
/* top:0 задан ЯВНО и без margin: на планшете шапка не должна «висеть в воздухе».
   height считаем вместе с env(safe-area-inset-top): под вырезом iPad/iPhone
   строка шапки не наезжает на статус-бар, а фон доходит до самой кромки экрана.
   Без viewport-fit=cover env() = 0 — на обычных экранах ничего не меняется. */
/* ── ПЛАШКА ШАПКИ ВСЕГДА НЕПРОЗРАЧНА (правка владельца 11.08) ──────────────
   БЫЛО: три источника фона под меню — прозрачность (вверху страницы),
   ГРАДИЕНТНЫЙ СКРИМ .hdr::before и непрозрачный фон .is-stuck, причём цвет
   ТЕКСТА назначал JS (класс .is-dark по пробе elementsFromPoint), а цвет
   ФОНА определял контент страницы. Две независимые величины — и они
   расходились:
     · вверху главной на >860 px шапка светлотемая (текст графитовый), а её
       правая половина висит НАД тёмным видео. Скрим гасится к низу до нуля,
       поэтому «Контакты», телефон и подпись логотипа печатались тёмным по
       тёмному кадру — то самое «чёрное меню на чёрном фоне»;
     · над светлым фото/секцией без data-theme срабатывала обратная пара —
       светлый текст по светлому;
     · переход .is-dark <-> обычная тема ехал анимацией
       `background-color .32s` + `color .26s`. В СЕРЕДИНЕ перехода фон и текст
       одновременно проходят через средне-серый — контраст падает до ~1:1.
       В WebKit шапка — fixed-слой с собственным композитным слоем, и
       полукадр такого перехода там залипает (на соседнем dental-med-2 у
       клиентки на macOS Safari именно так застревала «белёсая» шапка).
   СТАЛО: плашка НЕПРОЗРАЧНА в любом состоянии прокрутки, а фон и цвет текста
   заданы ОДНОЙ парой правил и переключаются МГНОВЕННО и ВМЕСТЕ. Разойтись им
   больше нечем: даже если JS ошибётся с темой секции, внутри шапки всегда
   светлый текст на тёмной плашке или тёмный на светлой. Полупрозрачных
   градиентов и backdrop-filter в шапке нет вовсе — залипать в WebKit нечему. */
.hdr{
  position:fixed;top:0;right:0;left:0;bottom:auto;margin:0;z-index:120;
  height:calc(var(--header-h) + env(safe-area-inset-top,0px));
  padding-top:env(safe-area-inset-top,0px);
  display:flex;align-items:center;
  color:var(--c-dark);background:var(--c-light);
  box-shadow:0 1px 0 rgba(20,21,29,.09);
  /* НИКАКИХ переходов цвета фона и текста: пара «плашка + текст» обязана
     меняться одним кадром, иначе появляется промежуточное состояние без
     контраста (см. комментарий выше). */
  transition:none;
}
/* Скрим удалён вместе с прозрачностью — плашка сама себе подложка. */
.hdr::before{content:none}
.hdr__in{display:flex;align-items:center;gap:clamp(14px,2vw,34px);width:100%;min-width:0}
/* ЕДИНСТВЕННАЯ пара «фон + цвет текста» для тёмной темы шапки.
   .is-stuck фон больше НЕ меняет — он и так непрозрачный; класс оставлен,
   на нём висит только усиление тени под приклеенной шапкой. */
.hdr.is-dark{background:var(--c-dark);color:var(--c-light);box-shadow:0 1px 0 rgba(234,232,232,.12)}
.hdr.is-stuck{box-shadow:0 1px 0 rgba(20,21,29,.09),0 8px 24px -18px rgba(20,21,29,.5)}
.hdr.is-stuck.is-dark{box-shadow:0 1px 0 rgba(234,232,232,.12),0 8px 24px -18px rgba(0,0,0,.6)}
/* ОТКРЫТОЕ МОБИЛЬНОЕ МЕНЮ. .mmenu — тёмная панель во весь экран (z-index 115),
   шапка лежит ПОВЕРХ неё (z-index 120). Если страница светлотемая, поверх
   тёмной панели оставалась светлая плашка с графитовым крестиком — бургер
   сливался с панелью ровно так же, как на соседнем сайте. Пока меню открыто,
   шапка принудительно тёмная и совпадает с панелью. */
body.menu-open .hdr{background:var(--c-dark);color:var(--c-light);box-shadow:none}

/* min-height — тап-цель логотипа: без неё бокс логотипа 26 px по высоте (WCAG 2.5.8) */
.logo{display:flex;align-items:center;gap:11px;flex:none;color:inherit;min-height:44px}
.logo svg{width:40px;height:26px;overflow:visible}
.logo svg path{stroke:currentColor;fill:none;stroke-width:2.1;stroke-linecap:round}
.logo b{font-family:var(--serif);font-size:19px;font-weight:500;line-height:1.05;letter-spacing:-.01em;display:block}
/* ПОДПИСЬ ЛОГОТИПА: ОПАСНОСТЬ ДВОЙНОЙ ПРОЗРАЧНОСТИ.
   Разметка логотипа — <span><b>Дентал Мед</b><span>эстетическая…</span></span>,
   то есть селектор `.logo span` попадал В ОБА span'а. opacity — свойство
   ГРУППЫ: внешние .62 множились на внутренние .62 = 0.384, и подпись во всех
   состояниях шла контрастом 2,4:1 (на светлой плашке) — 3,2:1 (на тёмной),
   а заодно на 62 % гасилось и само название клиники внутри внешнего span.
   Прозрачность здесь не нужна вовсе: приглушение задаём ЦВЕТОМ, который
   считается и проверяется (тёмная плашка 8,6:1, светлая 6,9:1). */
.logo span{font-size:9.5px;letter-spacing:.22em;text-transform:uppercase;display:block;font-weight:600;opacity:1}
.logo span span,.logo i{color:var(--c-dark-60)}
.hdr.is-dark .logo span span,.hdr.is-dark .logo i,
body.menu-open .hdr .logo span span,body.menu-open .hdr .logo i{color:var(--c-light-60)}

.nav{display:flex;align-items:center;gap:clamp(10px,1.5vw,26px);margin-left:clamp(10px,2vw,40px);
  flex:0 1 auto;min-width:0}
.nav a{position:relative;font-size:14.5px;font-weight:500;padding:6px 0;opacity:.82;transition:opacity .3s}
.nav a::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1px;background:currentColor;transition:right .4s var(--ease-out-quint)}
.nav a:hover{opacity:1}
.nav a:hover::after,.nav a.is-active::after{right:0}
.nav a.is-active{opacity:1;color:var(--c-gold-ink)}
.hdr.is-dark .nav a.is-active{color:var(--c-gold-soft)}

.hdr__right{margin-left:auto;display:flex;align-items:center;gap:clamp(10px,1.3vw,20px);min-width:0}
.hdr__cta{flex:none}
/* КНОПКА В ШАПКЕ НА ТЁМНОЙ ПЛАШКЕ. Базовый .btn — графитовая заливка со
   светлым текстом: на тёмной плашке текст читался (13:1), а САМА кнопка как
   объект пропадала — её граница давала к фону шапки ~1,3:1 при требуемых 3:1
   (WCAG 1.4.11), пилюля превращалась в тёмное пятно на тёмном. Инвертируем —
   так же, как это уже сделано для .dark .btn в остальном макете.
   Ховер базового .btn (`background:transparent;color:var(--c-dark)`) на тёмной
   плашке дал бы графит по графиту — перекрываем и его. */
.hdr.is-dark .hdr__cta,body.menu-open .hdr .hdr__cta{
  background:var(--c-light);border-color:var(--c-light);color:var(--c-dark)}
.hdr.is-dark .hdr__cta:hover,body.menu-open .hdr .hdr__cta:hover{
  background:transparent;border-color:var(--c-light);color:var(--c-light)}
.hdr__cta .s{display:none}
@media (max-width:1340px){.hdr__cta .l{display:none}.hdr__cta .s{display:inline}}
.slotline{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;letter-spacing:.01em;
  white-space:nowrap;flex:0 1 auto;min-width:0;overflow:hidden}
/* Индикатор «есть запись». На тёмной плашке #3FA97A даёт 5,9:1, на светлой —
   всего 2,3:1 при норме 3:1 для нетекстового элемента (WCAG 1.4.11).
   Оттенок тот же зелёный, просто на две ступени темнее — 3,4:1. */
.slotline .dot{width:7px;height:7px;border-radius:50%;background:#2E8B63;flex:none;animation:pulse 2.4s ease-in-out infinite}
.hdr.is-dark .slotline .dot{background:#3FA97A}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}

.phones{position:relative}
.phones__top{display:flex;align-items:center;gap:7px;font-size:15px;font-weight:600;cursor:pointer;white-space:nowrap}
.phones__top .ic{width:13px;height:13px;transition:transform .4s var(--ease-out-quint)}
.phones:hover .phones__top .ic{transform:rotate(180deg)}
.phones__list{
  position:absolute;top:calc(100% + 12px);right:0;min-width:270px;
  background:var(--c-dark);color:var(--c-light);border-radius:16px;padding:8px;
  clip-path:polygon(0 0,100% 0,100% 0,0 0);
  transition:clip-path .8s var(--ease-menu);
}
.phones:hover .phones__list,.phones:focus-within .phones__list,.phones.is-open .phones__list{clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}
.phones.is-open .phones__top .ic{transform:rotate(180deg)}
.phones__list a{display:block;padding:11px 14px;border-radius:10px;transition:background-color .3s}
.phones__list a:hover{background:rgba(255,255,255,.08)}
.phones__list b{display:block;font-size:16px;font-weight:600}
.phones__list i{display:block;font-style:normal;font-size:12px;opacity:.55;margin-top:2px}

.burger{width:44px;height:44px;border:1px solid currentColor;border-radius:50%;background:none;cursor:pointer;
  display:none;align-items:center;justify-content:center;flex:none;transition:background-color .3s,color .3s}
.burger span{display:block;width:17px;height:1.4px;background:currentColor;position:relative;transition:background-color .2s}
.burger span::before,.burger span::after{content:"";position:absolute;left:0;width:17px;height:1.4px;background:currentColor;transition:transform .4s var(--ease-out-quint)}
.burger span::before{top:-5px}.burger span::after{top:5px}
body.menu-open .burger span{background:transparent}
body.menu-open .burger span::before{transform:translateY(5px) rotate(45deg)}
body.menu-open .burger span::after{transform:translateY(-5px) rotate(-45deg)}

/* мобильное меню */
.mmenu{position:fixed;inset:0;z-index:115;background:var(--c-dark);color:var(--c-light);
  padding:calc(var(--header-h) + env(safe-area-inset-top,0px) + 30px) var(--gut) calc(40px + env(safe-area-inset-bottom,0px));
  clip-path:polygon(0 0,100% 0,100% 0,0 0);transition:clip-path .8s var(--ease-menu);
  overflow-y:auto;display:flex;flex-direction:column;gap:6px}
body.menu-open .mmenu{clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}
.mmenu a{font-family:var(--serif);font-size:clamp(28px,7vw,44px);line-height:1.25;padding:6px 0}
.mmenu a.is-active{color:var(--c-gold-soft)}
.mmenu__foot{margin-top:auto;padding-top:28px;border-top:1px solid rgba(255,255,255,.15);display:grid;gap:6px;justify-items:start}
/* Главный CTA в мобильном меню. Показывается РОВНО там, где кнопка в шапке
   уже не помещается в строку (<=400 px, см. правило ниже): без этого на узких
   телефонах «Бесплатная консультация» пропадала из постоянной навигации совсем,
   и добраться до формы можно было только прокруткой страницы до конца. */
.mmenu a.mmenu__cta{display:none}
/* Специфичность выше, чем у .mmenu a (кегль пунктов меню 28-44 px) и чем у
   мобильного правила .btn{white-space:normal}: кнопка должна остаться кнопкой,
   а не превратиться в трёхстрочный пункт меню. */
@media (max-width:400px){.mmenu a.mmenu__cta{display:inline-flex;justify-self:stretch;
  margin-bottom:18px;font-size:15px;line-height:1.2;padding:16px 22px;gap:10px;white-space:nowrap}}
.mmenu .xsmall,.mmenu .small,.mmenu__foot .xsmall{color:rgba(234,232,232,.78)}

/* ПЕРЕХОД МЕЖДУ СТРАНИЦАМИ ================================================= */
.ptrans{position:fixed;inset:0;z-index:300;pointer-events:none;display:grid;place-items:center;opacity:0}
.ptrans.is-on{pointer-events:all}
.ptrans__mask{position:absolute;left:50%;top:50%;width:180vmax;height:180vmax;margin:-90vmax 0 0 -90vmax;
  background:var(--c-dark);border-radius:50%;transform:scale(0)}
.ptrans__logo{position:relative;width:min(240px,52vw);color:var(--c-gold-soft);opacity:0}
.ptrans__logo svg{width:100%;height:auto;overflow:visible}
.ptrans__logo path{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}

/* HERO SPLIT =============================================================== */
.hero{position:relative;min-height:100svh;display:grid;align-content:space-between;overflow:hidden;
  padding-top:calc(var(--header-h) + clamp(16px,2.4vw,38px));padding-bottom:clamp(24px,3vw,44px);row-gap:clamp(20px,2.6vw,40px)}
.hero__bg{position:absolute;inset:0;display:grid;grid-template-columns:1fr 1fr}
/* левая половина — не «пустой белый блок», а тёплая световая панель с мягким градиентом */
.hero__bg .l{position:relative;background:
  radial-gradient(120% 96% at 8% 4%,#FBFAF9 0%,#F2EFEC 44%,#E7E3DE 100%)}
.hero__bg .l::after{content:"";position:absolute;inset:0;
  background:radial-gradient(58% 46% at 22% 30%,rgba(179,140,97,.13),rgba(179,140,97,0) 70%)}
.hero__bg .r{position:relative;overflow:hidden;background:var(--c-dark)}
.hero__bg .r video,.hero__bg .r img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Кадр-заглушка живёт ПОД видео и виден, пока видео не пошло: на iOS в режиме
   энергосбережения автоплей запрещён системой, и без подложки правая панель
   осталась бы чёрной. object-fit тот же — стык кадров незаметен. */
.media-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.hero__bg .r video{z-index:1}
/* Видимая кнопка запуска. Появляется ТОЛЬКО когда движок убедился, что
   автозапуск заблокирован (main.js §2a) — в обычной ситуации её нет. */
/* Кнопка стоит в свободном правом верхнем углу кадра, а не по центру: центр
   занят заголовком героя, и заглушка поверх текста была бы хуже самой проблемы. */
.vplay{position:absolute;right:clamp(12px,2vw,22px);
  top:calc(var(--header-h) + env(safe-area-inset-top,0px) + 14px);z-index:5;
  width:52px;height:52px;border-radius:50%;display:none;place-items:center;
  background:rgba(20,21,29,.55);color:#fff;border:1px solid rgba(255,255,255,.72);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);cursor:pointer;
  transition:transform .3s var(--ease-out-quint),background-color .3s}
.vplay svg{width:20px;height:20px;margin-left:2px;fill:currentColor}
.vplay:hover{background:rgba(20,21,29,.78);transform:scale(1.06)}
.vplay:active{transform:scale(.94)}
.is-video-blocked .vplay{display:grid}
.vplay b{position:absolute;right:0;top:calc(100% + 8px);
  font-size:11.5px;font-weight:600;letter-spacing:.03em;white-space:nowrap;
  color:#fff;text-shadow:0 1px 6px rgba(20,21,29,.9)}
/* шов между панелями: медиа мягко втекает в светлую половину, жёсткой границы нет */
.hero__bg .r::before{content:"";position:absolute;inset:0;z-index:2;
  background:linear-gradient(90deg,#E7E3DE 0%,rgba(231,227,222,.72) 4%,rgba(231,227,222,0) 17%)}
/* нижняя «подложка» под правой колонкой текста: белый текст поверх светлого кадра
   без неё давал ~1,2:1 — читаемость восстановлена скримом, а не изменением цвета */
.hero__bg .r::after{content:"";position:absolute;inset:0;z-index:2;
  background:linear-gradient(180deg,rgba(20,21,29,.44) 0%,rgba(20,21,29,.18) 26%,
    rgba(20,21,29,.60) 46%,rgba(20,21,29,.74) 72%,rgba(20,21,29,.88) 100%)}
.hero__in{position:relative;z-index:2;width:100%;display:grid;grid-template-columns:minmax(0,1fr);
  row-gap:clamp(20px,2.6vw,40px);align-content:space-between}

/* верхний левый блок — лёгкий вход */
.hero__top{display:grid;grid-template-columns:minmax(0,1fr);justify-items:start;gap:clamp(10px,1vw,15px);
  min-width:0;max-width:min(50ch,calc(50vw - var(--gut) - 34px))}
.hero__kicker{margin:0}
/* ПРАВКА ВЛАДЕЛЬЦА 06.08: обещание («начинаем с бесплатной консультации…») —
   это первое, что читают, и на 1440 оно проигрывало по весу кнопке под ним.
   Поднимаем на одну ступень: 18-23 -> 20-26. Ширина в ch не менялась, поэтому
   число строк осталось прежним. */
.hero__promise{font-family:var(--serif);font-size:clamp(20px,1.62vw,26px);line-height:1.3;margin:0;color:var(--c-dark);max-width:min(34ch,100%)}
.hero__cta{display:flex;flex-wrap:wrap;align-items:center;gap:12px 20px;margin-top:2px;max-width:100%;min-width:0}
.hero__micro{margin:0;font-size:12.5px;line-height:1.5;color:var(--c-dark-60);max-width:min(52ch,100%)}

.hero__title{position:relative;margin:0;font-size:clamp(34px,min(6.4vw,11.4svh),104px)}
/* ПРАВКА ВЛАДЕЛЬЦА 06.08: слово «стоматология» уезжало на правую панель с видео
   и висело белым поверх кадра. Заголовок теперь целиком живёт на светлой
   половине: ширина ограничена ровно левой панелью (50vw минус поле и запас),
   а третья строка задана переносом в разметке (RU и EN).
   Побочный эффект намеренный: JS §3a ставит --split в точку шва панелей, и
   когда заголовок кончается ЛЕВЕЕ шва, значение упирается в ширину строки —
   светлый слой lay-2 просто не рисуется, текст ровный тёмный на бежевом.
   Только широкий экран: на узком панель одна и работает смыв золотом. */
@media (min-width:861px){
  .hero__title{max-width:calc(50vw - var(--gut) - 34px)}
  .hero__title .lay{white-space:normal;overflow-wrap:normal;hyphens:none}
}
.split-title{position:relative;display:block}
.split-title .lay{display:block}
.split-title .lay-1,.split-title .lay-2{position:absolute;inset:0;pointer-events:none}
.split-title .lay-2{color:var(--c-light);clip-path:polygon(var(--split,50%) 0,100% 0,100% 100%,var(--split,50%) 100%);
  text-shadow:0 2px 30px rgba(20,21,29,.55),0 1px 3px rgba(20,21,29,.32)}
.split-title .lay-1{color:var(--c-dark);clip-path:polygon(0 0,var(--split,50%) 0,var(--split,50%) 100%,0 100%)}
.split-title .lay-0{color:transparent}
.hero__meta{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap;max-width:100%}
.hero__meta .rt{text-align:right;color:#fff;max-width:min(32ch,100%);min-width:0}
.hero__meta .rt .xsmall{color:rgba(255,255,255,.86)}
.hero__meta .lt{max-width:min(38ch,100%);min-width:0}
.hero__cities b{display:block;font-size:15px;font-weight:600}
.rating{display:inline-flex;align-items:center;gap:9px;font-size:14px;font-weight:600;max-width:100%;
  border:1px solid var(--c-dark-10);border-radius:999px;padding:8px 15px;background:rgba(255,255,255,.62);margin-top:14px}
.rating .ic{width:15px;height:15px;color:var(--c-gold-ink)}
.line-mask{display:block;overflow:hidden;padding-bottom:.12em;margin-bottom:-.12em}

/* СЦЕНА-ЭМОЦИЯ ============================================================= */
.scene{position:relative;min-height:104svh;overflow:hidden;display:grid;place-items:center;background:var(--c-dark)}
/* стык «светлый герой -> тёмная сцена»: растушёвываем границу, а не рубим её.
   ── ПРАВКА 12.08: ТО ЖЕ САМОЕ СНИЗУ. Верхний стык был растушёван с самого
   начала, а НИЖНИЙ рубился: тёмный кадр с пациенткой (яркость ~45) обрывался
   в бумагу (яркость ~232) одной пиксельной строкой — на автоскане стыков это
   самый контрастный «срез» главной. Симметричная растушёвка снизу — тот же
   приём, что уже был сверху, поэтому дизайн не меняется, уходит только линия.
   Кнопка «Смотреть работы» лежит выше по стеку (z-index 4) и своей заливки
   не теряет — её читаемость правкой не затронута. */
/* inset снизу -2px: при дробной высоте секции наложение округлялось на пиксель
   вверх и в самой нижней строке проступал НЕрастушёванный кадр — замер показал
   ровно одну тёмную строку (61,62,67) между градиентом (232) и бумагой (234).
   overflow:hidden у .scene всё лишнее срезает, поэтому вынос безопасен. */
/* ── ПРАВКА ВЛАДЕЛЬЦА 12.08 (ред. 2): растушёвка КОРОТКАЯ и деликатная.
   Было по 150/140 px с молоком уже на трети полосы — на 1920 это ~14 vh
   белёсого шлейфа поверх кадра. Стало ≤7 vh, молоко собрано у самой кромки. */
.scene::before{content:"";position:absolute;inset:0 0 -2px;z-index:2;pointer-events:none;
  background-image:
    linear-gradient(180deg,var(--c-light) 0%,rgba(234,232,232,.55) 22%,rgba(234,232,232,.14) 55%,rgba(234,232,232,0) 100%),
    linear-gradient(0deg,var(--c-light) 0%,rgba(234,232,232,.55) 22%,rgba(234,232,232,.14) 55%,rgba(234,232,232,0) 100%);
  background-repeat:no-repeat;background-position:top center,bottom center;
  background-size:100% clamp(46px,7vh,84px),100% clamp(44px,6.5vh,80px)}
.scene__media{position:absolute;inset:-12% 0;}
.scene__media img,.scene__media video{width:100%;height:100%;object-fit:cover}
.scene::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(20,21,29,.56) 0%,rgba(20,21,29,.40) 34%,
    rgba(20,21,29,.54) 58%,rgba(20,21,29,.80) 100%)}
.scene__title{position:relative;z-index:3;color:#fff;text-align:center;padding-inline:var(--gut);width:100%;
  text-shadow:0 2px 34px rgba(20,21,29,.6),0 1px 4px rgba(20,21,29,.35)}
.scene__btm{position:absolute;left:0;right:0;bottom:clamp(24px,4vw,54px);z-index:4;display:flex;justify-content:center}

/* МИССИЯ ==================================================================== */
.mission{display:grid;grid-template-columns:minmax(220px,24%) minmax(0,1fr);gap:clamp(24px,4vw,72px);align-items:start}
/* aspect-ratio и обрезка живут на КАРТИНКЕ, а не на <figure>: подпись — сестра
   картинки внутри figure, и при aspect-ratio на самом figure она вылезала за
   его высоту, обрезалась overflow:hidden и налезала на «О клинике» ниже. */
/* grayscale(1) снят: портрет главврача был единственной ч/б карточкой врача на
   сайте (лента .avatars/.team__p/.doc__ph — цветная), и он выбивался из ленты.
   Осталась только мягкая градация контраста. */
.mission__ph{position:relative;border-radius:2px;filter:contrast(1.05)}
.mission__ph img{width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;border-radius:2px}
.mission__txt{max-width:38ch}
.avatars{display:flex;align-items:center;margin-top:22px}
.avatars img,.avatars .more{width:52px;height:52px;border-radius:50%;object-fit:cover;border:2px solid var(--c-light);margin-left:-14px}
.avatars img:first-child{margin-left:0}
.avatars .more{display:grid;place-items:center;background:var(--c-dark);color:var(--c-light);font-size:14px;font-weight:700}
.mission__big{margin-top:clamp(36px,5vw,80px)}
[data-fill] .char{transition:none}

/* ОБЛАКО ТЕГОВ ============================================================= */
.tags{display:flex;flex-wrap:wrap;gap:9px;margin-top:32px}
.tag{border:1px solid var(--c-dark-10);border-radius:999px;padding:10px 17px;font-size:14.5px;font-weight:500;
  background:transparent;cursor:pointer;transition:background-color .3s var(--default-ease),color .3s var(--default-ease),border-color .3s}
.tag:hover{background:var(--c-dark);color:var(--c-light);border-color:var(--c-dark)}
.tag.is-on{background:var(--c-dark);color:var(--c-light);border-color:var(--c-dark)}
.dark .tag{border-color:rgba(234,232,232,.2)}
.dark .tag:hover,.dark .tag.is-on{background:var(--c-light);color:var(--c-dark);border-color:var(--c-light)}
.tag:focus-visible,.slot:focus-visible,.acc__head:focus-visible,.cat__menu button:focus-visible,
.tech__list button:focus-visible,.btn:focus-visible,.link-arrow:focus-visible,a:focus-visible{
  outline:2px solid var(--c-gold);outline-offset:3px;border-radius:4px}

/* ★ ПИННИРОВАННЫЙ КАТАЛОГ НАПРАВЛЕНИЙ ====================================== */
.cat{position:relative;background:var(--c-dark);color:var(--c-light);overflow:hidden}
.cat__stage{height:100vh;height:100svh;position:relative;overflow:hidden;display:grid;grid-template-columns:44% 56%}
.cat__bg{position:absolute;inset:0;background:radial-gradient(120% 90% at 15% 0%,#262835 0%,#14151D 62%)}
/* visibility на неактивных слайдах: они смещены transform:translateX(±8%) и при
   opacity:0 всё равно занимают геометрию за краем экрана (на 1024 и 932×430 это
   давало вынос .cat__right/.cat__sub на 74–82 px) и остаются в таб-порядке.
   Переключается мгновенно при открытии и после доигранной анимации при закрытии. */
.cat__slide{position:absolute;inset:0;display:grid;grid-template-columns:44% 56%;opacity:0;pointer-events:none;
  visibility:hidden;
  transition:opacity .9s var(--slide-ease),transform .9s var(--slide-ease),filter .9s var(--slide-ease),
    visibility 0s linear .9s;
  transform:translateX(8%);filter:blur(6px)}
.cat__slide.is-active{opacity:1;transform:translateX(0);filter:blur(0);pointer-events:auto;visibility:visible;
  transition:opacity .9s var(--slide-ease) .08s,transform .9s var(--slide-ease) .08s,
    filter .9s var(--slide-ease) .08s,visibility 0s linear 0s}
.cat__slide.is-prev{opacity:0;transform:translateX(-8%);filter:blur(6px)}
.cat__left{position:relative}
.cat__ph{position:absolute;overflow:hidden;filter:contrast(1.04) saturate(.92)}
.cat__ph img{width:100%;height:100%;object-fit:cover}
.cat__ph.a{left:0;top:7%;width:46%;height:35%}
.cat__ph.b{left:20%;top:42%;width:52%;height:33%}
.cat__right{position:relative;padding:calc(var(--header-h) + 34px) var(--gut) clamp(120px,13vw,190px) clamp(18px,2.4vw,44px);
  display:flex;flex-direction:column;gap:16px;justify-content:center;
  /* max-width — это border-box, а правый padding равен var(--gut) и на 2560 достигает
     560 px: плоские 760px оставляли колонке 156 px контента, кнопка и описание
     обрезались. Кап считаем ОТ КОНТЕНТА: 760 + внешний отступ сетки. */
  max-width:calc(760px + var(--gut))}
.cat__desc{font-size:clamp(16px,1.2vw,19.5px);line-height:1.5;color:var(--c-light-60);max-width:46ch}
.cat__sub{display:grid;gap:1px;background:rgba(234,232,232,.14);border-block:1px solid rgba(234,232,232,.14);max-width:520px}
.cat__sub a{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--c-dark);
  padding:11px 2px;font-size:14.5px;transition:padding-left .3s var(--ease-out-quint),color .3s}
.cat__sub a:hover{padding-left:10px;color:var(--c-gold-soft)}
.cat__sub .ic{width:13px;height:13px;flex:none;opacity:.55;transition:transform .3s}
.cat__sub a:hover .ic{transform:translate(3px,-3px);opacity:1}
.cat__price{font-size:14px;font-weight:600;color:var(--c-gold-soft);white-space:nowrap}
.cat__thumb{width:clamp(96px,9vw,140px);aspect-ratio:4/5;overflow:hidden;border-radius:2px;flex:none}
.cat__thumb img{width:100%;height:100%;object-fit:cover}
.cat__row{display:flex;gap:20px;align-items:flex-start}
.cat__name{position:absolute;left:calc(var(--gut) + 220px);right:var(--gut);bottom:clamp(26px,3.2vw,54px);overflow:hidden;padding-bottom:.26em;z-index:4;pointer-events:none;
  font-family:var(--serif);font-size:clamp(28px,4.2vw,66px);line-height:1;letter-spacing:-.02em;text-align:center;margin:0}
.cat__menu{position:absolute;left:var(--gut);bottom:clamp(20px,2.6vw,42px);z-index:5;display:grid;gap:5px;width:200px}
.cat__menu button{background:none;border:0;padding:2px 0;text-align:left;cursor:pointer;font-size:14.5px;font-weight:500;
  color:var(--c-light-40);transition:color .4s var(--default-ease)}
.cat__menu button.is-active{color:var(--c-light)}
.cat__counter{position:absolute;right:var(--gut);top:calc(var(--header-h) + 24px);z-index:5;font-family:var(--serif);font-size:16px;opacity:.55}
.cat__mobile{display:none}

/* ТЕХНОЛОГИИ =============================================================== */
.tech{display:grid;grid-template-columns:minmax(120px,16%) 1fr minmax(240px,27%);gap:clamp(20px,3vw,54px);align-items:center}
.tech__count{font-family:var(--serif);font-size:clamp(40px,5vw,84px);line-height:1;display:flex;align-items:baseline;gap:4px}
.tech__count .num{display:inline-block;overflow:hidden;height:1em}
.tech__count .num i{display:block;font-style:normal;transition:transform .5s var(--ease-out-quint)}
.tech__count .den{font-size:.34em;opacity:.42}
.tech__media{position:relative;aspect-ratio:16/10;overflow:hidden;background:#ddd;border-radius:2px}
.tech__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transform:scale(1.06);
  transition:opacity .6s ease-out,transform .6s ease-out}
.tech__media img.is-active{opacity:1;transform:scale(1)}
.tech__list{display:grid;gap:3px}
.tech__list button{background:none;border:0;text-align:left;padding:7px 0;cursor:pointer;
  font-family:var(--serif);font-size:19px;line-height:1.2;color:var(--c-dark-40);
  transition:color .45s var(--ease-menu),font-size .45s var(--ease-menu)}
.tech__list button.is-active{color:var(--c-dark);font-size:24px}
.tech__benefit{margin-top:18px;padding-top:16px;border-top:1px solid var(--c-dark-10);min-height:76px}
.tech__benefit b{display:block;font-size:15px;font-weight:700;color:var(--c-gold-ink)}

/* СТОПКА ЗАКРЕПЛЁННЫХ КАРТОЧЕК ============================================= */
.stack{position:relative;background:var(--c-light)}
[sticky-card]{position:relative;min-height:100svh;display:grid;grid-template-columns:1fr 1fr;
  align-items:stretch;overflow:hidden;background:var(--c-light)}
[sticky-card]::after{content:"";position:absolute;inset:0;background:#14151D;opacity:var(--after-opacity,0);pointer-events:none;z-index:9}
.sc__media{position:relative;overflow:hidden}
.sc__media img{width:100%;height:100%;object-fit:cover}
.sc__body{display:flex;flex-direction:column;justify-content:center;gap:20px;padding:clamp(34px,5vw,86px);min-width:0}
[sticky-card].alt{direction:rtl}
[sticky-card].alt>*{direction:ltr}
.sc__num{font-family:var(--serif);font-size:clamp(46px,5vw,84px);line-height:1;color:var(--c-gold-ink);opacity:.8}
.sc__proof{border-left:2px solid var(--c-gold-ink);padding-left:16px;font-size:15.5px;line-height:1.5;max-width:44ch}
.sc__proof b{display:block;font-weight:700;margin-bottom:2px}

/* КОМАНДА ================================================================== */
/* КЕГЕЛЬ ЗАГОЛОВКА ЖИВЁТ В ПЕРЕМЕННОЙ — от него же считается заход фигур.
   Глифы Playfair занимают 1.336em (ascender 1.082 + descender .254), а строка
   набрана с line-height .94, поэтому НИЖЕ бокса заголовка глифы выступают ещё
   на (1.336 - .94)/2 = .198em. Раньше ряд портретов вдобавок подтягивался вверх
   отрицательным margin — и вместе это закрывало четверть высоты букв.
   Теперь ряд отступает вниз на .198em - .12em: заход остаётся ровно .12em,
   это ~9 % высоты глифа, то есть лёгкое касание, а не перекрытие. */
.team{position:relative;background:radial-gradient(110% 80% at 50% 12%,#2A2C39 0%,#14151D 60%);color:var(--c-light);overflow:hidden;
  padding-block:clamp(96px,10vw,150px) 0;--tt-fs:clamp(44px,8.4vw,148px)}
.team__title{position:relative;z-index:1;text-align:center;font-size:var(--tt-fs);
  background:var(--grad-gold);-webkit-background-clip:text;background-clip:text;color:transparent}
.team__row{position:relative;z-index:2;display:flex;justify-content:center;align-items:flex-end;gap:clamp(4px,.7vw,14px);
  margin-top:calc(var(--tt-fs) * 0.078);padding-inline:clamp(12px,2vw,40px)}
.team__p{position:relative;width:clamp(120px,15.4vw,222px);flex:none}
/* Верх кадра растушёван: полоса, которая ложится на буквы, работает как тень
   пересечения — надпись читается сквозь неё. Низ растушёван как и раньше. */
.team__p img{width:100%;aspect-ratio:3/4;object-fit:cover;border-radius:3px;
  -webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,.34) 3.5%,rgba(0,0,0,.76) 7.5%,#000 12%,#000 76%,transparent 100%);
  mask-image:linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,.34) 3.5%,rgba(0,0,0,.76) 7.5%,#000 12%,#000 76%,transparent 100%)}
.team__p figcaption{margin-top:-14px;position:relative;z-index:3}
.team__p b{display:block;font-size:14.5px;font-weight:700}
.team__p span{display:block;font-size:12px;color:var(--c-light-40);margin-top:2px}
.team__foot{position:relative;z-index:3;display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap;
  padding:clamp(24px,3vw,50px) var(--gut) clamp(50px,6vw,90px)}

/* ЦИФРЫ-ПУЗЫРИ ============================================================= */
.stats{position:relative;background:var(--c-dark);color:var(--c-light);padding-block:clamp(60px,7vw,110px);overflow:hidden}
/* .stats__arc снят 06.08 по требованию владельца: кривая сквозь круги убрана
   совсем, «зубной ряд» держится только позициями кругов (см. блок ниже). */
.stats__row{position:relative;display:flex;justify-content:space-between;align-items:center;gap:clamp(6px,1vw,20px);flex-wrap:wrap}
/* ── ЦЕНТРОВКА СВЯЗКИ «ЧИСЛО + ПОДПИСЬ» В КРУГЕ (правка владельца 12.08, ред. 2)
   БЫЛО (ред. 1 того же дня): по центру круга ставилось само ЧИСЛО, а подпись
   выводилась из потока (position:absolute) и подвешивалась под ним. При подписи
   в 2–3 строки связка целиком уезжала вниз: сверху воздуха оставалось заметно
   больше, чем снизу, и круг выглядел «сползшим». Владелец забраковал.
   СТАЛО: круг — flex-КОЛОНКА с центровкой по обеим осям, число и подпись стоят
   в потоке и центрируются КАК ЕДИНАЯ ГРУППА. Никаких absolute-смещений: воздух
   сверху и снизу равен при любом числе строк подписи. Расстояние число↔подпись
   фиксированное (gap:.32em ≈ 5 px) и от длины подписи не зависит.
   Ширины b/span ограничены в долях диаметра, чтобы текст не выходил за
   окружность на узких экранах (круг вмещает квадрат со стороной 0,707·D). */
.bub{--numfs:clamp(22px,2.4vw,40px);
  position:relative;border-radius:50%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.32em;
  text-align:center;flex:none;
  background:radial-gradient(120% 120% at 30% 20%,rgba(218,200,183,.22),rgba(179,140,97,.09));
  border:1px solid rgba(218,200,183,.3);padding:10px}
.bub b{display:block;font-family:var(--serif);font-size:var(--numfs);line-height:1;max-width:76%}
.bub span{display:block;font-size:clamp(10.5px,2.9vw,11.5px);line-height:1.25;
  color:var(--c-light-60);max-width:min(14ch,80%)}
.bub.s1{width:clamp(120px,13vw,200px);aspect-ratio:1}
.bub.s2{width:clamp(104px,11vw,168px);aspect-ratio:1}
.bub.s3{width:clamp(92px,9.4vw,144px);aspect-ratio:1}

/* ДО / ПОСЛЕ =============================================================== */
.ba__filters{display:flex;flex-wrap:wrap;gap:8px;margin:26px 0 34px}
.ba__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:clamp(16px,2vw,30px)}
.ba__card{background:var(--c-paper);border:1px solid var(--c-dark-10);border-radius:3px;overflow:hidden;
  transition:transform .5s var(--ease-out-quint),box-shadow .5s var(--ease-out-quint)}
.ba__card:hover{transform:translateY(-5px);box-shadow:0 20px 46px -22px rgba(20,21,29,.4)}
.ba__card[hidden]{display:none}
.ba__cmp{position:relative;aspect-ratio:1;overflow:hidden;cursor:ew-resize;touch-action:pan-y;background:#ddd;
  -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.ba__cmp img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none;-webkit-user-drag:none}
.ba__cmp .after{clip-path:inset(0 0 0 var(--x,50%))}
.ba__cmp.is-drag{cursor:grabbing}
.ba__handle{position:absolute;top:0;bottom:0;left:var(--x,50%);width:2px;background:#fff;box-shadow:0 0 0 1px rgba(0,0,0,.15);z-index:3;
  touch-action:none;cursor:ew-resize}
.ba__handle::after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:42px;height:42px;border-radius:50%;background:#fff;box-shadow:0 6px 18px rgba(0,0,0,.25);transition:box-shadow .3s,transform .3s}
.ba__handle .ic{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:20px;height:20px;color:var(--c-dark);z-index:2}
.ba__cmp:hover .ba__handle::after{transform:translate(-50%,-50%) scale(1.06)}
.ba__handle:focus{outline:none}
.ba__handle:focus-visible::after{box-shadow:0 0 0 3px var(--c-gold),0 6px 18px rgba(0,0,0,.25)}
.ba__hint{display:inline-flex;align-items:center;gap:8px;margin-top:14px;font-size:12.5px;color:var(--c-dark-60)}
.ba__hint svg{width:15px;height:15px;flex:none;color:var(--c-gold)}
.ba__tag{position:absolute;top:12px;z-index:4;background:rgba(20,21,29,.84);color:#fff;font-size:11px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;padding:5px 10px;border-radius:3px}
.ba__tag.l{left:12px}.ba__tag.r{right:12px;background:rgba(133,99,60,.97)}
.ba__meta{padding:18px 20px 22px}
.ba__meta dl{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;margin:12px 0 0;font-size:13.5px}
.ba__meta dt{color:var(--c-dark-40)}
.ba__meta dd{margin:0;font-weight:600;text-align:right}

/* ОТЗЫВЫ =================================================================== */
.rev{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:clamp(16px,2vw,28px);margin-top:40px}
.rev__card{border:1px solid rgba(234,232,232,.16);border-radius:3px;padding:clamp(22px,2.4vw,34px);
  display:flex;flex-direction:column;gap:14px;transition:border-color .3s,background-color .3s}
.rev__card:hover{border-color:var(--c-gold);background:rgba(255,255,255,.03)}
.rev__tag{align-self:flex-start;border:1px solid var(--c-gold);color:var(--c-gold-soft);border-radius:999px;
  padding:5px 12px;font-size:12px;font-weight:600}
.rev__q{font-family:var(--serif);font-size:clamp(19px,1.6vw,26px);line-height:1.25}
.rev__body{font-size:15px;line-height:1.6;color:var(--c-light-60)}
.rev__who{display:flex;align-items:center;gap:12px;margin-top:auto;padding-top:12px;border-top:1px solid rgba(234,232,232,.14)}
.rev__who img{width:44px;height:44px;border-radius:50%;object-fit:cover;flex:none}
.rev__who b{display:block;font-size:14.5px}
.rev__who span{display:block;font-size:12px;color:var(--c-light-40)}
.stars{display:inline-flex;gap:2px;color:var(--c-gold)}
.rev .stars{color:var(--c-gold-soft)}
.stars .ic{width:13px;height:13px}

/* ТАБЛИЦЫ И ПРАЙС ========================================================== */
/* Прайс НЕ растягиваем по общему контейнеру: у него своя логика на узких экранах —
   min-width + горизонтальный скролл с видимой подсказкой, а не сплющенные колонки. */
.ptable{width:100%;min-width:440px;border-collapse:collapse;font-size:15px}
.ptable th,.ptable td{text-align:left;padding:14px 12px;border-bottom:1px solid var(--c-dark-10);vertical-align:top}
.ptable th{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--c-dark-40);font-weight:600}
.ptable td:last-child,.ptable th:last-child{text-align:right;white-space:nowrap;font-weight:600}
.ptable td:first-child{max-width:52ch}
.ptable tr:hover td{background:rgba(179,140,97,.06)}
.dark .ptable th,[data-theme="dark"] .ptable th{color:var(--c-light-60)}
.dark .ptable th,.dark .ptable td,[data-theme="dark"] .ptable th,[data-theme="dark"] .ptable td{border-color:rgba(234,232,232,.16)}
/* container-type — чтобы решение «сплющить или скроллить» принималось по ШИРИНЕ
   КОЛОНКИ, а не по ширине экрана: на 768 те же таблицы попадают в колонку .g2
   шириной 342 px, и min-width:440 выносил их на 836 px за правый край. */
.tbl-scroll{position:relative;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
  container-type:inline-size}
.tbl-scroll:focus-visible{outline:2px solid var(--c-gold);outline-offset:2px}
/* подсказка «таблица прокручивается» — только там, где она реально не влезает */
.tbl-hint{display:none;align-items:center;gap:7px;margin:0 0 10px;font-size:12px;color:var(--c-dark-60)}
.tbl-hint svg{width:14px;height:14px;flex:none;color:var(--c-gold)}
.is-scrollable>.tbl-hint{display:inline-flex}
.dark .tbl-hint,[data-theme="dark"] .tbl-hint{color:rgba(234,232,232,.7)}
/* колонка «Гарантия» — текст, а не цена: nowrap раздувал таблицу до 616 px
   и заставлял её скроллиться даже на 1280 */
.ptable--wrap td:last-child,.ptable--wrap th:last-child{white-space:normal;min-width:15ch}
/* На телефоне таблицу НЕ отправляем в горизонтальный скролл: снимаем min-width
   и переносим НАЗВАНИЕ услуги — строка остаётся таблицей и для screen reader.
   ── ПРАВКА ВЛАДЕЛЬЦА 12.08: ЦЕНА ВСЕГДА В ОДНУ СТРОКУ.
   БЫЛО: здесь стояло white-space:normal и на 390 px самая длинная вилка
   «$825 – $1,850» (13 знаков) ломалась на две строки — «$825 –» и «$1,850».
   Сумма, разорванная переносом, читается как две разные цены.
   СТАЛО: nowrap на ячейку суммы (кегль ужат до 13,5 px, чтобы вилка влезала
   на 360 px), переносится только колонка названия. .ptable--wrap исключена:
   в ней последняя колонка — не цена, а текст гарантии, ему nowrap вреден. */
@media (max-width:560px){
  .ptable{font-size:13.5px;min-width:0}
  .ptable th,.ptable td{padding:11px 8px}
  .ptable:not(.ptable--wrap) td:last-child,
  .ptable:not(.ptable--wrap) th:last-child{white-space:nowrap;min-width:0}
  .ptable--wrap td:last-child,.ptable--wrap th:last-child{white-space:normal;min-width:9ch}
  .ptable td:first-child{max-width:none;overflow-wrap:break-word}
}
/* То же самое, но по ширине КОНТЕЙНЕРА: узкая колонка на планшете получает
   мобильную раскладку таблицы вместо выноса за экран. */
@container (max-width:520px){
  .ptable{font-size:13.5px;min-width:0}
  .ptable th,.ptable td{padding:11px 8px}
  .ptable:not(.ptable--wrap) td:last-child,
  .ptable:not(.ptable--wrap) th:last-child{white-space:nowrap;min-width:0}
  .ptable--wrap td:last-child,.ptable--wrap th:last-child{white-space:normal;min-width:9ch}
  .ptable td:first-child{max-width:none;overflow-wrap:break-word}
}

/* ритм прайса: заголовок раздела не должен «слипаться» с заголовком секции */
[data-price-group]{margin-top:clamp(26px,3vw,44px)}
[data-price-group]+[data-price-group]{margin-top:clamp(34px,4vw,56px)}
.price-empty{border:1px dashed var(--c-dark-10);border-radius:3px;padding:clamp(22px,3vw,38px);
  background:var(--c-paper);margin-bottom:44px}
.price-empty[hidden]{display:none}

/* АККОРДЕОН ================================================================ */
.acc{border-top:1px solid var(--c-dark-10)}
.acc__item{border-bottom:1px solid var(--c-dark-10)}
.acc__head{width:100%;background:none;border:0;cursor:pointer;display:flex;align-items:center;justify-content:space-between;
  gap:18px;padding:22px 0;text-align:left}
.acc__head .t{font-family:var(--serif);font-size:clamp(19px,1.7vw,27px);line-height:1.2;min-width:0;overflow-wrap:anywhere}
.acc__ic{width:34px;height:34px;border:1px solid var(--c-dark-10);border-radius:50%;flex:none;display:grid;place-items:center;
  transition:background-color .4s,color .4s}
/* Крутим ВНУТРЕННЮЮ иконку, а не сам кружок: rotate(45deg) на боксе 34×34
   раздувал его bounding box до 48 px и выносил на 7 px за правый край шапки. */
.acc__ic svg{width:14px;height:14px;transition:transform .4s var(--ease-out-quint)}
.acc__item.is-open .acc__ic{background:var(--c-dark);color:var(--c-light)}
.acc__item.is-open .acc__ic svg{transform:rotate(45deg)}
/* Схлопнутое тело: grid-template-rows:0fr + overflow:hidden прячут его ВИЗУАЛЬНО,
   но дочерние абзацы сохраняют полную геометрию и накладываются на следующие
   секции. visibility:hidden убирает их из потока взаимодействия и из замеров,
   переключаясь без задержки при открытии и после анимации при закрытии. */
.acc__body{display:grid;grid-template-rows:0fr;visibility:hidden;
  transition:grid-template-rows .4s var(--ease-out-quint),visibility 0s linear .4s}
.acc__item.is-open .acc__body{grid-template-rows:1fr;visibility:visible;
  transition:grid-template-rows .4s var(--ease-out-quint),visibility 0s linear 0s}
.acc__inner{overflow:hidden}
.acc__inner>*:first-child{padding-top:2px}
.acc__inner>*:last-child{padding-bottom:26px}
.dark .acc,.dark .acc__item{border-color:rgba(234,232,232,.16)}
.dark .acc__ic{border-color:rgba(234,232,232,.28)}
.dark .acc__item.is-open .acc__ic{background:var(--c-light);color:var(--c-dark)}

/* SCROLL-МАСШТАБИРОВАНИЕ МЕДИА ============================================= */
/* ПРАВКА ВЛАДЕЛЬЦА (кадры 12-39-49 «эту анимацию убрать — обычный блок с
   картинкой» и 13-00-18 «раздел Технология: блоки просто друг за другом»).
   Было: сцена во весь экран, кадр стартовал с scale .42 и разъезжался
   скроллом при пиннированной секции. Стало: обычный блок в потоке —
   кадр во всю ширину контейнера, подпись видна сразу, скролл не перехватывается. */
.zoom{position:relative;z-index:6;background:var(--c-light)}
/* ПРАВКА ВЛАДЕЛЬЦА 06.08: «картинка фоном во весь блок». Было — кадр в
   контейнере 1440 с полями и скруглением, вокруг виднелась подложка секции.
   Стало — full-bleed: ни боковых, ни вертикальных полей, ширина 100vw,
   кадр кроется object-fit:cover, подпись остаётся поверх. */
.zoom__stage{height:auto;display:block;overflow:visible;background:var(--c-light);padding:0}
.zoom__frame{width:100%;max-width:none;margin-inline:0;aspect-ratio:16/9;
  overflow:hidden;border-radius:0;position:relative}
.zoom__frame img,.zoom__frame video{width:100%;height:100%;object-fit:cover}
/* скрим под подписью — иначе белый текст ложится на светлый интерьер (было ~1,2:1) */
/* ── БЕЗ РЕЗКОЙ ПОЛОСЫ НА СТЫКЕ С БУМАГОЙ (правка владельца 12.08) ─────────
   БЫЛО: скрим доходил до низа кадра почти чёрным (.88), а сразу под кадром
   начиналась светлая секция #EAE8E8 — контраст 20:1 в одну пиксельную строку,
   ровно то «фон обрывается резкой полосой», на что жаловался владелец.
   СТАЛО: последние 9 % высоты кадра скрим уводится в цвет самой секции —
   снимок растворяется в бумаге, границы-линии нет. Подпись поднята выше
   зоны растворения (см. .zoom__cap ниже), её контраст не изменился. */
/* ── ред. 2 (12.08): молоко у самой кромки. Уход в цвет секции начинается на
   96 % высоты кадра, а не размазан по последней десятой — снимок «доезжает»
   до низа тёмным, стык не превращается в белёсую полосу поверх фотографии. */
.zoom__frame::after{content:"";position:absolute;inset:0 0 -2px;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(20,21,29,0) 38%,rgba(20,21,29,.62) 74%,
    rgba(20,21,29,.88) 96%,var(--c-light) 100%)}
/* ── ВЕРХНИЙ СТЫК «ТЁМНЫЙ ГЕРОЙ -> СВЕТЛЫЙ КАДР» (правка владельца 12.08) ───
   На «Технологиях» сразу под тёмным героем начинается почти белый снимок
   операционной: замер стыка — яркость 34 сверху и 149 снизу в одной строке.
   Это ровно тот «срез резкой полосой» со скриншота владельца 204921.
   Верх кадра уводится в цвет героя, снимок ПРОЯВЛЯЕТСЯ из темноты.
   Селектор с соседством: правило работает только там, где .zoom реально
   стоит под героем (Технологии). На главной .zoom идёт после светлой секции
   и остаётся без затемнения сверху. */
.phero + .zoom .zoom__frame::after{
  background:linear-gradient(180deg,var(--c-dark) 0%,rgba(20,21,29,.62) 6%,rgba(20,21,29,0) 16%,
    rgba(20,21,29,0) 38%,rgba(20,21,29,.62) 74%,rgba(20,21,29,.88) 96%,var(--c-light) 100%)}
/* opacity больше не 0: подпись проявлял scrub-таймлайн, которого нет */
.zoom__cap{position:absolute;left:clamp(16px,3vw,44px);right:clamp(16px,3vw,44px);
  bottom:clamp(46px,7.5vw,110px);z-index:4;color:#fff;
  display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap;opacity:1}
.zoom__cap .small{color:rgba(255,255,255,.9)}

/* ГОРИЗОНТАЛЬНАЯ ЛЕНТА ===================================================== */
.hscroll{overflow:hidden;background:var(--c-dark);color:var(--c-light)}
.hscroll__track{display:flex;gap:clamp(14px,1.6vw,26px);padding-inline:var(--gut)}
.hcard{width:clamp(260px,25vw,380px);flex:none;border:1px solid rgba(234,232,232,.16);border-radius:3px;overflow:hidden;
  display:flex;flex-direction:column;transition:border-color .3s}
.hcard:hover{border-color:var(--c-gold)}
.hcard img{aspect-ratio:4/3;object-fit:cover;width:100%}
.hcard__b{padding:20px 22px 24px;display:flex;flex-direction:column;gap:8px;flex:1}
.hcard__b .pr{margin-top:auto;padding-top:10px;font-size:14px;font-weight:700;color:var(--c-gold-soft)}

/* СЕТКИ ==================================================================== */
.g2{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:clamp(20px,3vw,60px)}
.g3{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(270px,100%),1fr));gap:clamp(16px,2vw,34px)}
.g4{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(210px,100%),1fr));gap:clamp(18px,2.2vw,40px)}
/* цифры-показатели в узкой 4-колоночной сетке: при 68px «6 техников» и «3 врача»
   почти смыкались — кегль привязан к ширине колонки, а не к ширине экрана */
.g4 .t-h2{font-size:clamp(28px,2.8vw,46px);line-height:1.06}
.g4 .t-h3{font-size:clamp(22px,2vw,32px)}
/* Та же причина, что и у .g4: auto-fit в .g2/.g3 на 1536–2560 разворачивается
   в 4 колонки по ~305 px, а .t-h3 в этот момент уже уперся в свой максимум 40 px —
   слово «Интраоральный» вылезало за правую границу карточки. Кегль заголовка
   в карточке считаем от колонки, а не от ширины экрана. */
.g2 .card .t-h3,.g3 .card .t-h3{font-size:clamp(22px,1.7vw,30px);line-height:1.15;overflow-wrap:break-word}
.card{border:1px solid var(--c-dark-10);border-radius:3px;padding:clamp(20px,2.2vw,32px);background:var(--c-paper);
  display:flex;flex-direction:column;gap:12px;transition:transform .5s var(--ease-out-quint),box-shadow .5s var(--ease-out-quint),border-color .3s}
.card:hover{transform:translateY(-5px);box-shadow:0 22px 48px -26px rgba(20,21,29,.42);border-color:var(--c-gold)}
.dark .card{background:rgba(255,255,255,.03);border-color:rgba(234,232,232,.16)}
.ico{display:block;width:40px;height:40px;color:var(--c-gold-ink);flex:none}
.dark .ico,[data-theme="dark"] .ico{color:var(--c-gold-soft)}
.ico svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.3;stroke-linecap:round;stroke-linejoin:round}

.blist{display:grid;gap:11px;margin-top:6px}
.blist li{display:grid;grid-template-columns:20px 1fr;gap:11px;align-items:start;font-size:15.5px;line-height:1.45}
.blist li svg{width:18px;height:18px;margin-top:2px;color:var(--c-gold-ink);fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.dark .blist li svg,[data-theme="dark"] .blist li svg{color:var(--c-gold-soft)}
.dark .chip.gold,[data-theme="dark"] .chip.gold{border-color:var(--c-gold-soft);color:var(--c-gold-soft)}
.dark .sc__proof,[data-theme="dark"] .sc__proof{border-left-color:var(--c-gold-soft)}

/* фото в левой колонке блока «Шесть шагов». Когда колонки стоят рядом, кадр
   добирает РОВНО остаток высоты колонки со списком шагов (flex:1 в растянутой
   на всю строку грида колонке) и кадрируется по object-fit — поэтому секция
   больше не растягивается ниже списка и под фото нет дыры. В стопке (узкий
   экран) фото ложится в горизонтальный кроп фиксированной пропорции. */
.steps__ph{overflow:hidden;border-radius:2px}
.steps__ph img{width:100%;height:auto;aspect-ratio:16/11;object-fit:cover;object-position:50% 45%;display:block;border-radius:2px}
@media (min-width:1000px){
  .steps__col{display:flex;flex-direction:column;align-self:stretch}
  .steps__ph{flex:1 1 0;min-height:220px}
  .steps__ph img{height:100%;min-height:0;aspect-ratio:auto}
}
/* Ниже 1000px колонка под фото становится настолько узкой, что растянутый кадр
   превращался бы в полоску 1:2.4, а нерастянутый оставлял бы под собой дыру.
   Поэтому на планшете и уже блок честно складывается в одну колонку. */
@media (max-width:999px){.steps__grid{grid-template-columns:1fr}}
@media (max-width:900px){.steps__ph{margin-top:24px!important}}
.steps{counter-reset:s;display:grid;gap:0;border-top:1px solid var(--c-dark-10)}
.steps li{counter-increment:s;display:grid;grid-template-columns:minmax(56px,7%) 1fr;gap:clamp(14px,2vw,40px);
  padding:24px 0;border-bottom:1px solid var(--c-dark-10)}
.steps li::before{content:"0" counter(s);font-family:var(--serif);font-size:clamp(22px,2vw,34px);color:var(--c-gold-ink);line-height:1}
.dark .steps li::before,[data-theme="dark"] .steps li::before{color:var(--c-gold-soft)}
.dark .steps,.dark .steps li{border-color:rgba(234,232,232,.16)}

/* ВРАЧИ ==================================================================== */
.doc{display:grid;grid-template-columns:minmax(220px,32%) 1fr;gap:clamp(20px,3vw,54px);align-items:start;
  padding-block:clamp(34px,4vw,70px);border-top:1px solid var(--c-dark-10)}
.doc__ph{position:relative;overflow:hidden;border-radius:3px;background:#ddd}
.doc__ph img{width:100%;aspect-ratio:3/4;object-fit:cover;transition:transform .8s var(--ease-out-quint)}
.doc:hover .doc__ph img{transform:scale(1.035)}
.doc__facts{display:flex;flex-wrap:wrap;gap:8px;margin:6px 0 4px}
.chip{border:1px solid var(--c-dark-10);border-radius:999px;padding:6px 13px;font-size:13px;font-weight:600}
.chip.gold{border-color:var(--c-gold-ink);color:var(--c-gold-ink)}
.personal{background:var(--c-light-2);border-left:2px solid var(--c-gold-ink);padding:16px 20px;border-radius:0 3px 3px 0}
.personal b{display:block;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--c-gold-ink);margin-bottom:6px}

/* ФОРМА ==================================================================== */
/* ВЕРТИКАЛЬНЫЙ РИТМ ФОРМЫ (LAYOUT-STANDARDS §5).
   ГЛАВНАЯ ПРИЧИНА СЛИПАНИЯ: gap:14px стоял на .form, а её единственные дети —
   .form__body и .form__ok. Сами группы (клиника / слоты / имя-телефон / сообщение /
   согласие / кнопка) лежат ВНУТРИ .form__body, у которого раскладки не было вовсе —
   блочный поток без margin давал между группами РОВНО 0 px. Поэтому сетку с шагом
   объявляем там, где живут группы, и даём воздух по ступеням:
   между группами > между полем и его подписью > между чипами внутри группы. */
.form{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(18px,2vw,26px);max-width:min(760px,100%)}
.form__body{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(20px,2.4vw,30px)}
.form__row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(14px,1.6vw,20px)}
.field{display:grid;gap:9px}
.field>label{font-size:12.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--c-dark-40)}
/* пояснение под группой слотов — отдельная ступень, не прилипает к чипам */
.field>.xsmall{margin-top:3px;line-height:1.5}
.dark .field>label{color:var(--c-light-40)}
.field input,.field textarea,.field select{
  width:100%;background:transparent;border:1px solid var(--c-dark-10);border-radius:999px;padding:14px 20px;
  font-size:16px;transition:border-color .3s,background-color .3s}
.field textarea{border-radius:16px;min-height:110px;resize:vertical}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:var(--c-gold)}
.dark .field input,.dark .field textarea,.dark .field select{border-color:rgba(234,232,232,.24);color:var(--c-light)}
.dark .field select option{color:#14151D}
.field.err input,.field.err textarea,.field.err select{border-color:#C4553F}
.field .msg{font-size:12.5px;color:#C4553F;min-height:1em}
.radios{display:flex;flex-wrap:wrap;gap:10px 12px}
.radios label{display:inline-flex;align-items:center;gap:9px;border:1px solid var(--c-dark-10);border-radius:999px;
  padding:11px 18px;cursor:pointer;font-size:14.5px;transition:border-color .3s,background-color .3s}
.dark .radios label{border-color:rgba(234,232,232,.24)}
.radios input{accent-color:var(--c-gold);width:16px;height:16px;margin:0}
.radios label:has(input:checked){border-color:var(--c-gold);background:rgba(179,140,97,.1)}
.slots{display:flex;flex-wrap:wrap;gap:10px}
.slot{border:1px solid var(--c-dark-10);border-radius:999px;padding:10px 16px;font-size:14px;font-weight:600;
  background:transparent;cursor:pointer;transition:all .3s var(--default-ease)}
.dark .slot{border-color:rgba(234,232,232,.24)}
.slot.is-on{background:var(--c-gold);border-color:var(--c-gold);color:#fff}
.slot[disabled]{opacity:.32;cursor:not-allowed;text-decoration:line-through}
/* Согласие 152-ФЗ — отдельная смысловая группа: отбиваем её тонкой линией,
   иначе мелкий текст читается как продолжение поля «Что вас беспокоит». */
.consent{display:grid;grid-template-columns:20px 1fr;gap:12px;align-items:start;font-size:12.5px;line-height:1.55;color:var(--c-dark-40);
  padding-top:clamp(14px,1.6vw,20px);border-top:1px solid var(--c-dark-10)}
.dark .consent,[data-theme="dark"] .consent{border-top-color:rgba(234,232,232,.16)}
.dark .consent,[data-theme="dark"] .consent{color:rgba(234,232,232,.74)}
.consent input{width:17px;height:17px;margin:2px 0 0;accent-color:var(--c-gold)}
.consent a{text-decoration:underline}
.form__send{display:grid;grid-template-columns:minmax(0,1fr);justify-items:start;gap:clamp(12px,1.4vw,16px);margin-top:clamp(2px,.6vw,8px)}
.form__micro{margin:0;font-size:12.5px;line-height:1.6;color:var(--c-dark-60);max-width:56ch}
.dark .form__micro,[data-theme="dark"] .form__micro{color:rgba(234,232,232,.72)}
.form__ok{display:none;border:1px solid var(--c-gold);background:rgba(179,140,97,.1);border-radius:3px;padding:20px 24px;gap:8px}
.form.is-sent .form__ok{display:grid}
.form.is-sent .form__body{display:none}

/* ПОДВАЛ-«УЛЫБКА» ========================================================== */
/* ПРАВКА ВЛАДЕЛЬЦА 06.08 (кадр broken-1701). Три поломки в одном месте:
   1) .pre-cta__big — это <p>, и ему доставался БРАУЗЕРНЫЙ margin-bottom:1em.
      При кегле 137-182 px это 137-182 px пустоты: ровно та «дыра» на весь
      экран между заголовком и строкой «Премиальная … · Москва». Обнуляем.
   2) кегль 10vw без верхней границы по высоте: на 1920 заголовок уезжал в три
      строки на 500 px и вылезал за верх секции. 6.4vw / максимум 110 px даёт
      те же две строки на всех ширинах и оставляет силуэт крупной подачи.
   3) БЕЛЫЕ ПЯТНА. У .foot скруглены верхние углы, а лежал он ПОД тёмной
      секцией — в вырезах дуги просвечивал светлый фон body (#EAE8E8), и по
      краям читались белые клинья. Теперь подвал НАЕЗЖАЕТ на .pre-cta ровно
      на высоту дуги (--foot-arc): тёмное идёт сплошняком, а полукруг подвала
      выразительно ложится ПОВЕРХ тёмного, как и просил владелец. */
:root{--foot-arc:clamp(70px,7vw,120px)}
.pre-cta{position:relative;background:var(--c-dark);color:var(--c-light);overflow:hidden;
  padding-top:clamp(52px,5.6vw,92px);
  padding-bottom:calc(clamp(52px,5.6vw,92px) + var(--foot-arc))}
.pre-cta__big{margin:0;font-family:var(--serif);font-size:clamp(40px,6.4vw,110px);line-height:1.02;text-align:center;
  background:var(--grad-gold);-webkit-background-clip:text;background-clip:text;color:transparent;opacity:.85}
.foot{position:relative;z-index:2;background:var(--c-dark-2);color:var(--c-light);
  margin-top:calc(-1 * var(--foot-arc));
  border-top-left-radius:50% var(--foot-arc);border-top-right-radius:50% var(--foot-arc);
  padding-block:calc(clamp(60px,6vw,96px) + var(--foot-arc) * .45) 34px;overflow:hidden}
.foot__logo{width:120px;margin:0 auto clamp(30px,4vw,56px);color:var(--c-gold-soft)}
.foot__logo svg{width:100%;height:auto;overflow:visible}
.foot__logo path{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
.foot__cols{display:grid;grid-template-columns:1fr 1fr 2.1fr;gap:clamp(24px,3vw,56px)}
.foot h4{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--c-gold-soft);font-family:var(--sans);
  font-weight:600;margin-bottom:14px}
.foot ul{display:grid;gap:9px}
.foot ul a{font-size:15px;opacity:.82;transition:opacity .3s,color .3s}
.foot ul a:hover{opacity:1;color:var(--c-gold-soft)}
.foot__addr{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(210px,100%),1fr));gap:22px}
.foot__addr b{display:block;font-size:15px;font-weight:700;margin-bottom:6px}
.foot__addr p{font-size:13.5px;line-height:1.55;color:var(--c-light-60);margin:0}
.foot__addr a{color:var(--c-gold-soft)}
.foot__legal{margin-top:clamp(30px,4vw,56px);padding-top:22px;border-top:1px solid rgba(234,232,232,.14);
  display:flex;flex-wrap:wrap;gap:10px 26px;align-items:center;justify-content:space-between}
.foot__legal .lnks{display:flex;flex-wrap:wrap;gap:8px 22px}
.foot .xsmall,.foot .small{color:rgba(234,232,232,.72)}
.foot__legal a{font-size:12.5px;color:rgba(234,232,232,.72);transition:color .3s}
.foot__legal a:hover{color:var(--c-light)}
.disclaimer{margin-top:16px;font-size:11.5px;line-height:1.6;color:rgba(234,232,232,.66);max-width:96ch}

/* ХЛЕБНЫЙ HERO ВНУТРЕННИХ СТРАНИЦ ========================================= */
/* ── МИНИМАЛЬНАЯ ВЫСОТА ХЛЕБНОГО ГЕРОЯ (правка владельца 12.08) ────────────
   БЫЛО: у .phero не было min-height вообще — высота равнялась «контент плюс
   паддинги». Замер (Playwright, до правки): 1440x900 — 596-625 px = 66-69 %
   экрана, 1920x1080 — 645-689 px = 60-64 %, 834x1112 — 458-468 px = 41-42 %,
   390x844 — 431-482 px = 51-57 %. Под абзацем оставалось 56-102 px, поэтому
   следующая секция начиналась почти впритык к тексту, а фоновый кадр не успевал
   прочитаться как кадр — блок выглядел обрезанным.
   ПРОМЕЖУТОЧНАЯ ПОПЫТКА (84/74/66 svh, обычный поток) ВЛАДЕЛЬЦА НЕ УСТРОИЛА:
   «блок очень узкий, расширь вниз». 84 svh на 1080p — это 907 px, кадр
   обрывался примерно на середине последней трети экрана, а следующая секция
   показывалась узкой полосой у нижней кромки. Плюс весь избыток уходил ТОЛЬКО
   вниз, и текст всё равно жался к верхней трети.

   СТАЛО: первый экран занимает экран целиком (96/92/90 svh), а свободное место
   делится ПОРОВНУ над и под текстом (flex-колонка с центрированием ниже).
   Поэтому больше нет ни «узкого блока», ни пустой полосы под абзацем.

   svh (а не vh) — чтобы адресная строка мобильного браузера не растягивала
   секцию на высоту, которой на экране нет; строка на vh оставлена фолбэком для
   движков без svh.

   ПОТОЛОК В ПИКСЕЛЯХ. Доля растёт вместе с высотой окна, а содержимое героя
   (крошки + двухстрочный заголовок + абзац) по высоте почти постоянно —
   290-440 px. На очень высоком вьюпорте одна доля даёт абсурд: 2560x1440 —
   96 svh = 1382 px под 400 px текста. Поэтому доля ограничена сверху через
   min(): на обычных экранах (1080p, 900p, 834x1112, 390x844) выигрывает доля,
   на ВЫСОКИХ — потолок.

   НИЗКИЕ ЭКРАНЫ БЕЗОПАСНЫ САМИ ПО СЕБЕ: min-height — это ПОЛ, а не height.
   На альбомном телефоне (844x390) и низком ноутбуке (1366x640) содержимое
   выше доли экрана, секция просто РАСТЁТ по контенту, ничего не обрезается и
   не выдавливается за экран. По той же причине правило не режет «Услуги» с
   облаком из 12 тегов. overflow:hidden при этом не опасен: раз высота растёт
   по контенту, центрирование не создаёт отрицательного выноса вверх.

   ── ПРАВКА 12.08 (фидбэк владельца: «блоки с фоном обрываются резкой полосой»)
   ЗАМЕР ДО: 1440x900 — .phero 864 px при вьюпорте 900 ⇒ под тёмным героем
   торчала СВЕТЛАЯ ПОЛОСА следующей секции высотой 36 px. Ровно её видно на
   всех четырёх скриншотах владельца (technology / doctors / prices / contacts):
   кадр «срезан» тонкой белой лентой у нижней кромки экрана. Причина — доля
   96/92/90 svh и потолок min(...,1300px): любая доля меньше 100 % оставляет
   зазор, а потолок делает его тем больше, чем выше окно.
   СТАЛО: ровно 100 svh — фон занимает экран целиком, полосы нет ни на одной
   ширине. Потолок в пикселях снят: он и создавал полосу на высоких окнах,
   а «абсурдной» высоты 100 svh дать не может по определению — это ровно
   один экран. vh оставлен фолбэком для движков без svh. */
.phero{position:relative;
  /* КОНТЕНТ РАСПРЕДЕЛЁН ПО ВЕРТИКАЛИ, А НЕ ПРИЖАТ К ВЕРХУ.
     Раньше блок был обычным потоком: весь избыток высоты уходил ВНИЗ, под
     абзац, и получалось «текст в верхней трети + пустая полоса под ним».
     Теперь колонка-флекс с центрированием: свободное место делится поровну
     над и под текстом. padding-top остаётся нижней границей отступа от
     шапки, padding-bottom — от следующей секции. */
  display:flex;flex-direction:column;justify-content:center;
  padding-top:calc(var(--header-h) + clamp(32px,4.5vw,72px));
  padding-bottom:clamp(48px,5vw,88px);
  min-height:100vh;min-height:100svh;
  background:var(--c-dark);color:var(--c-light);overflow:hidden}
/* АЛЬБОМНЫЙ ТЕЛЕФОН — ВЫСОТУ ОТДАЁМ СОДЕРЖИМОМУ. При высоте окна ~390 px крошки,
   заголовок и абзац занимают 430-680 px, то есть заведомо больше любой доли
   экрана, и доля-пол тут всё равно не срабатывает (замер 12.08: 844x390 —
   min-height 351 px против фактических 430-678 px на всех пяти страницах обеих
   локалей). Правило поставлено как страховка на будущее: если содержимое героя
   когда-нибудь станет короче, доля не начнёт растягивать секцию на экране, где
   и без того нет вертикального места. */
@media (orientation:landscape) and (max-height:560px){.phero{min-height:auto}}
.phero__bg{position:absolute;inset:0;opacity:.32}
.phero__bg img{width:100%;height:100%;object-fit:cover}
.phero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(20,21,29,.86),rgba(20,21,29,.62))}
.phero .wrap{position:relative;z-index:2}
/* ── НИЗ ХЛЕБНОГО ГЕРОЯ НЕ РУБИТСЯ О СВЕТЛУЮ СЕКЦИЮ (правка владельца 12.08) ─
   Автоскан стыков показал: на «Контактах», «Врачах» и «Ценах» тёмный кадр
   героя (яркость ~30, фактура фото читается — ножки кресел, интерьер)
   обрывается в бумагу #EAE8E8 одной строкой. Владелец: «блоки с фоном
   обрываются резкой полосой... плавный переход, чтобы не было среза полос».
   Растушёвка ставится ТОЛЬКО там, где следующая секция светлая: :has()
   отбирает соседа без data-theme="dark", поэтому «Технологии» (.zoom) и
   «Услуги» (.hscroll) — тёмные соседи — остаются без изменений.
   z-index:1 обязателен: .phero::after (скрим) идёт в DOM позже и при auto
   перекрыл бы растушёвку; .wrap с z-index:2 остаётся выше, текст не тускнеет.
   bottom:-2px — страховка от дробной высоты секции (та же, что у .scene). */
   ── ПРАВКА ВЛАДЕЛЬЦА 12.08 (ред. 2): «расширь верхний блок вниз чуть и
   НЕМНОГО градиента перехода, а не как ты сделал».
   БЫЛО: полоса clamp(80px,10vw,170px) с молоком уже на 48 % высоты — на 1920
   это 170 px ≈ 16 vh, и низ тёмного героя превращался в длинное белёсое
   «мыло» (скриншоты prices/doctors/contacts 2255 22).
   СТАЛО: полоса КОРОТКАЯ — clamp(48px,7vh,86px) (≤8 vh на любом экране), и
   молоко в ней собрано у самой кромки (до 58 % высоты прозрачность ≥ 80 %).
   Тёмный кадр тем самым «продлевается вниз», а переход остаётся деликатным. */
.phero:has(+ section:not([data-theme="dark"]))::before{content:"";position:absolute;
  left:0;right:0;bottom:-2px;height:clamp(48px,7vh,86px);z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(234,232,232,0) 0%,rgba(234,232,232,.18) 58%,
    rgba(234,232,232,.62) 84%,var(--c-light) 100%)}
/* ── EYEBROW ВМЕСТО ХЛЕБНЫХ КРОШЕК (правка владельца 12.08) ────────────────
   БЫЛО: <nav class="crumbs">Главная / Технологии</nav> — «подпись-крошка»
   над H1. Владелец: убрать «Главная» и разделитель, оставить чистый
   eyebrow-заголовок раздела. СТАЛО: <p class="label phero__eyebrow">Технологии</p>
   — тот же надзаголовок, что во всех остальных секциях сайта (.label:
   uppercase, 12px, letter-spacing .14em, золотой на тёмном). Правило .crumbs
   снято целиком: разметки с этим классом на сайте больше нет. */
.phero__eyebrow{margin-bottom:20px}

/* Декоративные «дышащие» пятна ============================================ */
/* filter:blur(78px) на пятне в треть экрана — самый дорогой пиксель страницы.
   Само пятно статично, анимируется ТОЛЬКО transform, поэтому размытие
   растеризуется один раз, а не каждый кадр (contain:paint + свой слой).
   Пока секция за кадром, main.js §23 ставит .fx-idle и анимация замирает:
   бесконечный keyframe за экраном отнимал кадры у скролл-анимаций. */
.decor{position:absolute;border-radius:50%;filter:blur(78px);pointer-events:none;z-index:0;
  contain:layout paint size;backface-visibility:hidden}
.decor-1{width:38vw;height:38vw;background:rgba(179,140,97,.24);left:-8%;top:6%;animation:decor-1 18s ease-in-out infinite alternate}
.decor-2{width:30vw;height:30vw;background:rgba(218,200,183,.16);right:-6%;bottom:2%;animation:decor-2 22s ease-in-out infinite alternate}
.fx-idle .decor,.fx-idle.decor{animation-play-state:paused}
@keyframes decor-1{0%{transform:translate(0) rotate(-4deg)}100%{transform:translate(15%,20%) rotate(10deg)}}
@keyframes decor-2{0%{transform:translate(0) rotate(-10deg)}100%{transform:translate(-10%,15%) rotate(-5deg)}}

/* Курсор ------------------------------------------------------------------- */
.cursor{position:fixed;top:0;left:0;width:30px;height:30px;border:1px solid var(--c-gold);border-radius:50%;
  z-index:400;pointer-events:none;transform:translate(-50%,-50%);opacity:0;transition:width .3s,height .3s,opacity .3s,background-color .3s}
.cursor.on{opacity:.85}
.cursor.big{width:58px;height:58px;background:rgba(179,140,97,.16)}

/* Тап-состояния вместо кастомного курсора ----------------------------------
   На тач-устройстве курсора нет, поэтому обратную связь даёт нажатие: лёгкое
   «вдавливание» и подсветка. Только transform/opacity/цвет — без теней. */
@media (hover:none),(pointer:coarse){
  .btn,.tag,.slot,.link-arrow,.acc__head,.cat__menu button,.tech__list button,
  .card,.hcard,.ba__card,.chip,.foot ul a,.mmenu a{
    -webkit-tap-highlight-color:transparent;
    transition:transform .16s var(--ease-out-quint),opacity .16s var(--default-ease),
      background-color .2s var(--default-ease),color .2s var(--default-ease);
  }
  .btn:active,.tag:active,.slot:active,.chip:active{transform:scale(.96)}
  .link-arrow:active,.foot ul a:active,.mmenu a:active,.cat__menu button:active,
  .tech__list button:active{opacity:.55;transform:translateX(2px)}
  .card:active,.hcard:active,.ba__card:active{transform:scale(.985)}
  .acc__head:active .acc__ic{transform:scale(.9)}
  .burger:active{transform:scale(.92)}
}

/* ТОЧЕЧНЫЙ will-change (п.11) ----------------------------------------------
   Постоянный will-change:transform держал КАЖДУЮ карточку стопки, кадр зума и
   всю ленту в отдельном слое композитора всё время жизни страницы — на планшете
   это десятки мегабайт видеопамяти и просадка там, где анимации сейчас нет.
   Слой поднимается классом .fx-live, который main.js §23 вешает на время, пока
   сцена реально в кадре, и СНИМАЕТ, как только она ушла. */
.fx-live{will-change:transform}
/* .zoom__frame из списка убран: секция больше не анимируется (см. блок ЗУМ) */
.hscroll__track.fx-live{will-change:transform}

/* Медиа с ЖЁСТКОЙ пропорцией можно не отрисовывать за кадром: высота бокса
   задана aspect-ratio, поэтому пропуск содержимого не двигает вёрстку и не
   ломает замеры пинов ScrollTrigger. Секции и пиннируемые узлы НЕ трогаем. */
.tech__media,.ba__cmp{content-visibility:auto}

/* Появление ---------------------------------------------------------------- */
[data-rv]{opacity:0}
.no-motion [data-rv]{opacity:1}

/* АДАПТИВ ================================================================== */
/* шапка: убираем элементы по мере сужения, чтобы строка не ломалась в две.
   Порог для «Запись: сегодня …» = 1560: при контейнере 1440 строка требует ~1420 px,
   на 1536 и уже она выталкивала кнопку CTA за правый край колонки. */
@media (max-width:1559px){.slotline{display:none}}
@media (max-width:1240px){.phones{display:none}}
@media (max-width:1100px){
  .nav{display:none}
  .burger{display:inline-flex}
  .slotline{display:none}
  .phones{display:none}
  .logo svg{width:34px}
  .mission{grid-template-columns:1fr}
  .mission__ph{max-width:300px}
  /* 26.08: фото 896×1280 — портретное; 4/3 с cover резало голову и ноги. Держим 3/4 без обрезки. */
  .mission__ph img{aspect-ratio:3/4;object-fit:cover;object-position:center top}
  .tech{grid-template-columns:1fr;gap:22px}
  .tech__count{font-size:clamp(34px,7vw,54px)}
  .doc{grid-template-columns:1fr}
  .doc__ph{max-width:340px}
  .foot__cols{grid-template-columns:1fr 1fr}
  .foot__cols>*:last-child{grid-column:1/-1}
}
@media (max-width:860px){
  :root{--header-h:64px}
  .hero__bg{grid-template-columns:1fr}
  .hero__bg .l{display:none}
  .hero__bg .r{grid-column:1/-1}
  .hero__bg .r::before{display:none}
  /* середина скрима была .5: на светлом кадре видео мелкая подпись под кнопками
     уходила примерно в 3:1. Поднимаем до .62 — фон читается, текст тоже. */
  .hero__bg .r::after{background:linear-gradient(180deg,rgba(20,21,29,.72),rgba(20,21,29,.62) 42%,rgba(20,21,29,.84))}
  /* Разрез заголовка. На узких панель одна, поэтому «графитовая» половина стала бы
     чёрным по тёмному видео — перекрашиваем её в золото, и JS (§3a) прогоняет
     границу --split справа налево: тот же механизм, читаемый на одном фоне. */
  .split-title .lay-1{color:var(--c-gold-soft);
    text-shadow:0 2px 30px rgba(20,21,29,.55),0 1px 3px rgba(20,21,29,.32)}
  .hero__top{max-width:100%}
  /* на мобиле фон героя тёмный: чернильное золото ушло бы в 2:1 */
  .hero__kicker{color:var(--c-gold-soft)}
  .hero__promise{color:#fff}
  .hero__micro{color:rgba(255,255,255,.82)}
  .hero__meta .lt,.hero__meta .rt{color:var(--c-light);text-align:left;max-width:100%}
  /* .xsmall несёт СВОЙ цвет (--c-dark-40) и перебивал цвет родителя: подпись
     «Три клиники в Москве:» ложилась тёмно-серым на тёмный скрим (~1,6:1). */
  .hero__meta .lt .xsmall,.hero__meta .rt .xsmall{color:rgba(255,255,255,.82)}
  .hero .rating{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.25);color:#fff}
  .hero .btn-gold:hover{background:var(--c-gold);color:#fff}
  .hero .link-arrow{color:#fff}
  /* ПИННИРОВАННЫЙ КАТАЛОГ НА УЗКИХ.
     .cat__mobile — статичный фолбэк для reduced-motion и для «без JS».
     Когда движок жив, main.js §9 ставит .is-pinned, и работает ТА ЖЕ сцена, что
     на десктопе: пин + snap + смена слайдов скроллом. Меняется только раскладка —
     из двух колонок 44/56 она разворачивается в «кадры сверху, текст снизу». */
  .cat__stage{height:auto}
  .cat__mobile{display:block}
  .cat__desktop{display:none}
  .cat.is-slider .cat__mobile{display:none}
  .cat.is-slider .cat__desktop{display:block;height:100svh}
  /* Смена слайда на телефоне ведётся ТОЛЬКО сдвигом и прозрачностью.
     blur(6px) на слое размером с экран — самая дорогая часть перехода:
     мобильный GPU перерисовывает его каждый кадр обеих сторон перехода.
     Ощущение глубины отдаём чуть большим сдвигом (см. translateX ниже). */
  .cat.is-slider .cat__slide{filter:none;
    transition:opacity .72s var(--slide-ease),transform .72s var(--slide-ease),visibility 0s linear .72s}
  .cat.is-slider .cat__slide.is-active{filter:none;
    transition:opacity .72s var(--slide-ease) .06s,transform .72s var(--slide-ease) .06s,visibility 0s linear 0s}
  .cat.is-slider .cat__slide.is-prev{filter:none}
  .cat.is-slider .cat__slide{grid-template-columns:minmax(0,1fr);
    grid-template-rows:minmax(0,25svh) minmax(0,1fr);transform:translateX(6%)}
  .cat.is-slider .cat__slide.is-prev{transform:translateX(-6%)}
  .cat.is-slider .cat__slide.is-active{transform:translateX(0)}
  .cat.is-slider .cat__left{margin-top:calc(var(--header-h) + 34px)}
  .cat.is-slider .cat__ph.a{left:var(--gut);top:0;width:44%;height:82%}
  .cat.is-slider .cat__ph.b{left:calc(var(--gut) + 30%);top:18%;width:52%;height:82%}
  .cat.is-slider .cat__right{padding:14px var(--gut) 0;max-width:none;gap:9px;justify-content:flex-start}
  .cat.is-slider .cat__desc{font-size:14.5px;line-height:1.45;max-width:none;
    display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
  .cat.is-slider .cat__row{gap:12px}
  .cat.is-slider .cat__thumb{width:66px}
  .cat.is-slider .cat__sub{max-width:none;flex:1 1 auto;min-width:0}
  /* 40 px тап-зоны на каждую позицию прайса (WCAG 2.5.8): пять ссылок дают
     204 px вместо 174 — вертикальный бюджет кадра это выдерживает даже на 640. */
  .cat.is-slider .cat__sub a{min-height:40px;padding:6px 2px;font-size:13px;gap:8px}
  .cat.is-slider .cat__sub .cat__price{font-size:12.5px}
  .cat.is-slider .cat__right .btn{padding:11px 18px;font-size:13.5px}
  .cat.is-slider .cat__name{left:var(--gut);right:var(--gut);bottom:52px;text-align:left;
    font-size:clamp(22px,6.4vw,34px);line-height:1.06}
  .cat.is-slider .cat__counter{top:calc(var(--header-h) + 8px);right:var(--gut);font-size:14px}
  /* меню направлений на телефоне — горизонтальный ряд номеров под шапкой */
  .cat.is-slider .cat__menu{left:var(--gut);right:var(--gut);bottom:6px;top:auto;width:auto;
    display:flex;gap:8px;align-items:center}
  /* подпись «Направления:» съедала 105 px строки, и на 360 полоска-переключатель
     ужималась до 35 px — меньше минимальной тап-цели. Роль подписи здесь и так
     несёт счётчик «02 / 05», поэтому на телефоне отдаём ширину кнопкам. */
  .cat.is-slider .cat__menu .label{display:none}
  /* 40 px по высоте — тап-цель; видимая часть кнопки — полоска-индикатор */
  .cat.is-slider .cat__menu button{flex:1 1 0;min-width:0;height:40px;font-size:0;
    padding:0;position:relative;background:transparent}
  .cat.is-slider .cat__menu button::after{content:"";position:absolute;left:0;right:0;top:19px;height:2px;
    border-radius:2px;background:var(--c-light);opacity:.3;
    transition:opacity .45s var(--default-ease),background-color .45s var(--default-ease)}
  .cat.is-slider .cat__menu button.is-active::after{opacity:1;background:var(--c-gold-soft)}
  /* СТОПКА ЗАКРЕПЛЁННЫХ КАРТОЧЕК НА УЗКИХ.
     Карточка снова во весь экран — это база, от которой считается дистанция пина
     (main.js §8). Чтобы контент реально помещался в 640 px самого низкого телефона,
     ужимаем кадр, поля и номер: 759 -> ~610 px. Всё анимируемое — transform/opacity. */
  [sticky-card]{grid-template-columns:1fr;min-height:100svh;align-content:center}
  .sc__media{aspect-ratio:16/9}
  .sc__body{padding:clamp(18px,4.4vw,40px);gap:12px}
  .sc__num{font-size:clamp(32px,8.4vw,52px)}
  .sc__proof{font-size:14px;padding-left:13px}
  .sc__body .t-h3{font-size:clamp(21px,5.6vw,28px)}
  .sc__body .lead{font-size:clamp(15px,3.9vw,17px)}
  .form__row{grid-template-columns:1fr}
  .foot__cols{grid-template-columns:1fr}
  .foot{--foot-arc:60px}
  .pre-cta{--foot-arc:60px}
  .zoom__stage{padding-inline:0}
  /* ── ПРАВКА ВЛАДЕЛЬЦА 12.08: КАДР НЕ «ЩЕЛЬ». При 4/3 на 390 px кадр получал
     всего 292 px высоты, а подпись из заголовка в две строки и трёх строк
     текста занимает ~150 px — блок читался как узкая полоска, зажатая между
     героем и следующей секцией. Даём кадру портретную пропорцию и пол по
     высоте: снимок операционной снова читается как полноценный кадр, подписи
     остаётся воздух. Пропорцию НЕ меняем — ставим пол по высоте: на планшете
     834 px те же 4/3 дают 625 px и пол не срабатывает, планшетный фикс цел. */
  .zoom__frame{width:100%;aspect-ratio:4/3;min-height:clamp(420px,58svh,520px);border-radius:0}
  /* На узком экране подпись занимает почти всю высоту кадра и заголовок оказывается
     выше точки, где скрим ещё прозрачен, — белый текст ложился на хирургическую лампу.
     Затемнение начинаем раньше и делаем плотнее (только ≤860px, десктоп не трогаем). */
  /* тот же уход в цвет секции, что и на десктопе (см. базовое правило):
     иначе на узких кадр обрывается почти чёрной полосой в светлую страницу */
  .zoom__frame::after{background:linear-gradient(180deg,rgba(20,21,29,.18) 0%,rgba(20,21,29,.55) 30%,
    rgba(20,21,29,.8) 62%,rgba(20,21,29,.92) 91%,var(--c-light) 100%)}
  .cursor{display:none}
  .steps li{grid-template-columns:1fr;gap:6px}
  /* Лента карточек едет по вертикальному скроллу и на телефоне (main.js §15).
     Нативный свайп со snap остаётся фолбэком для reduced-motion и «без JS». */
  .hscroll.is-native,.no-motion .hscroll{overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;
    scroll-snap-type:x proximity;scroll-padding-inline:var(--gut)}
  .hscroll.is-native .hcard,.no-motion .hscroll .hcard{scroll-snap-align:start}
}
/* НИЗКИЕ ЭКРАНЫ В ПОРТРЕТЕ (360×640 и подобные).
   Сцена каталога та же — пин, snap, смена слайдов. Ужимаем только то, что
   упирается в 640 px: описание в две строки вместо трёх и заголовок направления
   мельче, иначе он наезжал на кнопку «Подробнее о направлении». */
@media (max-width:860px) and (max-height:700px) and (orientation:portrait){
  .cat.is-slider .cat__desc{-webkit-line-clamp:2;font-size:14px}
  .cat.is-slider .cat__right{gap:7px}
  .cat.is-slider .cat__sub a{font-size:12.5px}
  .cat.is-slider .cat__name{bottom:46px;font-size:clamp(19px,5.4vw,26px)}
  .cat.is-slider .cat__right .btn{padding:9px 15px;font-size:13px}
}
/* ТЕЛЕФОН/ПЛАНШЕТ В АЛЬБОМЕ (844×390, 932×430).
   Высоты 390 px не хватает на вертикальную раскладку «кадры сверху, текст снизу»:
   заголовок направления наезжал на список цен, а фото обрезались.
   Возвращаем ДВЕ КОЛОНКИ — широкий и низкий экран для них и создан, — а список
   позиций раскладываем в два столбца, чтобы пять строк уложились в три ряда.
   Сцена, пин, snap и смена слайдов не меняются: это только раскладка кадра. */
@media (max-width:1100px) and (max-height:560px) and (orientation:landscape){
  /* Строки ниже дублируют часть узкого блока (<=860) НАМЕРЕННО: на 932×430
     раскладка каталога берётся десктопная, и без них вертикальное меню
     направлений ложилось поверх кадров, а список цен обрезался на третьей позиции. */
  .cat.is-slider .cat__slide{grid-template-columns:38% 62%;grid-template-rows:minmax(0,1fr);
    filter:none;transition:opacity .72s var(--slide-ease),transform .72s var(--slide-ease),visibility 0s linear .72s}
  .cat.is-slider .cat__slide.is-active,.cat.is-slider .cat__slide.is-prev{filter:none}
  .cat.is-slider .cat__menu{left:var(--gut);right:auto;width:32%;bottom:8px;top:auto;
    display:flex;gap:8px;align-items:center}
  .cat.is-slider .cat__menu .label{display:none}
  .cat.is-slider .cat__menu button{flex:1 1 0;min-width:0;height:40px;font-size:0;padding:0;
    position:relative;background:transparent}
  .cat.is-slider .cat__menu button::after{content:"";position:absolute;left:0;right:0;top:19px;height:2px;
    border-radius:2px;background:var(--c-light);opacity:.3;
    transition:opacity .45s var(--default-ease),background-color .45s var(--default-ease)}
  .cat.is-slider .cat__menu button.is-active::after{opacity:1;background:var(--c-gold-soft)}
  .cat.is-slider .cat__left{margin-top:0}
  .cat.is-slider .cat__ph.a{left:var(--gut);top:14%;width:48%;height:42%}
  .cat.is-slider .cat__ph.b{left:calc(var(--gut) + 24%);top:46%;width:54%;height:42%}
  .cat.is-slider .cat__right{padding:calc(var(--header-h) + 40px) var(--gut) 38px 12px;
    gap:7px;justify-content:center;max-width:none}
  /* justify-content:center сжимал описание до нуля, когда сумма высот упиралась
     в 390 px, и текст направления просто исчезал. Запрещаем усадку явно. */
  .cat.is-slider .cat__right>*{flex:none}
  /* подпись «Направление 03» дублирует счётчик «03 / 05» — в альбоме её место
     занимает сам заголовок направления */
  .cat.is-slider .cat__right>.label{display:none}
  /* display:-webkit-box обязателен здесь ещё раз: на 932 узкий блок (<=860) не
     действует, и без него -webkit-line-clamp молчит — описание разворачивалось
     в четыре строки и подлезало под заголовок направления. */
  .cat.is-slider .cat__desc{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;font-size:13px;line-height:1.4;max-width:none}
  .cat.is-slider .cat__row{gap:12px}
  .cat.is-slider .cat__thumb{width:66px}
  /* два столбца позиций: 5 ссылок укладываются в 3 ряда по 40 px тап-зоны */
  .cat.is-slider .cat__sub{grid-template-columns:1fr 1fr}
  .cat.is-slider .cat__sub a{min-height:40px;font-size:12px;gap:6px}
  .cat.is-slider .cat__sub .cat__price{font-size:11.5px}
  .cat.is-slider .cat__right .btn{padding:8px 14px;font-size:12.5px;align-self:flex-start}
  /* заголовок направления встаёт в шапку правой колонки — на месте скрытой
     подписи, между кадрами и счётчиком. Пословное появление остаётся тем же */
  .cat.is-slider .cat__name{left:calc(38% + 12px);right:calc(var(--gut) + 76px);width:auto;
    top:calc(var(--header-h) + 4px);bottom:auto;text-align:left;
    font-size:clamp(17px,2.4vw,23px);line-height:1.1}
  .cat.is-slider .cat__counter{top:calc(var(--header-h) + 2px);right:var(--gut)}
}
/* ТАП-ЦЕЛИ НА СЕНСОРНЫХ ШИРИНАХ (WCAG 2.5.8 «Target Size (Minimum)», 24 px —
   берём практический порог 40/44 px). Самостоятельные ссылки-стрелки, пункты
   подвала, хлебные крошки и телефоны получают высоту бокса, а не только текста.
   Инлайновые ссылки внутри абзаца (согласие на обработку ПДн) не трогаем —
   раздувать строку абзаца хуже, чем оставить ссылку по высоте текста. */
@media (max-width:900px){
  /* padding сверху: подчёркивание link-arrow остаётся вплотную к тексту.
     18, а не 14: ссылки с локальным font-size:14px («Весь каталог») давали
     всего 36 px тап-зоны. Растёт только пустое поле НАД текстом. */
  .link-arrow{padding-top:18px}
  /* Инлайновая ссылка в абзаце согласия. Строку абзаца не раздуваем: вертикальный
     padding у строчного элемента не входит в line box, поэтому вёрстка не едет,
     а палец получает 41 px вместо 17. */
  .consent a{padding-block:12px;margin-block:-12px}
  /* .crumbs a — правило снято 12.08 вместе с самими крошками (см. .phero__eyebrow) */
  .foot ul{gap:0}
  .foot ul a{display:flex;align-items:center;min-height:44px}
  .foot__legal .lnks{gap:0 22px}
  .foot__legal a{display:inline-flex;align-items:center;min-height:40px}
  .foot__addr a{display:inline-flex;align-items:center;min-height:40px}
  /* длинная русская подпись кнопки обрезалась в узкой колонке формы (355 > 340) */
  .btn{white-space:normal;text-align:center}
  .hdr__cta{white-space:nowrap}
}
@media (max-width:700px){
  .btn{white-space:normal;text-align:center}
  .btn-lg{padding:16px 22px;font-size:15px}
  .hdr__cta{white-space:nowrap}
}
@media (max-width:620px){
  .hdr__cta{padding:11px 16px;font-size:13.5px;gap:9px}
  .hdr__cta .ic{width:16px;height:16px}
  /* Прячем ТОЛЬКО подпись под названием. Раньше здесь стояло `.logo span`, а
     этот селектор попадает и во ВНЕШНИЙ span-обёртку — то есть скрывал бы и само
     «Дентал Мед». Название спасал лишь инлайновый style="display:block" в
     разметке: удали кто-нибудь этот атрибут при правке HTML — и на телефоне
     логотип исчез бы целиком. Убираем зависимость от инлайнового стиля. */
  .logo span span,.logo i{display:none}
}
/* 414 px (iPhone XR/11): логотип 164 + CTA 155 + бургер 44 + два зазора = 387 при
   колонке 381 — бургер вылезал на 6 px за правый край. Сжимаем CTA, а не прячем. */
@media (max-width:460px){
  .hdr__cta{padding:10px 13px;font-size:13px;gap:8px}
  .hdr__cta .ic{width:15px;height:15px}
}
@media (max-width:400px){.hdr__cta{display:none}}
/* 3-line-guard (LAYOUT-STANDARDS §7): H1 внутренних страниц уходил в 4-5 строк */
@media (max-width:430px){
  .t-h1{font-size:clamp(26px,6.9vw,31px);line-height:1.1}
  .t-display{font-size:clamp(38px,11vw,54px)}
  .phero .lead{font-size:16px}
}
@media (max-width:480px){
  body{font-size:16px}
  .bub.s1,.bub.s2,.bub.s3{width:calc(50% - 8px);aspect-ratio:1}
  .stats__row{gap:14px}
}
/* Планшетная полоса 481–860: круги стоят на МИНИМУМАХ своих clamp (92/104/120 px
   — vw-член здесь ещё меньше нижней границы), а подпись оставалась 11,5 px.
   «лет гарантии на цирконий» ложилось в три строки шириной под коробку и
   выходило углами за окружность (замер: дальний угол = 111 % радиуса).
   Ужимаем кегль подписи и внутренние поля — связка снова целиком внутри круга.
   Ниже 481 px круги становятся половиной ряда (см. выше) и правило не нужно. */
@media (min-width:481px) and (max-width:860px){
  .bub{padding:7px}
  .bub b{max-width:92%}
  .bub span{font-size:clamp(9px,1.15vw,10px);line-height:1.2;max-width:88%}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
  [data-rv]{opacity:1 !important}
}

/* ==========================================================================
   ПРАВКИ ПО ФИДБЭКУ ВЛАДЕЛЬЦА (06.08.2026)
   Блок идёт последним НАМЕРЕННО: он переопределяет базовые правила выше,
   не переписывая их — исходную логику видно, правку тоже.
   ========================================================================== */

/* --- п.11. ЗАГОЛОВКИ: 1-2 строки, без «по слову на строку» ----------------
   text-wrap:balance выравнивает длины строк и не оставляет сироту из одного
   слова. Работает и с SplitType: разрез на .ln идёт ПОСЛЕ загрузки шрифтов,
   то есть по уже сбалансированной раскладке, и переносы фиксируются верные. */
h1,h2,h3,h4,h5,h6,
.t-display,.t-h1,.t-h2,.t-h3,.t-h4,
.cat__name,.team__title,.hero__promise,.sc__body .t-h3,.zoom__cap .t-h3{
  text-wrap:balance}
/* абзацам — pretty: сирот тоже не оставляет, но длины строк не выравнивает
   (для текста это правильнее, чем balance) */
.lead,.cat__desc,.sc__proof,.tech__benefit,.mission__txt,.zoom__cap .small{text-wrap:pretty}

/* --- п.4-5-8-9. КАТАЛОГ НАПРАВЛЕНИЙ: слайдер вместо пина ------------------ */
/* Секция больше не пиннируется и не листается скроллом (см. main.js §9).
   .cat__mobile — статичный дубль, нужный только когда движка нет. */
.cat.is-slider .cat__mobile{display:none}

/* п.5. ЛЕВАЯ КОЛОНКА (ТОЛЬКО ПК): две ч/б фотки ОДНОГО размера строго
   в столбик по одной левой линии, под ними — список специальностей.
   Было: .a 46%x35% со сдвигом left:0/top:7%, .b 52%x33% со сдвигом left:20% —
   разный размер и разные левые линии (кадр 12-49-29). */
@media (min-width:861px){
  /* селектор с ДВУМЯ классами намеренно: базовые .cat__ph.a/.cat__ph.b выше
     имеют ту же вес-пару, и одиночный .cat__ph им проигрывал бы по specificity */
  /* п.12. ЦВЕТ ВМЕСТО Ч/Б (решение по дизайну, сверено скриншотами
     _verify-k/shots/cat-bw-1440.png vs cat-color-1440.png). Обесцвеченная пара
     на тёмно-синем фоне читалась как сток-заглушка и спорила с золотом бренда;
     у цветных версий (*-color.webp, генерация genmedia) тёплая латунная гамма —
     она ложится на золотые акценты секции и «оживляет» левую колонку, при этом
     единственное лицо крупно остаётся у миниатюры результата справа.
     grayscale(1) снят, оставлена мягкая градация: контраст +4 %, насыщенность
     -8 % — чтобы фото не спорили яркостью с ценами. */
  .cat__ph.a,.cat__ph.b{position:absolute;left:var(--gut);right:clamp(22px,3.2vw,68px);
    width:auto;height:25.5%;min-height:150px;max-height:300px;
    overflow:hidden;filter:contrast(1.04) saturate(.92);border-radius:2px}
  .cat__ph.a{top:calc(var(--header-h) + 26px)}
  /* ── НИЖНИЙ КАДР НЕ НАЕЗЖАЕТ НА СПИСОК НАПРАВЛЕНИЙ (правка владельца 12.08) ──
     БЫЛО: высота кадра — доля высоты сцены (25,5 %), а .cat__menu приклеено
     к НИЗУ в ПИКСЕЛЯХ (список 182 px + отступ 31 px = 213 px). Доля сжимается
     вместе с окном быстрее, чем пиксели, поэтому на невысоких окнах кадр
     доезжает до списка. Замер 12.08 при 1194x714: зазор всего 9 px, а на
     iPad Карины (photo 15-05-12) «НАПРАВЛЕНИЯ» и «Имплантация» уже лежат
     НА светлой фотографии и не читаются.
     СТАЛО: сверху высота ограничена так, чтобы от низа кадра до верха списка
     всегда оставалось ~24 px. Считаем от 100svh (ровно высота .cat__stage),
     а не от 100 % — контейнер слайда бывает на пару десятков пикселей выше
     сцены, и процент от него давал бы заниженный запас.
     На окнах от ~900 px высотой ограничение НЕ срабатывает: раскладка та же. */
  .cat__ph.b{top:calc(var(--header-h) + 26px + 27.5%);
    max-height:calc(100svh - 237px - var(--header-h) - 26px - 27.5%)}
  /* «экран визуально делится на две неравные части» — граница колонок 44/56
     получает волосяную линию, чтобы деление читалось, а не угадывалось */
  .cat__left::after{content:"";position:absolute;right:0;top:16%;bottom:14%;width:1px;
    background:linear-gradient(180deg,transparent,rgba(234,232,232,.2) 16%,
      rgba(234,232,232,.2) 84%,transparent);pointer-events:none}
  /* список специальностей стоит на той же левой линии, что и фотки */
  .cat__menu{left:var(--gut);right:auto;width:clamp(170px,15vw,240px)}
}

/* п.4. СТРЕЛКИ. Одна пара на обе ширины: на ПК — под счётчиком «01 / 05»
   в правом верхнем углу сцены (там нет ни заголовка, ни списка цен),
   на телефоне — по краям строки-переключателя внизу. */
.cat__nav{position:absolute;z-index:7;display:flex;gap:10px;
  right:var(--gut);top:calc(var(--header-h) + 58px)}
.cat__arrow{width:46px;height:46px;flex:none;padding:0;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;color:var(--c-light);
  background:rgba(255,255,255,.07);border:1px solid rgba(234,232,232,.3);
  transition:background-color .3s var(--default-ease),border-color .3s var(--default-ease),
    color .3s var(--default-ease),transform .2s var(--default-ease)}
.cat__arrow svg{width:20px;height:20px}
.cat__arrow:hover{background:var(--c-gold-soft);border-color:var(--c-gold-soft);color:var(--c-dark)}
.cat__arrow:active{transform:scale(.93)}
.cat__arrow:focus-visible{outline:2px solid var(--c-gold);outline-offset:3px}

/* --- п.6. ЦИФРЫ-ПУЗЫРИ: симметричная дуга «как зубной ряд» (ТОЛЬКО ПК) ----
   Кадр 12-50-11 + эскиз 12-50-14: размер убывает ОТ ЦЕНТРА К КРАЯМ,
   центры лежат на одной дуге. На телефоне (<=860) блок не трогаем — владелец:
   «на телефоне отлично», там остаётся сетка 2-в-ряд без дуги.
   Геометрия: дуга — квадратичная кривая M0 0 Q600 100 1200 0 в боксе высотой
   2*--arc-drop, поэтому её ордината в долях --arc-drop равна 2*t*(1-t):
   Значения t взяты ЗАМЕРОМ реальных центров (пузыри разной ширины, слоты
   неравные): край t=.158 -> .531, середина t=.279 -> .805, центр t=.423 -> .976.
   Отсюда сдвиги пузырей = разница с крайним: 0 / .274 / .445, а сама дуга
   поднята на .531*drop, чтобы в точке крайнего пузыря лечь на его центр. */
/* ПРАВКА ВЛАДЕЛЬЦА 06.08 (референс-схема ревьюера).
   БЫЛО: ряд на flex — ширины пузырей разные, поэтому и промежутки между
   центрами были разные, «зубной ряд» читался вразнобой; сквозь пузыри шла
   svg-кривая.
   СТАЛО: шесть РАВНЫХ колонок грида — расстояние между центрами одинаковое
   всегда. Диаметры зеркальны относительно вертикальной оси: пара центральных
   самая крупная, следующая меньше, крайние самые мелкие. Кривую убрали
   совсем (по прямому требованию владельца), сама дуга задана позициями.

   ГЕОМЕТРИЯ. Центр каждого пузыря обязан лежать на одной параболе-«улыбке»
   (прогиб вниз, концы приподняты). Нормируем позицию колонки u = ±1, ±.6, ±.2
   и берём глубину f = 1 - u²  ->  края 0, средние .64, центральные .96.
   Пузыри разного диаметра, поэтому сдвиг СВЕРХУ доводим до общего центра:
       margin-top = f·drop + (Dmax - D)/2
   тогда центр = 0.48·Dmax + f·drop и от диаметра не зависит — пары стоят
   строго на одной высоте, ряд симметричен.
   Проценты берутся от ширины КОЛОНКИ (для margin-top % тоже считается от
   инлайн-размера), поэтому всё масштабируется без единого числа в JS. */
@media (min-width:861px){
  .stats__row{position:relative;--drop:clamp(32px,4.6vw,78px);
    display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:0;
    align-items:start;justify-items:center;padding-bottom:0}
  .stats__row .bub{position:relative;z-index:1;top:0;width:var(--d);aspect-ratio:1;
    margin-top:calc(var(--f) * var(--drop) + (96% - var(--d)) / 2)}
  /* :nth-of-type считает по ТИПУ элемента — нумерация пузырей 1..6 честная */
  .stats__row .bub:nth-of-type(1),.stats__row .bub:nth-of-type(6){--d:70%;--f:0;--bk:.84}
  .stats__row .bub:nth-of-type(2),.stats__row .bub:nth-of-type(5){--d:83%;--f:.64;--bk:.92}
  .stats__row .bub:nth-of-type(3),.stats__row .bub:nth-of-type(4){--d:96%;--f:.96;--bk:1}
  /* кегль числа убывает к краю вместе с диаметром — иначе «10» в мелком круге
     упирается в кромку. Подпись НЕ масштабируем: ниже 9,5 px она нечитаема.
     Кегль задаётся через --numfs; связку «число + подпись» центрирует базовое
     правило .bub (flex-колонка), от смены кегля центровка не ломается. */
  .stats__row .bub{--numfs:calc(clamp(19px,2.1vw,36px) * var(--bk,1))}
  /* Круг — это вписанный квадрат со стороной 0,707·D. Держим текст в 72 %
     диаметра: в этот коридор влезают самые длинные подписи мелких кругов
     («лет гарантии на цирконий», «клиники в Москве») в две строки. */
  .stats__row .bub b{max-width:72%}
  .stats__row .bub span{max-width:72%}
  /* переносы ВНУТРИ слова не включаем: в подписи из двух слов «непрерыв-ной»
     читается как опечатка. */
  .stats__row .bub span{font-size:clamp(9.5px,.8vw,11.5px);
    overflow-wrap:normal;hyphens:manual;-webkit-hyphens:manual}
}

/* --- п.10. ВРАЧИ: текст и фото больше не разъезжаются --------------------- */
/* ПК. Было align-items:flex-end — ряд выравнивался по НИЗУ подписи, а подписи
   разной длины (одна строка против двух) поднимали свои портреты на разную
   высоту: именно это «поехало» на кадрах IMG_8665. Выравниваем по ВЕРХУ
   кадров — картинки одного размера встают в одну линию всегда, а подписи
   свободно висят снизу. */
.team__row{align-items:flex-start}
.team__p figcaption{margin-top:-14px}
/* две строки специальности резервируются заранее, чтобы низ ряда был ровным */
.team__p span{min-height:2.6em}

@media (max-width:860px){
  /* Телефон: flex с переносом давал «пляшущие» пары разной высоты.
     Сетка 2 в ряд с выравниванием по верху — ряды ровные при любой длине ФИО. */
  .team__row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:clamp(18px,4.6vw,30px) clamp(10px,3vw,18px);
    align-items:start;justify-items:stretch;
    margin-top:clamp(14px,4vw,26px);padding-inline:var(--gut)}
  .team__p{width:100%}
  /* маска существовала, чтобы кадр растворялся под большим заголовком.
     На телефоне заголовок стоит ОТДЕЛЬНОЙ строкой выше, наезда нет, а маска
     срезала портрет сверху и снизу — на кадре f05 от врача остаётся халат. */
  .team__p img{-webkit-mask-image:none;mask-image:none;border-radius:3px}
  .team__p figcaption{margin-top:8px}
  .team__p b{font-size:14px;line-height:1.25}
  .team__p span{font-size:11.5px;line-height:1.3;min-height:0}
  /* пятый врач в паре не остаётся прижатым к левому краю */
  .team__p:last-child:nth-child(odd){grid-column:1 / -1;justify-self:center;width:calc(50% - 9px)}
}

/* --- п.1. СТОПКА КАРТОЧЕК НА ТЕЛЕФОНЕ: просто друг за другом -------------- */
/* main.js §8 на узком экране ставит .stack-flow на <html> вместо четырёх пинов.
   Карточке больше не нужна высота в целый экран — она была базой пина. */
.stack-flow [sticky-card]{min-height:0}
.stack-flow [sticky-card]::after{display:none}

/* --- п.4/8/9. КАТАЛОГ НА ТЕЛЕФОНЕ ---------------------------------------- */
@media (max-width:860px){
  /* сцена больше не пиннируется, поэтому высоту задаёт содержимое:
     активный слайд встаёт в поток, остальные лежат под ним без веса */
  .cat.is-slider .cat__desktop{display:block;height:auto}
  .cat.is-slider .cat__stage{height:auto;overflow:hidden;position:relative;
    /* место под заголовок направления и строку-переключатель со стрелками */
    padding-bottom:clamp(104px,27vw,140px)}
  .cat.is-slider .cat__slide{position:absolute;left:0;right:0;top:0;bottom:auto;
    grid-template-rows:auto auto}
  .cat.is-slider .cat__slide.is-active{position:relative}
  /* кадрам нужна опорная высота: внутри они позиционированы в процентах */
  .cat.is-slider .cat__left{height:clamp(150px,25svh,230px);margin-top:calc(var(--header-h) + 30px)}
  .cat.is-slider .cat__ph{right:auto;border-radius:2px}
  .cat.is-slider .cat__right{padding-bottom:12px}

  /* п.9: «голубой блок услуги с ценами — в полный размер, фотку сдвинуть
     ВНИЗ под таблицу» (кадр 13-18-00). п.8: та же фотка «выглядит странно»
     (кадр 13-17-35) — вертикальный кроп 4/5 ужимался до 66 px и резал сюжет. */
  .cat.is-slider .cat__row{flex-direction:column;align-items:stretch;gap:14px}
  .cat.is-slider .cat__sub{order:1;width:100%;max-width:none;flex:none}
  .cat.is-slider .cat__thumb{order:2;width:100%;max-width:none;flex:none;
    aspect-ratio:16/9;border-radius:2px}
  .cat.is-slider .cat__thumb img{object-position:50% 42%}
  /* описание разворачиваем на 3 строки — вертикального бюджета больше нет */
  .cat.is-slider .cat__desc{-webkit-line-clamp:4}

  /* стрелки уходят по краям строки-переключателя, полоски — между ними */
  .cat.is-slider .cat__nav{top:auto;right:auto;left:0;bottom:8px;width:100%;
    padding-inline:var(--gut);justify-content:space-between;pointer-events:none}
  .cat.is-slider .cat__arrow{width:44px;height:44px;pointer-events:auto}
  .cat.is-slider .cat__menu{left:calc(var(--gut) + 56px);right:calc(var(--gut) + 56px);bottom:16px}
  .cat.is-slider .cat__name{bottom:clamp(66px,17vw,86px)}
}
/* низкие экраны в портрете: подпись направления и полоски стояли впритык */
@media (max-width:860px) and (max-height:700px) and (orientation:portrait){
  .cat.is-slider .cat__desc{-webkit-line-clamp:3}
}
/* телефон в альбоме: сцена снова двухколоночная, значит и фото цены — в строку */
@media (max-width:1100px) and (max-height:560px) and (orientation:landscape){
  .cat.is-slider .cat__stage{padding-bottom:0}
  .cat.is-slider .cat__left{height:auto;margin-top:0}
  .cat.is-slider .cat__row{flex-direction:row;align-items:flex-start;gap:12px}
  .cat.is-slider .cat__thumb{order:0;width:66px;aspect-ratio:4/5}
  /* без сброса ширины/flex .cat__sub наследовал width:100%;flex:none из
     портретного правила (п.9 выше) и вылезал на ~78 px за край экрана в
     альбомной ориентации телефона — правая колонка цен пряталась за кадром. */
  .cat.is-slider .cat__sub{order:1;width:auto;flex:1 1 auto;min-width:0}
  .cat.is-slider .cat__nav{position:absolute;left:auto;right:var(--gut);bottom:auto;
    top:calc(var(--header-h) + 2px);width:auto;padding-inline:0}
  .cat.is-slider .cat__arrow{width:34px;height:34px}
  .cat.is-slider .cat__arrow svg{width:15px;height:15px}
  .cat.is-slider .cat__counter{right:calc(var(--gut) + 90px)}
  .cat.is-slider .cat__menu{left:var(--gut);right:auto;width:32%}
}

/* --- п.1. МЕЛОЧИ БЮДЖЕТА КАДРА ------------------------------------------- */
/* Медиа с ЖЁСТКОЙ пропорцией: за кадром содержимое можно не растеризовать,
   высота бокса всё равно известна из aspect-ratio, вёрстка не двигается. */
.cat__thumb,.sc__media img,.zoom__frame{content-visibility:auto;contain-intrinsic-size:auto 300px}
/* «Дышащие» пятна с blur(78px) на телефоне не окупаются: это самый дорогой
   фильтр страницы, а на 390 px от него виден лишь общий подсвет фона. */
@media (max-width:860px){
  .decor{animation:none !important;filter:blur(54px);opacity:.75}
}

/* === п.11. ЗАГОЛОВКИ: 1–2 СТРОКИ, БЕЗ «ПОСЛОВНОЙ ЛЕСЕНКИ» ================= */
/* ЧТО БЫЛО. Заголовки сидели на ручных кэпах вида max-width:16ch. В Playfair
   Display 1ch (ширина «0») заметно уже средней буквы, поэтому 16ch — это
   примерно 13–14 реальных знаков: строка «а не отдаём на сторону» в такой кэп
   не влезала, ломалась пополам, и заголовок вырастал в лесенку из 3–4 строк с
   одиноким словом в конце («сторону», «мышкой»). На кадре владельца это и был
   «заголовок в четыре строки».
   ПОЧЕМУ ИМЕННО ТАК. Кэпы не выкинуты: без них длинный заголовок растянулся бы
   на всю колонку и потерял бы силуэт. Они РАСШИРЕНЫ до значения, при котором
   авторский перенос (по <br> или по смысловой границе) остаётся единственным,
   а вторая строка помещается целиком. Значения замерены в браузере (см.
   _verify-k/tune-nojs.log): для каждого заголовка бралась минимальная ступень,
   дающая 2 строки на 390/834/1440 и в RU, и в EN, плюс запас ~4ch на то, что
   SplitType после разреза добавляет к строке ширину межсловных inline-block'ов.
   Кэпы живут в разметке (inline max-width) — здесь только то, что не выражается
   одним числом на элемент. */

/* Заголовок в узкой колонке .g2 на ПК. 68px базовой ступени рассчитаны на
   полную ширину; в половинной колонке (≈641px на 1440) той же строке нужно на
   20 % меньше кегля, иначе любая фраза из четырёх слов ломается на три строки.
   Имена врачей и короткие заголовки от этого не страдают — они и так короче. */
@media (min-width:861px){
  .g2>div>.t-h2{font-size:clamp(30px,3.5vw,52px)}
}

/* Заголовок предфинального CTA. Он повторяется на всех шести страницах и в
   обеих локалях, и именно он давал «Начните с бесплатной | консультации. |
   Дальше решаете вы.» — одинокое слово посередине. Причина не в кэпе, а в
   колонке: 34 знака при 60px требуют ~918px, а колонка формы оставляет 641px.
   Поэтому заголовок вынесен НАД двумя колонками (.cta-head в разметке) — там
   ему доступна вся ширина .wrap, и авторский <br> снова единственный перенос. */
.cta-head{margin-bottom:clamp(18px,2.2vw,34px)}
.cta-head .t-h2{max-width:30ch}
@media (max-width:860px){
  /* на телефоне колонки и так одна под другой — блок просто идёт первым */
  .cta-head{margin-bottom:14px}
}

/* п.11. «Заголовок слева — пояснение справа». Строка сделана flex-wrap'ом, но
   без базиса дети просто СЖИМАЮТСЯ: на 390 px заголовку оставалось 235 px, и
   «Полный каталог — чтобы не искать вторую клинику» разъезжался на три строки.
   Даём каждой половине базис 320 px: на узком экране строка честно переносится
   и заголовок получает всю ширину, на широком раскладка прежняя. */
.head-split>*{flex:1 1 400px;min-width:min(100%,400px)}
@media (min-width:861px){.head-split>*{flex:0 1 auto;min-width:0}}

/* п.11. Заголовок страницы врачей: не хватало 3–8 % кегля, чтобы вторая
   строка встала целиком (замер fitfont.cjs).
   Для .pre-cta__big правило снято 06.08: кегль ограничен в базовом блоке
   (clamp(40px,6.4vw,110px)), и повторное 9.5vw возвращало трёхстрочный
   заголовок на 1920. */

/* ==========================================================================
   ФИДБЭК ВЛАДЕЛЬЦА 12.08 — ГЛАВНЫЕ CTA НА ТЕЛЕФОНЕ ВО ВСЮ ШИРИНУ
   БЫЛО: .btn — inline-flex по содержимому. На 390 px «Записаться на бесплатную
   консультацию» занимала ~65 % колонки и вставала по ЛЕВОМУ краю (в hero —
   из-за flex-start у .hero__cta, в форме — из-за justify-items:start у
   .form__send). Кнопка читалась как прижатая к краю, а не как главное действие.
   СТАЛО: на ширинах <= 600 px все содержательные CTA растягиваются на ширину
   контейнера — один калибр на всех шести страницах и в обеих локалях, и
   вопрос выравнивания снимается сам собой.
   ИСКЛЮЧЕНИЕ: кнопка в шапке (.hdr__cta) — часть строки логотип+CTA+бургер,
   растягивание сломало бы шапку.
   ========================================================================== */
@media (max-width:600px){
  .btn{width:100%;max-width:100%}
  .hdr__cta{width:auto}
  /* ПОДПИСЬ КНОПКИ — В ОДНУ СТРОКУ (фидбэк владельца 12.08).
     Самая длинная подпись сайта — RU «Записаться на бесплатную консультацию»
     (36 знаков). Замер на 390: текст 280 + зазор 14 + иконка 20 + поля 44 =
     358 при кнопке 359 — ровно на грани, и округление роняло её на две строки.
     Ужимаем боковые поля и делаем кегль текучим: на 360 подпись занимает 322
     из 329, на 390 — 342 из 359. white-space:normal оставлен как страховка:
     сработать ему теперь не на чем, но при ещё более узком экране кнопка
     перенесёт текст, а не выпустит его за свою кромку. */
  .btn-lg{padding:16px;font-size:clamp(13px,3.5vw,15px);gap:8px}
  .btn-lg .ic{width:16px;height:16px}
  /* .scene__btm — абсолютный слой без внутренних полей: полноширинная кнопка
     упёрлась бы в кромки экрана, возвращаем боковое поле секции. */
  .scene__btm{padding-inline:var(--gut)}
  /* hero: .hero__top — грид с justify-items:start, поэтому сам блок кнопок
     сжимался по содержимому (255 из 359 px) и width:100% у кнопки считался от
     этой сжатой коробки. Растягиваем коробку, а внутри — колонка: кнопка и
     ссылка-стрелка перестают делить строку, каждая своей. */
  .hero__cta{justify-self:stretch;flex-direction:column;align-items:stretch}
  .hero__cta .link-arrow{align-self:flex-start}
  /* форма: колонка грида и так во всю ширину, снимаем только justify-items */
  .form__send{justify-items:stretch}
}

/* --- Фильтры «до/после»: сетка 2×2 вместо рваного переноса (аудит 12.08) ----
   Тот же калибр, что уже стоит на dental-med-2 (.filters, max-width:600px).
   БЫЛО: .ba__filters — flex с переносом, ширина кнопки по надписи. На 390 px
   четыре разных по длине подписи вставали рваной лесенкой: «Все работы» +
   «Виниры и эстетика» в первом ряду, «Восстановление» + «Имплантация» во
   втором, но колонки не совпадали и правая кромка гуляла на 40+ px.
   СТАЛО: две ровные колонки, два ряда, кнопки одной ширины, тап-зона 44 px. */
@media (max-width:600px){
  .ba__filters{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .ba__filters .tag{width:100%;justify-content:center;text-align:center;
    padding:10px 8px;font-size:13px;line-height:1.25;min-height:44px;
    display:inline-flex;align-items:center}
}

/* ==================== Правки по фидбэку владельца 13.08.2026 ==================== */

/* (фото 10, 11, 12, 30) ОБЛАКО ТЕГОВ — УПЛОТНИТЬ.
   БЫЛО: .tag — 10/17 px полей при кегле 14.5 и зазоре 9 px. На 390 в ряд
   влезал один-два тега, 36 тегов растягивались на два экрана прокрутки,
   справа от коротких подписей пустовала половина ширины. СТАЛО: поля и кегль
   ужаты, зазор 6 px — в ряд встаёт на один тег больше, высота блока падает
   примерно на треть. Тап-цель остаётся 36 px (список ссылок-фильтров, не
   основной CTA). Действует и на светлой главной, и на тёмном каталоге. */
@media (max-width:600px){
  .tags{gap:6px;margin-top:22px}
  .tag{padding:8px 12px;font-size:13px;line-height:1.2}
  /* фильтры «до/после» ниже переопределяют размеры сами — их не трогаем */
}

/* (фото 13) ВЫБОР КЛИНИКИ — ДВА В РЯД, ТРЕТИЙ ОТДЕЛЬНО И КРУПНЕЕ.
   БЫЛО: flex с переносом — три пилюли столбиком по одной, разной ширины.
   СТАЛО: сетка 2×2; третья клиника занимает весь второй ряд и набирается
   крупнее — так владелец и просил («два города в ряд, третий крупнее»). */
@media (max-width:600px){
  .radios{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .radios label{padding:11px 10px;font-size:12.5px;gap:7px;min-height:44px;
    justify-content:center;text-align:center;line-height:1.15}
  .radios input{width:14px;height:14px;flex:none}
  .radios label:nth-child(3){grid-column:1/-1;font-size:15px;padding:13px 14px}
  .radios label:nth-child(3) input{width:16px;height:16px}
}

/* (фото 14, 15) ВЕРТИКАЛЬНЫЕ ИНТЕРВАЛЫ НА ТЕЛЕФОНЕ.
   Владелец: блоки стоят слишком разрежённо, между полноэкранным кадром и
   следующим заголовком провал в пол-экрана. Секционные поля 72 px сверху и
   снизу + 40 px под заголовком давали 112 px пустоты подряд. Ужимаем до
   48 px и 24 px — плотность как на остальных экранах после этого фидбэка. */
@media (max-width:600px){
  .sec{padding-block:clamp(44px,7.5vw,72px)}
  .zoom + .sec{padding-top:clamp(34px,6vw,56px)}
  .zoom__stage{padding-block:0}
  .zoom + .sec .t-h2{margin-bottom:24px !important}
}

/* (фото 16–21) «ЗАПИСАТЬСЯ К ВРАЧУ» — К ПРАВОМУ КРАЮ.
   Ссылка-стрелка в карточке врача стояла у левой кромки, справа пустовала
   вся ширина колонки. Абзац-обёртка — последний элемент карточки, ему и
   ставим выключку вправо. Только телефон: на десктопе карточка двухколоночная
   и левый край ссылки держит ритм колонки. */
@media (max-width:900px){
  .doc > div > p:last-child:has(.link-arrow){text-align:right}
}

/* (фото 14) ТЁМНАЯ ШАПКА РАЗДЕЛА НА ТЕЛЕФОНЕ — БЕЗ ПОЛОСЫ ПУСТОТЫ.
   Замер на 390×844: .phero держал 100 svh = 844 px при содержимом 280 px —
   564 px пустоты, из них ~200 px тёмной полосой между текстом и кадром
   следующей секции (ровно то, что владелец обвёл на фото). Ограничиваем
   высоту 72 svh (не больше 640 px): экранная подача остаётся, провал уходит. */
@media (max-width:600px) and (orientation:portrait){
  .phero{min-height:min(72svh,640px);padding-bottom:clamp(28px,5vw,48px)}
}

/* ════════════════════════════════════════════════════════════════════════════
   ЗАКОН ВЛАДЕЛЬЦА 13.08: ФОТО-БЛОК НА ТЕЛЕФОНЕ = ПОЛНЫЙ ЭКРАН
   Дословно: «если я говорю сделать блоки больше — сделай БОЛЬШЕ, чтобы ОДИН
   БЛОК закрывал площадь экрана телефона — одна прокрутка колеса».

   ЧТО БЫЛО (замер 390×844, 13.08):
     .phero  — 608 px (72 % экрана) на «Врачах», «Ценах», «Технологиях»,
               «Контактах»; 683 px (81 %) на «Услугах». Виновник — правка
               выше по файлу: min(72svh,640px). Она решала «провал под
               текстом», но превратила кадр в полосу — владелец обвёл эти
               блоки на фото 2, 3, 4, 5.
     .zoom   — 490 px (58 %). Кадр операционной/интерьера читался узкой
               лентой между двумя светлыми секциями (фото 6, 7).

   ЧТО СТАЛО: ровно 100 svh — фото-секция занимает экран телефона целиком.
   svh (а не vh/dvh) — «маленький» вьюпорт: выдвинутые панели мобильного
   браузера кадр не режут и высота не скачет при скролле. Строка на vh
   оставлена ПЕРВОЙ как фолбэк для движков без svh.

   ГРАНИЦЫ ПРАВИЛА (десктоп и альбом не трогаем):
     • max-width:900px — телефоны и планшет в портрете (проверено 390, 414,
       768, 820, 900);
     • orientation:portrait — в альбомном телефоне высота окна 390-560 px,
       там и без того нет вертикального места, и работают прежние правила
       (@media (orientation:landscape) and (max-height:560px){.phero{min-height:auto}}).
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px) and (orientation:portrait){
  /* Тёмная шапка раздела: подложка-фото на весь экран, текст по центру
     колонки (display:flex/justify-content:center из базового правила),
     padding-top по-прежнему отбивает фиксированную шапку сайта. */
  .phero{min-height:100vh;min-height:100svh}

  /* Кадр .zoom: пропорция снимается (aspect-ratio:4/3 давала 292 px), место
     держит высота в экран. Снимок остаётся object-fit:cover — заполняет всю
     площадь без искажений; подпись .zoom__cap абсолютна по нижней кромке и
     ложится на плотную часть скрима, контраст не меняется.

     ВАЖНО — height, а НЕ min-height. .zoom__stage — обычный блок, и при
     height:auto у рамки процентная высота ребёнка (.zoom__frame img{height:100%})
     разрешаться не в чем: снимок падал до собственной пропорции (219 px на
     390 px ширины), а оставшиеся 625 px секции заливал один голый градиент
     скрима — «серая простыня» вместо фотографии (замер 13.08). Явная высота
     делает контейнер definite, и height:100% + object-fit:cover снова
     растягивают кадр на весь блок. */
  .zoom__stage{height:auto}
  .zoom__frame{aspect-ratio:auto;height:100vh;height:100svh}
}

/* ════════════════════════════════════════════════════════════════════════════
   ПРАВКА ВЛАДЕЛЬЦА 27.08 (два кадра с телефона)
   ════════════════════════════════════════════════════════════════════════════
   1) ПОРТРЕТ ГЛАВВРАЧА. Правка 26.08 дала фигуре max-width:300px в блоке
      @media (max-width:1100px). Колонка на телефоне — 331-381 px, поэтому
      фото прижималось к левой кромке, а справа оставалась пустая полоса
      30-80 px (кадр 1). Просто margin-inline:auto не сработал бы: у <figure>
      в разметке стоит инлайновый style="margin:0", а инлайн сильнее любого
      селектора — отсюда !important (правка только в CSS, разметку не трогаем).
      Отдаём фигуре всю ширину колонки с потолком 420 px: на 360/390/414 это
      честная полная ширина, на планшете в портрете — центр. Подпись живёт
      внутри figure, поэтому её левый край совпадает с левым краем кадра сам.

   2) ЗАГОЛОВОК ГЕРОЯ. Переносы заданы в разметке (<br> между словами), CSS их
      снять не может: display:none на <br> склеивает слова без пробела во всех
      трёх движках (проверено Chromium/Firefox/WebKit — ::after на <br> не
      рисуется). Поэтому берём второй вариант владельца — «увеличь кегль».
      Замер ширины строки на 1 px кегля: RU «стоматология» = 6.45 px/px,
      EN «dental care» = 4.48 px/px. Отсюда разные ступени по локали
      (html[lang]) — каждая рассчитана на заполнение ~90-96 % колонки:
        RU 13.7vw → 49 / 53 / 57 px на 360 / 390 / 414 (было 39.6 / 42.9 / 45.5)
        EN 18vw   → 65 / 70 / 74 px на тех же ширинах
      Ни одно слово не переносится внутри себя, hyphens не включаем.
      Границы: только телефон в портрете (<=620 px). Планшет 820, альбом
      844x390 и десктоп 1366 остаются на прежних правилах. */
@media (max-width:860px) and (orientation:portrait){
  .mission__ph{max-width:min(100%,420px);margin-inline:auto !important}
}
@media (max-width:620px) and (orientation:portrait){
  .hero__title{max-width:none;width:100%}
  .t-display.hero__title{font-size:clamp(44px,13.7vw,58px)}
  html[lang="en"] .t-display.hero__title{font-size:clamp(52px,18vw,76px)}
  .hero__title .lay{overflow-wrap:normal;hyphens:none}
}
