/* ДоброВет — раскладка и компоненты.
   Структура: Poster Fold (афиша) → Gallery Grid (сетка плит).
   Все цвета — только var(--token). Все отступы — только по шкале. */

/* ============ база ============ */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Разрешает переход height/block-size к ключевому слову auto —
     без этого ответ в FAQ раскрывается рывком. Где не поддержано
     (Firefox), просто остаётся сегодняшнее мгновенное раскрытие. */
  interpolate-size: allow-keywords;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Плавающая навигация перекрывает верх секции при переходе по якорю.
   Высота пилюли ~64px + воздух. */
:target,
section[id],
main[id] { scroll-margin-top: var(--s24); }

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Любой display в классе перебивает браузерное `[hidden] { display: none }`
   — и элемент, спрятанный атрибутом, остаётся на экране. Так экран
   «Заявка принята» показывался под незаполненной формой. */
[hidden] { display: none !important; }

h1, h2, h3, p, ul, ol, figure, blockquote, table { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { max-width: 100%; display: block; }
a { color: inherit; }

/* Фокус-кольцо берёт цвет у ближайшей поверхности, а не у секции.
   Раньше вся .emergency / .contacts / .footer получала лаймовое кольцо —
   и на лаймовой карточке телефонов оно давало контраст 1.00, в футере
   на светлом фоне 1.19, на белой карточке триажа 1.31. Кольца просто
   не было видно там, где оно нужнее всего: на кнопке экстренного звонка
   и на номерах телефонов. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--s1);
}
/* тёмные панели — лайм читается (13.24) */
.emergency,
.contacts { --focus: var(--accent); }
/* светлые и лаймовые плашки внутри них — кольцо чернильное (13.24 / 17.29) */
.contacts__block:first-child,
.triage__result--now,
.triage__result--today { --focus: var(--ink); }
/* футер светлый — работает синее кольцо по умолчанию (4.93 на surface) */

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: var(--s4); top: calc(-1 * var(--s16));
  background: var(--ink); color: var(--on-panel);
  padding: var(--s3) var(--s6); border-radius: var(--r-pill);
  text-decoration: none; font-weight: 600; z-index: 100;
}
.skip:focus { top: var(--s4); }

.shell {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ============ кнопки и чипы ============ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: var(--s3) var(--s6);
  border: 0;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: var(--t-small);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}
.btn--lg { min-height: 56px; padding: var(--s4) var(--s8); font-size: var(--t-body); }

.btn--primary { background: var(--primary); color: var(--on-primary); }
.btn--accent  { background: var(--accent);  color: var(--on-accent); }
.btn--onblue  { background: var(--paper);   color: var(--ink); }
/* Текст на светло-синей кнопке — это --ink в своей роли «тёмный текст»,
   а не --on-accent: тот описывает текст поверх лайма и здесь просто
   совпадал по значению. Токен вне своей роли ломается при первой же правке. */
.btn--onpanel { background: var(--primary-lift); color: var(--ink); }
/* Кнопка ПОВЕРХ лаймовой плашки. btn--accent там давала лайм на лайме
   (контраст 1.00): в вердикте «Не ждите. Выезжайте.» кнопка экстренного
   звонка была видна только по тексту. Тёмная заливка даёт 13.24 к лайму
   под ней и 17.29 к собственному тексту. */
.btn--onaccent { background: var(--panel); color: var(--on-panel); }
.btn--ghost   { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 2px var(--control-line); }

@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-2px); }
}
.btn:active { transform: translateY(0); }

/* ============ иконки ============ */
/* Одно семейство на весь сайт: инлайновый SVG 24×24, обводка currentColor,
   толщина 2, скруглённые концы. Заливок и эмодзи нет. */
.icon {
  flex: none;
  display: block;
  width: 20px;
  height: 20px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s4);
  border-radius: var(--r-pill);
  font-size: var(--t-small);
  font-weight: 500;
}
.chip__dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; flex: none;
}
.chip--status { background: var(--accent); color: var(--on-accent); }
.chip--status[data-open="false"] { background: var(--paper); color: var(--ink); }

/* ============ навигация · плавающая пилюля ============ */
.nav {
  position: fixed;
  top: var(--s3);
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  width: calc(100% - var(--gutter) * 2);
  max-width: 1120px;
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding: var(--s2) var(--s2) var(--s2) var(--s6);
  background: var(--paper);
  border-radius: var(--r-pill);
  box-shadow: 0 8px 32px rgb(19 26 46 / 0.10);
  transition: transform var(--dur-base) var(--ease-out);
}
/* Уход наверх при скролле вниз. Состояние ставит main.js классом:
   инлайновый transform из JS перетирал бы translateX(-50%) базы. */
.nav--hidden { transform: translateX(-50%) translateY(-140%); }
.nav__mark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
  text-decoration: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;          /* цель нажатия на мобильном */
}
.nav__logo { width: 28px; height: 28px; flex: none; border-radius: 7px; }
.nav__links {
  display: flex;
  gap: var(--s6);
  margin-inline-start: auto;
  font-size: var(--t-small);
  font-weight: 500;
}
.nav__links a {
  text-decoration: none;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  min-height: 44px;          /* зона клика, хотя на тач-экранах рейл скрыт */
}
@media (hover: hover) and (pointer: fine) { .nav__links a:hover { color: var(--ink); } }
.nav__cta { flex: none; }
.nav__cta-short,
.nav__cta-icon { display: none; }

@media (max-width: 1000px) {
  .nav__links { display: none; }
  .nav__cta { margin-inline-start: auto; }
}
@media (max-width: 420px) {
  .nav__cta-full { display: none; }
  .nav__cta-short { display: inline; }
  .nav__cta-icon { display: block; }
}
/* Раньше на 320px вордмарк (nowrap, ~133px) + кнопка «Позвонить» (~126px)
   не влезали в пилюлю шириной 288px, и слово «ДоброВет» пряталось уже
   с 400px — то есть на большинстве сегодняшних телефонов сайт открывался
   БЕЗ НАЗВАНИЯ КЛИНИКИ в шапке. Ужимаем не имя, а кнопку: ниже 360px
   она становится кружком с иконкой трубки, слово уходит в доступное имя
   ссылки. 44px кружка + 133px знака + отступы = 209px, запас есть
   и на 320px, и на любом фолбэке шрифта. */
@media (max-width: 360px) {
  .nav { padding-inline-start: var(--s3); gap: var(--s3); }
  .nav__cta {
    width: 48px;
    padding-inline: 0;
  }
  .nav__cta-short {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

/* ============ 1 · HERO · афиша ============ */
.hero {
  background: var(--primary);
  color: var(--on-primary);
  /* Было 176px сверху и 96px снизу: на ноутбуке 1440×900 hero вырастал
     до 1091px, и кнопка «Записаться» с телефоном оказывались ЗА сгибом —
     первый экран заканчивался на слове «честно». Экран у клиники должен
     заканчиваться действием, а не буквами. */
  padding-block: calc(var(--s24) + var(--s6)) var(--s16);
  border-radius: 0 0 var(--r-xl) var(--r-xl);
  position: relative;
  overflow: hidden;
}
.hero__inner {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  position: relative;
}
.hero__eyebrow {
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: var(--s6);
}
.hero__title {
  font-family: var(--font-display);
  /* Вторая половина той же задачи: заголовок в четыре строки — самая
     высокая часть первого экрана, и он обязан считаться с ВЫСОТОЙ окна,
     а не только с шириной. 11.5vh срабатывает только на низких окнах
     (900px → 103px вместо 118px); на мобильном min() всегда выбирает
     --t-hero, так что там ничего не меняется. */
  font-size: min(var(--t-hero), 11.5vh);
  font-weight: 800;
  /* кириллица: floor 1.05, не латинские 0.9 — иначе «у», «д», «ц» режутся */
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 0;
  position: relative;
  z-index: 2;
}
.hero__line {
  display: block;
  overflow: hidden;          /* маска, из-под которой выезжает строка */
  padding-bottom: 0.09em;    /* запас под кириллические выносные «у», «д», «ц» */
  margin-bottom: -0.09em;
}
.hero__line-in { display: block; }
/* Было 12%: строка «Считаем» уезжала вправо ровно настолько, что вырез
   накрывал её последнюю букву целиком — слово читалось как «Считаеı».
   Слом сетки должен перекрывать заголовок, а не съедать из него букву.
   Отступ уменьшен, а сам вырез расширен (см. .hero__cutout): наезд стал
   больше прежнего, но приходится на воздух за словом, а не на букву. */
.hero__line--indent { padding-inline-start: 10%; }

/* ЕДИНСТВЕННЫЙ намеренный слом сетки: вырез уходит за правый край
   и ложится поверх последних строк заголовка. */
.hero__cutout {
  position: absolute;
  z-index: 3;
  /* Геометрия подобрана замером АЛЬФА-КАНАЛА кадра, а не рамки <figure>:
     в полосе строки «Считаем» силуэт начинается только на 24% ширины
     кадра, поэтому прежние `right: -48px; top: 18%; width: min(50%,620px)`
     давали не наезд, а зазор в 94px — животные просто стояли рядом,
     и подписной приём не срабатывал.
     Текущие значения (замер на 1280): наезд +37px на хвост «Считаем»,
     запас до низа секции 66px, до строки лида 186px.
     Правый вылет убран: при вылете кадр приходилось расширять до 800px,
     и тогда лапы обрезал скруглённый низ секции. */
  right: 0;
  top: 4%;
  width: min(60%, 800px);
  aspect-ratio: 1120 / 1223;
  margin: 0;
  pointer-events: none;
}
.hero__lead {
  position: relative;
  z-index: 4;
  max-width: 34ch;
  margin-top: var(--s8);
  font-size: var(--t-lead);
  line-height: 1.5;
}
.hero__actions {
  position: relative;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  margin-top: var(--s8);
}
.hero__status {
  position: relative;
  z-index: 4;
  margin-top: var(--s6);
}

@media (max-width: 900px) {
  .hero { padding-block: calc(var(--s24) + var(--s12)) var(--s16); }
  .hero__line--indent { padding-inline-start: 0; }

  /* Порядок на мобильном: сначала обещание и телефон, потом картинка.
     Человеку в панике кнопка нужна раньше, чем красивый кадр. */
  .hero__inner { display: flex; flex-direction: column; }
  .hero__eyebrow { order: 1; }
  .hero__title   { order: 2; }
  .hero__lead    { order: 3; max-width: none; margin-top: var(--s6); }
  .hero__actions { order: 4; }
  .hero__status  { order: 5; }
  .hero__cutout {
    order: 6;
    position: relative;
    right: auto; top: auto;
    width: min(72%, 320px);
    margin: var(--s8) auto 0;
    /* слом сетки на узком экране снимаем — вырез встаёт в поток */
  }
}

/* ============ фотографии ============ */
/* width/height проставлены в разметке, чтобы страница не дёргалась при загрузке.
   Файлы в assets/photos — ВРЕМЕННЫЕ, помечены data-placeholder;
   перед публикацией их меняют реальные кадры клиники (PHOTO-PLAN.md). */
.hero__cutout img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom center;
}
.step__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--r-md);
}

/* ============ номера секций ============ */
.section-num {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  color: var(--primary);
  margin-bottom: var(--s6);
  font-variant-numeric: tabular-nums;
}
.section-num--panel { color: var(--accent); }
.section-num--onblue { color: var(--on-primary); opacity: 0.75; }

/* ============ 2 · ПРОБЛЕМА ============ */
.problem { padding-block: var(--s32); }
.problem__statement {
  font-family: var(--font-body);
  font-size: var(--t-h2);
  font-weight: 500;
  line-height: 1.28;
  letter-spacing: -0.01em;
  max-width: 32ch;
  text-wrap: balance;
}
/* Подпись, которая называет сцену. Без неё три карточки со временем
   читались как факт о клинике, а не как чужой вечер. */
.timeline__label {
  margin-top: var(--s16);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Три отметки идут поперёк страницы, а не стопкой: так это читается
   как ход времени и не оставляет пустой правый нижний угол. */
.timeline {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s6);
  margin-top: var(--s6);
}
/* Выход из сцены: говорит, что дальше на странице — иначе секция
   заканчивается на «никто не отвечает» и не ведёт никуда. */
.timeline__outro {
  margin-top: var(--s8);
  max-width: 46ch;
  color: var(--muted);
  font-size: var(--t-lead);
}
.timeline__item {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  padding: var(--s8);
  background: var(--paper);
  border-radius: var(--r-lg);
  position: relative;
}
/* Соединительная черта между отметками */
.timeline__item:not(:last-child)::after {
  content: "";
  position: absolute;
  top: calc(var(--s8) + 0.6em);
  inset-inline-end: calc(-1 * var(--s6));
  width: var(--s6);
  height: 2px;
  background: var(--border);
}
.timeline__time {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(28px, 3vw, 40px);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--primary);
}
.timeline__text { color: var(--muted); }

@media (max-width: 860px) {
  .timeline { grid-template-columns: 1fr; gap: var(--s3); }
  .timeline__item::after { display: none; }
}
@media (max-width: 640px) {
  .problem { padding-block: var(--s16); }
  .timeline__label { margin-top: var(--s8); }
  .timeline { margin-top: var(--s3); }
  .timeline__item { padding: var(--s6); }
  .timeline__outro { margin-top: var(--s6); }
}

/* ============ 3 · ЭКСТРЕННЫЙ БЛОК ============ */
.emergency {
  background: var(--panel);
  color: var(--on-panel);
  border-radius: var(--r-xl);
  margin-inline: var(--gutter);
  padding-block: var(--s24);
}
.emergency__grid {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: var(--s16);
  align-items: start;
}
.emergency__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  max-width: 14ch;
}
.emergency__lead {
  margin-top: var(--s6);
  font-size: var(--t-lead);
  color: var(--panel-muted);
  max-width: 34ch;
}
.emergency__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  margin-top: var(--s8);
}
.firstaid {
  background: color-mix(in srgb, var(--on-panel) 8%, transparent);
  border-radius: var(--r-lg);
  padding: var(--s8);
}
.firstaid__head {
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s4);
}
.firstaid__list { display: grid; gap: var(--s3); }
.firstaid__list li {
  padding-inline-start: var(--s6);
  position: relative;
  color: var(--on-panel);
}
.firstaid__list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.65em;
  width: 10px; height: 2px;
  background: var(--accent);
}

@media (max-width: 860px) {
  .emergency { padding-block: var(--s16); margin-inline: var(--s3); }
  .emergency__grid { grid-template-columns: 1fr; gap: var(--s8); }
  .firstaid { padding: var(--s6); }
}

/* ============ 4 · ПЛИТКИ ============ */
.rooms {
  background: var(--primary);
  color: var(--on-primary);
  border-radius: var(--r-xl);
  margin: var(--s3) var(--gutter);
  padding-block: var(--s32);
}
.rooms__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  max-width: 18ch;
}
.rooms__lead {
  margin-top: var(--s6);
  max-width: 46ch;
  font-size: var(--t-lead);
}
.tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 168px;
  gap: var(--s3);
  margin-top: var(--s16);
}
.tile {
  position: relative;
  border-radius: var(--r-lg);
  padding: var(--s6);
  display: flex;
  flex-direction: column;
  /* Название прижато к низу плитки, как подпись на афише. Раньше здесь
     стоял space-between, и вторым полюсом был номер — из-за этого номер
     набирался в 46px и оказывался крупнее самого названия кабинета. */
  justify-content: flex-end;
  gap: var(--s2);
  overflow: hidden;
  min-width: 0;
}
.tile--tall  { grid-row: span 2; }
.tile--wide  { grid-column: span 2; }
/* Фото — самая крупная плитка, 2x2 */
.tile--photo { grid-column: span 2; grid-row: span 2; padding: 0; }
.tile--photo img { width: 100%; height: 100%; object-fit: cover; }

.tile--paper { background: var(--paper); color: var(--ink); }
.tile--accent { background: var(--accent); color: var(--on-accent); }
.tile--panel { background: var(--panel); color: var(--on-panel); }
/* Номер — маркер в углу, а не содержание плитки. Крупный номер выигрывал
   у названия кабинета, хотя название и есть единственное, что здесь важно.
   Контраст на всех трёх подложках плиток при 0.7: ink/paper 6.41,
   ink/accent 5.73, on-panel/panel 8.94 — с запасом к порогу 4.5. */
.tile__num {
  position: absolute;
  top: var(--s4);
  inset-inline-end: var(--s6);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}
.tile__name { font-size: var(--t-h3); font-weight: 600; line-height: 1.2; }
/* Было 13px с opacity 0.65: единственное уточнение на всю мозаику
   набиралось мельче всего, что на ней есть. */
.tile__note { font-size: var(--t-small); opacity: 0.8; }
/* Кадр кабинета. На десктопе мозаика держится на одной крупной плитке
   .tile--photo, поэтому здесь display: none — и браузер эти шесть
   картинок не грузит: lazy-изображение внутри невидимого предка
   никогда не пересекает вьюпорт. */
.tile__media { display: none; }

@media (max-width: 1000px) {
  .tiles { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 160px; }
  .tile--wide, .tile--photo { grid-column: span 2; }
  .tile--photo { grid-row: span 1; }
}
@media (max-width: 520px) {
  .rooms { padding-block: var(--s16); margin-inline: var(--s3); }
  /* Мозаика 4×N на телефоне разваливается, поэтому здесь она становится
     стопкой: название кабинета → его кадр → следующий кабинет. Ряды
     считаются по содержимому — жёсткая высота обрезала бы фото. */
  .tiles { grid-template-columns: 1fr; grid-auto-rows: auto; margin-top: var(--s8); }
  .tile--wide, .tile--tall { grid-column: auto; grid-row: auto; }
  /* Один общий кадр интерьера на всю мозаику уходит: теперь свой кадр
     есть у каждого кабинета. */
  .tile--photo { display: none; }

  /* Порядок внутри плитки задаётся flex-order, а не разметкой: в DOM
     номер стоит последним, потому что на десктопе он абсолютный маркер
     в углу, и там порядок чтения задаёт не поток. */
  .tile {
    padding: var(--s2);
    justify-content: flex-start;
    gap: 0;
  }
  .tile__num  { position: static; order: 1; padding: var(--s3) var(--s3) 0; }
  .tile__name { order: 2; padding-inline: var(--s3); }
  .tile__note { order: 3; padding: 0 var(--s3); }
  .tile__media {
    display: block;
    order: 4;
    margin: var(--s3) 0 0;
  }
  /* Радиус кадра + padding плитки = её собственный радиус: 12 + 8 = 20.
     Концентричные скругления, иначе угол картинки спорит с углом плитки. */
  /* height: auto обязателен: в разметке у кадра стоят width/height
     (они держат место до загрузки), и без сброса высоты браузер берёт
     атрибут как `height: 900px` — aspect-ratio при заданных обоих
     размерах не применяется, и плитка вырастала до 977px. */
  .tile__media img {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--r-md);
  }
}

/* ============ 5 · КАК ПРОХОДИТ ВИЗИТ ============ */
.visit { padding-block: var(--s32); }
.visit__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s6);
  margin-top: var(--s16);
}
.step {
  background: var(--paper);
  border-radius: var(--r-lg);
  padding: var(--s6);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}
.step__media { margin: 0; }
/* Номер и заголовок стояли в одном ряду по базовой линии. Длинные шаги
   («Диагностика в тот же визит») переносились в две строки рядом с
   номером, и четыре карточки расходились по высоте текста. Номер
   отдельной строкой сверху — заголовки всех четырёх стартуют одинаково. */
.step__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s1);
}
.step__num {
  font-family: var(--font-display);
  font-size: clamp(30px, 3vw, 44px);
  font-weight: 700;
  line-height: 1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
  /* Номер шага — содержание, а не орнамент: он задаёт порядок чтения.
     При 0.32 контраст к белому был 1.65 при требуемых 3.0. */
  opacity: 0.7;
  flex: none;
}
.step__name { font-size: var(--t-h3); font-weight: 600; line-height: 1.2; }
.step__text { font-size: var(--t-small); color: var(--muted); }

@media (max-width: 900px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) {
  .visit { padding-block: var(--s16); }
  .steps { grid-template-columns: 1fr; gap: var(--s3); margin-top: var(--s8); }
}

/* ============ 6 · ЦЕНЫ ============ */
/* Спек-лист F6. Секция отвечает не на «сколько» (ответа пока нет),
   а на «за что» — состав услуги теперь основное содержание строки,
   а не серая приписка под гигантским прочерком. */
.prices { padding-block: var(--s24); }
/* Заголовок слева, ответ про цену справа — та же раскладка, что
   у .emergency__grid и .prep__grid. Раньше правая половина секции
   пустовала: лид упирался в 50ch, а таблица шла на всю ширину. */
.prices__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
  column-gap: var(--s16);
  row-gap: var(--s8);
  align-items: start;
}
.prices__intro { grid-column: 1; grid-row: 1; }
.pricelist     { grid-column: 1; grid-row: 2; }
/* Карточка стоит второй в разметке (мобильный порядок чтения),
   а на десктопе занимает вторую колонку на обе строки. */
.pledge        { grid-column: 2; grid-row: 1 / span 2; }
.prices__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.prices__lead { margin-top: var(--s6); max-width: 46ch; color: var(--muted); }

/* --- карточка «сколько это стоит» --- */
/* Один ответ вместо десяти прочерков в колонке. Формат повторяет
   карточку «Часы работы» в контактах: «—», состояние, что делать. */
.pledge {
  background: var(--paper);
  border-radius: var(--r-lg);
  padding: var(--s8);
  position: sticky;
  top: var(--s24);          /* ниже плавающей пилюли навигации */
}
.pledge__label {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: var(--s6);
}
.pledge__list { display: grid; gap: var(--s3); }
.pledge__list li {
  padding-inline-start: var(--s6);
  position: relative;
  font-size: var(--t-small);
}
/* Та же засечка, что в блоке «До приезда» на тёмной панели, — один приём
   для списков-перечислений по всей странице. */
.pledge__list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.62em;
  width: 10px; height: 2px;
  background: var(--primary);
}
.pledge__text {
  margin-top: var(--s6);
  font-size: var(--t-small);
  color: var(--muted);
}
.pledge__btn { margin-top: var(--s6); width: 100%; }

/* --- список услуг --- */
.pricelist {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  text-align: start;
}
.pricelist thead th {
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: start;
  padding-bottom: var(--s3);
  border-bottom: 2px solid var(--border);
}
.pricelist thead th:first-child { width: 37%; }
.pricelist thead th:last-child  { width: 14%; text-align: end; }
.pricelist tbody th,
.pricelist tbody td {
  padding-block: var(--s4);
  border-bottom: 1px solid var(--border);
  text-align: start;
  vertical-align: baseline;
}
/* Название услуги и её состав идут одним кеглем: состав — это
   единственное, что про услугу сейчас известно наверняка. */
.pricelist tbody th { font-weight: 600; padding-inline-end: var(--s8); }
.pricelist tbody td { color: var(--muted); }
/* Цена — единственное число в строке: моноширинные цифры, чтобы столбец
   не «дышал», и без переноса, чтобы «1 900 ₽» не разрывалось. */
.pricelist td.price {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: end;
}

/* Заголовок группы. Десять строк подряд читались как один поток —
   четыре группы дают глазу, за что зацепиться. */
.pricelist .pricegroup__head th {
  padding-block: var(--s12) var(--s4);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  border-bottom: 0;
}
/* Шапка таблицы и первый заголовок группы — оба капсом; без воздуха
   между ними они читаются как одна пара, а не как два уровня. */
.pricelist .pricegroup:first-of-type .pricegroup__head th { padding-top: var(--s12); }
/* Единственный акцент в списке — пакеты «под ключ», ради которых
   секция и существует. Раньше выделялась одна строка белой подложкой,
   и в ней всё равно стоял прочерк. */
.pricelist .pricegroup--key .pricegroup__head th { color: var(--primary); }

@media (max-width: 900px) {
  .prices__grid { grid-template-columns: 1fr; }
  .prices__intro, .pledge, .pricelist { grid-column: 1; grid-row: auto; }
  /* На узком экране липкая карточка съедала бы треть экрана — отключаем. */
  .pledge { position: static; }
  .pledge__btn { width: auto; }
}
@media (max-width: 720px) {
  .prices { padding-block: var(--s16); }
  .pricelist { table-layout: auto; }
  .pricelist thead { display: none; }

  /* Группа — стопка карточек с зазором, как чек-лист «что взять с собой». */
  .pricelist tbody { display: grid; gap: var(--s2); }

  /* Строка прайса становится белой плиткой. Раньше строки лежали прямо
     на --surface, а разделяла их линия --border: контраст 1.17, её
     физически не видно, и десять позиций читались одним серым потоком.
     На десктопе структуру держит колонка цифр справа; на телефоне
     колонки схлопываются, и держать становится нечему. Разделяем
     цветом плит, а не линейками — как и вся остальная страница. */
  .pricelist tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    column-gap: var(--s4);
    background: var(--paper);
    border-radius: var(--r-md);
    padding: var(--s4) var(--s6);
    border-bottom: 0;
  }
  .pricelist tbody th,
  .pricelist tbody td { border: 0; padding: 0; }

  .pricelist tbody th { grid-column: 1; grid-row: 1; }
  /* Цена возвращает себе правый край. В столбик она уезжала третьей
     строкой под состав, к левому краю, тем же кеглем, что название, —
     единственное число в строке пропадало совсем. */
  .pricelist td.price {
    grid-column: 2;
    grid-row: 1;
    text-align: end;
    font-family: var(--font-display);
    font-size: var(--t-h3);
    letter-spacing: -0.02em;
  }
  /* Состав — во всю ширину под названием и ценой. */
  .pricelist tbody td:not(.price) {
    grid-column: 1 / -1;
    grid-row: 2;
    margin-top: var(--s1);
    font-size: var(--t-small);
  }

  /* Заголовок группы плиткой не становится: это подпись НАД стопкой,
     а не позиция в ней. Раньше он висел капсом на пустом фоне без
     подложки и без линии — «ГРУМИНГ» читался как хвост предыдущей
     группы, а не как начало новой. */
  .pricelist .pricegroup__head {
    display: block;
    background: transparent;
    border-radius: 0;
    padding: var(--s6) 0 var(--s1);
  }
  .pricelist .pricegroup:first-of-type .pricegroup__head { padding-top: 0; }
  .pricelist .pricegroup__head th { padding: 0; }
}

/* ============ 7 · ВРАЧИ ============ */
.doctors { padding-block: var(--s24); }
.doctors__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.doctors__lead {
  margin-top: var(--s6);
  max-width: 52ch;
  color: var(--muted);
  font-size: var(--t-lead);
}
.team {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s6);
  margin-top: var(--s16);
}
.teammate {
  background: var(--paper);
  border-radius: var(--r-lg);
  padding: var(--s6);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}
.teammate__media { margin: 0; }
.teammate__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--r-md);
}
.teammate__name {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  /* Полное имя с отчеством переносится на две строки, а style-lock держит
     нижнюю границу интерлиньяжа дисплея для кириллицы на 1.05:
     при 1.0 выносные «у», «р», «ф» задевают строку ниже. */
  line-height: 1.1;
  text-wrap: balance;
}
.teammate__role { font-size: var(--t-small); color: var(--muted); }


@media (max-width: 860px) { .team { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) {
  .team { grid-template-columns: 1fr; gap: var(--s3); margin-top: var(--s8); }
  .rooms__photo { margin-top: var(--s8); }
}
.doctors__note { margin-top: var(--s8); font-size: var(--t-small); color: var(--muted); max-width: 62ch; }
@media (max-width: 640px) { .doctors { padding-block: var(--s16); } }

/* ============ горизонтальная лента (только телефон) ============ */
/* Врачи и шаги визита стопкой съедали по три-четыре экрана прокрутки
   каждая секция — из-за них до цен и контактов доходили единицы.
   Лента показывает первую карточку целиком и край второй: видно, что
   дальше есть ещё, и палец знает, куда вести. Блок должен стоять ПОСЛЕ
   правил .team и .steps — у него та же специфичность, и переопределяет
   он их только порядком. */
@media (max-width: 720px) {
  .hscroll {
    display: flex;
    gap: var(--s3);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    /* Лента идёт от края до края экрана, а карточки начинаются по колонке:
       отрицательный внешний отступ гасит padding .shell, а свой внутренний
       возвращает поля первой и последней карточке. */
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    /* Без этого лента сама уезжает на 16px при загрузке: `scroll-snap-align:
       start` меряет от края области прокрутки, а она по умолчанию идёт по
       padding-box — первая карточка прилипала к краю экрана, а не к колонке.
       scroll-padding задвигает эту область внутрь на тот же отступ. */
    scroll-padding-inline: var(--gutter);
    /* Место под тень и фокус-кольцо карточки, а не под полосу прокрутки. */
    padding-block-end: var(--s2);
    scrollbar-width: none;
  }
  .hscroll::-webkit-scrollbar { display: none; }
  .hscroll > * {
    flex: 0 0 min(76%, 300px);
    scroll-snap-align: start;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hscroll { scroll-snap-type: none; }
}

/* ============ 8 · ОТЗЫВ ============ */
.review { padding-block: var(--s24); }
/* P2 — цитата в широкой колонке, источник и оговорка на полях справа.
   Раньше всё лежало слева и правая половина секции пустовала. */
.quote {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
  gap: var(--s16);
  align-items: start;
}
.quote__text {
  /* Unbounded здесь стоял на пяти строках — style-lock держит дисплейный
     шрифт только на коротких строках (H1, вордмарк, номера). Отзыв — это
     абзац, он набирается Onest, как и .problem__statement того же кегля. */
  font-family: var(--font-body);
  font-size: clamp(22px, 3.6vw, 46px);
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}
.quote__meta {
  font-size: var(--t-small);
  color: var(--muted);
  display: grid;
  gap: var(--s2);
  padding-top: var(--s4);
  border-top: 2px solid var(--border);
}
.quote__source { font-weight: 600; color: var(--ink); }
.quote__link {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
@media (hover: hover) and (pointer: fine) { .quote__link:hover { text-decoration: underline; } }
/* Рейтинг набран крупнее источника — это то, за чем сюда смотрят. */
.quote__rating {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.quote__score {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1;
  color: var(--primary);
}

@media (max-width: 860px) {
  .quote { grid-template-columns: 1fr; gap: var(--s8); }
}
@media (max-width: 640px) { .review { padding-block: var(--s16); } }

/* ============ 9 · КОНТАКТЫ ============ */
.contacts {
  background: var(--panel);
  color: var(--on-panel);
  border-radius: var(--r-xl);
  margin-inline: var(--gutter);
  padding-block: var(--s32);
}
.contacts__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  max-width: 20ch;
}
/* Закрывающая секция держит три вещи разом: заявку, координаты и карту.
   Форма слева и крупнее — это единственное действие на странице, которое
   можно совершить, не выходя из неё. */
.contacts__layout {
  display: grid;
  grid-template-columns: minmax(340px, 36%) 1fr;
  gap: var(--s6);
  align-items: start;
  margin-top: var(--s16);
}
.contacts__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s3);
}
/* Колонки стали карточками: на тёмной панели плоский текст в четыре
   столбца читался как подвал, а это закрывающая секция. */
.contacts__block {
  background: color-mix(in srgb, var(--on-panel) 7%, transparent);
  border-radius: var(--r-lg);
  padding: var(--s6);
}
.contacts__block:first-child {
  background: var(--accent);
  color: var(--on-accent);
}
.contacts__block:first-child .contacts__label { color: var(--on-accent); opacity: 0.7; }
.contacts__label {
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s4);
}
.contacts__big {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(18px, 1.8vw, 23px);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  margin-bottom: var(--s3);
  min-height: 44px;
  letter-spacing: -0.01em;
}
.contacts__text { color: var(--on-panel); }
.contacts__muted { color: var(--panel-muted); font-size: var(--t-small); }
.contacts__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--primary-lift);
  font-weight: 600;
  text-decoration: none;
  margin-inline-end: var(--s4);
}
@media (hover: hover) and (pointer: fine) { .contacts__link:hover { text-decoration: underline; } }
.hours { border-collapse: collapse; font-variant-numeric: tabular-nums; }
.hours th, .hours td { padding-block: var(--s1); text-align: start; font-weight: 400; }
.hours th { padding-inline-end: var(--s6); color: var(--panel-muted); }
.hours td { color: var(--on-panel); }

@media (max-width: 980px) {
  .contacts__layout { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .contacts { padding-block: var(--s16); margin-inline: var(--s3); }
  .contacts__layout { margin-top: var(--s8); gap: var(--s3); }
  .contacts__grid { grid-template-columns: 1fr; gap: var(--s2); }
}

/* ============ ЗАЯВКА НА ПРИЁМ ============ */
/* ⚠️ ДЕМО: форма никуда не отправляет — см. комментарий над блоком
   в index.html. Верстается по-настоящему, чтобы её можно было
   подключить к бэкенду одной правкой обработчика. */
.booking {
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--r-xl);
  padding: var(--s8);
  /* Секция задаёт --focus: var(--accent) для тёмной панели. На белой
     карточке лайм даёт 1.31 — кольцо фокуса исчезает. Возвращаем синий. */
  --focus: var(--primary);
}
.booking__title {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
}
.booking__lead {
  margin-top: var(--s3);
  color: var(--muted);
  font-size: var(--t-small);
  max-width: 40ch;
}

.bform {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s4);
  margin-top: var(--s6);
}
.bform__row { display: grid; gap: var(--s2); min-width: 0; }
.bform__row--wide,
.bform__submit,
.bform__fine { grid-column: 1 / -1; }
.bform__label { font-size: var(--t-small); font-weight: 600; }
.bform__opt { color: var(--muted); font-weight: 400; }
.bform__input {
  font-family: inherit;
  /* Ровно 16px: на iOS поле мельче 16px заставляет Safari зумить страницу
     при фокусе, и человек оказывается на увеличенном сайте посреди заявки. */
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  /* --border здесь не годится: 1.29 на белом, рамка поля не видна
     (WCAG 1.4.11 требует 3.0). --control-line даёт 3.62. */
  border: 2px solid var(--control-line);
  border-radius: var(--r-md);
  padding: var(--s3) var(--s4);
  min-height: 48px;
  width: 100%;
}
.bform__input::placeholder { color: var(--muted); }
.bform__area { min-height: 72px; resize: vertical; padding-block: var(--s3); }
/* appearance: none здесь был бы вреден: без родной стрелки поле выбора
   ничем не отличается от текстового, и человек не понимает, что тут
   список. Нарисовать свою стрелку фоном нельзя — цвет в data-URI это
   хардкод мимо токенов. */
.bform__select { padding-inline-end: var(--s6); }
.bform__submit { margin-top: var(--s2); }
.bform__fine { font-size: var(--t-small); color: var(--muted); }
.bform__tel { color: var(--primary); font-weight: 600; }

.bform__err { font-size: var(--t-small); color: var(--danger); font-weight: 500; }
.bform__row--bad .bform__input { border-color: var(--danger); }

.booking__done { display: grid; gap: var(--s3); justify-items: start; }
.booking__done-title {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
}
.booking__done-text { color: var(--muted); max-width: 40ch; }

.booking__alt { margin-top: var(--s8); border-top: 1px solid var(--border); padding-top: var(--s6); }
.booking__alt-label {
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s3);
}
.booking__alt-row { display: flex; flex-wrap: wrap; gap: var(--s2); }
/* btn--onpanel рассчитана на тёмную подложку; здесь карточка белая,
   поэтому кнопка-ссылка перекрашивается под синюю обводку. */
.booking__alt-btn {
  background: transparent;
  color: var(--primary);
  box-shadow: inset 0 0 0 2px var(--primary);
  flex: 1 1 auto;
}
@media (hover: hover) and (pointer: fine) {
  .booking__alt-btn:hover { background: var(--surface); }
}

@media (max-width: 560px) {
  .booking { padding: var(--s6); }
  .bform { grid-template-columns: 1fr; }
}

/* ============ КАРТА ============ */
/* Тайлы OpenStreetMap, перекрашенные под палитру, пин по координатам.
   Файл лежит локально: карта не тянет ни скриптов, ни трекеров и не
   портит производительность на 4G. Атрибуция обязательна по ODbL. */
.mapcard {
  grid-column: 1 / -1;
  padding: 0;
  overflow: hidden;
  margin: 0;
}
.mapcard__link { display: block; position: relative; text-decoration: none; }
/* Полоса, а не полотно: при родных пропорциях 1280×860 карта в правой
   колонке вырастала выше формы и перевешивала секцию. Пин по центру
   кадра, поэтому object-fit: cover обрезает края, а не ориентир. */
.mapcard__img {
  display: block;
  width: 100%;
  height: clamp(200px, 26vw, 320px);
  object-fit: cover;
}
.mapcard__cta {
  position: absolute;
  inset-block-end: var(--s4);
  inset-inline-start: var(--s4);
  background: var(--primary);
  color: var(--on-primary);
  font-size: var(--t-small);
  font-weight: 600;
  padding: var(--s2) var(--s4);
  border-radius: var(--r-pill);
}
@media (hover: hover) and (pointer: fine) {
  .mapcard__cta { transition: transform var(--dur-fast) var(--ease-out); }
  .mapcard__link:hover .mapcard__cta { transform: translateY(-2px); }
}
.mapcard__caption {
  padding: var(--s2) var(--s4);
  font-size: var(--t-micro);
  color: var(--panel-muted);
}
.mapcard__caption a { color: var(--panel-muted); }

/* ============ 10 · ФУТЕР ============ */
.footer { padding-block: var(--s24) calc(var(--s24) + var(--s16)); }
.footer__inner { display: grid; gap: var(--s4); }
.footer__mark {
  font-family: var(--font-display);
  font-size: clamp(40px, 9vw, 120px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--primary);
}
.footer__line { color: var(--muted); font-size: var(--t-small); }
.footer__links { display: flex; flex-wrap: wrap; gap: var(--s6); font-size: var(--t-small); }
.footer__links a { text-decoration: none; color: var(--ink); display: inline-flex; align-items: center; min-height: 44px; }
@media (hover: hover) and (pointer: fine) { .footer__links a:hover { color: var(--primary); } }
.footer__legal { font-size: var(--t-micro); color: var(--muted); }

/* ============ мобильная липкая полоса ============ */
.stickybar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 45;
  display: none;
  gap: var(--s2);
  padding: var(--s3) var(--s3) calc(var(--s3) + env(safe-area-inset-bottom));
  background: var(--paper);
  box-shadow: 0 -8px 32px rgb(19 26 46 / 0.12);
}
.stickybar__btn { flex: 1; }
@media (max-width: 720px) {
  .stickybar { display: flex; }
  .footer { padding-bottom: calc(var(--s32) + var(--s8)); }
}
/* Пока hero на экране, полоса не нужна: в hero уже есть и «Записаться»,
   и телефон, а полоса добавляла к ним третью и четвёртую кнопку и резала
   вырез животного пополам. Класс вешает main.js по IntersectionObserver;
   без JS полоса видна всегда — это безопасный вариант по умолчанию. */
.stickybar--off {
  transform: translateY(115%);
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .stickybar { transition: transform var(--dur-base) var(--ease-out); }
}

/* ============ ОЦЕНКА СРОЧНОСТИ ============ */
/* Работает без JS: состояние держит radio, показ результата — :checked в CSS. */
.triage {
  margin-top: var(--s16);
  padding-top: var(--s12);
  border-top: 1px solid color-mix(in srgb, var(--on-panel) 18%, transparent);
}
.triage__group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.triage__legend {
  flex: 1 0 100%;
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: var(--s2);
}
/* Инструкция к списку. Стоит над пилюлями — там, где её ещё можно
   выполнить, а не под ними, где она уже неактуальна. */
.triage__hint {
  flex: 1 0 100%;
  color: var(--panel-muted);
  font-size: var(--t-small);
  margin-bottom: var(--s4);
}
.triage__radio {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.triage__option {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--s2) var(--s4);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--on-panel) 10%, transparent);
  color: var(--on-panel);
  font-size: var(--t-small);
  line-height: 1.3;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .triage__option:hover { transform: translateY(-2px); } }
.triage__radio:checked + .triage__option {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  /* выбранная пилюля лаймовая — лаймовое кольцо на ней было бы невидимо */
  --focus: var(--ink);
}
/* Фокус-кольцо на пилюле: сам radio невидим, поэтому рисуем на метке. */
.triage__radio:focus-visible + .triage__option {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

/* min-height: 190px здесь резервировал место под будущий результат, но до
   выбора это была просто дыра в 190px посреди тёмной панели. Сдвиг после
   клика инициирован самим человеком и происходит ниже пилюль — ничего
   из прочитанного не прыгает. */
/* Подсказка и все три вердикта лежат в ОДНОЙ ячейке сетки, друг поверх
   друга. Пока они были обычными блоками, в момент переключения ответа
   уходящая и приходящая карточки на четверть секунды оказывались в потоке
   одновременно: блок вырастал с 243 до 486 px и схлопывался обратно,
   а вся секция под ним дёргалась. В одной ячейке высота равна большей из
   карточек — раскладка при подмене стоит на месте. */
.triage__results {
  flex: 1 0 100%;
  margin-top: var(--s6);
  display: grid;
}
.triage__results > * { grid-area: 1 / 1; }
.triage__result {
  display: none;
  border-radius: var(--r-lg);
  padding: var(--s8);
  /* Вердикт раньше подменялся мгновенно: человек кликает пилюлю и под ней
     скачком возникает плашка в пол-экрана. Это ровно тот случай, ради
     которого движение и нужно, — смягчить резкую подмену.
     Здесь описан УХОД: старый ответ уже не нужен, он просто гаснет за
     160 мс, без сдвига — иначе уходящая и приходящая карточки едут
     навстречу друг другу и рябит. allow-discrete держит карточку в
     раскладке, пока она гаснет; где не поддержано — мгновенное скрытие. */
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out),
              display var(--dur-fast) allow-discrete;
}
.triage__result--now   { background: var(--accent); color: var(--on-accent); }
.triage__result--today { background: var(--paper);  color: var(--ink); }
.triage__result--plan  {
  background: transparent;
  color: var(--on-panel);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--on-panel) 26%, transparent);
}
.triage__verdict {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1.15;
  margin-bottom: var(--s3);
}
.triage__advice { max-width: 48ch; margin-bottom: var(--s6); }
.triage__result--today .triage__advice { color: var(--muted); }
.triage__result--plan .triage__advice { color: var(--panel-muted); }

.triage__idle {
  color: var(--panel-muted);
  font-size: var(--t-small);
  padding: var(--s8) 0;
}
/* Любая выбранная пилюля прячет подсказку и показывает свой результат. */
.triage__radio:checked ~ .triage__results .triage__idle { display: none; }
/* А это ПРИХОД: новый ответ поднимается и проявляется за 240 мс.
   Дольше ухода намеренно — уходящее внимания не требует, приходящее требует.
   Сдвиг живёт только в @starting-style: в обычном состоянии карточка
   не смещена, поэтому уход её никуда не дёргает. */
.triage__radio--now:checked   ~ .triage__results .triage__result--now,
.triage__radio--today:checked ~ .triage__results .triage__result--today,
.triage__radio--plan:checked  ~ .triage__results .triage__result--plan {
  display: block;
  opacity: 1;
  transition: opacity var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out);
}
@starting-style {
  .triage__radio--now:checked   ~ .triage__results .triage__result--now,
  .triage__radio--today:checked ~ .triage__results .triage__result--today,
  .triage__radio--plan:checked  ~ .triage__results .triage__result--plan {
    opacity: 0;
    transform: translateY(10px);
  }
}

.triage__disclaimer {
  margin-top: var(--s6);
  font-size: var(--t-micro);
  color: var(--panel-muted);
  max-width: 56ch;
}

@media (max-width: 640px) {
  .triage { margin-top: var(--s8); padding-top: var(--s8); }
  .triage__result { padding: var(--s6); }
}

/* ============ НАПРАВЛЕНИЯ ============ */
/* Связочная секция — намеренно легче основных, иначе ритм страницы плоский. */
.fields { padding-block: var(--s16); }
.fields__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.fields__lead { margin-top: var(--s6); max-width: 56ch; color: var(--muted); }
/* Мозаика направлений. Приём снят с референсов: карточки РАЗНОГО размера,
   каждая своего цвета, животное вырезано и стоит в правом нижнем углу.
   Ровная сетка одинаковых плиток читается как заготовка, а не как дизайн. */
.fields__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 210px;
  gap: var(--s3);
  margin-top: var(--s12);
}
.card {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  padding: var(--s6);
  display: flex;
  flex-direction: column;
  /* Название сверху, а не по краям: вторым полюсом у space-between был
     номер, и он раздувался до 52px. Низ карточки отдан животному —
     прижатая к низу подпись налезала бы на лапы (на «Дерматологии»
     корги накрывал хвост слова). */
  justify-content: flex-start;
  min-width: 0;
}
.card.tall { grid-row: span 2; }
.card.wide { grid-column: span 2; }

.card--accent  { background: var(--accent);  color: var(--on-accent); }
.card--primary { background: var(--primary); color: var(--on-primary); }
.card--panel   { background: var(--panel);   color: var(--on-panel); }
.card--paper   { background: var(--paper);   color: var(--ink); }
.card--surface { background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 2px var(--border); }

.card__label {
  position: relative;
  z-index: 2;
  font-size: var(--t-h3);
  font-weight: 600;
  line-height: 1.15;
  max-width: 11ch;
}
.card.wide .card__label { max-width: 16ch; }

/* Тот же разбор, что и в плитках: 52-пиксельный серый номер был самым
   крупным элементом карточки, а название направления — вдвое мельче.
   Номер уходит маркером в угол. */
.card__num {
  position: absolute;
  top: var(--s4);
  inset-inline-end: var(--s6);
  z-index: 2;
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}
/* Белый на синем при 0.7 даёт 3.40 — ниже порога 4.5 для мелкого кегля.
   На синих карточках номер идёт в полную силу (5.43). */
.card--primary .card__num { opacity: 1; }

/* Животное вырезано по контуру и упирается в нижний край карточки. */
.card__pet {
  position: absolute;
  z-index: 1;
  right: calc(-1 * var(--s3));
  bottom: 0;
  width: auto;
  height: 76%;
  object-fit: contain;
  object-position: bottom right;
  pointer-events: none;
}
.card.tall .card__pet { height: 62%; right: 0; }
.card.wide .card__pet { height: 96%; }

.card--surface { justify-content: flex-start; gap: var(--s6); }
.card__chips {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.card__chips li {
  padding: var(--s2) var(--s4);
  border-radius: var(--r-pill);
  background: var(--paper);
  font-size: var(--t-micro);
  font-weight: 500;
}

@media (max-width: 1000px) {
  .fields__grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 190px; }
  .card.wide { grid-column: span 2; }
  .card.tall { grid-row: span 2; }
}
@media (max-width: 560px) {
  /* Одна колонка растягивала семь карточек на 1230px прокрутки, и у
     «Стоматологии» с «Офтальмологией» — единственных без вырезанного
     животного — оставалось по полкарточки пустоты. Две колонки режут
     секцию почти вдвое и возвращают мозаике неровный ритм, ради
     которого она и существует.
     minmax, а не жёсткая высота ряда: карточка «Ещё принимают» с
     четырьмя чипами в фиксированный ряд не влезала, а `overflow: hidden`
     на .card молча срезал «Анестезиологию» по нижнему краю. */
  .fields__grid {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: minmax(140px, auto);
    gap: var(--s2);
    margin-top: var(--s8);
  }
  /* Пролёты пересобраны под две колонки: «Хирургия» и «Кардиология»
     на десктопе широкие, но здесь широкая карточка занимает целый ряд
     и оставляет дыру рядом с высокой соседкой. Высокими остаются две
     с самыми крупными вырезами, во всю ширину — только карточка чипов. */
  /* Классы .wide/.tall сбрасываются селектором из двух классов, поэтому
     и мобильные пролёты пишутся двумя — иначе сброс их перебивает
     и мозаика схлопывается в ровную сетку 2×4. */
  .card.wide, .card.tall { grid-column: auto; grid-row: auto; }
  .card.card--1, .card.card--3 { grid-row: span 2; }
  .card.card--7 { grid-column: span 2; }

  .card { padding: var(--s4); }
  /* Номер уходит из угла в поток над названием. В углу карточки шириной
     151px он ложился на хвост слова («Дерматология 03» читалось внахлёст),
     а на «Хирургии» его полностью закрывала голова собаки. */
  .card__num {
    position: static;
    order: -1;
    margin-bottom: var(--s1);
  }
  .card__label { font-size: var(--t-body); max-width: none; }
  /* Вырезы есть только у 01, 02, 03 и 06. Высокие карточки вдвое выше
     ряда, поэтому их животное берёт меньшую долю высоты — иначе кот
     на «Терапии» вырастает вдвое против собаки на «Хирургии» рядом. */
  .card.card--1 .card__pet, .card.card--3 .card__pet { height: 52%; right: 0; }
  .card--surface { gap: var(--s3); }
}
@media (max-width: 640px) { .fields { padding-block: var(--s16); } }

/* ============ ЧТО ВЗЯТЬ С СОБОЙ ============ */
.prep { padding-block: var(--s24); }
.prep__grid {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  gap: var(--s16);
  align-items: start;
}
.prep__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.prep__lead { margin-top: var(--s6); color: var(--muted); max-width: 40ch; }
.prep__reset { margin-top: var(--s6); }

.checklist { display: grid; gap: var(--s2); }
.checklist__item { display: flex; }
.checklist__box {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.checklist__label {
  display: flex;
  align-items: center;
  gap: var(--s4);
  width: 100%;
  min-height: 56px;
  padding: var(--s4) var(--s6);
  background: var(--paper);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out);
}
.checklist__label::before {
  content: "";
  flex: none;
  width: 22px; height: 22px;
  border-radius: 6px;
  box-shadow: inset 0 0 0 2px var(--control-line);
  background: var(--paper);
}
@media (hover: hover) and (pointer: fine) { .checklist__label:hover { transform: translateX(2px); } }
.checklist__box:checked + .checklist__label { background: var(--surface); }
.checklist__box:checked + .checklist__label::before {
  background: var(--accent);
  box-shadow: inset 0 0 0 2px var(--accent);
}
.checklist__box:checked + .checklist__label {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-color: var(--border);
}
.checklist__box:focus-visible + .checklist__label {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

@media (max-width: 860px) {
  .prep { padding-block: var(--s16); }
  .prep__grid { grid-template-columns: 1fr; gap: var(--s8); }
}

/* ============ ВОПРОСЫ ============ */
.faq { padding-block: var(--s24); }
.faq__title {
  text-wrap: balance;
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.faq__list { margin-top: var(--s12); display: grid; gap: var(--s2); }
.faq__item {
  background: var(--paper);
  border-radius: var(--r-md);
  overflow: hidden;
}
.faq__q {
  display: flex;
  align-items: center;
  gap: var(--s4);
  min-height: 64px;
  padding: var(--s4) var(--s6);
  font-size: var(--t-h3);
  font-weight: 600;
  line-height: 1.25;
  cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "";
  flex: none;
  margin-inline-start: auto;
  width: 14px; height: 14px;
  border-right: 2px solid var(--primary);
  border-bottom: 2px solid var(--primary);
  transform: rotate(45deg) translate(-3px, -3px);
  transition: transform var(--dur-base) var(--ease-out);
}
.faq__item[open] .faq__q::after { transform: rotate(225deg) translate(-3px, -3px); }
.faq__q:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; }
/* Ответ раскрывается, а не появляется рывком. Высота — единственное, что
   здесь можно анимировать: transform-эквивалента у раскрытия нет.
   Держится на interpolate-size (см. html) и ::details-content;
   где не поддержано — прежнее мгновенное раскрытие. */
.faq__item::details-content {
  block-size: 0;
  overflow: clip;
  transition: block-size var(--dur-mid) var(--ease-out),
              content-visibility var(--dur-mid) allow-discrete;
}
.faq__item[open]::details-content { block-size: auto; }
.faq__a {
  padding: 0 var(--s6) var(--s6);
  color: var(--muted);
  max-width: 68ch;
}
.faq__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) { .faq__link:hover { text-decoration: underline; } }
@media (max-width: 640px) {
  .faq { padding-block: var(--s16); }
  .faq__q { font-size: var(--t-body); }
}

@media (prefers-reduced-motion: reduce) {
  .triage__option, .checklist__label, .faq__q::after { transition: none; }
  /* Меньше движения, а не ноль: смена прозрачности остаётся — она помогает
     заметить, что появился ответ, — а сдвиг и раскрытие высоты убираем. */
  .triage__radio--now:checked   ~ .triage__results .triage__result--now,
  .triage__radio--today:checked ~ .triage__results .triage__result--today,
  .triage__radio--plan:checked  ~ .triage__results .triage__result--plan {
    transition: opacity var(--dur-mid) var(--ease-out);
  }
  @starting-style {
    .triage__radio--now:checked   ~ .triage__results .triage__result--now,
    .triage__radio--today:checked ~ .triage__results .triage__result--today,
    .triage__radio--plan:checked  ~ .triage__results .triage__result--plan {
      transform: none;
    }
  }
  .faq__item::details-content { transition: none; }
}

/* ============ движение ============ */
/* Прячем ТОЛЬКО когда движение точно доступно: класс ставит инлайновый скрипт
   в <head>, а main.js снимает его, если GSAP не приехал. Без этой защиты
   упавший CDN означал бы пустую страницу у человека в панике. */
.js-motion [data-reveal] { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .js-motion [data-reveal] { opacity: 1 !important; transform: none !important; }
  .btn { transition: none; }
  .nav { transition: none !important; }
}
