/* РАСКЛАДКИ ПЕРВОГО ЭКРАНА - ЗЕРКАЛО, А НЕ СВОЯ ВЕРСИЯ.

   Источник: design/v4/site-hero/kit/ (7 файла). Собирает tools/adopt-hero.php;
   правка руками теряется при следующем срезе и теряется молча.

   Отступления от побайтовой копии объявлены В КОДЕ ИНСТРУМЕНТА и печатаются отчётом
   прогона. Их 52. */

/* ===== hero.css ===== */
/* ПЕРВЫЙ ЭКРАН - оболочка, роли, шкала, рецепт вуали. Слой САЙТА (sc-base): ни одного --sc-*.

   РЕШЁТКА. Вариант - это пресет значений ОСЕЙ, а не отдельная раскладка. Осей четыре:
     --ls-hero-h     рост секции: во весь экран (100cqh) | по содержимому
     data-align      выравнивание текста: start | center
     data-edge       к какому краю прижат текстовый блок: middle | start | end
     data-hold       чем держится контраст: veil (вуаль) | card (панель) | band (полоса) | none
   Пятая ось только у A6: data-corner - у какого края стоит угловая карточка.
   Сочетание, не дающее ЗАМЕРЯЕМОГО отличия, вариантом не становится: у компактной секции
   «верх / центр / низ» неразличимы, потому что высоту задаёт сам блок.

   ШКАЛА КЕГЛЕЙ - те же десять ступеней с отношением 1,25, но интерлиньяж МОНОТОННЫЙ и
   проверен на КИРИЛЛИЦЕ, а не на латинице: минимум 1,109 (диакритика прописных Ё и Й).
     12,8 - 1,4   |  16 - 1,5   |  20 - 1,4   |  25 - 1,3   |  31,25 - 1,25
     39,06 - 1,2  |  48,83 - 1,18 | 61,04 - 1,15 | 76,29 - 1,14 | 95,37 - 1,12
   Выброс разведки (1,1 на 48,83) снят: он был дефектом, а не решением, и на кириллице
   давал столкновение чернил. Ступень 39,06 занята - A3 берёт её на узком, A4 на среднем,
   поэтому шкала остаётся десятиступенчатой. Ни одна ступень не даёт интерлиньяж меньше
   1,112 - запас к кириллице есть на каждой.

   ДВА ПОРОГА, И ВТОРОЙ ОБЪЯВЛЕН ОСОЗНАННО:
     700  - узкий: всё в один столбец;
     1040 - средний: ряд ещё жив, но вылеты и трёхколонные полосы уже нет.
   Без среднего не выражаются A5 (полоса в три колонки) и A7 (два края): на 900 точках они
   уже не столбец, но ряд из трёх колонок там даёт колонку в 180 точек - меру в 22 знака.
   Порог один на всю систему, а не по месту.

   ПЕРВЫЙ ЭКРАН ВЛЕЗАЕТ В ПЕРВЫЙ ЭКРАН. Рабочая высота монитора - 940 (1080 минус полоса
   браузера и панель системы), и ни один набор не имеет права её перерастать: секция, которая
   выше экрана, обрезает своё же действие. Поэтому вертикальные поля 96/72/56 вместо
   128/96/72, а КАЖДАЯ фиксированная высота медиа взята в min() со долей cqh: число задаёт
   замысел, доля не даёт ему выйти за экран. Высота при этом НЕ фиксируется (правило 03) -
   секция по-прежнему растёт под кириллический заголовок, просто медиа уступает ему место.
   Доли считаны от 940 при полях 96: под содержимое остаётся 748. */

/* --- СИСТЕМНЫЕ ЗНАЧЕНИЯ СЛОЯ САЙТА. Объявлены ЗДЕСЬ, а не живут запасными значениями в
   var(): девять ссылок (--ls-body, --ls-eb, --ls-btn, --ls-sm, --ls-dur-*, --ls-ease*,
   --ls-focus-w, --ls-hero-pic-pos) не были определены ни в одном файле проекта - числа стояли
   в таблицах как переменные, а подстроить их было нельзя. Роли палитры сюда НЕ входят: они
   приходят из данных клиента инлайном. --- */
.ls-w,.ls-hero{--ls-body:20px;--ls-eb:12.8px;--ls-btn:16px;--ls-sm:14px;
  --ls-dur-fast:140ms;--ls-dur-base:220ms;--ls-dur-screen:320ms;
  --ls-ease:cubic-bezier(.2,.6,.3,1);--ls-ease-enter:cubic-bezier(.2,.8,.3,1);
  --ls-focus-w:2px;--ls-tap:44px;--ls-hero-pic-pos:50% 40%;
  --ls-hero-pad-compact:56px;--ls-hero-pad-cosy:96px;--ls-hero-pad-spacious:144px}
.ls-w{container-type:inline-size;container-name:ls}
/* Кадр во весь экран: рост секции считается от контейнера, поэтому ему нужна ОПРЕДЕЛЁННАЯ
   высота - container-type:size. У компактных кадров остаётся inline-size. */
/* ВЫСОТА ШАПКИ ВЫЧИТАЕТСЯ ЗДЕСЬ, И ЧИТАТЕЛЬ У НЕЁ РОВНО ОДИН.
   Пакет шапки (02-TOKENS) объявляет `--ls-bar-h-full` на `.ls-site` и называет первый
   экран ЕДИНСТВЕННЫМ её читателем. До этой строки экран `на всю высоту` стоял НАД
   полосой и в сумме был выше окна ровно на неё: человек листал, чтобы увидеть низ
   первого экрана, при полностью исправной вёрстке.

   `--ls-bar-over` - множитель, а не условие: у семьи A полоса занимает место (1, и
   тогда вычитается вся её высота), у семьи B она лежит ПОВЕРХ экрана (0, и вычитать
   нечего). Написанное умножением, правило не требует ни второй ветки, ни признака в
   разметке - набор объявляет своё число сам.

   `-full`, а не `-h`: в полную высоту входят верхняя полоса, полоса объявления и
   второй ряд меню, когда набор их рисует. Взять `--ls-bar-h` значило бы вычесть
   только главный ряд и оставить экран выше окна у всей семьи C. */
.ls-w--vp .ls-hero{--ls-hero-h:calc(var(--ls-vp,100svh)
  - var(--ls-bar-h-full,80px) * var(--ls-bar-over,1))}

/* Коробка по кромке: в слое сайта сброса box-sizing нет, а min-block-size:100cqh применяется
   к КОНТЕНТНОЙ коробке - поля 128+128 добавлялись сверху, и секция вырастала до 1066 при
   бумаге 810. Низ A2 и A5 при этом уезжал за кромку. */
.ls-hero,.ls-hero *,.ls-hero *::before,.ls-hero *::after{box-sizing:border-box}

.ls-hero{position:relative;isolation:isolate;overflow:clip;
  min-block-size:var(--ls-hero-h,auto);
  display:grid;align-content:var(--ls-hero-ac,center);
  padding-block:var(--ls-hero-pad,96px);padding-inline:var(--ls-hero-pin,24px);
  background:var(--ls-paper,#fff);color:var(--ls-ink,#000);
  font-family:var(--ls-text-face,system-ui);font-size:var(--ls-body,20px);line-height:1.4}
@container ls (max-width:1040px){.ls-hero{--ls-hero-pad:72px}}
@container ls (max-width:700px){.ls-hero{--ls-hero-pad:56px;--ls-hero-pin:20px}}
.ls-hero[data-edge="start"]{--ls-hero-ac:start}
.ls-hero[data-edge="end"]{--ls-hero-ac:end}
.ls-hero__in{position:relative;z-index:2;inline-size:100%;max-inline-size:var(--ls-hero-max,var(--ls-max,1536px));
  margin-inline:auto}

/* --- ФОТОГРАФИЯ. Отдельный <img>, а не фон: первый экран - это LCP, и предзагрузка
   работает только по настоящему тегу. Главная картинка ЖАДНАЯ (fetchpriority="high",
   без loading="lazy"), все прочие в секции - ленивые. --- */
.ls-hero [data-ar]{aspect-ratio:var(--ls-media-ar,auto);block-size:auto;min-block-size:0}
.ls-hero__pic{position:absolute;inset:0;z-index:0;display:block;overflow:hidden;
  background:var(--ls-band,#eee)}
.ls-hero__pic img{inline-size:100%;block-size:100%;display:block;object-fit:cover;
  object-position:var(--ls-hero-pic-pos,50% 40%)}
/* Картинки нет: коробка ОСТАЁТСЯ, вуали нет вовсе - вуаль на пустой плоскости даёт серую
   муть. Под текстом работает сама плоскость палитры, текст берёт чернила. */
.ls-hero__pic[data-empty]{background:var(--ls-band,#eee)}
.ls-w[data-edit] .ls-hero__pic[data-empty]::after{content:"image";pointer-events:none;position:absolute;inset-block-start:50%;
  inset-inline-start:50%;translate:-50% -50%;font-family:"Material Symbols Rounded";
  font-size:44px;color:var(--ls-muted,#666);opacity:.4}

/* --- ВУАЛЬ. Рецепт ОДИН на всю семью A и задан числами.
   1. Плоская заливка чернил палитры: alpha = --ls-veil (0,44 по умолчанию).
   2. Плюс градиент в СТОРОНУ ТЕКСТА, угол в переменной: 200deg по умолчанию, в RTL 160deg.
      Стопы 20% / 62% / 86% - плотный конец под текстовым блоком.
   3. Цвет текста поверх - роль --ls-ink-on-media: светлейшая роль палитры, а не «белый».
      Базовая плотность плоской заливки 50%, а не 44: на 44 самый светлый кадр давал 4,28
      замером - ниже порога.
      Если её контраст к вуали ниже порога, PHP наращивает --ls-veil шагами по 0,06 до
      порога: цвет от палитры, плотность вычисляемая.
   ПОРОГИ: заголовок 4,5:1 (не 3:1 - на фотографии шум и мелкие блики съедают крупный
   кегль), абзац 4,5:1, надпись 4,5:1. Мерить по САМОЙ СВЕТЛОЙ точке области под текстом,
   а не по средней: средняя прощает облако в углу.
   ВУАЛЬ СТРОИТСЯ ИЗ СВОЕЙ РОЛИ --ls-veil-ink, А НЕ ИЗ --ls-ink: в тёмной палитре чернила
   светлые, и вуаль на них превращалась в белую пелену - замер давал контраст 1,03 вместо
   4,5. Роль вуали тёмная во ВСЕХ 24 палитрах; светлеет только текст поверх.
   ГЕОМЕТРИЯ ВУАЛИ ЗАВИСИТ ОТ ВЫРАВНИВАНИЯ, а не назначается на глаз: у текста от начала
   строки плотный конец градиента приходится в его угол (200deg, стопы 20/62/86), у
   центрированного текст сидит в середине кадра, где наклонный градиент даёт всего 0,32-0,40
   альфы - поэтому там вуаль вертикальная, стопы ранние и плоская заливка выше. --- */
.ls-hero__veil{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(var(--ls-veil-dir,200deg),
      transparent var(--ls-veil-s1,20%),
      color-mix(in oklab,var(--ls-veil-ink,#000) 72%,transparent) var(--ls-veil-s2,62%),
      color-mix(in oklab,var(--ls-veil-ink,#000) 88%,transparent) var(--ls-veil-s3,86%)),
    color-mix(in oklab,var(--ls-veil-ink,#000) calc(var(--ls-veil,50) * 1%),transparent)}
[dir="rtl"] .ls-hero__veil{--ls-veil-dir:160deg}
/* В РЕЖИМЕ ПРАВКИ НИ ОДИН СЛОЙ НЕ СТОИТ ВЫШЕ ОРГАНОВ ПРАВКИ.

   Плашка «Replace / Regenerate» печатается ВНУТРИ `.ls-hero__pic`, а у той свой
   `z-index:0`, то есть собственный контекст наложения: `z-index:3` плашки разрешается
   внутри поддерева и наружу не выходит. Вуаль - сосед на 1, и она накрывает плашку при
   любом числе внутри. Поднять изнутри нельзя: между ними шесть контекстов наложения.

   Поэтому поднимается САМА КАРТИНКА и только на время наведения или фокуса - ровно
   пока человек работает со снимком. Читает текст - вуаль на месте. У посетителя
   признака `data-edit` нет вовсе, и порядок не меняется ни на йоту.

   Второй слой - глиф пустого гнезда: это псевдоэлемент РОДИТЕЛЯ, а он рисуется позже
   всех детей и потому тоже накрывает плашку. Уводить его вниз нельзя (уйдёт под
   заливку коробки и исчезнет) - поднимается горячее место.

   Подъём привязан к САМОМУ ОРГАНУ, а не к наведению на фотографию: `:has()` спрашивает
   «есть ли внутри задетое горячее место». Разница видна у слайдера, где сцена одна, а
   кадров четыре, и у обложки, чья коробка растянута на всю секцию. */
.ls-w[data-edit] .ls-hero__pic:has(.sc-se__hot:hover),
.ls-w[data-edit] .ls-hero__pic:has(.sc-se__hot:focus-within),
.ls-w[data-edit] .ls-a8__stage:has(.sc-se__hot:hover),
.ls-w[data-edit] .ls-a8__stage:has(.sc-se__hot:focus-within){z-index:2}
/* Центрированный вариант: своя геометрия и своя плотность - проверено числом. */
.ls-hero[data-align="center"]{--ls-veil:58;--ls-veil-dir:180deg;--ls-veil-s1:4%;
  --ls-veil-s2:34%;--ls-veil-s3:76%}
[dir="rtl"] .ls-hero[data-align="center"] .ls-hero__veil{--ls-veil-dir:180deg}
/* Текст поверх фотографии берёт СВОЮ роль, а не белый. */
.ls-hero[data-hold="veil"] .ls-hero__in{color:var(--ls-ink-on-media,var(--ls-paper,#fff))}
.ls-hero[data-hold="veil"] .ls-hero__p{color:var(--ls-ink-on-media,var(--ls-paper,#fff));opacity:.94}
.ls-hero[data-hold="veil"] .ls-hero__eb{color:var(--ls-ink-on-media,var(--ls-paper,#fff));opacity:.94}
/* Без картинки вуаль снимается, роли возвращаются к плоскости палитры. */
.ls-hero[data-hold="veil"]:has(.ls-hero__pic[data-empty]) .ls-hero__veil{display:none}
.ls-hero[data-hold="veil"]:has(.ls-hero__pic[data-empty]) .ls-hero__in,
.ls-hero[data-hold="veil"]:has(.ls-hero__pic[data-empty]) .ls-hero__p,
.ls-hero[data-hold="veil"]:has(.ls-hero__pic[data-empty]) .ls-hero__eb{color:var(--ls-ink,#000)}

/* --- ТЕКСТОВЫЙ БЛОК. Колонка при выравнивании по центру ШИРЕ, но не настолько, как в
   разведке: 880 против 967. Мера 60-70 знаков - на 967 и кегле 20 строка идёт под 96
   знаков, и абзац перестаёт читаться. --- */
.ls-hero__txt{display:grid;gap:var(--ls-hero-gap,24px);min-inline-size:0;
  max-inline-size:var(--ls-hero-col,640px);text-wrap:pretty}
.ls-hero[data-align="center"] .ls-hero__txt{--ls-hero-col:880px;justify-items:center;
  text-align:center;margin-inline:auto}
@container ls (max-width:700px){.ls-hero__txt{--ls-hero-col:100%;--ls-hero-gap:20px}}
.ls-hero__eb{display:flex;align-items:center;gap:14px;margin:0;
  font-size:var(--ls-eb,12.8px);line-height:1.4;font-weight:500;letter-spacing:.025em;
  color:var(--ls-muted,#666)}
/* Линия уходит вместе с надписью: одна висящая черта - мусор. */
.ls-hero__eb::before{content:"";inline-size:40px;block-size:1px;flex:none;
  background:currentColor;opacity:.6}
.ls-hero[data-align="center"] .ls-hero__eb{justify-content:center}
.ls-hero__h{margin:0;min-inline-size:0;font-family:var(--ls-head-face,inherit);
  font-size:min(var(--ls-hero-h1,76.29px),var(--ls-hero-long,9999px));line-height:var(--ls-hero-lh,1.14);
  font-weight:var(--ls-hero-hw,600);letter-spacing:var(--ls-hero-ls,-0.01em)}
@container ls (max-width:1040px){.ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}}
@container ls (max-width:700px){.ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
.ls-hero__p{margin:0;font-size:var(--ls-body,20px);line-height:1.4;
  max-inline-size:var(--ls-hero-pw,60ch);color:var(--ls-muted,#666)}
/* ДЛИННЫЙ ЗАГОЛОВОК СТУПАЕТ ВНИЗ ПО ШКАЛЕ, А НЕ ЛОМАЕТ ЭКРАН. Вершина шкалы (95,37) держит
   две-три строки; кириллический заголовок на 60+ знаков брал четыре, секция вырастала до 1215
   при экране 940, и первый экран перестал быть первым экраном. Фиксировать высоту нельзя
   (правило 03), поэтому уступает КЕГЛЬ: PHP ставит data-long при заголовке длиннее 48 знаков,
   и ступень падает на одну. Мера при этом остаётся - строка не растягивается. */
.ls-hero .ls-hero__h[data-long]{--ls-hero-long:61.04px;--ls-hero-lh:1.15;max-inline-size:22ch}
@container ls (max-width:1040px){.ls-hero .ls-hero__h[data-long]{--ls-hero-long:48.83px;--ls-hero-lh:1.18}}
@container ls (max-width:700px){.ls-hero .ls-hero__h[data-long]{--ls-hero-long:31.25px;--ls-hero-lh:1.25}}

/* --- КНОПКИ. Высота 52, поля 14/28, скругление 14 - намеренно не 56 и не 16: у нас своя
   шкала органов. Вторая кнопка - контур; первой нет - вторая НЕ прыгает в центр, потому что
   ряд выровнен по началу строки, а не по центру. --- */
.ls-hero__pts{display:grid;gap:10px;margin:0;padding:0;list-style:none;font-size:17px;line-height:1.4;color:var(--ls-ink,#000)}
.ls-hero__pt{display:flex;align-items:flex-start;gap:10px}
.ls-hero__pt > .sc-icon{flex:none;font-size:20px;margin-block-start:1px;color:var(--ls-acc,#333)}
.ls-hero[data-hold="veil"] .ls-hero__pts{color:var(--ls-ink-on-media,var(--ls-paper,#fff))}
.ls-hero[data-hold="veil"] .ls-hero__pt-i{color:inherit}
.ls-hero[data-hold="veil"]:has(.ls-hero__pic[data-empty]) .ls-hero__pts{color:var(--ls-ink,#000)}
.ls-hero[data-align="center"] .ls-hero__pts{justify-items:center}
@container ls (max-width:700px){.ls-hero__pts{font-size:16px;gap:8px}}
.ls-c1__say{display:grid;gap:20px}
.ls-hero__acts{display:flex;flex-wrap:wrap;gap:12px;margin-block-start:12px}
.ls-hero[data-align="center"] .ls-hero__acts{justify-content:center}
.ls-hero__btn{display:inline-flex;align-items:center;justify-content:center;
  min-block-size:52px;padding-block:14px;padding-inline:28px;border:0;border-radius:var(--ls-radius,14px);
  background:var(--ls-acc,#333);color:var(--ls-acc-on,#fff);font:inherit;
  font-size:var(--ls-btn,16px);font-weight:500;text-decoration:none;cursor:pointer;
  transition:background-color var(--ls-dur-fast,140ms) var(--ls-ease,ease)}
.ls-hero__btn:hover{background:color-mix(in oklab,var(--ls-acc,#333) 88%,var(--ls-ink,#000))}
.ls-hero__btn--ghost{background:transparent;color:inherit;
  box-shadow:inset 0 0 0 1px color-mix(in oklab,currentColor 42%,transparent)}
.ls-hero__btn--ghost:hover{background:color-mix(in oklab,currentColor 12%,transparent)}
/* ОТСТУПЛЕНИЕ: своя рамка фокуса НЕ КРАСИТ ПРАВИМЫЙ ТЕКСТ.
   В правке у текстового слота своя рамка - голубая рамка системного акцента кабинета,
   одна на весь проект. Здесь селектор потомка ловил и её: специфичность у обоих (0,2,0),
   побеждает порядок подключения, и человек видел рамку цветом текста. Замерено на живом
   холсте: rgb(251,248,242) 2px вместо rgb(47,111,208) 1px.
   У посетителя `.sc-se__edit` не печатается вовсе - его рамка фокуса не меняется. */
.ls-hero :focus-visible:not(.sc-se__edit){outline:var(--ls-focus-w,2px) solid currentColor;outline-offset:3px}

/* --- ЗНАЧОК. Гарнитура объявляется В СЛОЕ САЙТА: base.css кабинета сюда не подключается, а
   без правила лигатура печатается СЛОВОМ. --- */
.sc-icon-KIT-HERO{font-family:"Material Symbols Rounded";font-weight:300;font-style:normal;
  line-height:1;letter-spacing:normal;white-space:nowrap;font-feature-settings:"liga";
  font-variation-settings:"FILL" 0,"wght" 300}

/* Строка, видимая ТОЛЬКО в редакторе: печатается всегда, показывается признаком data-edit
   на обёртке страницы. У посетителя её нет. Тон - сообщение, не предупреждение. */
.ls-only-edit{display:none}
.ls-w[data-edit] .ls-only-edit,.ls-page[data-edit] .ls-only-edit{display:flex;align-items:center;gap:8px;background:color-mix(in oklab,#fff 88%,transparent);color:#3f4650;
  margin-block-start:20px;padding-block:8px;padding-inline:12px;
  border-inline-start:2px solid var(--ls-line,rgba(0,0,0,.14));
  font-size:var(--ls-sm,14px);color:var(--ls-muted,#666);text-wrap:pretty}
.ls-only-edit .sc-icon{flex:none;font-size:18px;opacity:.7}

/* Приглушённые чернила НА ПРИПОДНЯТОЙ ПЛОСКОСТИ - своя роль: --ls-muted подобрана к
   плоскости, а панель стоит на band, которая темнее, и на тёплой палитре контраст падал до
   4,26. Считается от band, поэтому держит порог во всех 24 палитрах. */
.ls-panel-ink{--ls-muted:color-mix(in oklab,var(--ls-ink,#000) 78%,var(--ls-band,#eee))}

@media (prefers-reduced-motion:reduce){.ls-hero *{transition-duration:1ms !important;
  animation:none !important}}
/* ВТОРОЙ ТРИГГЕР ЗАМИРАНИЯ - НАШ СОБСТВЕННЫЙ ВИДЖЕТ ДОСТУПНОСТИ, и кит о нём знать не
   может. Он гасит движение НЕ снятием, а сжатием: animation-duration:0.01ms плюс
   animation-iteration-count:1, то есть анимация мгновенно ДОИГРЫВАЕТ до конца. У кадра
   слайдера конец - opacity:0, заливки (fill-mode) у него нет намеренно, и элемент
   возвращается к базовому стилю, тоже прозрачному. Человек, включивший тумблер «меньше
   анимаций», получил бы первый экран без единой фотографии. Правило одно, триггера два. */
html.atx-rm .ls-hero *{transition-duration:1ms !important;animation:none !important}

/* ===== hero-a.css ===== */
/* СЕМЬЯ A - МЕДИА ПОД ТЕКСТОМ. Семь наборов. Контраст держит вуаль (рецепт в hero.css),
   панель или полоса - это ось data-hold, а не свойство набора.

   ЧИСЛО ВАРИАНТОВ ВЫВОДИТСЯ ИЗ ОСЕЙ:
   A1 рост x выравнивание = 4        A2 рост = 2 (прижим выводится из роста)
   A3 рост = 2                       A4 положение панели x рост = 3 + 1 = 4
   A5 край x рост = 3 (у компактной края неразличимы)
   A6 угол = 2 (компактная с угловой карточкой не живёт)
   A7 рост = 2
   Итого 19 вариантов против 23 в разведке - разница ровно в дублях и в сочетаниях, не
   дающих замеряемого отличия. */

/* A1. Текст на фоновом фото. Всё уже в оболочке: набор задаётся только осями. */
.ls-a1 .ls-hero__h{--ls-hero-hw:600}

/* A2. Текст прижат к краю, заголовок и кнопки в один ряд по НИЖНЕЙ базовой линии.
   Ряд держится на align-items:end у грида: при трёхстрочном заголовке кнопки остаются
   на его последней строке, а не уезжают к первой. Абзаца в наборе нет.
   Узкий: --ls-a2-cols. */
.ls-a2__row{display:grid;grid-template-columns:var(--ls-a2-cols,minmax(0,1fr) auto);
  gap:var(--ls-a2-gap,40px);align-items:end}
@container ls (max-width:700px){.ls-a2__row{--ls-a2-cols:1fr;--ls-a2-gap:28px}}
.ls-a2__row .ls-hero__acts{margin-block-start:0}
/* Абзац у клиента заполнен, а набор его не показывает: раскладка не предлагается вовсе,
   пока в секции есть body. Молча прятать текст нельзя, а показывать мелко - значит
   ломать набор, который на отсутствии абзаца и построен. Сообщение - в подборщике. */

/* A3. Компактная полоса на фоне: узкая колонка по центру, заголовок на четыре ступени ниже.
   Кнопка у нас ОБЩАЯ (52), а не своя 50: своя высота ради одного набора заводит вторую
   шкалу органов. Вуаль плотнее не потому, что текст мелкий, а потому, что колонка узкая и
   фотография видна вокруг неё: --ls-veil 56 против 44.
   Узкий: наследует оболочку. */
.ls-hero.ls-a3{--ls-veil:56}
/* A3 центрирована, значит берёт центральную геометрию вуали; своя плотность выше
   центральной базовой 58, потому что колонка узкая и фотография видна вокруг неё. */
.ls-hero.ls-a3[data-align="center"],.ls-hero.ls-a3{--ls-veil:64}
.ls-a3 .ls-hero__txt{--ls-hero-col:720px;justify-items:center;text-align:center;
  margin-inline:auto}
.ls-a3 .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25;--ls-hero-hw:600;--ls-hero-ls:0}
@container ls (max-width:700px){.ls-a3 .ls-hero__h{--ls-hero-h1:25px;--ls-hero-lh:1.3}}
.ls-a3 .ls-hero__p{--ls-hero-pw:46ch;font-size:16px;line-height:1.5}

/* A4. Панель с текстом поверх фото. Контраст держит ПАНЕЛЬ, фотография остаётся чистой -
   вуали нет. Панель - роль ПЛОСКОСТИ палитры, текст - чернила. На тёмной палитре плоскость
   и есть тёмная панель, поэтому «панель поверх фото» читается и там: её отличает от фона не
   светлота, а собственная кромка и скругление.
   Узкий: --ls-a4-w. */
.ls-a4 .ls-hero__in{display:grid;justify-items:var(--ls-a4-just,start)}
.ls-a4__card{inline-size:var(--ls-a4-w,560px);max-inline-size:100%;padding:40px;
  border-radius:var(--ls-radius,18px);background:var(--ls-paper,#fff);color:var(--ls-ink,#000);
  box-shadow:0 24px 60px -30px color-mix(in oklab,var(--ls-ink,#000) 60%,transparent)}
@container ls (max-width:1040px){.ls-a4__card{--ls-a4-w:480px;padding:32px}}
@container ls (max-width:700px){.ls-a4__card{--ls-a4-w:100%;padding:24px}}
.ls-a4__card .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18;--ls-hero-ls:-0.02em}
@container ls (max-width:1040px){.ls-a4__card .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
@container ls (max-width:700px){.ls-a4__card .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
.ls-a4__card .ls-hero__txt{--ls-hero-col:100%}
.ls-a4__card .ls-hero__p{--ls-hero-pw:52ch}

/* A5. Широкая полоса у края: три колонки - заголовок, пустота, кнопки. Полоса - плоскость,
   текст внутри - чернила, то есть роли ВНУТРИ полосы противоположны ролям снаружи (там
   чернила поверх фотографии). На тёмной палитре полоса становится приподнятой плоскостью, и
   пара «плоскость / чернила» продолжает работать - потому что обе роли из одной палитры.
   Средний порог обязателен: на 900 три колонки дают колонку в 180 - меру в 22 знака.
   Узкий и средний: --ls-a5-cols. */
.ls-a5__band{display:grid;grid-template-columns:var(--ls-a5-cols,minmax(0,1fr) auto);
  gap:var(--ls-a5-gap,48px);align-items:end;padding:44px 48px;border-radius:var(--ls-radius,18px);
  background:var(--ls-paper,#fff);color:var(--ls-ink,#000)}
@container ls (max-width:1040px){.ls-a5__band{--ls-a5-cols:1fr;--ls-a5-gap:28px;padding:36px}}
@container ls (max-width:700px){.ls-a5__band{padding:24px}}
.ls-a5__band .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}
@container ls (max-width:1040px){.ls-a5__band .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}}
@container ls (max-width:700px){.ls-a5__band .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
.ls-a5__band .ls-hero__txt{--ls-hero-col:100%}
.ls-a5__band .ls-hero__acts{margin-block-start:0}

/* A6. Фон плюс угловая карточка. Сетка 5 колонок; переход к 5x5 на очень широком - ОДНА
   раскладка и одна переменная --ls-hero-pic-area: меняется только ячейка карточки.
   Карточки нет: ячейка ОСТАЁТСЯ и держит приподнятую плоскость со значком - иначе текст
   переезжает, а правило 06 это запрещает.
   Узкий: --ls-a6-cols. */
.ls-a6 .ls-hero__in{display:grid;grid-template-columns:var(--ls-a6-cols,repeat(5,minmax(0,1fr)));
  gap:24px;align-items:center}
.ls-a6__txt{grid-column:2 / 5;justify-items:center;text-align:center}
.ls-a6__corner{position:relative;grid-area:var(--ls-hero-pic-area,1 / 5 / 2 / 6);inline-size:176px;
  block-size:176px;justify-self:end;overflow:hidden;border-radius:var(--ls-radius,18px);
  background:var(--ls-band,#eee)}
.ls-a6[data-corner="start"] .ls-a6__corner{grid-area:var(--ls-a6-corner-start,1 / 1 / 2 / 2);
  justify-self:start}
.ls-a6__corner img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-a6__corner[data-empty]::after{content:"image";display:grid;place-items:center;
  block-size:100%;font-family:"Material Symbols Rounded";font-size:34px;
  color:var(--ls-muted,#666);opacity:.42}
.ls-a6 .ls-hero__h{--ls-hero-h1:95.37px;--ls-hero-lh:1.12;--ls-hero-hw:700}
@container ls (max-width:1040px){.ls-a6 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}}
@container ls (max-width:700px){
  .ls-a6 .ls-hero__in{--ls-a6-cols:1fr}
  .ls-a6__txt{grid-column:1 / -1}
  .ls-a6__corner{grid-area:auto;inline-size:120px;block-size:120px;justify-self:center}
  .ls-a6 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}
}

/* A7. Заголовок у одного края, абзац и кнопки у другого, между ними намеренная пустота.
   ПУСТОТА ДЕРЖИТСЯ КОЛОНКАМИ, а не разгоном: minmax(0,1fr) на обеих плюс зазор 64. При
   заголовке в два слова колонка не сжимается - пустота остаётся ровно той же, потому что
   доли считаются от ряда, а не от содержимого. Разгон (space-between) дал бы обратное:
   короткий заголовок съехал бы к своему краю, и пустота стала бы вдвое шире.
   Средний и узкий: --ls-a7-cols. */
.ls-a7__row{display:grid;grid-template-columns:var(--ls-a7-cols,minmax(0,1fr) minmax(0,1fr));
  gap:var(--ls-a7-gap,64px);align-items:end}
@container ls (max-width:1040px){.ls-a7__row{--ls-a7-cols:1fr;--ls-a7-gap:36px}}
.ls-a7__row .ls-hero__txt{--ls-hero-col:100%}
.ls-a7__side{display:grid;gap:24px;padding-block-start:78px}
@container ls (max-width:1040px){.ls-a7__side{padding-block-start:0}}
.ls-a7__side .ls-hero__p{--ls-hero-pw:44ch}
.ls-a7__side .ls-hero__acts{margin-block-start:0}

/* ===== hero-a8.css ===== */
/* A8. ФОТОСЛАЙДЕР С ДЫХАНИЕМ - второе и последнее исключение из правила 01.
   Первый экран не двигается сам; здесь двигается, и поэтому движение обязано быть
   выключаемым опцией и обязано исчезать при «меньше движения» - не замедляться, а
   исчезать (правило 07). Всё на CSS: смена слайдов, зум, текст, точки, кольца кнопки -
   ни одной строки скрипта. Молчание скрипта оставляет читаемый первый экран, а не пустоту.

   ЧИСЛА, ВСЕ В ПЕРЕМЕННЫХ:
     --ls-a8-dur    32s   полный круг на четыре слайда
     --ls-a8-slide   8s   один слайд (dur / 4)
     --ls-a8-zoom   1.08  Ken Burns: 100% -> 108% за показ слайда
     --ls-a8-pan     2.5% пан по обеим осям, знак по --ls-mirror
     --ls-a8-blur     8px размытие входящего кадра, гаснет к нулю
     --ls-a8-ring   2.8s  интервал кольца-эха
     --ls-a8-ring-d  .34s  задержка между кольцами: волна, а не одновременный пуск
     --ls-a8-hov    .25s  наведение
     --ls-a8-tap    .15s  нажатие

   КРОСС-ФЕЙД НЕ СВОЕЙ КРУТКОЙ, А ДОЛЕЙ КРУГА: 3,4% от --ls-a8-dur, то есть 1,1с при 32с.
   Отдельная переменная здесь была бы обманом: кейфреймы считают проценты от длительности
   анимации, и число в такой переменной ни на что не влияло бы. Темп меняется ОДНИМ
   числом - --ls-a8-dur, - и вместе с ним меняются и показ, и фейд, и появление текста.

   ПОЧЕМУ КРОСС-ФЕЙД, А НЕ СДВИГ: Ken Burns уже двигает кадр, и сдвиг слайда спорит с ним -
   два движения в разные стороны читаются как рывок. Наложение к зуму не спорит.

   ПОЧЕМУ РАЗМЫТИЕ ТОЛЬКО НА ВХОДЕ: размытие обоих кадров даёт кашу на два стопа контраста
   ниже порога; входящий приходит из мягкого фокуса и наводится - уходящий остаётся резким.

   RTL: пан и magnetic-сдвиг кнопки берут знак из --ls-mirror, углы вуали живут в оболочке. */

.ls-hero.ls-a8{--ls-mirror:1;--ls-a8-dur:32s;--ls-a8-slide:8s;--ls-a8-zoom:1.08;
  --ls-a8-pan:2.5%;--ls-a8-blur:8px;--ls-tap:44px;
  /* Разгон круга: 3,4% от --ls-a8-dur, то есть те же 1,1с, что и кросс-фейд. Все задержки
     сдвинуты на него НАЗАД, поэтому t=0 - это устоявшийся первый кадр, а не преддверие. */
  --ls-a8-lead:calc(var(--ls-a8-dur) * .034)}
.ls-hero.ls-a8[dir="rtl"],[dir="rtl"] .ls-hero.ls-a8{--ls-mirror:-1}
/* ТЕМП КАДРА - ОБЪЯВЛЕННАЯ ОСЬ, У КОТОРОЙ В КИТЕ НЕТ ПРАВИЛ. `11-AXES.md` выводит
   четыре варианта A8 из «автосмена (вкл/выкл) x длина кадра (6 / 8 / 11 с)», но в CSS
   стоят только 32с/8с - то есть три варианта из четырёх совпали бы по вычисленным
   стилям посимвольно, а это ровно тот дефект, который пакет сам забраковал у сплита.
   Круг считается как четыре кадра, разгон пересчитается сам: он доля от --ls-a8-dur. */

.ls-hero.ls-a8[data-pace="6"]{--ls-a8-slide:6s;--ls-a8-dur:24s}
.ls-hero.ls-a8[data-pace="11"]{--ls-a8-slide:11s;--ls-a8-dur:44s}

/* РАЗБРОС ПУСТОГО КАДРА ОБЪЯВЛЯЕТ CSS, А НЕ PHP. В холсте эти три переменные стоят
   инлайном у каждого кадра - холст статичен, ему так проще. У нас печатать `--ls-x:`
   свойством запрещено: инлайновая переменная запирает таблицу стилей навсегда и молча.
   Числа те же, что в холсте; они нужны, чтобы четыре пустых кадра не читались одним
   серым пятном - под вуалью 58% разброс в 3% неразличим. */
.ls-a8__sl:nth-child(1){--t:8;--fx:30%;--fy:20%}
.ls-a8__sl:nth-child(2){--t:26;--fx:70%;--fy:30%}
.ls-a8__sl:nth-child(3){--t:16;--fx:40%;--fy:70%}
.ls-a8__sl:nth-child(4){--t:40;--fx:62%;--fy:62%}

/* --- СЦЕНА. Четыре кадра лежат друг на друге, показывается один: окно прозрачности своё у
   каждого, поэтому порядок и длительности читаются из одного числа. --- */
.ls-a8__stage{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--ls-band,#eee)}
.ls-a8__sl:nth-child(1){--d:0}
.ls-a8__sl:nth-child(2){--d:1}
.ls-a8__sl:nth-child(3){--d:2}
.ls-a8__sl:nth-child(4){--d:3}
.ls-a8__sl{position:absolute;inset:0;opacity:0;
  animation:ls-a8-show var(--ls-a8-dur) linear
    calc(var(--ls-a8-slide) * var(--d,0) - var(--ls-a8-lead)) infinite}
/* 8 из 32 - это 25%: кадр держится до 22%, гаснет к 25%, следующий уже поднимается. */
/* ОТСТУПЛЕНИЕ: кадры НАКЛАДЫВАЮТСЯ, а не сменяются через пустоту.
   Владелец: «картинки должны сменять одна другую, а не исчезать, а потом появляется
   другая». У кита кадр держится до 22%, гаснет к 25.4%, а следующий поднимается
   только с 25% - перекрытие выходит 0.4% цикла, то есть 0.128 секунды из 32.
   Замерено на живом холсте: в худший момент (7040мс) прозрачности кадров
   [0, 0.12, 0, 0], сквозь них видно 88.2% фона. Комментарий кита обещает обратное
   («следующий уже поднимается») - то есть замысел верен, а арифметика нет: держать
   надо до ШАГА между кадрами (25%), а не до 22%.

   Простой симметричный кросс-фейд эту дыру не закрывает до конца: два кадра по
   половинной прозрачности пропускают четверть фона в середине перехода. Поэтому
   уходящий кадр ДЕРЖИТ полную непрозрачность, пока следующий поднимается ПОВЕРХ
   него, и гаснет уже закрытым. Фона не видно вовсе ни в один момент.

   Порядок наложения задаёт САМА анимация, а не порядок в разметке, и без этого
   приём ломается на стыке круга: четвёртый кадр стоит в разметке ПОЗЖЕ первого,
   поэтому первый поднимался бы ПОД ним и не был бы виден. Поднимающийся кадр
   всегда z-index:2, показанный - 1, погашенный - 0. Уровни местные: у сцены
   `.ls-a8__stage` свой контекст наложения (position:absolute плюс z-index:0),
   поэтому точки, вуаль и текст поверх сцены не задеты. */
@keyframes ls-a8-show{
  0%{opacity:0;z-index:2}
  3.4%{opacity:1;z-index:2}
  3.5%{opacity:1;z-index:1}
  28.4%{opacity:1;z-index:1}
  28.5%{opacity:0;z-index:0}
  100%{opacity:0;z-index:0}
}
/* Ken Burns и наводка фокуса - на внутреннем узле: прозрачность и трансформация на одном
   элементе делят одну композиторскую очередь и дают дрожание на слабой машине. */
.ls-a8__sl > span{position:absolute;inset:0;display:block;overflow:hidden;
  animation:ls-a8-burns var(--ls-a8-dur) linear
    calc(var(--ls-a8-slide) * var(--d,0) - var(--ls-a8-lead)) infinite}
@keyframes ls-a8-burns{
  0%{scale:1;translate:0 0;filter:blur(var(--ls-a8-blur))}
  4%{filter:blur(0)}
  25%{scale:var(--ls-a8-zoom);
    translate:calc(var(--ls-a8-pan) * var(--ls-mirror,1)) calc(var(--ls-a8-pan) * -1);
    filter:blur(0)}
  100%{scale:var(--ls-a8-zoom);
    translate:calc(var(--ls-a8-pan) * var(--ls-mirror,1)) calc(var(--ls-a8-pan) * -1)}
}
.ls-a8__sl img{inline-size:100%;block-size:100%;object-fit:cover;display:block;
  object-position:var(--ls-hero-pic-pos,50% 45%)}
/* Настоящее место под фотографию: слот заполняет кадр целиком. Анимация - зум, размытие,
   кросс-фейд - живёт на родителе, поэтому проверяется на реальном снимке, а не на градиенте. */
.ls-a8__sl image-slot{position:absolute;inset:0;display:block;inline-size:100%;block-size:100%}
/* СЛУЖЕБНАЯ ЗАГЛУШКА СЛОТА УХОДИТ В УГОЛ. Она центрируется по кадру, и текст набора тоже
   центрирован - иконка садилась на подзаголовок, а английская ссылка «browse files» заходила
   внутрь кольца кнопки. Компонент отдаёт part="empty", поэтому заглушка прижимается к
   верхнему углу по началу строки: центр кадра остаётся текстом набора, а место дропа видно и
   нажимаемо. Признак живёт только на холсте - в вёрстке слота нет вовсе. */
.ls-a8__sl image-slot::part(empty){align-items:flex-start;justify-content:flex-start;
  padding:24px 28px;text-align:start}

/* ПУСТОЕ СОСТОЯНИЕ ОБЯЗАНО ПОКАЗЫВАТЬ ДВИЖЕНИЕ. Прежние заглушки различались на 3% светлоты,
   и под вуалью 58% разница падала до 1%: четыре кадра читались как одно ровное пятно, а зум
   8% на гладком градиенте измерять было нечем - в кадре не было ни одной границы.
   Поэтому: разброс тона в четыре раза шире (--t 8 / 26 / 16 / 40), СВОЯ точка фокуса у
   каждого кадра (--fx / --fy) и крупная сетка 96 - по ней наезд виден глазом. */
.ls-a8__sl[data-empty] > span{background:
  /* Пометка нужна не вёрстке, а линтеру, и стоять она обязана ВПЛОТНУЮ: он смотрит ту же
     строку или ровно одну выше, а без объявленной причины исключение не засчитывается.
     rtl-ok: узор из волосяных линий шагом 96 симметричен, зеркалить нечего */
  repeating-linear-gradient(90deg,color-mix(in oklab,var(--ls-ink,#000) 10%,transparent) 0 1px,transparent 1px 96px),
  repeating-linear-gradient(0deg,color-mix(in oklab,var(--ls-ink,#000) 10%,transparent) 0 1px,transparent 1px 96px),
  radial-gradient(90% 80% at var(--fx,30%) var(--fy,20%),color-mix(in oklab,var(--ls-ink,#000) calc(var(--t,8) * 1.4%),var(--ls-band,#eee)),transparent 72%),
  color-mix(in oklab,var(--ls-ink,#000) calc(var(--t,8) * .9%),var(--ls-band,#eee))}
.ls-w[data-edit] .ls-a8__sl[data-empty] > span::after{content:"image";position:absolute;inset-block-start:50%;
  inset-inline-start:50%;translate:-50% -50%;font-family:"Material Symbols Rounded";
  font-size:40px;color:var(--ls-muted,#666);opacity:.34}

/* --- ТЕКСТ. Появление на смене кадра: прозрачность и подъём 12, заголовок на 100мс раньше
   подзаголовка. Один и тот же приём на первый показ и на каждую смену - отдельного «первого
   раза» нет, иначе он расходится с остальными. --- */
/* ПЛИТА ТЕКСТА ПРОЗРАЧНА ДЛЯ УКАЗАТЕЛЯ. Фотография занимает весь кадр, а текст лежит
   поверх её середины: с pointer-events:auto плита перехватывала и дроп снимка, и наведение на
   саму картинку - файл, отпущенный над заголовком, уходил в текст. Указатель возвращается
   только тому, что действительно нажимают: кнопке и ссылкам. Точки живут вне .ls-hero__in. */
.ls-a8 .ls-hero__in{pointer-events:none}
.ls-a8 .ls-hero__in a,.ls-a8 .ls-hero__in button,.ls-a8__cta{pointer-events:auto}
.ls-a8 .ls-hero__in [data-sc-edit]{pointer-events:auto}
.ls-a8 .ls-hero__txt{--ls-hero-col:1080px;justify-items:center;text-align:center;
  margin-inline:auto;--ls-hero-gap:20px}
.ls-a8 .ls-hero__h{--ls-hero-h1:76.29px;--ls-hero-lh:1.14;--ls-hero-hw:300;
  --ls-hero-ls:0.1em;text-transform:uppercase}
@container ls (max-width:1040px){.ls-a8 .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-ls:0.08em}}
@container ls (max-width:700px){.ls-a8 .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-ls:0.06em}}
.ls-a8 .ls-hero__p{font-size:25px;line-height:1.3;--ls-hero-pw:38ch;letter-spacing:.04em}
@container ls (max-width:700px){.ls-a8 .ls-hero__p{font-size:20px;line-height:1.4}}
/* ОТСТУПЛЕНИЕ: ТЕКСТ ПЕРВОГО ЭКРАНА НЕ ДВИЖЕТСЯ ВОВСЕ.
   Владелец: «текст не должен анимироваться, текст стоит на месте без изменений».
   У кита заголовок и абзац крутили `ls-a8-rise` во всю длину круга: на каждой смене
   кадра они гасли и подпрыгивали на 12 точек - четыре раза за 32 секунды. Замерено на
   живом холсте: по одной анимации на `.ls-hero__h` и `.ls-hero__p`, обе 32000мс.

   Убраны ОБЪЯВЛЕНИЯ, а не заглушены важностью: правило `animation:none` поверх живого
   объявления оставляет вопрос «а что тут вообще анимировалось» следующему читателю.
   Кадры `ls-a8-rise` убраны вместе с ними по той же причине - набор кадров, на который
   никто не ссылается, читается как обещание движения, которого нет.

   Состояние покоя специально доводить не нужно: базовых `opacity` и `translate` у этих
   узлов нет, то есть по умолчанию текст непрозрачен и на месте. Ровно это состояние кит
   и назначает под «меньше движения» - теперь оно единственное. */

/* --- КРУГЛАЯ КНОПКА С ЭХОМ. Кольца - три отдельных узла, а не тени: тень нельзя разогнать
   по времени, а волна из трёх колец с задержкой 0,8 - это и есть приглашение.
   ВСЕ ДЕТИ СИДЯТ В ОДНОЙ ЯЧЕЙКЕ (grid-area:1/1): кольца как участники сетки становились
   рядами высотой 2 и выдавливали подпись вниз; подпись имеет СВОЙ класс, а не селектор
   «любой span внутри», иначе правило подписи ложится и на кольца. --- */
/* КРУТКИ КНОПКИ ЖИВУТ НА САМОЙ КНОПКЕ, А НЕ НА СЦЕНЕ: вынутая из .ls-a8 кнопка теряла
   все четыре значения, а var() без запаса в свойстве animation делает всю строку невалидной на
   этапе вычисления: animation:none, колец нет вовсе. Компонент обязан работать вне сцены. */
.ls-a8__cta{--ls-a8-cta:168px;--ls-a8-ring:2.8s;--ls-a8-ring-d:.34s;--ls-a8-hov:.25s;
  --ls-a8-tap:.15s;--ls-tap:44px;
  position:relative;display:grid;place-items:center;
  inline-size:var(--ls-a8-cta,168px);block-size:var(--ls-a8-cta,168px);
  margin-block-start:28px;margin-inline:auto;border:0;border-radius:50%;
  background:transparent;color:inherit;font:inherit;font-size:var(--ls-btn,16px);
  font-weight:500;letter-spacing:.08em;text-transform:uppercase;text-decoration:none;
  cursor:pointer;
  transition:scale var(--ls-a8-hov,.25s) var(--ls-ease-enter,cubic-bezier(.2,.8,.3,1)),
    background-color var(--ls-a8-hov,.25s) var(--ls-ease,ease)}
@container ls (max-width:700px){.ls-a8__cta{--ls-a8-cta:140px;--ls-tap:44px}}
/* ОТСТУПЛЕНИЕ: в ПРАВКЕ внешний отступ кнопки несёт ОБЁРТКА, а не сама кнопка.
   Затемнение при наведении рисуется по коробке горячего места, а она обнимает
   обёртку вместе с отступом: замерено 168x196 при круге 168x168, то есть на круглой
   кнопке загорался ТЁМНЫЙ ПРЯМОУГОЛЬНИК с хвостом сверху. Скругление кнопке даёт
   PHP (`radius`), а совпадение размеров - эти две строки: отступ уезжает на обёртку,
   у кнопки обнуляется, сумма та же. Оба селектора требуют `.sc-se__hot`, которого у
   посетителя нет вовсе - опубликованная страница не меняется ни на точку. */
.sc-se__hot:has(> .ls-a8__cta){margin-block-start:28px}
.sc-se__hot > .ls-a8__cta{margin-block-start:0}
.ls-a8__cta > *{grid-area:1 / 1}
.ls-a8__lab{position:relative;z-index:2;text-align:center;padding-inline:12px;
  place-self:center}
/* Обводка самой кнопки - волосяная, чтобы кольца читались как её продолжение. */
.ls-a8__cta::before{content:"";position:absolute;inset:0;border-radius:50%;
  border:1px solid color-mix(in oklab,currentColor 46%,transparent)}
.ls-a8__cta > .ls-a8__ring{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:1px solid currentColor;opacity:0;z-index:1;
  animation:ls-a8-echo var(--ls-a8-ring) var(--ls-ease-enter,cubic-bezier(.2,.8,.3,1)) infinite}
.ls-a8__cta > .ls-a8__ring:nth-of-type(2){animation-delay:var(--ls-a8-ring-d)}
.ls-a8__cta > .ls-a8__ring:nth-of-type(3){animation-delay:calc(var(--ls-a8-ring-d) * 2)}
@keyframes ls-a8-echo{0%{scale:1;opacity:.5}70%{opacity:.06}100%{scale:1.46;opacity:0}}
/* Наведение: кнопка растёт, эхо УЧАЩАЕТСЯ - остановка на наведении читалась бы как поломка. */
.ls-a8__cta:hover,.ls-a8__cta[data-hover="true"]{scale:1.06;
  background:color-mix(in oklab,currentColor 12%,transparent)}
.ls-a8__cta:hover .ls-a8__ring,.ls-a8__cta[data-hover="true"] .ls-a8__ring{--ls-a8-ring:1.5s;
  --ls-a8-ring-d:.4s}
/* Нажатие: сжатие с отдачей и одно яркое кольцо наружу - подтверждение, а не украшение. */
.ls-a8__cta:active,.ls-a8__cta[data-active="true"]{scale:.96;
  transition-duration:var(--ls-a8-tap,.15s)}
.ls-a8__cta[data-active="true"] > .ls-a8__ring:first-of-type{animation:ls-a8-shot .4s
  var(--ls-ease-enter,cubic-bezier(.2,.8,.3,1)) forwards}
@keyframes ls-a8-shot{0%{scale:1;opacity:.9}100%{scale:1.6;opacity:0}}
/* Фокус с клавиатуры: кольцо СТАТИЧНОЕ и обнимает всю цель. */
.ls-a8__cta:focus-visible,.ls-a8__cta[data-focus="true"]{outline:var(--ls-focus-w,2px) solid currentColor;
  outline-offset:6px}

/* --- ТОЧКИ. Активная растёт до 1,4 и заливается акцентом за 0,3. Цель нажатия 44 держится
   полем, а не размером точки: точка 8, поле вокруг - остальное. Размер цели живёт в --ls-tap:
   токена кабинета (--sc-*) в слое сайта нет и быть не может - base.css кабинета сюда не
   подключается, и работало бы только запасное значение. --- */
.ls-a8__dots{position:absolute;inset-block-end:28px;inset-inline:0;z-index:3;
  display:flex;justify-content:center;gap:4px}
/* ОТСТУПЛЕНИЕ: в ПРАВКЕ точки уезжают выше панели секции.
   Замерено в браузере: панель редактора стоит 34 от низа при росте 42 (полоса
   34..76), точки - 28 при росте 44 (полоса 28..72). Полосы накладываются почти
   целиком, и сверху оказывались попеременно то кнопки панели, то точки: нерабочими
   были ОБА органа - нажатие в «Edit Content» проглатывала точка, нажатие в точку -
   панель. Кит об этом знать не может: панель - наша оснастка правки, у посетителя
   её нет, и там точки остаются ровно там, где нарисовал макет.
   88 = 76 (верх панели) + 12 (зазор): ниже 76 снова накладывается, выше - отрывает
   точки от края без нужды. Признак `data-edit` печатает только холст, поэтому
   опубликованная страница не меняется ни на точку. */
.ls-w[data-edit] .ls-a8__dots{inset-block-end:88px}
.ls-a8__dot{position:relative;inline-size:var(--ls-tap,44px);block-size:var(--ls-tap,44px);
  display:grid;place-items:center;padding:0;border:0;background:transparent;cursor:pointer}
.ls-a8__dot::after{content:"";inline-size:8px;block-size:8px;border-radius:50%;
  background:color-mix(in oklab,var(--ls-ink-on-media,#fff) 46%,transparent);
  transition:scale .3s var(--ls-ease,ease),background-color .3s var(--ls-ease,ease)}
/* Признак aria-current ставит тот единственный обработчик, который бриф разрешает («минимум
   JS - смена активного класса»): CSS менять разметку не может, а точка, вечно объявленная
   активной, лжёт диктору 24 секунды из 32. В статичных кадрах (data-still, «меньше движения»,
   снятая автосмена) признак стоит честно - там правда показан первый кадр. */
.ls-a8__dot[aria-current="true"]::after{scale:1.4;background:var(--ls-acc,#a11)}
.ls-a8__dot:focus-visible{outline:var(--ls-focus-w,2px) solid var(--ls-ink-on-media,#fff);
  outline-offset:-8px;border-radius:50%}
/* Точки идут по кругу вместе со сценой: они показывают ход, а не принимают решение.
   ЗАДЕРЖКА ЕДЕТ ПЕРЕМЕННОЙ --d, А НЕ ОТДЕЛЬНЫМ ПРАВИЛОМ: шорткат animation сбрасывает
   animation-delay в ноль, и правило с большей специфичностью убивало задержки по номеру -
   все четыре точки пульсировали в унисон, показывая четыре активных кадра сразу. Переменная
   подставляется В САМ шорткат, поэтому специфичность больше ничего не решает. */
.ls-a8__dot:nth-child(1){--d:0}
.ls-a8__dot:nth-child(2){--d:1}
.ls-a8__dot:nth-child(3){--d:2}
.ls-a8__dot:nth-child(4){--d:3}
.ls-a8:not([data-still]):not([data-auto="off"]) .ls-a8__dot::after{
  animation:ls-a8-dot var(--ls-a8-dur) linear
    calc(var(--ls-a8-slide) * var(--d,0) - var(--ls-a8-lead)) infinite}
@keyframes ls-a8-dot{
  0%{scale:1.4;background:var(--ls-acc,#a11)}
  25%{scale:1.4;background:var(--ls-acc,#a11)}
  26%{scale:1;background:color-mix(in oklab,var(--ls-ink-on-media,#fff) 46%,transparent)}
  100%{scale:1;background:color-mix(in oklab,var(--ls-ink-on-media,#fff) 46%,transparent)}
}

/* --- ПРАВИЛО 07 И ОПЦИЯ. «Меньше движения» и снятая опция автосмены дают ОДНО состояние:
   первый кадр стоит резким, текст на месте, эхо погасло, активна первая точка. Ни замедления,
   ни половинчатого шага - подмена. --- */
@media (prefers-reduced-motion:reduce){
  .ls-a8__sl,.ls-a8__sl > span,.ls-a8 .ls-hero__h,.ls-a8 .ls-hero__p,
  .ls-a8__ring,.ls-a8__dot::after{animation:none !important}
  .ls-a8__sl{opacity:0}
  .ls-a8__sl:first-child{opacity:1}
  .ls-a8__sl > span{scale:1;translate:0 0;filter:none}
  .ls-a8 .ls-hero__h,.ls-a8 .ls-hero__p{opacity:1;translate:0 0}
}
/* Тот же блок под НАШ тумблер «меньше анимаций» - подробности у близнеца в hero.css.
   Здесь он важнее всего: без подмены все четыре кадра остаются прозрачными, то есть
   первого экрана нет вовсе. */
html.atx-rm .ls-a8__sl,html.atx-rm .ls-a8__sl > span,
html.atx-rm .ls-a8 .ls-hero__h,html.atx-rm .ls-a8 .ls-hero__p,
html.atx-rm .ls-a8__ring,html.atx-rm .ls-a8__dot::after{animation:none !important}
html.atx-rm .ls-a8__sl{opacity:0}
html.atx-rm .ls-a8__sl:first-child{opacity:1}
html.atx-rm .ls-a8__sl > span{scale:1;translate:0 0;filter:none}
html.atx-rm .ls-a8 .ls-hero__h,html.atx-rm .ls-a8 .ls-hero__p{opacity:1;translate:0 0}
/* ДВА ПОВОДА ОСТАНОВИТЬ СЦЕНУ - ДВА РАЗНЫХ СОСТОЯНИЯ, а не один признак на оба.
   Общее у них одно: сцена стоит, кадр резкий, текст на месте.
     data-still      «меньше движения»: человек попросил убрать движение - эхо кнопки ГАСНЕТ
                     тоже. Приглашать анимацией того, кто её отключил, - не уважение, а обход
                     настройки.
     data-auto="off" автосмена снята опцией: движения сцены нет, но человек движения не
                     запрещал - эхо кнопки ЖИВО, точки рабочие, и активная стоит на том кадре,
                     который человек выбрал сам, а не обязательно на первом.
   Раньше оба кадра несли data-still и совпадали посимвольно - два кадра утверждали различие,
   которого не было. */
.ls-a8[data-still] .ls-a8__sl,.ls-a8[data-still] .ls-a8__sl > span,
.ls-a8[data-still] .ls-hero__h,.ls-a8[data-still] .ls-hero__p,
.ls-a8[data-still] .ls-a8__ring,.ls-a8[data-still] .ls-a8__dot::after,
.ls-a8[data-auto="off"] .ls-a8__sl,.ls-a8[data-auto="off"] .ls-a8__sl > span,
.ls-a8[data-auto="off"] .ls-hero__h,.ls-a8[data-auto="off"] .ls-hero__p,
.ls-a8[data-auto="off"] .ls-a8__dot::after{animation:none}
.ls-a8[data-still] .ls-a8__sl,.ls-a8[data-auto="off"] .ls-a8__sl{opacity:0}
.ls-a8[data-still] .ls-a8__sl:first-child{opacity:1}
.ls-a8[data-still] .ls-a8__sl > span,.ls-a8[data-auto="off"] .ls-a8__sl > span{scale:1;
  translate:0 0;filter:none}
.ls-a8[data-still] .ls-hero__h,.ls-a8[data-still] .ls-hero__p,
.ls-a8[data-auto="off"] .ls-hero__h,.ls-a8[data-auto="off"] .ls-hero__p{opacity:1;translate:0 0}
/* «Меньше движения»: эхо гаснет совсем. */
.ls-a8[data-still] .ls-a8__ring{opacity:0;animation:none}
/* Автосмена снята: показан ВЫБРАННЫЙ кадр, а не первый - его номер в --slide. */
.ls-a8[data-auto="off"] .ls-a8__sl:nth-child(1){opacity:0}
.ls-a8[data-auto="off"] .ls-a8__sl[data-shown]{opacity:1}

/* Кадр для съёмки середины кросс-фейда: два слоя одновременно, входящий ещё в мягком
   фокусе. В работе такого признака нет - он для холста и для сверки числами. */
.ls-a8[data-at="cross"] .ls-a8__sl,.ls-a8[data-at="cross"] .ls-a8__sl > span,
.ls-a8[data-at="cross"] .ls-hero__h,.ls-a8[data-at="cross"] .ls-hero__p,
.ls-a8[data-at="cross"] .ls-a8__dot::after{animation:none}
.ls-a8[data-at="cross"] .ls-a8__sl{opacity:0}
.ls-a8[data-at="cross"] .ls-a8__sl:nth-child(1){opacity:.42}
.ls-a8[data-at="cross"] .ls-a8__sl:nth-child(1) > span{scale:1.08;filter:none}
.ls-a8[data-at="cross"] .ls-a8__sl:nth-child(2){opacity:.72}
.ls-a8[data-at="cross"] .ls-a8__sl:nth-child(2) > span{scale:1.01;filter:blur(4px)}
.ls-a8[data-at="cross"] .ls-hero__h{opacity:.5;translate:0 6px}
.ls-a8[data-at="cross"] .ls-hero__p{opacity:.3;translate:0 9px}

/* ===== hero-b.css ===== */
/* СЕМЬЯ B - МЕДИА РЯДОМ С ТЕКСТОМ. Текст и картинка делят ряд, а не слои: вуали здесь нет
   и не нужно, контраст держит плоскость палитры.

   РЕШЁТКА B1 - четыре оси, и запреты названы:
     side   (2) начало | конец
     split  (2) пополам | перевес к медиа (0,42 / 0,58)
     edge   (2) с полем | в край (вылет)
     height (2) по содержимому | во весь экран
   16 сочетаний, из них ЗАПРЕЩЕНЫ шесть:
     - вылет при росте по содержимому (4 сочетания): вылет без высоты читается как обрезка
       фотографии, а не как замысел;
     - вылет при перевесе к тексту (2 сочетания): узкое медиа с вылетом становится полосой.
   Остаётся 10 различимых вариантов. Выравнивание текста осью НЕ является: в колонке 576
   центрированный текст при мере 60 знаков от левого не отличается ничем замеряемым - это
   и есть неразличимое сочетание, которого в разведке напечатано четыре.

   ВЫЛЕТ ЗА КРАЙ - логическим свойством и в cqw, а не vw:
     --ls-hero-bleed: calc((100cqw - 100%) / 2)  и  margin-inline-end: calc(бleed * -1).
   Сторож прокрутки - overflow:clip на секции (оболочка) плюс обнуление вылета на узком.
   Итого семья B: B1 10 + B2 2 + B3 2 + B4 2 + B5 2 = 18 вариантов. */

/* ─── B1. Сплит: текст и фотография делят ряд. Узкий: --ls-b1-cols ─── */
.ls-b1__row{display:grid;grid-template-columns:var(--ls-b1-cols,1fr 1fr);
  gap:var(--ls-b1-gap,48px);align-items:center}
.ls-b1[data-split="media"] .ls-b1__row{--ls-b1-cols:0.42fr 0.58fr}
.ls-b1[data-side="start"] .ls-b1__media{order:-1}
@container ls (max-width:1040px){.ls-b1__row{--ls-b1-gap:36px}}
@container ls (max-width:700px){.ls-b1__row,
  .ls-b1[data-split="media"] .ls-b1__row{--ls-b1-cols:1fr;--ls-b1-gap:28px}}
.ls-b1 .ls-hero__txt{--ls-hero-col:576px}
.ls-b1 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}
@container ls (max-width:1040px){.ls-b1 .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}}
@container ls (max-width:700px){.ls-b1 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
/* Абзац на ступень крупнее, чем в семье A: колонка уже (576 против 640), и на 20 строка
   становится короче меры. */
.ls-b1 .ls-hero__p{font-size:25px;line-height:1.25;--ls-hero-pw:44ch}
@container ls (max-width:700px){.ls-b1 .ls-hero__p{font-size:20px;line-height:1.4}}
.ls-b1__media{position:relative;overflow:hidden;border-radius:var(--ls-b1-rad,calc(18px * var(--ls-r-k,1)));
  min-block-size:min(var(--ls-b1-min,520px),68cqh)}
.ls-b1__media img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-b1__media[data-empty]{background:var(--ls-band,#eee)}
.ls-b1__media[data-empty]::after{content:"image";position:absolute;inset-block-start:50%;
  inset-inline-start:50%;translate:-50% -50%;font-family:"Material Symbols Rounded";
  font-size:40px;color:var(--ls-muted,#666);opacity:.42}
/* Вылет: логическое поле ровно в отступ секции - медиа доходит до кромки и не дальше.
   Проценты в calc((100cqw - 100%) / 2) разрешались от ЯЧЕЙКИ грида (672), а не от полосы
   содержимого, и вылет получался -384 вместо -24: триста шестьдесят точек фотографии
   выбрасывалось за кромку. Единицы остались контейнерными: отступ секции сам зависит от порога. */
.ls-b1[data-edge="bleed"] .ls-b1__media{
  --ls-hero-bleed:var(--ls-hero-pin,24px);
  margin-inline-end:calc(var(--ls-hero-bleed,24px) * -1);
  border-start-end-radius:0;border-end-end-radius:0}
.ls-b1[data-edge="bleed"][data-side="start"] .ls-b1__media{
  margin-inline:calc(var(--ls-hero-bleed,24px) * -1) 0;
  border-start-end-radius:var(--ls-b1-rad,calc(18px * var(--ls-r-k,1)));border-end-end-radius:var(--ls-b1-rad,calc(18px * var(--ls-r-k,1)));
  border-start-start-radius:0;border-end-start-radius:0}
@container ls (max-width:700px){
  .ls-b1[data-edge="bleed"] .ls-b1__media{--ls-hero-bleed:0px;
    border-radius:var(--ls-b1-rad,calc(18px * var(--ls-r-k,1)))}
}

/* ─── B2. Панель и фото пополам. Панель - роль ПРИПОДНЯТОЙ ПЛОСКОСТИ (--ls-band), а не
   прозрачность: 7,5% белого читается панелью только на тёмной палитре, а у нас их 24.
   Стык - прямая линия: скругления логические, внутренние кромки нулевые.
   Узкий: --ls-b2-cols ─── */
.ls-hero.ls-b2{--ls-hero-pad:0px;--ls-hero-pin:0px}
.ls-b2__row{display:grid;grid-template-columns:var(--ls-b2-cols,1fr 1fr);
  min-block-size:min(var(--ls-b2-min,720px),100cqh)}
@container ls (max-width:700px){.ls-b2__row{--ls-b2-cols:1fr;--ls-b2-min:auto}}
.ls-b2__panel{display:grid;align-content:center;padding:88px 72px;
  --ls-muted:color-mix(in oklab,var(--ls-ink,#000) 78%,var(--ls-band,#eee));
  background:var(--ls-band,#eee);color:var(--ls-ink,#000)}
@container ls (max-width:1040px){.ls-b2__panel{padding:56px 40px}}
@container ls (max-width:700px){.ls-b2__panel{padding:40px 20px}}
.ls-b2[data-side="start"] .ls-b2__media{order:-1}
.ls-b2__panel .ls-hero__txt{--ls-hero-col:420px}
.ls-b2__panel .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}
@container ls (max-width:1040px){.ls-b2__panel .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}}
@container ls (max-width:700px){.ls-b2__panel .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
.ls-b2__media{position:relative;overflow:hidden;min-block-size:min(var(--ls-b2-min,720px),100cqh)}
.ls-b2__media img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-b2__media[data-empty]{background:var(--ls-band,#eee);
  box-shadow:inset 0 0 0 1px var(--ls-line,rgba(0,0,0,.14))}

/* ─── B3. Текст и сетка трёх фотографий. Сетка хочет РОВНО три.
   Меньше трёх - раскладка не предлагается вовсе (в подборщике сказано словами).
   Больше трёх - берёт первые три, остальные целы: строка в редакторе, тон как у D1.
   Узкий: --ls-b3-cols ─── */
.ls-b3__row{display:grid;grid-template-columns:var(--ls-b3-cols,1fr 1fr);
  gap:var(--ls-b3-gap,72px);align-items:center}
@container ls (max-width:1040px){.ls-b3__row{--ls-b3-gap:40px}}
@container ls (max-width:700px){.ls-b3__row{--ls-b3-cols:1fr;--ls-b3-gap:28px}}
.ls-b3[data-side="start"] .ls-b3__grid{order:-1}
.ls-b3 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}
@container ls (max-width:700px){.ls-b3 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
.ls-b3 .ls-hero__p{font-size:25px;line-height:1.25;--ls-hero-pw:42ch}
@container ls (max-width:700px){.ls-b3 .ls-hero__p{font-size:20px;line-height:1.4}}
.ls-b3__grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.ls-b3__grid > span{position:relative;overflow:hidden;border-radius:calc(14px * var(--ls-r-k,1));
  block-size:min(var(--ls-b3-cell,300px),33cqh);background:var(--ls-band,#eee)}
.ls-b3__grid > span:nth-child(3){grid-column:1 / -1}
.ls-b3__grid img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-b3__grid > span[data-empty]::after{content:"image";position:absolute;inset-block-start:50%;
  inset-inline-start:50%;translate:-50% -50%;font-family:"Material Symbols Rounded";
  font-size:30px;color:var(--ls-muted,#666);opacity:.42}
@container ls (max-width:700px){.ls-b3__grid{--ls-b3-cell:180px}}

/* ─── B4. Бенто: узкая панель, большая фотография, малая поверх неё.
   Рост - в cqh, а не vh: 90vh в редакторе дало бы высоту ОКНА, а сайт стоит на бумаге 390.
   Узкий: --ls-b4-cols ─── */
/* Рост задаётся СЕКЦИИ (--ls-hero-h:100cqh), как у остальных наборов, а строка тянется по
   её содержимому. Вычитание полей руками в строке давало переполнение на 128: вычиталось
   одно поле вместо двух. */
.ls-w--vp .ls-hero.ls-b4{--ls-hero-ac:stretch}
.ls-w--vp .ls-b4 .ls-hero__in,.ls-w--vp .ls-b4 .ls-b4__row{block-size:100%}
.ls-b4__row{display:grid;grid-template-columns:var(--ls-b4-cols,35% 1fr);
  gap:var(--ls-b4-gap,36px);align-items:stretch}
@container ls (max-width:1040px){.ls-b4__row{--ls-b4-cols:42% 1fr;--ls-b4-gap:24px}}
@container ls (max-width:700px){.ls-b4__row{--ls-b4-cols:1fr;--ls-b4-gap:20px}}
.ls-b4__panel{display:grid;align-content:center;gap:24px;padding:48px;border-radius:calc(18px * var(--ls-r-k,1));
  --ls-muted:color-mix(in oklab,var(--ls-ink,#000) 78%,var(--ls-band,#eee));
  background:var(--ls-band,#eee);color:var(--ls-ink,#000)}
@container ls (max-width:700px){.ls-b4__panel{padding:28px}}
.ls-b4__panel .ls-hero__txt{--ls-hero-col:100%}
.ls-b4__panel .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}
@container ls (max-width:700px){.ls-b4__panel .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
.ls-b4__stack{position:relative;overflow:hidden;border-radius:calc(18px * var(--ls-r-k,1));background:var(--ls-band,#eee)}
.ls-b4__stack img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
/* Малая фотография наложена логическими вставками: физических left/right нет. */
.ls-b4__small{position:absolute;inset-block-end:24px;inset-inline-end:24px;
  inline-size:var(--ls-b4-sw,280px);aspect-ratio:16 / 11;overflow:hidden;border-radius:calc(14px * var(--ls-r-k,1));
  box-shadow:0 20px 44px -20px color-mix(in oklab,var(--ls-ink,#000) 70%,transparent);
  background:var(--ls-band,#eee)}
.ls-b4__small img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
@container ls (max-width:700px){.ls-b4__small{--ls-b4-sw:150px;inset-block-end:14px;inset-inline-end:14px}}
.ls-b4__stack[data-empty]::after,.ls-b4__small[data-empty]::after{content:"image";
  position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%;
  font-family:"Material Symbols Rounded";font-size:34px;color:var(--ls-muted,#666);opacity:.42}

/* ─── B5. Диагональная сетка. Раскладка выражена ОДНОЙ переменной - шаблоном областей
   целиком (--ls-hero-area), а не набором номеров ячеек: у разведки переход между порогами
   менял всю сетку, и это прямо противоречит правилу «одна переменная на одно изменение».
   Направление диагонали - вторая ось, тем же шаблоном.
   Узкий и средний: --ls-hero-area ─── */
.ls-b5__grid{display:grid;gap:var(--ls-b5-gap,18px);
  grid-template-columns:repeat(4,minmax(0,1fr));
  grid-template-areas:var(--ls-hero-area,
    "txt txt big big" "txt txt big big" "sml . big big");
  align-items:stretch}
.ls-b5[data-diag="end"] .ls-b5__grid{--ls-hero-area:
  "big big txt txt" "big big txt txt" "big big . sml"}
@container ls (max-width:1040px){
  .ls-b5__grid{--ls-hero-area:"txt txt txt txt" "big big big big" "sml sml . ."}
  .ls-b5[data-diag="end"] .ls-b5__grid{--ls-hero-area:
    "txt txt txt txt" "big big big big" ". . sml sml"}
}
@container ls (max-width:700px){
  .ls-b5__grid,.ls-b5[data-diag="end"] .ls-b5__grid{--ls-hero-area:
    "txt txt txt txt" "big big big big" "sml sml sml sml"}
}
.ls-b5__txt{grid-area:txt;display:grid;gap:24px;align-content:center}
.ls-b5__big{grid-area:big;position:relative;overflow:hidden;border-radius:calc(18px * var(--ls-r-k,1));
  min-block-size:min(var(--ls-b5-big,480px),52cqh);background:var(--ls-band,#eee)}
.ls-b5__sml{grid-area:sml;position:relative;overflow:hidden;border-radius:calc(14px * var(--ls-r-k,1));
  min-block-size:min(var(--ls-b5-sml,200px),22cqh);background:var(--ls-band,#eee)}
.ls-b5__big img,.ls-b5__sml img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-b5__big[data-empty]::after,.ls-b5__sml[data-empty]::after{content:"image";
  position:absolute;inset-block-start:50%;inset-inline-start:50%;translate:-50% -50%;
  font-family:"Material Symbols Rounded";font-size:34px;color:var(--ls-muted,#666);opacity:.42}
.ls-b5 .ls-hero__h{--ls-hero-h1:76.29px;--ls-hero-lh:1.14}
@container ls (max-width:1040px){.ls-b5 .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}}
@container ls (max-width:700px){.ls-b5 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
.ls-b5 .ls-hero__p{--ls-hero-pw:40ch}

/* ===== hero-b6.css ===== */
/* B6. КЛИНИКА - сплит с фотографией у края, карточкой-акцией и пилюлями поверх снимка.

   ЧЕМ ОТЛИЧАЕТСЯ ОТ B1. B1 - чистый сплит: текст и фотография делят ряд, и всё. Здесь под
   текстом живёт ВТОРОЙ уровень содержимого - карточка акции, которую можно листать, - а на
   фотографии лежат пилюли-достоинства. То есть набор несёт две вещи, которых у B1 нет:
   собственную карусель внутри половины ряда и подписи поверх медиа.
   Это не вариант B1: у B1 нет ни поля акций, ни пилюль, и решётка осей у них разная.

   ОСИ И РЕШЁТКА: сторона медиа (начало / конец) x высота (во весь экран / по содержимому) x
   карточка (есть / нет) = 8 сочетаний. Запрещены два: «нет карточки + по содержимому» при
   любой стороне - там от B1 не остаётся ни одного замеряемого отличия, кроме пилюль, а пилюли
   переезжают в B1 одной строкой. Итого ШЕСТЬ вариантов.

   ПИЛЮЛИ - ЕДИНСТВЕННЫЙ ТЕКСТ ПОВЕРХ ФОТОГРАФИИ В ЭТОЙ СЕМЬЕ, и рецепт вуали семьи A тут не
   работает: вуаль во весь кадр убила бы лицо на снимке. Поэтому контраст держит сама пилюля -
   стекло с размытием 14 и заливкой 26% чернил кадра, а не палитры: на светлом снимке пилюля
   темнеет, на тёмном светлеет. Порог 4,5:1 замеряется по САМОЙ СВЕТЛОЙ точке под пилюлей.

   Узкий: --ls-b6-cols (ряд в столбец, фотография между текстом и карточкой - как в присланном
   образце: заголовок, кнопки, снимок с пилюлями, карточка, органы). */

.ls-hero.ls-b6{--ls-mirror:1;--ls-hero-pin:0px;--ls-tap:44px;
  /* РОСТ ДО КРОМКИ. .ls-hero - сетка с align-content:center, поэтому .ls-hero__in считался по
     содержимому (791 при секции 940), и min-block-size:100% строки разрешался от 791 - снимок
     не доходил до кромок на 74 сверху и снизу. Растяжение объявляется секции, как в B4. */
  --ls-hero-ac:stretch}
.ls-hero.ls-b6[dir="rtl"],[dir="rtl"] .ls-hero.ls-b6{--ls-mirror:-1}
.ls-hero.ls-b6{--ls-hero-pad:0px}
.ls-b6 .ls-hero__in{block-size:100%;--ls-hero-max:none}

/* --- СТРОКА НА ОБЛАСТЯХ СЕТКИ. Карточка акции НЕ вложена в текстовую колонку: на телефоне
   порядок обязан быть «заголовок, кнопки, снимок, карточка, органы», а вложенная карточка
   тянула бы снимок в конец столбца. Область решает порядок одной переменной. --- */
.ls-b6__row{display:grid;block-size:100%;
  grid-template-columns:var(--ls-b6-cols,minmax(0,1fr) minmax(0,1fr));
  grid-template-areas:var(--ls-b6-areas,"txt media" "promo media");
  grid-template-rows:var(--ls-b6-rows,1fr auto);
  gap:var(--ls-b6-gap,0px);position:relative;
  /* Дуга уходит за кромку строки по построению - строка её и обрезает. Без этого
     scrollWidth секции рос на 403, и горизонтальную прокрутку страницы держал только
     overflow секции: сторож в вёрстке проверяет именно scrollWidth. */
  overflow:clip}
.ls-b6__txt{grid-area:txt;position:relative;z-index:1;display:grid;align-content:end;
  padding-block:var(--ls-b6-pad,72px) 0;
  padding-inline:var(--ls-b6-pin,72px) var(--ls-b6-pie,56px)}
.ls-b6__aside{grid-area:promo;position:relative;z-index:1;
  padding-block:24px var(--ls-b6-pad,72px);
  padding-inline:var(--ls-b6-pin,72px) var(--ls-b6-pie,56px)}
.ls-b6__media{grid-area:media}
/* Медиа у начала строки: меняются местами области, а не порядок узлов - иначе диктор читает
   снимок раньше заголовка. */
.ls-b6[data-side="start"] .ls-b6__row{--ls-b6-areas:"media txt" "media promo"}
@container ls (max-width:1040px){.ls-b6__row{--ls-b6-cols:minmax(0,1fr) minmax(0,.9fr)}
  .ls-b6__txt,.ls-b6__aside{--ls-b6-pin:40px;--ls-b6-pie:32px}}
@container ls (max-width:700px){.ls-b6__row{--ls-b6-cols:1fr;--ls-b6-gap:20px;
  --ls-b6-areas:"txt" "media" "promo";--ls-b6-rows:auto auto auto}
  .ls-b6[data-side="start"] .ls-b6__row{--ls-b6-areas:"txt" "media" "promo"}
  .ls-b6__txt{--ls-b6-pad:28px;--ls-b6-pin:20px;--ls-b6-pie:20px}
  .ls-b6__aside{--ls-b6-pad:28px;--ls-b6-pin:20px;--ls-b6-pie:20px;padding-block-start:0}}

/* --- ДУГА. Отделяет текст от снимка без линии: приподнятая плоскость, уведённая за кромку
   большим скруглением. Живёт на СТРОКЕ и разворачивается вместе со стороной медиа: раньше она
   была приклеена к концу строки, поэтому в зеркальном варианте выпуклость смотрела в сторону
   ОТ снимка, а сама фигура вылезала за кромку на 72. --- */
.ls-b6__row::before{content:"";position:absolute;inset-block:-20%;z-index:0;
  inline-size:78%;inset-inline-start:-28%;
  border-start-end-radius:50% 60%;border-end-end-radius:50% 60%;
  background:var(--ls-band,#eee);opacity:.55;pointer-events:none}
.ls-b6[data-side="start"] .ls-b6__row::before{inset-inline-start:auto;inset-inline-end:-28%;
  border-radius:0;border-start-start-radius:50% 60%;border-end-start-radius:50% 60%}
@container ls (max-width:700px){.ls-b6__row::before{display:none}}

.ls-b6 .ls-hero__txt{--ls-hero-col:100%;--ls-hero-gap:20px}
.ls-b6 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15;--ls-hero-hw:500;
  --ls-hero-ls:-0.01em;max-inline-size:20ch}
@container ls (max-width:1040px){.ls-b6 .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}}
@container ls (max-width:700px){.ls-b6 .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
.ls-b6 .ls-hero__p{font-size:20px;line-height:1.4;--ls-hero-pw:46ch}
/* Кнопки: главная залита акцентом, вторая - контур. Первой нет - вторая НЕ прыгает: ряд
   выровнен по началу строки. */
.ls-b6 .ls-hero__acts{margin-block-start:16px;gap:14px}
.ls-b6 .ls-hero__btn{min-block-size:52px;padding-inline:26px;border-radius:calc(10px * var(--ls-r-k,1));
  font-size:14px;font-weight:500;letter-spacing:.06em;text-transform:uppercase}
.ls-b6 .ls-hero__btn--ghost{box-shadow:inset 0 0 0 1px var(--ls-acc,#333);color:var(--ls-acc,#333)}
.ls-b6 .ls-hero__btn--ghost:hover{background:color-mix(in oklab,var(--ls-acc,#333) 10%,transparent)}

/* --- КАРТОЧКА АКЦИИ. Второй уровень содержимого: снимок, заголовок, ссылка со стрелкой.
   Скругление 18, поля 16, плоскость - приподнятая: карточка стоит НА плоскости, а не рядом. */
.ls-b6__promo{margin-block-start:36px;max-inline-size:var(--ls-b6-pw,430px);
  padding:16px;border-radius:calc(18px * var(--ls-r-k,1));background:var(--ls-paper,#fff);
  box-shadow:0 18px 40px -28px color-mix(in oklab,var(--ls-ink,#000) 46%,transparent);
  display:grid;gap:14px}
@container ls (max-width:700px){.ls-b6__promo{--ls-b6-pw:100%;margin-block-start:0}}
.ls-b6__shot{position:relative;display:block;overflow:hidden;border-radius:calc(12px * var(--ls-r-k,1));
  block-size:var(--ls-b6-sh,190px);background:var(--ls-band,#eee)}
@container ls (max-width:1040px){.ls-b6__shot{--ls-b6-sh:150px}}
.ls-b6__shot image-slot{position:absolute;inset:0;display:block;inline-size:100%;block-size:100%}
.ls-b6__shot img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-b6__shot[data-empty]::after{content:"image";position:absolute;inset-block-start:50%;
  inset-inline-start:50%;translate:-50% -50%;font-family:"Material Symbols Rounded";
  font-size:30px;color:var(--ls-muted,#666);opacity:.4}
.ls-b6__promo b{display:block;font-family:var(--ls-head-face,inherit);font-size:20px;
  font-weight:500;line-height:1.25;color:var(--ls-ink,#000);text-wrap:pretty}
.ls-b6__more{display:inline-flex;align-items:center;gap:10px;min-block-size:44px;
  align-self:start;background:none;border:0;padding:0;cursor:pointer;
  font:inherit;font-size:13px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ls-ink,#000);text-decoration:none}
.ls-b6__more > span:last-child{inline-size:26px;block-size:26px;display:grid;place-items:center;
  border-radius:50%;background:var(--ls-acc,#333);color:var(--ls-acc-on,#fff);
  transition:translate var(--ls-dur-fast,140ms) var(--ls-ease,ease)}
.ls-b6__more .sc-icon{font-size:16px}
.ls-b6__more:hover > span:last-child,.ls-b6__more[data-hover="true"] > span:last-child{
  translate:calc(4px * var(--ls-mirror,1)) 0}
.ls-b6__more:focus-visible,.ls-b6__more[data-focus="true"]{outline:var(--ls-focus-w,2px) solid
  var(--ls-acc,#333);outline-offset:4px;border-radius:6px /* kit-free: кольцо фокуса, форма не предмет вкуса */}

/* --- ОРГАНЫ КАРУСЕЛИ. Указатель положения - точки; стрелки стоят по краям строки, потому что
   карточка узкая и стрелки рядом с ней слиплись бы с текстом. Цель нажатия 44 у всего. --- */
/* СЕРВЕР ПЕЧАТАЕТ ВСЕ КАРТОЧКИ, а скрипт только переключает признак: узлов он не
   создаёт. Отсюда общий слой - карточки лежат В ОДНОЙ ячейке сетки и меняются
   прозрачностью за 220мс, как объявлено в карте движения пакета.
   ПРЯЧЕМ ПРОЗРАЧНОСТЬЮ И ВИДИМОСТЬЮ, А НЕ `display` - он не анимируется ничем,
   и объявленный китом переход не сыграл бы. Видимость уводится задержкой в
   длину перехода: иначе диктор и табуляция видят спрятанное. */
.ls-b6__promos{display:grid;margin-block-start:36px;max-inline-size:var(--ls-b6-pw,430px)}
.ls-b6__promos > .ls-b6__promo{grid-area:1 / 1;margin-block-start:0;max-inline-size:none;
  transition:opacity var(--ls-dur-base,220ms) var(--ls-ease,ease),
    visibility 0s linear var(--ls-dur-base,220ms)}
.ls-b6__promo[data-on='false']{opacity:0;visibility:hidden;pointer-events:none}
.ls-b6__promo[data-on='true']{opacity:1;visibility:visible;transition-delay:0s}
@media (prefers-reduced-motion:reduce){.ls-b6__promos > .ls-b6__promo{transition:none}}
html.atx-rm .ls-b6__promos > .ls-b6__promo{transition:none}
.ls-b6__nav{margin-block-start:20px;max-inline-size:var(--ls-b6-pw,430px);
  display:flex;align-items:center;justify-content:space-between}
.ls-b6__arw{inline-size:var(--ls-tap,44px);block-size:var(--ls-tap,44px);display:grid;
  place-items:center;padding:0;border:0;border-radius:50%;background:transparent;
  color:var(--ls-ink,#000);cursor:pointer;
  transition:background-color var(--ls-dur-fast,140ms) var(--ls-ease,ease)}
.ls-b6__arw .sc-icon{font-size:22px}
/* Стрелка «назад» смотрит по направлению чтения - зеркалится знаком, а не двумя значками. */
.ls-b6__arw[data-dir="prev"] .sc-icon{scale:var(--ls-mirror,1) 1}
.ls-b6__arw[data-dir="next"] .sc-icon{scale:var(--ls-mirror,1) 1}
.ls-b6__arw:hover,.ls-b6__arw[data-hover="true"]{background:color-mix(in oklab,var(--ls-ink,#000) 8%,transparent)}
.ls-b6__arw:focus-visible,.ls-b6__arw[data-focus="true"]{outline:var(--ls-focus-w,2px) solid
  var(--ls-acc,#333);outline-offset:2px}
.ls-b6__arw[disabled]{color:var(--ls-muted,#666);opacity:.45;cursor:default}
.ls-b6__dots{display:flex;align-items:center;gap:2px}
.ls-b6__dot{inline-size:var(--ls-tap,44px);block-size:var(--ls-tap,44px);display:grid;
  place-items:center;padding:0;border:0;background:transparent;cursor:pointer}
.ls-b6__dot::after{content:"";inline-size:7px;block-size:7px;border-radius:50%;
  background:color-mix(in oklab,var(--ls-ink,#000) 26%,transparent);
  transition:inline-size var(--ls-dur-base,220ms) var(--ls-ease,ease),
    background-color var(--ls-dur-base,220ms) var(--ls-ease,ease)}
/* Активная точка ТЯНЕТСЯ в черту, а не только красится: цвет один сигнал не несёт. */
.ls-b6__dot[aria-current="true"]::after{inline-size:34px;border-radius:999px /* kit-free: наследует форму своего корня - иначе состояние разойдётся с покоем */;
  background:var(--ls-acc,#333)}
.ls-b6__dot:focus-visible{outline:var(--ls-focus-w,2px) solid var(--ls-acc,#333);
  outline-offset:-10px;border-radius:50%}

/* --- ФОТОГРАФИЯ. Выходит на кромку секции, скруглена только по внутренней стороне. --- */
.ls-b6__media{position:relative;overflow:hidden;min-block-size:var(--ls-b6-min,520px);
  border-start-start-radius:var(--ls-b6-rad,calc(28px * var(--ls-r-k,1)));border-end-start-radius:var(--ls-b6-rad,calc(28px * var(--ls-r-k,1)));
  background:var(--ls-band,#eee)}
.ls-b6[data-side="start"] .ls-b6__media{border-radius:0;
  border-start-end-radius:var(--ls-b6-rad,calc(28px * var(--ls-r-k,1)));border-end-end-radius:var(--ls-b6-rad,calc(28px * var(--ls-r-k,1)))}
@container ls (max-width:700px){.ls-b6__media{--ls-b6-min:200px;--ls-b6-rad:calc(18px * var(--ls-r-k,1));
  border-radius:calc(18px * var(--ls-r-k,1));margin-inline:20px}}
.ls-b6__media image-slot{position:absolute;inset:0;display:block;inline-size:100%;block-size:100%}
.ls-b6__media img{inline-size:100%;block-size:100%;object-fit:cover;display:block;
  object-position:var(--ls-hero-pic-pos,50% 30%)}
.ls-b6__media[data-empty]::after{content:"image";position:absolute;inset-block-start:50%;
  inset-inline-start:50%;translate:-50% -50%;font-family:"Material Symbols Rounded";
  font-size:44px;color:var(--ls-muted,#666);opacity:.4}

/* Пилюли: стекло на снимке. Ряд прижат к низу, переносится, цель нажатия не нужна - это
   подписи, а не кнопки, поэтому они и не нажимаются. */
.ls-b6__tags{position:absolute;inset-block-end:28px;inset-inline:24px;z-index:2;
  display:flex;flex-wrap:wrap;justify-content:center;gap:8px;pointer-events:none}
.ls-b6__tag,.ls-b6__tags .sc-se__hot{pointer-events:auto}
@container ls (max-width:700px){.ls-b6__tags{inset-block-end:16px;inset-inline:12px;gap:6px}}
/* СТЕКЛО СВЕТЛОЕ, ЧЕРНИЛА ТЁМНЫЕ - роль перевёрнута намеренно. Тёмная заливка 26% не задаёт
   светлоту фона: она лишь чуть притемняет снимок, а backdrop-filter светлоту не меняет вовсе.
   Замер композита белого текста на такой пилюле: 1,86:1 на светлом снимке и 3,79:1 на среднем -
   порог не держался нигде, кроме тёмного кадра. Светлая заливка 88% сама задаёт светлоту, и
   тёмные чернила дают 12:1 и выше НА ЛЮБОМ снимке - контраст перестаёт зависеть от фотографии.
   Размытие осталось отделкой, а не носителем контраста. */
.ls-b6__tag{min-block-size:44px;display:inline-flex;align-items:center;padding-inline:22px;
  border-radius:var(--ls-r-pill,999px);font-size:15px;line-height:1.25;text-align:center;font-weight:500;
  color:var(--ls-ink,#000);
  background:color-mix(in oklab,var(--ls-ink-on-media,#fff) 88%,transparent);
  /* СИЛУЭТ ДЕРЖИТ КРОМКА И ТЕНЬ, А НЕ ЗАЛИВКА: светлое стекло на светлом снимке отличалось от
     фона на 1,01:1 - оставался висящий тёмный текст без формы. Кромка 20% чернил плюс мягкая
     тень под плашкой дают форму на любом снимке. */
  box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--ls-ink,#000) 20%,transparent),
    0 6px 18px -8px color-mix(in oklab,var(--ls-veil-ink,#000) 46%,transparent);
  backdrop-filter:blur(14px)}
@container ls (max-width:700px){.ls-b6__tag{min-block-size:38px;padding-inline:14px;
  font-size:12.5px}}
/* Без размытия сквозь стекло проступает рисунок снимка, поэтому заливка становится глухой:
   порог держит число, а не эффект. */
@supports not (backdrop-filter:blur(1px)){
  .ls-b6__tag{background:var(--ls-ink-on-media,#fff)}
}

/* КАРТОЧКИ НЕТ - УХОДИТ ВЕСЬ ВТОРОЙ РЯД, А ТЕКСТ ВСТАЁТ ПО ЦЕНТРУ. Скрывать только карточку
   и органы было мало: сама область оставалась с полями 96, второй ряд не пустел, а положение
   текста держалось на align-content:end, который читается как центр лишь при заполненном
   втором ряде - заголовок падал к нижней кромке (замер: ряды 844 / 96, заголовок на 616).
   Поэтому область скрывается целиком, а колонка центрируется и получает поле снизу. */
.ls-b6[data-promo="off"] .ls-b6__aside{display:none}
.ls-b6[data-promo="off"] .ls-b6__txt{align-content:center;
  padding-block:var(--ls-b6-pad,72px)}

/* КНОПКИ ТЕЛЕФОНА - В КОНЦЕ ФАЙЛА, А НЕ РЯДОМ С ПОЛЯМИ. Правило узкого вида стояло выше
   базового `.ls-b6 .ls-hero__btn` при равной специфичности, и базовое побеждало порядком:
   кнопки оставались 52 и переносились в два ряда, уводя секцию за экран. В одном ряду они
   уступают кегль и поля, цель нажатия 44 остаётся. */
@container ls (max-width:700px){
  .ls-b6 .ls-hero__acts{flex-wrap:nowrap}
  .ls-b6 .ls-hero__btn{min-block-size:44px;padding-inline:12px;font-size:11.5px;
    letter-spacing:.03em;white-space:nowrap;flex:1 1 0;justify-content:center}
}

/* ===== hero-c.css ===== */
/* СЕМЬЯ C - БЕЗ МЕДИА. Только плоскость палитры и типографика: проверочная семья, поэтому
   сделана раньше остальных по существу (шкала из hero.css - её результат).

   ЗДЕСЬ ПЕРВЫЙ ЭКРАН РАБОТАЕТ БЕЗ КАРТИНКИ ПО ЗАМЫСЛУ, а не как аварийное состояние:
   половина квизов кончается без картинки, и такому клиенту достаётся раскладка, а не
   пустая коробка.

   ШКАЛА, ПОЛНОСТЬЮ (та же, что в hero.css, здесь - с пределами строки):
     кегль   интерлиньяж  разрядка   вес   предел строки
     12,8    1,4          +0,025em   500   32 знака   (надпись)
     16      1,5          0          400   64         (мелкий текст)
     20      1,4          0          400   60         (абзац A, B)
     25      1,3          0          400   44         (абзац C, B1, B3)
     31,25   1,25         0          600   36         (заголовок A3)
     39,06   1,2          -0,005em   600   30         (заголовок на узком)
     48,83   1,18         -0,02em    600   26         (заголовок A4, средний)
     61,04   1,15         -0,01em    600   24         (заголовок B, средний C)
     76,29   1,14         -0,01em    600   20         (заголовок A1, A7, B5)
     95,37   1,12         -0,015em   700   16         (заголовок C1, C2, A6)
   Интерлиньяж МОНОТОННЫЙ и проверен на кириллице: минимум 1,12 против нужных 1,109.
   Предел строки задан МЕРОЙ В ЗНАКАХ (ch), а не числом точек: точки врут при смене пары
   гарнитур, а их десять. Отношение 3:2 между заголовком и абзацем из разведки сохранено -
   но выражено мерой: 16ch против 24ch на вершине шкалы.

   ПУСТОТА между верхом и низом C1 ТЯНЕТСЯ, а не фиксирована: 168 - её минимум. Задана как
   разгон по краям (align-content:space-between) плюс минимальный зазор - при коротком
   заголовке пустота растёт, при длинном не схлопывается ниже 168. Фиксированное число
   давало бы обрыв на четырёхстрочном заголовке. */

/* ─── C1. Крупный заголовок вверху, абзац и кнопки внизу в две колонки.
   Разгон живёт ВНУТРИ .ls-hero__in, а секция держит РАСТЯГИВАНИЕ: space-between на самой
   секции снимал растяжение её единственного ряда, block-size:100% разрешался от содержимого
   (замер: 382 при коробке 554), и распределять было нечего - пустота стояла фиксированной.
   Узкий: --ls-c1-cols ─── */
.ls-hero.ls-c1{--ls-hero-ac:stretch}
.ls-c1 .ls-hero__in{display:grid;grid-template-rows:auto auto;gap:var(--ls-c1-gap,168px);
  align-content:space-between;min-block-size:100%}
@container ls (max-width:1040px){.ls-c1 .ls-hero__in{--ls-c1-gap:96px}}
@container ls (max-width:700px){.ls-c1 .ls-hero__in{--ls-c1-gap:56px}}
.ls-c1__top{display:grid;gap:24px}
.ls-c1 .ls-hero__h{--ls-hero-h1:95.37px;--ls-hero-lh:1.12;--ls-hero-hw:700;
  --ls-hero-ls:-0.015em;max-inline-size:16ch}
@container ls (max-width:1040px){.ls-c1 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15;
  --ls-hero-ls:-0.01em;max-inline-size:18ch}}
@container ls (max-width:700px){.ls-c1 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2;
  max-inline-size:100%}}
/* Низ: две колонки, выравнивание по нижнему краю. Одной переменной уходит в столбец. */
.ls-c1__bottom{display:grid;grid-template-columns:var(--ls-c1-cols,minmax(0,1fr) minmax(0,1fr));
  gap:var(--ls-c1-bg,24px);align-items:end}
@container ls (max-width:1040px){.ls-c1__bottom{--ls-c1-cols:1fr;--ls-c1-bg:28px}}
.ls-c1__bottom .ls-hero__p{font-size:25px;line-height:1.3;--ls-hero-pw:44ch}
@container ls (max-width:700px){.ls-c1__bottom .ls-hero__p{font-size:20px;line-height:1.4}}
.ls-c1__bottom .ls-hero__acts{margin-block-start:0;justify-content:var(--ls-c1-aj,flex-end)}
@container ls (max-width:1040px){.ls-c1__bottom{--ls-c1-aj:flex-start}}
/* Положение низа - вторая ось: прижат к низу секции (по умолчанию) или поднят к тексту. */
.ls-c1[data-bottom="near"] .ls-hero__in{--ls-c1-gap:56px;align-content:start;min-block-size:0}

/* ─── C2. Только текст по центру. Ни одной своей опции: у такой раскладки вкладка
   Customize исчезает целиком, и лист остаётся с одной вкладкой.
   Узкий: наследует оболочку ─── */
.ls-c2 .ls-hero__txt{--ls-hero-col:100%;justify-items:center;text-align:center;
  margin-inline:auto;--ls-hero-gap:36px}
.ls-c2 .ls-hero__h{--ls-hero-h1:95.37px;--ls-hero-lh:1.12;--ls-hero-hw:700;
  --ls-hero-ls:-0.015em;max-inline-size:16ch}
@container ls (max-width:1040px){.ls-c2 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15;
  max-inline-size:18ch}}
@container ls (max-width:700px){.ls-c2 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2;
  max-inline-size:100%}}
/* Отношение 3:2 из разведки сохранено, но мерой: 24ch у абзаца против 16ch у заголовка. */
.ls-c2 .ls-hero__p{font-size:25px;line-height:1.3;--ls-hero-pw:24ch;margin-inline:auto}
@container ls (max-width:700px){.ls-c2 .ls-hero__p{font-size:20px;line-height:1.4;--ls-hero-pw:34ch}}
.ls-c2 .ls-hero__acts{gap:24px;margin-block-start:12px}

/* ===== hero-d.css ===== */
/* СЕМЬЯ D - СЦЕНА И ДВИЖЕНИЕ. Медиа не иллюстрация к тексту, а сцена вокруг него.

   ДВИЖЕНИЕ. Правило 01 рамки в силе: первый экран не двигается сам. Единственное
   исключение - дорожки D2, и там движение выключается опцией и правилом 07.
   D1 (орбита) СТАТИЧНА намеренно: три окружности с медальонами - это композиция, а не
   карусель; вращать её значит заставить человека ждать, пока нужная картинка приедет.

   RTL. Позиции орбиты заданы сдвигом от центра, и знак сдвига вынесен в переменную
   --ls-mirror: 1 в LTR, -1 в RTL. Форма медальонов при зеркалении НЕ меняется: лежачий
   остаётся лежачим - форма принадлежит картинке, а не направлению чтения. */

/* ─── D1. Орбита: текст в середине, медальоны на трёх окружностях.
   Сцена НЕСИММЕТРИЧНА намеренно: место 3 сидит на средней окружности, место 4 - на внешней.
   Узкий: --ls-d1-scale ─── */
.ls-hero.ls-d1{--ls-mirror:1}
/* Зеркаление: признак dir может стоять И НА САМОЙ секции, и на обёртке - селектор потомка
   на элементе, несущем dir, не срабатывает вовсе. */
.ls-hero.ls-d1[dir="rtl"],[dir="rtl"] .ls-hero.ls-d1{--ls-mirror:-1}
.ls-d1 .ls-hero__in{position:relative;display:grid;place-items:center;
  min-block-size:min(var(--ls-d1-min,900px),100cqh)}
/* СЦЕНА ВЛЕЗАЕТ В ЭКРАН - И ПЕРЕВЫВЕДЕНА ИЗ НОВЫХ РАДИУСОВ, А НЕ СЖАТА.
   При 940 и полях 96 под сцену остаётся 748 по вертикали и 1392 по горизонтали. Круг в 748
   зажимает текст внутрь внутреннего круга шириной 404 - текстовая колонка туда не влезает ни
   при каких сдвигах, и медальоны ложатся на чернила. Поэтому орбиты - ЭЛЛИПСЫ: сцена
   ограничена ВЫСОТОЙ, а ширины у неё в два раза больше, и именно там живут места.
     внутренняя  700 x 380   (rx 350, ry 190)
     средняя      980 x 530   (rx 490, ry 265)
     внешняя     1260 x 680   (rx 630, ry 340)
   Места считаны по этим эллипсам (rx·cos, ry·sin), а не взяты от сцены 1440 и не умножены
   на масштаб: умножение сдвигов на 0,52 стаскивало все шесть мест внутрь внутреннего
   круга и прямо на текст. Несимметрия сохранена: места 1, 2, 3, 6 на средней, 4 и 5 на внешней.
   Запас до текста проверен замером: колонка 380 (полуширина 190) против ближайшего
   медальона на 346 - внутренняя кромка на 283. */
.ls-hero.ls-d1{--ls-d1-scale:1;--ls-d1-msc:.85;--ls-d1-min:748px}
/* ИСХОДНЫЙ РАЗМЕР СЦЕНЫ - ВТОРАЯ ОСЬ ОРБИТЫ, и оба числа тут КИТОВЫ:
   несжатые лежат у него же запасными значениями (`--ls-d1-msc` 1 и
   `--ls-d1-min` 900px). Строка ничего не выдумывает - она их возвращает. */
.ls-hero.ls-d1[data-size="full"]{--ls-d1-msc:1;--ls-d1-min:900px}
@container ls (max-width:1040px){.ls-d1 .ls-hero__in{--ls-d1-min:760px}}
@container ls (max-width:700px){.ls-d1 .ls-hero__in{--ls-d1-min:560px}}
/* Окружности - волосяная линия, диаметры одной переменной масштаба: 1400 / 1224 / 960 в
   разведке заменены на кратные шагу 224, чтобы три порога считались от одного числа. */
/* rtl-ok: центр сцены, а не смещение - своё смещение зеркалит --ls-mirror */
.ls-d1__ring{position:absolute;inset-block-start:50%;left:50%;
  /* rtl-ok: left:50% здесь - ЦЕНТР сцены, а не кромка чтения: центр один в любом
     направлении. Логическое inset-inline-start в RTL привязывало бы ПРАВУЮ кромку, и
     сдвиг -50% переставал центровать - сцена ехала целиком. Зеркаление живёт только в
     знаке --ls-mirror. */
  translate:-50% -50%;border-radius:50%;
  border:1px solid color-mix(in oklab,var(--ls-ink,#000) 14%,transparent);pointer-events:none}
.ls-d1__ring[data-r="in"]{inline-size:calc(700px * var(--ls-d1-scale,1));
  block-size:calc(380px * var(--ls-d1-scale,1))}
.ls-d1__ring[data-r="mid"]{inline-size:calc(980px * var(--ls-d1-scale,1));
  block-size:calc(530px * var(--ls-d1-scale,1))}
.ls-d1__ring[data-r="out"]{inline-size:calc(1260px * var(--ls-d1-scale,1));
  block-size:calc(680px * var(--ls-d1-scale,1))}
@container ls (max-width:1040px){.ls-hero.ls-d1{--ls-d1-scale:.74;--ls-d1-min:600px}}
@container ls (max-width:700px){.ls-hero.ls-d1{--ls-d1-scale:1;--ls-d1-msc:1}}
/* Места на эллипсах - числа здесь, а не в разметке: геометрия сцены принадлежит
   раскладке, а не данным, и при смене порога считается от одного масштаба. */
.ls-d1__med[data-seat="1"]{--dx:-346px;--dy:-187px}
.ls-d1__med[data-seat="2"]{--dx:346px;--dy:-187px}
.ls-d1__med[data-seat="3"]{--dx:-520px;--dy:236px}
.ls-d1__med[data-seat="4"]{--dx:-600px;--dy:0px}
.ls-d1__med[data-seat="5"]{--dx:600px;--dy:-56px}
.ls-d1__med[data-seat="6"]{--dx:346px;--dy:187px}
/* Медальон: место задано двумя числами в переменных, знак по inline-оси - через --ls-mirror.
   Три формы: лежачая 180x126, квадрат 130x130, стоячая 126x180. */
/* rtl-ok: центр сцены, а не смещение - своё смещение зеркалит --ls-mirror */
.ls-d1__med{position:absolute;inset-block-start:50%;left:50%;overflow:hidden;
  /* rtl-ok: тот же центр-якорь, что у окружностей. */
  border-radius:calc(14px * var(--ls-r-k,1));background:var(--ls-band,#eee);
  translate:calc(-50% + (var(--dx,0px) * var(--ls-mirror,1)) * var(--ls-d1-scale,1))
            calc(-50% + var(--dy,0px) * var(--ls-d1-scale,1));
  inline-size:calc(var(--mw,130px) * var(--ls-d1-scale,1) * var(--ls-d1-msc,1));
  block-size:calc(var(--mh,130px) * var(--ls-d1-scale,1) * var(--ls-d1-msc,1))}
.ls-d1__med img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-d1__med[data-empty]::after{content:"image";position:absolute;inset:0;display:grid;
  place-items:center;font-family:"Material Symbols Rounded";font-size:26px;
  color:var(--ls-muted,#666);opacity:.4}
/* УЗКИЙ ВИД - НЕ УМЕНЬШЕННАЯ СЦЕНА, А СТОЛБЕЦ. Причина структурная: текстовая колонка на
   390 разворачивается почти во всю полосу содержимого (350 на 332), а места медальонов -
   сдвиги от центра, поэтому любое место в пределах половины ширины неизбежно попадает
   внутрь текста; уменьшение окружностей не спасает - текст растёт быстрее, чем сжимается
   сцена, и чернила ложились на фотографию с контрастом 1,58.
   Поэтому на узком окружности снимаются, а три медальона встают РЯДОМ над текстом. */
@container ls (max-width:700px){
  .ls-d1 .ls-hero__in{display:flex;flex-flow:row wrap;gap:12px;align-items:start;
    min-block-size:0}
  .ls-d1__ring{display:none}
  .ls-d1__med{position:static;translate:none;flex:1 1 30%;inline-size:auto;block-size:112px}
  .ls-d1 .ls-hero__txt{flex:1 1 100%;order:2;margin-block-start:12px}
}

.ls-d1 .ls-hero__txt{position:relative;z-index:2;--ls-hero-col:380px;justify-items:center;
  text-align:center;margin-inline:auto}
@container ls (max-width:1040px){.ls-d1 .ls-hero__txt{--ls-hero-col:300px}}
.ls-d1 .ls-hero__h{--ls-hero-h1:48.83px;--ls-hero-lh:1.18}
@container ls (max-width:1040px){.ls-d1 .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
@container ls (max-width:700px){.ls-d1 .ls-hero__h{--ls-hero-h1:31.25px;--ls-hero-lh:1.25}}
.ls-d1 .ls-hero__eb{justify-content:center}
/* Меньше картинок - орбита ПЕРЕСТРАИВАЕТСЯ на три места, а не рвётся пустыми медальонами.
   Место задано ПРИЗНАКОМ data-seat, а не nth-of-type: окружности и медальоны - один тег
   span, и счёт по типу прятал все шесть медальонов вместо трёх последних.
   Ниже трёх картинок раскладка не предлагается. */
.ls-d1[data-seats="3"] .ls-d1__med[data-seat="4"],
.ls-d1[data-seats="3"] .ls-d1__med[data-seat="5"],
.ls-d1[data-seats="3"] .ls-d1__med[data-seat="6"]{display:none}
@container ls (max-width:700px){
  .ls-d1 .ls-d1__med{display:none}
}

/* ─── D2. Две дорожки картинок навстречу. Единственное движение первого экрана.
   ЧЕМ ДВИЖЕМСЯ: чистой CSS-анимацией - набор напечатан ДВАЖДЫ и лента едет на -50%.
   Скрипта не нужно вовсе (п. 7.1 рамки): молчание скрипта оставляет дорожки стоящими и
   читаемыми, а не пустыми.
   ТРИ СКОРОСТИ ЧИСЛАМИ: Slow 90s, Medium 60s, Fast 36s на полный проход - линейно.
   Узкий: --ls-d2-cols ─── */
.ls-d2__row{display:grid;grid-template-columns:var(--ls-d2-cols,minmax(0,1fr) auto);
  gap:var(--ls-d2-gap,64px);align-items:center}
@container ls (max-width:1040px){.ls-d2__row{--ls-d2-gap:36px}}
@container ls (max-width:700px){.ls-d2__row{--ls-d2-cols:1fr;--ls-d2-gap:28px}}
.ls-d2 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}
@container ls (max-width:700px){.ls-d2 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
.ls-d2 .ls-hero__p{font-size:25px;line-height:1.3;--ls-hero-pw:44ch}
@container ls (max-width:700px){.ls-d2 .ls-hero__p{font-size:20px;line-height:1.4}}
.ls-d2__lanes{display:flex;gap:16px;overflow:hidden;
  block-size:min(var(--ls-d2-h,640px),100cqh);
  /* Вылет за край - логическим полем ровно в отступ секции, как в B1. */
  margin-inline-end:calc(var(--ls-hero-pin,24px) * -1);
  /* Кромки гасятся маской: лента не обрывается прямой линией. */
  mask-image:linear-gradient(to bottom,transparent,#000 12%,#000 88%,transparent)}
@container ls (max-width:1040px){.ls-d2__lanes{--ls-d2-h:520px}}
@container ls (max-width:700px){.ls-d2__lanes{--ls-d2-h:280px;margin-inline-end:0}}
.ls-d2__lane{inline-size:var(--ls-d2-w,288px);flex:none;overflow:hidden}
@container ls (max-width:700px){.ls-d2__lane{--ls-d2-w:calc(50% - 8px)}}
.ls-d2__belt{display:grid;gap:16px;
  animation:ls-lane var(--ls-d2-dur,60s) linear infinite;
  animation-direction:var(--ls-d2-dir,normal)}
.ls-d2__lane:nth-child(2) .ls-d2__belt{--ls-d2-dir:reverse}
@keyframes ls-lane{from{translate:0 0}to{translate:0 -50%}}
/* Правило 07: дорожки останавливаются СОВСЕМ и замирают в НАЧАЛЬНОМ положении - первая
   картинка каждой дорожки видна целиком, а не обрезанной посередине. */
@media (prefers-reduced-motion:reduce){.ls-d2__belt{animation:none;translate:0 0}}
/* ВТОРОЙ ТРИГГЕР ЗАМИРАНИЯ - НАШ СОБСТВЕННЫЙ ВИДЖЕТ ДОСТУПНОСТИ, и кит о нём
   знать не может: он ставит класс на html. Правило 07 пакета требует, чтобы
   дорожки замирали в НАЧАЛЬНОМ положении, а не там, где их застало нажатие. */
html.atx-rm .ls-d2__belt{animation:none;translate:0 0}
.ls-d2[data-speed="slow"] .ls-d2__belt{--ls-d2-dur:90s}
.ls-d2[data-speed="fast"] .ls-d2__belt{--ls-d2-dur:36s}
.ls-d2[data-still] .ls-d2__belt{animation:none;translate:0 0}
.ls-d2__belt > span{position:relative;display:block;aspect-ratio:3 / 4;overflow:hidden;
  border-radius:calc(12px * var(--ls-r-k,1));background:var(--ls-band,#eee)}
.ls-d2__belt img{inline-size:100%;block-size:100%;object-fit:cover;display:block}

/* ─── D3. Заголовок сверху по центру, пара картинок снизу в ряд.
   ОТЛИЧИЕ ОТ A6 - в плитке каталога: у A6 фотография во всю секцию и малая карточка ПОВЕРХ
   неё в углу, здесь фотографий нет в фоне вовсе, а две картинки стоят В РЯД под текстом на
   плоскости палитры. В плитке 320 это читается как «тёмный кадр с меткой» против «светлого
   листа с двумя окнами».
   Узкий: --ls-d3-cols ─── */
.ls-d3 .ls-hero__in{display:grid;gap:var(--ls-d3-gap,48px);justify-items:center}
@container ls (max-width:700px){.ls-d3 .ls-hero__in{--ls-d3-gap:28px}}
.ls-d3 .ls-hero__txt{--ls-hero-col:900px;justify-items:center;text-align:center}
/* \u0421\u0442\u0443\u043f\u0435\u043d\u044c 76,29 \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b 95,37: \u043d\u0430 95 \u0442\u0440\u0451\u0445\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0439 \u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0431\u0440\u0430\u043b 320\n   \u0442\u043e\u0447\u0435\u043a, \u0438 \u0441\u0435\u043a\u0446\u0438\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043f\u0430\u0440\u043e\u0439 \u0443\u0445\u043e\u0434\u0438\u043b\u0430 \u043d\u0430 1080 \u043f\u0440\u0438 \u044d\u043a\u0440\u0430\u043d\u0435 940. \u0412\u0435\u0440\u0448\u0438\u043d\u0430 \u0448\u043a\u0430\u043b\u044b \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0443 C1 \u0438\n   C2, \u0433\u0434\u0435 \u043f\u043e\u0434 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u043c \u043d\u0435\u0442 \u043c\u0435\u0434\u0438\u0430. */
.ls-d3 .ls-hero__h{--ls-hero-h1:76.29px;--ls-hero-lh:1.14;--ls-hero-hw:700;
  --ls-hero-ls:-0.015em;max-inline-size:20ch}
@container ls (max-width:1040px){.ls-d3 .ls-hero__h{--ls-hero-h1:61.04px;--ls-hero-lh:1.15}}
@container ls (max-width:700px){.ls-d3 .ls-hero__h{--ls-hero-h1:39.06px;--ls-hero-lh:1.2}}
/* Пара держит ПРОПОРЦИЮ, а влезание в экран решается пределом ШИРИНЫ: большая 12:9 при 1440
   давала 718 высоты, а вместе с заголовком 95 и зазором 64 секция уходила за 1500. Обрезать
   высоту нельзя - пропорция тут замысел, поэтому сужается сама пара. */
.ls-d3__pair{inline-size:100%;
  /* Высота сцены у нас едет ПЕРЕМЕННОЙ, а не контейнерной единицей -
     подробности у отступления про `.ls-w--vp`. Доля от неё та же, что у кита. */
  max-inline-size:min(1440px,calc(var(--ls-hero-h,100svh) * 0.66));display:grid;
  grid-template-columns:var(--ls-d3-cols,minmax(0,1fr) minmax(0,2.4fr));
  gap:var(--ls-d3-pg,36px);align-items:end}
.ls-d3[data-big="start"] .ls-d3__pair{--ls-d3-cols:minmax(0,2.4fr) minmax(0,1fr)}
/* На узком пара ОСТАЁТСЯ рядом, а не встаёт столбиком: две картинки друг под другом давали
   1128 при экране телефона 844 - первый экран переставал быть первым экраном. */
@container ls (max-width:700px){.ls-d3__pair{--ls-d3-cols:minmax(0,1fr) minmax(0,1.7fr);--ls-d3-pg:12px;max-inline-size:none}
  .ls-d3[data-big="start"] .ls-d3__pair{--ls-d3-cols:minmax(0,1.7fr) minmax(0,1fr)}}
.ls-d3__pair > span{position:relative;overflow:hidden;border-radius:calc(16px * var(--ls-r-k,1));
  background:var(--ls-band,#eee)}
.ls-d3__pair > span:first-child{aspect-ratio:1}
.ls-d3__pair > span:last-child{aspect-ratio:12 / 9}
.ls-d3[data-big="start"] .ls-d3__pair > span:first-child{aspect-ratio:12 / 9}
.ls-d3[data-big="start"] .ls-d3__pair > span:last-child{aspect-ratio:1}
.ls-d3__pair img{inline-size:100%;block-size:100%;object-fit:cover;display:block}
.ls-d3__pair > span[data-empty]::after{content:"image";position:absolute;inset:0;
  display:grid;place-items:center;font-family:"Material Symbols Rounded";font-size:30px;
  color:var(--ls-muted,#666);opacity:.4}
.ls-d3__aside{max-inline-size:32ch;justify-self:start}

