/* ==========================================================================
   Секция 5 — «Где это работает»: ниши-переключатели и диалог ИИ БРО
   --------------------------------------------------------------------------
   Третий заход по экрану. Было: восемь высоких карточек (значок сверху,
   подпись под ним) и здоровый скриншот интерфейса записи «Beauty Studio»
   справа. Заказчик снял и то и другое: «сделай иконку и надпись в одной
   строке — карточки будут компактнее», «вместо скриншота справа визуализация
   чатика, и чтоб при выборе карточки включался другой чатик — как происходит
   общение в этой нише».

   Отсюда вся раскладка: слева заголовочный блок и восемь карточек-кнопок
   в две колонки, справа одно окно переписки, в котором меняется разговор.
   Мокап assets/mockup-booking.webp из секции убран (файл оставлен в проекте).
   ========================================================================== */

/* overflow: hidden у секции снят вместе с мокапом: резать больше нечего,
   декор держится внутри, а световой омут вывода обрезка бы съела.
   position: relative приходит из .section в base.css — декору хватает.

   Но по горизонтали резать всё-таки надо. Полка вывода (.verdict::before
   в base.css) выступает за фразу на --verdict-lead / --verdict-trail,
   и на 375 блок вывода занимает весь контейнер: полка уезжает с 20px
   до 455px при экране в 375. Секция ничего не обрезала, и
   documentElement.scrollWidth становился 456 — горизонтальную прокрутку
   гасил только overflow-x: hidden на body, то есть страница держалась
   на затычке. Соседние секции для этого стоят на overflow: hidden.
   Здесь взят clip и только по оси X: он не заводит скролл-контейнер
   (иначе ломается position: sticky и якорная прокрутка) и не трогает
   вертикаль — верхняя и нижняя кромки остаются проницаемыми, стыков
   с соседями не появляется. Омут вывода приходит к нулевой альфе
   на 74% радиуса, у кромок экрана от него остаётся около 0.01 —
   резать нечего. */
.niches { overflow-x: clip; }

/* ---------- Декор ----------
   Объект секции — окно переписки справа, объект-окно, значит точки
   (docs/visual-language.md, «Декор: два вопроса»).

   Были кольца, и стояли они посреди левой колонки: круг проходил прямо
   по заголовку «ИИ БРО УЖЕ ХОРОШО РАБОТАЕТ В ПОПУЛЯРНЫХ НИШАХ» и наполовину
   прятался за окном переписки — ни ореола за объектом, ни самостоятельной
   фигуры, а по контрасту он спорил с текстом. Кольца — ореол силуэта,
   а силуэта на экране нет.

   Точки садятся на внутренний нижний угол окна: правый край чата упирается
   в кромку экрана, наружу узору идти некуда, внутрь — есть. Коробка 200×160
   при left 47% и top 68% занимает 677..877 по горизонтали и 734..894
   по вертикали: чат начинается с 763 и кончается на 799, то есть верхняя
   часть коробки уходит под окно, а наружу выступает только угол. До нижней
   кромки секции остаётся 186px, до верхней — 734: обрезать нечего. */
.niches__dots {
  left: 47%;
  top: 68%;
  width: 200px;
  height: 160px;
}

/* ---------- Сетка: текст с карточками слева, переписка справа ----------

   Левая колонка чуть шире: в ней две колонки карточек с подписями до трёх
   слов, и на равных долях «Клиники и стоматологии» ломались на две строки
   раньше, чем начинал ужиматься кегль.

   align-items: start, а не center. Высота правой колонки зависит от того,
   какой диалог открыт, и при центрировании окно переписки прыгало бы
   по вертикали на каждом переключении. */

.niches__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
  align-items: start;
  gap: var(--s-7);
}

.niches__col { min-width: 0; }

/* ---------- Заголовочный блок ---------- */

/* Общая для секций 2-5 отбивка «лид → контент»: 48px. Заказчик отметил,
   что подзаголовок стоял вплотную к карточкам, — правило было в файле
   и потерялось при прошлой правке. */
.niches__head { margin-bottom: var(--s-7); }

/* Отбивки по макету: бейдж → заголовок 40px, заголовок → лид 25px.
   text-wrap: initial обязателен — balance ломает разбивку макета
   «ИИ БРО УЖЕ ХОРОШО / РАБОТАЕТ В ПОПУЛЯРНЫХ / НИШАХ» на три равные строки. */
/* Кегль общий — --fz-h2. Свой (41px против 55.4 на 1440) был снят с макета,
   но единого H2 в макете нет вовсе — по нему восемь громкостей и набрались. */
.niches__title {
  margin-block: calc(var(--s-6) + var(--s-2)) var(--s-5);
  text-wrap: initial;
}

/* Кегль, интерлиньяж и мера — общие из .lead. Мера была в пикселях. */

/* ---------- Карточки ниш = переключатели диалога ----------

   Значок и подпись в одну строку (правка заказчика): карточка с 158px
   в макете опустилась до 72-80px, восемь штук встают в две колонки и больше
   не забирают полэкрана. Иконки оставлены как есть — заказчик их похвалил.

   Это кнопки с role="tab": по клику справа открывается разговор из этой ниши.
   Нумерация «1. Салоны красоты» из макета по-прежнему не нужна — порядок
   и так виден (docs/sections.md, замечания к экрану 5). */

.niches__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}

/* Кнопка, а не <li>: сбрасываем всё, что браузер даёт кнопке по умолчанию,
   и оставляем материал карточки из base.css (.card + .card--interactive). */
.niches__card {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 0;
  border-radius: var(--r-md);
  text-align: left;
  cursor: pointer;
  /* Кроме подъёма и тени из .card--interactive плавно меняется и заливка:
     выбранная карточка загорается брендовым тоном, а не переключается рывком.
     Ступень одна на все три свойства — --t-fast: и подъём, и заливка здесь
     отвечают на руку человека, а не на смену содержимого (правило в base.css,
     раздел «Движение»). Было 220 — карточка догорала уже после того,
     как справа собрался новый разговор. */
  transition: transform var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}

/* Обёртка над знаком и подписью. Нужна телефону: там знак уходит внутрь
   строки текста (у обёртки display: block), и по центру чипа встаёт она
   целиком, а не два отдельных бокса — иначе подпись в одну строку висела бы
   у верхней кромки чипа, высота которого задана соседом в две строки.
   На десктопе обёртка повторяет ровно ту флекс-строку, что была у самой
   кнопки: те же выключка, зазор и min-width, коробка не меняется. */
.niches__card-body {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  min-width: 0;
}

.niches__card-icon {
  /* Кружок берётся ступенью --sm из base.css (48/22, на телефоне 40/18):
     промежуточных размеров на сайте не заводим. Здесь только переход,
     чтобы значок загорался ВМЕСТЕ с карточкой — значит и ступень у него
     та же, что у карточки. */
  transition: background var(--t-fast), box-shadow var(--t-fast),
              border-color var(--t-fast), color var(--t-fast);
}

.niches__card-title {
  min-width: 0;
  /* Нижняя граница 15px: на 1200-1300 колонка узкая, и при 1.15vw кегль
     ушёл бы к 13 — «Клиники и стоматологии» перестали бы читаться. */
  font-size: var(--fz-body);
  font-weight: 500;
  line-height: 1.28;
}

/* Отклик: кружок загорается фирменным переливом — тот же приём, что
   у .icon-badge--accent, только по наведению.

   Правило разведено на два: выбранная вкладка (aria-selected) обязана
   гореть везде, в том числе на телефоне, а наведение — только там, где
   есть указатель. Иначе после тапа по нише кружок соседней карточки
   оставался бы подсвеченным наравне с выбранной, и на экране горели бы
   две «активные» вкладки. Разбор медиазапроса — в base.css. */
.niches__card[aria-selected="true"] .niches__card-icon {
  background: var(--grad-brand);
  border-color: transparent;
  box-shadow: var(--glow-brand);
  color: #fff;
}

@media (hover: hover) {
  .niches__card:hover .niches__card-icon {
    background: var(--grad-brand);
    border-color: transparent;
    box-shadow: var(--glow-brand);
    color: #fff;
  }
}

/* Выбранная ниша. Сигнал двойной — заливка карточки уходит в брендовый
   перелив и загорается кружок: одного кружка мало, взглядом по восьми
   карточкам активную не найти. Свечение привязано к самой карточке
   и гаснет в её габаритах, фоном секции не становится. */
.niches__card[aria-selected="true"] {
  background: var(--grad-soft);
  box-shadow: 0 0 0 1px rgba(124, 59, 246, .22),
              0 2px 6px rgba(27, 22, 51, .05),
              0 16px 40px rgba(124, 59, 246, .16);
}

.niches__card[aria-selected="true"] .niches__card-title { font-weight: 600; }

/* ---------- Окно переписки ----------

   Материал один в один с экрана 2 (.client-chat в 02-problem.css): рамка,
   скругление --r-xl, тень --sh-lift, перелив в шапке, пузыри на --bg-tint
   и --brand-soft. Классы свои, а не общие: секции обязаны быть независимыми,
   и удаление экрана 2 не должно раздевать этот блок. Кандидат на переезд
   в base.css общим компонентом — см. отчёт.

   overflow: hidden обязателен: шапка залита переливом до самой кромки
   и без обрезки вылезала бы за скругление. */

.niches__demo { min-width: 0; }

.niches__chat {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--sh-lift);
  overflow: hidden;
}

.niches__chat-head {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-5) var(--s-6);
  border-bottom: 1px solid var(--line);
  background:
    linear-gradient(115deg, rgba(124, 59, 246, .085) 0%, rgba(124, 59, 246, 0) 64%),
    var(--surface);
}

/* Кружок под знаком ИИ БРО. Перелив и свечение — те же, что у
   .icon-badge--accent: собеседник читается как активный, а не как наклейка.
   Кружок рисует CSS, а не сам рисунок: знак одноцветный и лежит в спрайте
   (assets/icons/bro.svg), поэтому фон и тон задаются снаружи. Тон — --ink:
   персонаж на рендерах чёрный, а не фиолетовый. */
.niches__chat-avatar {
  display: inline-flex;
  width: 58px;
  height: 58px;
  flex: none;
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--grad-soft);
  color: var(--ink);
  box-shadow: var(--glow-brand);
}

.niches__chat-avatar svg {
  display: block;
  width: 100%;
  height: 100%;
}

.niches__chat-who {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.niches__chat-name {
  color: var(--ink);
  font-size: var(--fz-body);
  font-weight: 700;
  line-height: 1.2;
}

/* Точка «на связи» — кружок с мягким ореолом, а не сплошной кружок.
   #726C87 на белом даёт 5.06:1. */
.niches__chat-status {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--muted-2);
  font-size: var(--fz-caption);
  line-height: 1.2;
}

.niches__chat-status::before {
  content: '';
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--brand);
  box-shadow: 0 0 0 3px rgba(124, 59, 246, .16);
}

.niches__chat-time {
  margin-left: auto;
  flex: none;
  align-self: flex-start;
  color: var(--muted-2);
  font-size: var(--fz-caption);
  line-height: 1.2;
}

/* ---------- Стопка диалогов ----------

   Все восемь разговоров лежат в одной ячейке грида. Без скрипта лишние
   скрыты атрибутом hidden (виден первый). Со скриптом они остаются в потоке,
   но гасятся видимостью: тогда высота ячейки равна самому длинному диалогу
   и окно не прыгает при переключении. Короткий разговор прижимается к низу —
   так ведёт себя любой мессенджер. */

.niches__demo-stack { display: grid; }

.niches__chat-log {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* flex-start, а не stretch: иначе пузырь всегда во всю ширину колонки,
     и короткая реплика выглядит пустой полосой. Пузырь обжимает текст. */
  align-items: flex-start;
  padding: var(--s-6);
}

/* Скрытый диалог занимает место, но не виден и не читается скринридером */
.niches__chat-log--off { visibility: hidden; }

.niches__chat-log > * + * { margin-top: var(--s-4); }

/* Реплики подряд от одного собеседника идут плотнее, чем ответ на ответ:
   так переписка читается репликами, а не восемью одинаковыми плашками. */
.niches__msg--bro + .niches__msg--bro { margin-top: var(--s-2); }

/* Плашка-тема вместо отбивки дня в мессенджере. Единственное место, где
   названа ниша: шапка окна общая на все восемь диалогов, а меняется
   разговор — и вместе с ним эта строка. */
.niches__chat-topic {
  align-self: center;
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--muted-2);
  font-size: var(--fz-caption);
  line-height: 1.3;
}

.niches__chat-topic + .niches__msg { margin-top: var(--s-5); }

/* 86% — чтобы у входящих оставался виден край справа, а ответ ИИ БРО
   не сливался с ними в один столбец. Кегль общий с экраном 2. */
.niches__msg {
  max-width: 86%;
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-lg);
  border-bottom-left-radius: var(--s-1);
  background: var(--bg-tint);
  color: var(--ink);
  font-size: var(--fz-lead);
  font-weight: 500;
  line-height: 1.3;
}

/* Реплики ИИ БРО справа и брендовым тоном: фиолетовый на этом экране —
   это голос продукта, серое — входящая заявка клиента. */
.niches__msg--bro {
  align-self: flex-end;
  border-bottom-left-radius: var(--r-lg);
  border-bottom-right-radius: var(--s-1);
  background: var(--brand-soft);
}

/* ==========================================================================
   Появление реплик — единственное осмысленное движение на странице
   --------------------------------------------------------------------------
   Движение отвечает на действие: нажал карточку ниши — разговор собрался
   заново, репликами сверху вниз. Это половина работы. Вторая половина —
   ЧТО именно оно сообщает.

   Продукт — агент, который отвечает мгновенно. Раньше реплики выезжали
   ровной лесенкой по 55 мс: красиво и ровно ничего не значит, разговор
   выглядел одним блоком, разложенным на слои. Теперь пауза перед репликой
   зависит от того, чья она:

     перед репликой ИИ БРО   60 мс   он отвечает сразу
     перед репликой клиента 170 мс   человек читает и печатает

   Почти втрое — разницу видно, и она и есть содержание: на экране буквально
   происходит то, что обещает заголовок сайта. Ни одного лишнего пикселя
   движения при этом не добавлено, это та же лесенка с другим ритмом.

   Числа считает js/sections/05-niches.js и кладёт в --d на каждую реплику:
   накопительную сумму («задержка предыдущей плюс своя пауза») в CSS
   не выразить, а привязывать её к nth-child нельзя — порядок реплик
   в восьми диалогах свой, и правка текста молча сломала бы ритм.

   Общая длина у диалога из пяти реплик — около 440 мс до последнего пузыря
   плюс 220 мс на его появление. Свод: до 400 мс — крупное перемещение,
   свыше 500 раздражает; здесь ни одно ОТДЕЛЬНОЕ движение не длится дольше
   --t-base, а суммарная длина последовательности — это темп разговора,
   и он должен читаться разговором.

   Начальное состояние живёт только в кадрах анимации, поэтому при
   prefers-reduced-motion (base.css проигрывает таймлайн за 0.01 мс)
   пузыри оказываются в конечном кадре, то есть просто нарисованы. */

.niches__chat-log--enter > * {
  /* --t-base целиком: это «220ms ease-out», а сокращение animation принимает
     длительность и кривую подряд. Своего числа здесь нет — появление
     содержимого идёт по той же ступени, что и везде на сайте. */
  animation: niche-msg-in var(--t-base) both;
  /* Запасное 0ms — на случай, если класс появился без расчёта: тогда
     разговор просто проявится целиком, а не останется прозрачным. */
  animation-delay: var(--d, 0ms);
}

@keyframes niche-msg-in {
  from { opacity: 0; transform: translateY(8px); }
}

/* Собственных стилей у знака ИИ БРО здесь нет и быть не должно: рисунок
   один на весь сайт и лежит в assets/icons/bro.svg. Прежде тут стоял свой
   робот с антенной и улыбкой, а на экране 9 — другой, в шлеме, и оба
   красились классами .avatar-bro__*, объявленными в двух файлах сразу.
   09-selling.css подключается после этого, поэтому его значения побеждали,
   и робот здесь красился не тем, чем задумано. Секция про это больше
   не знает: тон задаёт color обёртки. */

/* ---------- Вывод секции ----------
   Полка света вместо плашки (.verdict в base.css). Перечисление ниш снято
   по правке заказчика, осталась одна фраза и набрана крупно.
   Полка по центру: вывод следует не из окна переписки, а из всего экрана
   разом — «в любой из этих ниш».

   Мера не изменилась — 22em, изменилась длина фразы: с 84 знаков до 75.
   На 22em под текст остаётся 20.6em (мера минус боковые поля .verdict),
   и фраза ломается один раз, после «ИИ БРО»: хайлайтер «встанет
   на входящие» открывает вторую строку целиком, а не разрывается.
   Замерено на 1280 / 1440 / 1600 / 1920 — две строки на всех четырёх
   (570+620, 642+698, 713+775, 796+866). */

.niches__callout {
  --verdict-measure: 22em;
  margin-top: calc(var(--s-6) + var(--s-2));
}

/* ---------- Адаптив ---------- */

/* Две колонки ещё держатся, но левая узкая: карточкам оставляем зазор
   поменьше, кегль подписи ужимается сам (clamp выше). */
@media (max-width: 1300px) {
  .niches__grid { gap: var(--s-6); }
  .niches__list { gap: var(--s-2); }
}

/* ==========================================================================
   ВОСЕМЬ НИШ НА ВИДУ: сетка вместо ленты
   --------------------------------------------------------------------------
   Что здесь стояло раньше. Когда колонки складываются, столбик из восьми
   карточек встаёт НАД окном переписки и отодвигает его на экран с лишним:
   восемь карточек по 64px с зазорами занимали 596px (0,73 экрана на 375),
   и после нажатия на первую вкладку окна переписки на экране не было
   видно вовсе. Прошлый круг вылечил это горизонтальной лентой с боковой
   прокруткой: одна строка вместо восьми, 72px.

   Заказчик ленту снял: «перечисление ниш в мобильной версии сейчас — вот
   такой листающийся вправо полоской. Надо подумать, как по-другому это
   сделать… никто не будет листать, из-за этого этот элемент будет не особо
   кликабельным, никто так не будет».

   Замер подтверждает: лента 1932px при экране 375 — видно 19% списка.
   Шесть с половиной ниш из восьми не существуют для человека, который
   не догадался потянуть вбок, а горизонтальный свайп вне карусели
   с картинками ничем себя не выдаёт. Указатель ленты, поставленный
   прошлым кругом, сообщал долю честно, но доступнее ниши не делал:
   чтобы дойти до восьмой, всё равно четыре свайпа.

   Вместо ленты — та же сетка два на четыре, что на десктопе. Все восемь
   на виду, любая в одно касание, листать нечего. Разметка не изменилась
   ни на знак: те же восемь кнопок с role="tab", тот же порядок, тот же
   скрипт, та же клавиатура (стрелки в 05-niches.js ходят и по вертикали,
   и по горизонтали, Home/End — на края). Без JS секция работает ровно как
   прежде: открыт первый диалог, остальные скрыты атрибутом hidden.

   ПОЧЕМУ НЕ <select>. Он дешевле всех по высоте — одна строка вместо
   четырёх рядов — и на телефоне действительно открывается системным
   колесом, то есть выглядит родным. Но первое требование к этому экрану:
   должно быть ВИДНО, ЧТО НИШ ВОСЕМЬ. Заголовок обещает «работает
   в популярных нишах», и восемь ниш здесь не настройка демо,
   а само доказательство обещания; список, свёрнутый в одну строку, прячет
   доказательство за нажатие. Два довода помельче: без JS <select> — это
   орган управления, который открывается и ничего не делает (кнопки в том
   же положении хотя бы ничего не обещают), и правильный tablist пришлось
   бы разобрать и собрать заново на listbox — ровно та работа, в которой
   теряют доступность.

   ПОЧЕМУ НЕ АККОРДЕОН (восемь строк, выбранная разворачивает диалог под
   собой). Восемь строк по 44px с зазорами — это 380px против 276 у сетки,
   и это ещё не считая того, что окно переписки начинает ездить по вертикали
   вслед за выбором и связка «выбор сверху, ответ снизу» разваливается.
   И главное: панели, вставленные между вкладками, ломают дерево
   доступности — вкладки обязаны быть детьми одного tablist.

   ЦЕНА. Сетка занимает 276px на 375/393/430 и 268 на 320 против 72 у ленты.
   Это плата за то, что элементом наконец пользуются: восемь целей выше 44px
   и три зазора по 8, ужать тут нечего.
   ========================================================================== */
@media (max-width: 1100px) {
  /* minmax(0, 1fr), а не 1fr: у трека 1fr минимум равен min-content. */
  .niches__grid {
    grid-template-columns: minmax(0, 1fr);
    /* Сетка ниш и окно переписки — один прибор «выбрал нишу — вот разговор».
       16 при 8 внутри самой сетки: вдвое больше внутреннего зазора и втрое
       меньше отбивки шапки (--s-7), закон близости выдержан. При ленте
       здесь стояло 12 — лента была одной строкой и жалась к окну. */
    gap: var(--s-4);
  }

  /* Во всю ширину планшета строка в пузыре уходит за сотню знаков,
     а карточка ниши растягивается на полэкрана ради двух слов. Оба блока
     ограничены одной колонкой — так же, как переписка на экране 2. */
  .niches__col,
  .niches__demo { max-width: 760px; }

  /* В одну колонку окно переписки встаёт под карточки во всю ширину,
     и «внутреннего» угла у него больше нет: слева и справа кромки экрана.
     Узор уходит вместе с раскладкой — привязать его не к чему, а поставить
     «где-нибудь» значило бы вернуть ровно ту постановку по настроению,
     из-за которой правило и появилось. */
  .niches__dots { display: none; }
}

@media (max-width: 640px) {
  .niches__head { margin-bottom: var(--s-5); }

  /* ---------- Чип на телефоне: знак в строке, а не в кружке ----------

     Арифметика, из-за которой кружок уходит. Колонка на 375 — 327px,
     две ячейки по 159.5. Десктопный материал карточки (кружок 40 + зазор 16
     + поля 16) оставляет подписи 87.5px. Самый длинный неразрывный кусок
     в наборе — «и строительство»: он неразрывен, потому что после союза
     стоит нбсп, и это правило свода, а не случайность вёрстки. При кегле 15
     кусок занимает 122.5px, при 16 — 130.6. Ни на одной телефонной ширине
     он в 87.5 не помещается: подпись вылезала бы за борт чипа в соседнюю
     колонку. Значит либо кружок, либо две колонки — вместе они на телефоне
     не живут.

     Кружок уступает, потому что две колонки дороже: восемь ниш в один
     столбик — это те самые 596px, из-за которых прошлый круг и завёл ленту.

     Значок становится знаком в строке текста: он стоит инлайном ПЕРЕД
     подписью и укорачивает ТОЛЬКО первую строку, а вторая получает всю
     ширину чипа — 143.5 на 375 при полях 8. 122.5 < 143.5, запас 21px,
     и он держится на всех ширинах от 360 (на 360 остаётся 136, запас 13.5).
     Этим же приёмом набрана строка вопроса в калькуляторе — там он снимает
     третью строку у самого длинного вопроса.

     Что теряется: заливка кружка, которая на десктопе загорается
     у выбранной ниши. Сигнал выбора не пропадает — его несут заливка самой
     карточки (--grad-soft), кольцо тени и вес подписи; на чипе это видно
     даже лучше, потому что он мельче и красится целиком. */
  .niches__list { gap: var(--s-2); }

  /* Знак перестаёт быть отдельным боксом строки и становится знаком
     ВНУТРИ текста: обёртка — обычный блок, флекса в ней больше нет.
     Сама кнопка остаётся флексом с align-items: center, поэтому
     содержимое стоит по центру чипа независимо от числа строк. */
  .niches__card-body { display: block; }

  .niches__card {
    /* По горизонтали 8, а не 12. Четыре пикселя с каждой стороны решают,
       встанет ли первое слово рядом со знаком или знак останется на строке
       один: при полях 12 «Юридические» (103.1) не помещалось на 360
       в 101.6 доступных, ряд становился на 19px выше трёх соседних, и то же
       было с «Недвижимостью» на 375. При полях 8 все восемь чипов на всех
       ширинах от 320 до 640 выходят одной высоты — замер в отчёте круга. */
    padding: var(--s-3) var(--s-2);
    border-radius: var(--r-sm);
    /* Нижняя граница тач-цели. Две строки подписи с полями дают 63px,
       одна — 43.5, и на широком телефоне короткие подписи («Недвижимость»,
       «Онлайн-школы») в одну строку и встают. 44 — норма для пальца. */
    min-height: 44px;
    /* Кегль и интерлиньяж объявлены на САМОЙ кнопке, а не только на подписи.
       Высоту строки в блоке задаёт не текст, а «распорка» — невидимый бокс
       из шрифта и интерлиньяжа контейнера. Пока они висели на подписи,
       распоркой оставалось наследство от .card: 16px × 1.6 = 25.6, и чип
       в две строки выходил 75.2 вместо 63 — двенадцать лишних пикселей
       на каждом из восьми. */
    font-size: var(--fz-small);
    line-height: 1.3;
  }

  /* Кружок разбирается до голого знака. Свойства снимаются поимённо,
     а класс .icon-badge--sm остаётся в разметке: на десктопе он и рисует
     кружок, и разметка обязана быть одна на обе раскладки. */
  .niches__card-icon {
    width: auto;
    height: auto;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    /* 4, а не 8: между двумя <span> в разметке стоит перевод строки,
       и он схлопывается в обычный пробел шириной ~4.4px — тот самый зазор,
       который в кружковой раскладке задавал gap флекса. Вместе выходит
       около 8, то есть ступень шкалы. Считать пробел надо явно: он занимает
       место в ПЕРВОЙ строке, а от неё зависит, встанет ли первое слово
       рядом со знаком. При поле 8 знак съедал бы 30.4px из 143.5,
       и «Недвижимость» (112) не помещалась бы в остаток. */
    margin-right: var(--s-1);
    /* Знак садится на строку текста, а не на её верх */
    vertical-align: -3px;
  }

  .niches__card-icon .icon { width: 18px; height: 18px; }

  .niches__card-title {
    display: inline;
    font-size: inherit;
    line-height: inherit;
  }

  /* Выбранная ниша: у голого знака нет ни кружка, ни кромки — заливать
     нечего, загорается только цвет. Специфичность та же, что у десктопного
     правила, побеждает порядок в файле. */
  .niches__card[aria-selected="true"] .niches__card-icon {
    background: none;
    box-shadow: none;
    color: var(--brand-dark);
  }

  @media (hover: hover) {
    .niches__card:hover .niches__card-icon {
      background: none;
      box-shadow: none;
      color: var(--brand-dark);
    }
  }

  .niches__chat-head { padding: var(--s-4) var(--s-5); }
  .niches__chat-avatar { width: 48px; height: 48px; }
  .niches__chat-log { padding: var(--s-4); }

  /* ---------- Пузырь на телефоне ----------

     Кегль. На десктопе реплика набрана --fz-lead — там пузырь шириной 380px
     и строка выходит 45-50 знаков. На 375 тот же токен даёт 18px в пузыре
     шириной 240: двадцать шесть знаков в строке, и разговор из пяти реплик
     разворачивается на 546px одних только пузырей. --fz-body (16px) — это
     основной кегль сайта, ниже которого свод опускаться запрещает
     (docs/premium-web.md, «Длина строки»: уменьшать кегль ради «влезет
     больше» бессмысленно — но здесь мы не ужимаем текст, а возвращаем его
     к общему для страницы размеру). В строке становится тридцать знаков,
     реплики теряют по строке каждая, а мессенджеры ровно так и набраны.

     Перенос. У всех <p> на сайте стоит text-wrap: pretty (base.css).
     На широкой колонке он полезен, в пузыре шириной 240 — вредит: Chromium
     подтягивает слова ради последней строки и отдаёт «Привет! Можно /
     записаться / на стрижку в субботу?» вместо двух ровных строк. Мокап
     переписки обязан выглядеть снимком мессенджера, а мессенджеры ничего
     не балансируют — это та же причина, по которой у .niches__msg отключены
     переносы по слогам (base.css). Возвращаем обычный жадный перенос.

     Ширина. 86% — десктопное число: там пузырь 380px и обрезанный правый
     край нужен, чтобы входящие не сливались с ответами в один столбец.
     На 375 та же доля вместе с полями складывается в цепочку 327 → 325 →
     277 → 238 → 206, то есть под текст остаётся 55% ширины экрана,
     и «Привет! Можно записаться» перестаёт помещаться в строку целиком.
     Замер: реплика в 45 знаков вставала в три строки, из которых вторая —
     одно слово. 92% при поле лога 16 дают под текст 236px, реплика
     укладывается в две. Отличать входящие от ответов это не мешает:
     на телефоне их разводят цвет, сторона и форма нижнего угла, а сдвиг
     в 8% остаётся видимым. */
  .niches__msg {
    max-width: 92%;
    padding: var(--s-3) var(--s-4);
    font-size: var(--fz-body);
    line-height: 1.35;
    text-wrap: wrap;
  }
}

/* ---------- Узкий телефон: ступень кегля у подписи ----------
   На 320 колонка контейнера 288px, ячейка сетки 140, под текст остаётся 124.
   «И строительство» при кегле 15 занимает 122.5 — формально влезает,
   с запасом в полтора пикселя. Полтора пикселя это не запас: подпись держат
   метрики Golos Text, а до его подгрузки строка набрана подогнанным
   фолбэком, и любое расхождение выносит её за борт чипа в соседнюю колонку
   (при полях 12 это и было замерено: +6.5px). Ступень кегля вниз даёт
   110.2 при тех же 124 — запас 13.8.

   Почему не одна колонка. Восемь чипов в столбик на 320 — это 408px против
   268 у сетки, то есть ровно та высота, из-за которой прошлый круг и завёл
   ленту, и на самом узком экране она дороже всего. Ступень «узкого телефона»
   в проекте уже есть у полей и отбивок (tokens.css), подпись чипа идёт
   по тому же правилу и новой границы медиазапроса не заводит. */
@media (max-width: 359px) {
  .niches__card { font-size: var(--fz-caption); }

  /* Поле у знака снимается совсем: зазор держит схлопнутый перевод строки
     из разметки (~3.6px на этом кегле). Четыре пикселя решают дело — без
     них «Юридические» (92.8) не помещалось рядом со знаком при 90.4
     доступных, знак оставался на строке один, и ряд становился на 17px
     выше трёх остальных. */
  .niches__card-icon { margin-right: 0; }
}
