/* ==========================================================================
   ТЕРРИТОРИЯ КРАСОТЫ И СТИЛЯ — стили сайта
   Строгий чёрно-белый editorial. Один шрифт, ноль цвета, всю иерархию
   держит только размер и вес текста.

   Порядок разделов:
    1. Переменные            9. Мастера
    2. Сброс и база         10. Услуги (колористика / косметология)
    3. Типографика          11. Работы
    4. Фирменная скобка     12. Прайс
    5. Заглушки фото        13. Журнал
    6. Кнопки и ссылки      14. Контакты и форма записи
    7. Шапка и меню         15. Липкая панель, лайтбокс, «наверх»
    8. Первый экран         16. Появление при прокрутке / брейкпоинты
   ========================================================================== */

/* ==========================================================================
   1. ПЕРЕМЕННЫЕ
   ========================================================================== */
:root {
  /* Чёрно-белая палитра. Чистые #000/#FFF не берём для больших плоскостей —
     на экране это выглядит дёшево, лёгкий уход в графит/тёплый белый мягче. */
  --black:     #0A0A0A;
  --white:     #FFFFFF;
  --grey-bg:   #F2F2F2;
  --grey-text: #8C8C8C;
  --grey-line: #E0E0E0;

  /* Линия и приглушённый текст текущей секции — переопределяются по теме */
  --line:  var(--grey-line);
  --muted: var(--grey-text);
  /* Цвет ещё «не напечатанной» буквы — светлее линии, чтобы фраза
     читалась целиком и до прокрутки, но явно ждала своей очереди */
  --typeon-dim: #D8D8D8;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Ритм и сетка */
  --section-padding: clamp(80px, 12vw, 180px);
  --container: 1280px;
  --gutter: clamp(20px, 5vw, 60px);
  --header-h: clamp(80px, 11vw, 108px);

  /* Шрифты выбраны Вероникой 03.09.2026. Заголовочный — Dela Gothic One,
     тяжёлый гротеск с одним начертанием. Основной — Cormorant, антиква
     с высоким контрастом штриха и переменным весом 300–700.
     Запасные подобраны по характеру: если основной не загрузится, текст
     останется с засечками, а заголовок — плотным гротеском. */
  --font-display: 'Dela Gothic One', Impact, 'Arial Black', sans-serif;
  /* ⚠ Основной снова Cormorant — решение Вероники 05.09.2026. Первую
     попытку 03.09 откатили: «не нравится десктопная версия». Причина
     тогда была не в самом шрифте, а в кегле: у Cormorant низкие
     строчные буквы, и при размере, подобранном под гротеск, текст
     выглядел мелким и бледным. Поэтому вместе со шрифтом подняты
     размеры и межстрочное расстояние (см. --fs-* ниже).

     Commissioner оставлен в запасных: если Cormorant не загрузится,
     текст не рассыплется.

     ⚠ ОТМЕНЕНО 06.09.2026. Вероника: «мне снова не нравится как
     смотрится cormorant, поэтому возвращаем шрифт основной который был
     ранее, но начертания и жирность оставляем как есть везде, просто
     саму гарнитуру меняем». Основной снова Commissioner.
     Начертания, веса и размеры НЕ трогались — менялась только гарнитура.
     ⚠ Размеры --fs-* остались поднятыми под антикву (см. ниже): если
     текст покажется крупным, это правится отдельно и по её слову. */
  --font-accent:  'Cormorant', 'Times New Roman', serif;
  --font-body:    'Geometria', 'Commissioner', 'Onest', sans-serif;

  /* Шкала размеров — вся на clamp(), без переопределений в брейкпоинтах */
  --fs-h1:    clamp(40px, 12vw, 110px);
  --fs-h2:    clamp(28px, 7vw, 56px);
  --fs-h3:    clamp(20px, 4.5vw, 28px);
  /* ⚠ Кегль поднят 05.09.2026 вместе с переходом на Cormorant. У антиквы
     строчные буквы ниже, чем у гротеска при том же размере: 17px
     Commissioner и 17px Cormorant выглядят по-разному, второй заметно
     мельче. Прибавка 2–3px возвращает привычную величину текста. */
  --fs-body:  clamp(17px, 4.6vw, 20px);
  --fs-small: clamp(14px, 3.6vw, 16px);
}

/* ==========================================================================
   1.5 ШРИФТЫ
   Файлы лежат в /fonts, подключены локально — без запроса к Google Fonts.
   Oswald и Commissioner — переменные (variable) файлы, поэтому у обоих
   диапазон font-weight, а не одно фиксированное число: браузер сам
   берёт нужную насечку внутри диапазона под конкретный font-weight
   в CSS, отдельный файл на каждый вес не нужен.

   Файлы разрезаны по алфавитам: отдельно кириллица, отдельно латиница.
   Браузер смотрит на unicode-range и качает только тот кусок, буквы из
   которого встретились на странице. Сайт русский, поэтому латинский
   файл почти всегда остаётся нескачанным.

   Вес всех четырёх файлов вместе — 75 КБ против 330 КБ у прежней пары
   Oswald + Commissioner.
   ========================================================================== */
@font-face {
  font-family: 'Dela Gothic One';
  src: url('../fonts/DelaGothicOne-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  /* Начертание у шрифта одно. Диапазон 100–900 указан нарочно: иначе
     браузер, встретив font-weight: 700, дорисует жирность сам, и без
     того тяжёлая гарнитура поплывёт. */
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Dela Gothic One';
  src: url('../fonts/DelaGothicOne-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Commissioner';
  src: url('../fonts/Commissioner-Variable.woff2') format('woff2'),
       url('../fonts/Commissioner-Variable.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
/* Geometria Light — шрифт, выбранный Вероникой 06.09.2026 по образцу с
   сайта «Шум фена». Файл прислала она сама, установлен у неё на
   компьютере.

   ⚠ Начертание пока ОДНО — Light, вес 300. Жирных нет. Диапазон объявлен
   300–400, чтобы обычный текст (400) рисовался этим же файлом без
   подделки. Всё, что тяжелее — 600, 700, 800 — браузер утолщает сам, и
   выглядит это грязно. Нужны настоящие Regular, Medium и Bold.

   ⚠ Geometria — платный шрифт студии Brownfox. О лицензии Вероника
   предупреждена 06.09.2026, решение принято ею. */
@font-face {
  font-family: 'Geometria';
  src: url('../fonts/Geometria-Light.woff2') format('woff2');
  font-weight: 300 400;
  font-style: normal;
  font-display: swap;
}
/* Medium и Bold прислала Вероника 06.09.2026: «давай я загружу шрифты для
   жирных акцентов, но мы просто попробуем с ними, потому что мне может не
   понравиться».

   ⚠ Regular (400) в наборе НЕТ — её слова. Поэтому диапазоны разведены
   так, чтобы каждый вес, который есть на сайте, попал на настоящее
   начертание, а не на подделку браузера:
     100, 300, 400 → Light   (400 отдан Light, раз Regular отсутствует)
     500, 600      → Medium
     700, 800, 900 → Bold
   Без этого браузер обводил бы Light по контуру, и жирный текст выглядел
   бы размазанным. */
@font-face {
  font-family: 'Geometria';
  src: url('../fonts/Geometria-Medium.woff2') format('woff2');
  font-weight: 500 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Geometria';
  src: url('../fonts/Geometria-Bold.woff2') format('woff2');
  font-weight: 700 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Cormorant';
  src: url('../fonts/Cormorant-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Cormorant';
  src: url('../fonts/Cormorant-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   2. СБРОС И БАЗА
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--white);
  color: var(--black);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  /* 300 у Cormorant — волосяной, на экране он «пропадает». Рабочий вес
     антиквы для основного текста — 400. */
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

img, svg { display: block; max-width: 100%; }
[hidden] { display: none !important; }

ul, ol, dl, dd { margin: 0; padding: 0; list-style: none; }
figure, blockquote, p, h1, h2, h3 { margin: 0; }
button { font: inherit; color: inherit; }
a { color: inherit; }
input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

/* Текст, который видит только поисковик и читалка для незрячих: с экрана
   убран, из разметки — нет. Понадобился 05.09.2026, когда с блока
   «О студии» сняли видимый заголовок. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Знак студии под текстом «О студии». Металл на белом фоне гасим тем же
   приёмом, что в шапке и подвале, — иначе светлый знак почти пропадает. */
/* Знак студии из блока убран 05.09.2026: на его место встала цитата.

   ⚠ На телефоне цитата должна остаться там, где была раньше, — в самом
   низу блока, после ленты кадров. В разметке она теперь лежит внутри
   текстовой колонки (так её требует компьютер), поэтому на узком экране
   раскладку разбираем: display: contents убирает обёртки из потока, и
   все части блока становятся соседями. Тогда порядком можно управлять
   напрямую — цитата уходит последней.

   Отступ, который давала обёртка .about__text, возвращаем лиду вручную:
   вместе с обёрткой из раскладки уходит и её margin. */
@media (max-width: 767px) {
  #about > .container { display: flex; flex-direction: column; }
  .about__grid,
  .about__text { display: contents; }
  .section-head { order: 0; }
  /* Лид идёт первым, до фотографии — правка Вероники 05.09.2026:
     раздел открывается фразой, кадр следом. */
  .about__lead { order: 1; margin-bottom: clamp(20px, 5vw, 28px); }
  .about__photo { order: 2; }
  .about__text .prose { order: 3; margin-top: clamp(24px, 5vw, 32px); }
  /* ⚠ Обёртка .about__point тоже участвует в раскладке напрямую (у
     .about__text стоит display: contents), поэтому место ей задаётся
     наравне с остальными. Без этого блок с подзаголовком уезжал в начало
     раздела, выше фотографии. */
  .about__note,
  .about__point { order: 4; }
  /* ⚠ Ролики-знакомства (28.09.2026) — тоже прямой ребёнок контейнера,
     значит место им нужно задать наравне с остальными. Без этого они
     получают order: 0 и уезжают в самое начало блока, выше заголовка. */
  .about__reels { order: 5; }
  /* Блок, который идёт после ленты кадров, — там же, где прежде стояла
     цитата (06.09.2026 она разобрана на заголовок и абзац). */
  .about__point--after-strip { order: 7; }
  .about__strip { order: 6; }
  .about__quote { order: 7; }
}

/* Ссылка «Перейти к содержанию» убрана 05.09.2026 по указанию Вероники.
   Она была невидимой и появлялась только при обходе сайта с клавиатуры
   (клавишей Tab), чтобы можно было перескочить меню и попасть сразу к
   тексту. Если понадобится вернуть — правило и тег восстанавливаются из
   этого коммита. */

/* --- Секции и контейнер --- */
.section { padding-block: var(--section-padding); position: relative; }
.section--tight { padding-top: calc(var(--section-padding) * 0.45); }

/* Разделитель между светлыми блоками. Появился 06.09.2026, когда с
   «Направлений» сняли серую подложку («убрать серую подложку в блоке
   направления, в месте разделения блоков провести черту»): без заливки
   соседние белые блоки сливались в одно полотно, и граница пропадала.

   ⚠ Правка того же дня: сначала черта шла от края до края экрана, как
   раньше шла подложка. Вероника поправила — «надо (как в контактах)
   сделать, не доводя до краёв». Поэтому ширина повторяет содержимое
   контейнера: те же поля по бокам, что у текста и у линий в контактах.

   Рисуется псевдоэлементами, а не рамкой секции: рамка тянется на всю
   ширину и укоротить её нельзя. */
/* Черта только сверху — для стыков, где у соседа снизу своей черты нет.
   Заведено 06.09.2026: между «Командой» и «О студии» разделителя не было
   вовсе, а поставить обычный section--line нельзя — снизу «О студии»
   уже стоит черта «Обучения», и линии сдвоились бы. */
.section--line-top { position: relative; }
.section--line-top::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(calc(100% - var(--gutter) * 2), calc(var(--container) - var(--gutter) * 2));
  height: 1px;
  background: var(--grey-line);
  pointer-events: none;
}

.section--line { position: relative; }
.section--line::before,
.section--line::after {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: min(calc(100% - var(--gutter) * 2), calc(var(--container) - var(--gutter) * 2));
  height: 1px;
  background: var(--grey-line);
  pointer-events: none;
}
.section--line::before { top: 0; }
.section--line::after { bottom: 0; }

.section--white { background: var(--white); color: var(--black); --line: var(--grey-line); --muted: var(--grey-text); --typeon-dim: #DCDCDC; }
.section--grey  { background: var(--grey-bg); color: var(--black); --line: #D8D8D8; --muted: var(--grey-text); --typeon-dim: #D2D2D2; }
.section--black { background: var(--black); color: var(--white); --line: rgba(255,255,255,0.2); --muted: #A6A6A6; --typeon-dim: rgba(255,255,255,0.22); }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: 760px; }

[id] { scroll-margin-top: calc(var(--header-h) + 8px); }

/* ==========================================================================
   3. ТИПОГРАФИКА
   Один гротеск — Onest. Иерархию держат вес и размер, не гарнитура.
   ========================================================================== */
h1, h2, h3 { font-family: var(--font-display); }

.h1 {
  font-size: var(--fs-h1);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1;
}
.h2 {
  font-size: var(--fs-h2);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1;
}
.h3 {
  font-size: var(--fs-h3);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.05;
}

.body-l { font-size: clamp(18px, 2.6vw, 24px); font-weight: 400; line-height: 1.45; }

/* Надзаголовок: английское слово, мелкий капс, разрежен */
.eyebrow {
  display: block;
  font-size: 12px;
  font-weight: 400;
  text-transform: lowercase;
  letter-spacing: 0.2em;
  color: var(--muted);
}

/* Подпись / caption */
.caption {
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.prose { max-width: 36em; }
.prose p + p { margin-top: 20px; }

/* Заголовок секции: номер в скобке + eyebrow + h2 настоящий (для Яндекса) */
/* ⚠ Шапка раздела по центру — правка Вероники 05.09.2026: «заголовки по
   центру, мелкий текст под заголовки». Прежде заголовок стоял у левого
   края, а пояснение на компьютере уходило во вторую колонку справа.
   Теперь и то и другое по центру, пояснение — строкой ниже. */
.section-head {
  display: flex;
  justify-content: center;
  margin-bottom: clamp(40px, 6vw, 72px);
  text-align: center;
}
.section-head__text { display: flex; flex-direction: column; align-items: center; gap: 10px; }
/* Пояснение под заголовком опущено ниже — просьба Вероники 06.09.2026
   («сделай чуть ниже текст основной под заголовком»). Было 10 точек,
   стало 18.

   Только на телефоне: на широком экране этот отступ задаётся отдельно
   (см. правило в @media min-width: 1024px ниже по файлу), и десктоп
   правка не трогает.

   Фактически действует на один блок — «Направления». Пояснение под
   заголовком есть только у него, у остальных разделов в шапке один
   элемент, и разводить там нечего. */
@media (max-width: 767px) {
  .section-head__text { gap: 18px; }
}
/* Примечание к разделу — курсивом и тише заголовка. Заведено 05.09.2026
   по референсу kate.studio: пояснение живёт при заголовке, а не отдельным
   абзацем в теле блока. На компьютере встаёт во вторую колонку шапки,
   на телефоне — строкой под заголовком. */
/* ⚠ Курсив снят 05.09.2026 везде на сайте — решение Вероники: «убрать
   везде курсив, оставить просто цвет такой бледный как есть». Разницу
   между пояснением и основным текстом теперь держит только цвет. */
.section-note {
  font-size: clamp(15px, 3.7vw, 17px);
  line-height: 1.5;
  color: var(--muted);
  /* Ширина ограничена: центрированная строка длиннее 60 знаков читается
     тяжело — глаз теряет начало следующей строки. */
  max-width: 56ch;
  margin-inline: auto;
}

/* ==========================================================================
   4. ФИРМЕННАЯ СКОБКА
   Незамкнутая рамка — приём из логотипа (линия сверху и слева, обрыв,
   отдельный штрих справа). Используется ровно в трёх местах: номер
   секции, кнопка «Записаться», рамка по углам фото в галерее при наведении.
   ========================================================================== */
.bracket {
  position: relative;
  flex: none;
}
.bracket::before {
  /* линия сверху + слева */
  content: "";
  position: absolute;
  inset: 0;
  border-top: 1px solid currentColor;
  border-left: 1px solid currentColor;
}
.bracket::after {
  /* отдельный штрих справа — намеренный разрыв, рамка не замкнута */
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 22%;
  width: 0;
  border-right: 1px solid currentColor;
}

.section-num {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  padding: 10px 10px 16px;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--muted);
  align-self: stretch;
}

/* ==========================================================================
   5. ЗАГЛУШКИ ФОТО
   ========================================================================== */
/* ⚠ Заглушка убрана целиком — правка Вероники 04.09.2026: «до загрузки
   остаётся пустое место без плейсхолдера, рамки и текста».

   Раньше здесь были серый фон, рамка и подпись с именем файла
   (data-ph). Подпись задумывалась как рабочая пометка «сюда нужен такой
   кадр», но на живом сайте она читается как поломка: гость видит
   SERVICE_BROWS.JPG вместо фотографии.

   Место под кадр сохраняется: aspect-ratio держит высоту, поэтому при
   загрузке фотографий страница не прыгает. Атрибуты data-ph в разметке
   оставлены — они не показываются, но по ним видно, какого кадра не
   хватает. */
.ph {
  position: relative;
  margin: 0;
  background: none;
  aspect-ratio: var(--ar, 4 / 5);
  overflow: hidden;
}
.ph::before, .ph::after { content: none; }
.ph img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 3;
  transition: opacity 0.5s var(--ease);
}
/* ⚠ Прячем фотографию до загрузки ТОЛЬКО при работающем JS — показать её
   обратно может лишь он (класс is-loaded). Раньше opacity: 0 стояло
   безусловно, и при неотработавшем скрипте сайт оставался вообще без
   единой фотографии: были видны одни серые заглушки с именами файлов.
   Приём тот же, что и у прелоадера выше: класс js ставится строкой в
   <head>, до отрисовки. */
.js .ph img { opacity: 0; }
.js .ph img.is-loaded { opacity: 1; }

/* Тонкая белая обводка при наведении (десктоп) — сигнал, что фото
   кликабельно/открывается в лайтбоксе. Реализовано через box-shadow,
   а не ::before/::after: у .ph оба псевдоэлемента уже заняты (рамка и
   подпись-заглушка), их повторное использование раньше приводило к тому,
   что подпись-заглушка была не видна на устройствах с мышью. */
@media (hover: hover) {
  .ph-hover { transition: box-shadow 0.3s var(--ease); }
  .ph-hover:hover,
  .ph-hover:focus-visible { box-shadow: inset 0 0 0 1px var(--white); }
}

/* ==========================================================================
   6. КНОПКИ И ССЫЛКИ
   ========================================================================== */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 14px 32px 18px 20px;
  border: 0;
  border-radius: 0;
  background: none;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease);
}
/* Кнопка построена как скобка, но с лёгкой асимметрией — левая сторона
   короче, правая длиннее (перекликается с незамкнутой рамкой логотипа,
   а не просто копирует её симметрично) */
.btn.bracket::before { bottom: 35%; }
.btn.bracket::after { bottom: 8%; }

/* ⚠ Прямоугольная кнопка — правка Вероники 04.09.2026, скобка снята со
   всех кнопок «Записаться». Рамка замкнутая, углы прямые, без
   скруглений. Отступы симметричные: у скобки правый был больше левого,
   чтобы текст не наезжал на разрыв рамки, — теперь разрыва нет. */
.btn--box {
  border: 1px solid currentColor;
  border-radius: 0;
  padding: 15px 26px;
}
.btn--block { width: 100%; justify-content: center; }

.btn--dark { color: var(--black); }
.btn--dark:hover, .btn--dark:focus-visible { background: var(--black); color: var(--white); }

.btn--light { color: var(--white); }
.btn--light:hover, .btn--light:focus-visible { background: var(--white); color: var(--black); }

/* Кнопка в шапке: без заливки, наследует цвет текущего состояния шапки
   (белый поверх геро-фото, чёрный после прокрутки) — при наведении заливка
   и текст инвертируются под то же состояние */
.btn--bare { color: inherit; }
.btn--bare:hover, .btn--bare:focus-visible { background: var(--white); color: var(--black); }
.header.is-scrolled .btn--bare:hover,
.header.is-scrolled .btn--bare:focus-visible { background: var(--black); color: var(--white); }

/* Ссылка с подчёркиванием, растущим слева направо */
.link-line {
  position: relative;
  display: inline-block;
  padding: 10px 0;
  font-size: 15px;
  text-decoration: none;
}
.link-line::before,
.link-line::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 6px;
  height: 1px;
  background: currentColor;
}
.link-line::before { opacity: 0.25; }
.link-line::after {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.link-line:hover::after,
.link-line:focus-visible::after { transform: scaleX(1); }

/* ==========================================================================
   7. ШАПКА И МЕНЮ
   ========================================================================== */
.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* Выше мобильного меню (z-index 70) — иначе открытая панель перекрывает
     шапку, а вместе с ней и крестик закрытия: закрыть меню становится
     нечем. */
  z-index: 80;
  height: var(--header-h);
  color: var(--white);
  transition: height 0.4s var(--ease), background-color 0.4s var(--ease), color 0.4s var(--ease);
}
/* Пока меню открыто, шапка всегда прозрачная с белым крестиком —
   не важно, была ли она уже белой от прокрутки. Так весь экран меню
   читается как одна сплошная чёрная панель без белой полосы сверху. */
.header.menu-open {
  background: transparent !important;
  color: var(--white) !important;
  border-bottom: 0 !important;
}
.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.header.is-scrolled {
  /* Высота задаётся переменной, а не числом: по ней же считается предел
     для логотипа (см. .logo__mark). Раньше знак в 88px не помещался в
     шапку 80px и вылезал за её границы — правка Вероники 04.09.2026. */
  --header-h: clamp(64px, 8vw, 80px);
  height: var(--header-h);
  background: var(--white);
  color: var(--black);
  border-bottom: 1px solid var(--grey-line);
}

.logo { display: inline-flex; align-items: center; color: inherit; text-decoration: none; }
/* Логотип — металлический PNG с прозрачным фоном, тот же, что стоял на
   странице журнала (решение Вероники 02.09.2026). Исходный файл был
   1080×1920 и почти весь состоял из пустых полей: обрезан по знаку и
   уменьшен — 419 КБ превратились в 114 КБ.

   invert(1) отсюда снят: он был нужен чёрному SVG, чтобы стать белым на
   тёмном фоне. Металлический знак светлый сам по себе и выворачивать
   его нельзя — вывернутый он станет тёмно-коричневым. */
.logo__mark {
  width: auto;
  /* Знак никогда не выше самой шапки: что бы ни насчитал clamp, остаётся
     запас 22px — по 11px сверху и снизу. */
  height: min(clamp(48px, 6vw, 88px), calc(var(--header-h) - 22px));
  object-fit: contain;
  flex: none;
  transition: filter 0.4s var(--ease);
}
/* Знак металлический, то есть светло-серый. На тёмном ролике он читается,
   на белом фоне почти пропадает — притемняем. Не выворачиваем (invert
   сделал бы его тёмно-коричневым), а именно гасим яркость и добавляем
   контраст: металл остаётся металлом, только темнее. */
.header.is-scrolled .logo__mark,
.footer .logo__mark { filter: brightness(0.42) contrast(1.35); }
/* Открытое мобильное меню всегда тёмное — логотип остаётся белым
   независимо от того, была ли шапка уже белой от прокрутки */
/* В открытом меню фон чёрный — металлический знак на нём и так светлый,
   выворачивать больше нечего */

.nav { display: none; }

.burger {
  position: relative;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.burger__line {
  position: absolute;
  left: 11px;
  width: 22px;
  height: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease), opacity 0.25s var(--ease);
}
.burger__line:nth-child(1) { top: 19px; }
.burger__line:nth-child(2) { top: 25px; }
.burger[aria-expanded="true"] .burger__line:nth-child(1) { transform: translateY(3px) rotate(45deg); }
.burger[aria-expanded="true"] .burger__line:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
  padding: calc(var(--header-h) + 32px) var(--gutter) calc(28px + env(safe-area-inset-bottom));
  background: var(--black);
  color: var(--white);
  --line: rgba(255,255,255,0.2);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
  overflow-y: auto;
}
.mobile-menu.is-open { opacity: 1; }
.mobile-menu__nav { display: flex; flex-direction: column; }
.mobile-menu__link {
  padding: 14px 0;
  font-family: var(--font-body);
  font-size: 28px;
  font-weight: 600;
  text-transform: uppercase;
  line-height: 1.2;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.mobile-menu__foot { display: flex; flex-direction: column; gap: 12px; }
.mobile-menu__contact {
  padding: 12px 0;
  font-size: 15px;
  letter-spacing: 0.02em;
  text-decoration: none;
  color: #C9C9C9;
}

/* ==========================================================================
   8. ПЕРВЫЙ ЭКРАН
   ========================================================================== */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100vh;
  min-height: 100dvh;
  padding: calc(var(--header-h) + 40px) var(--gutter) 96px;
  overflow: hidden;
  color: var(--white);
}
/* --ar влияет только на резервируемое место до подгрузки img (CLS) —
   сам блок растянут инсетом на всю высоту герой-секции */
.hero__media { position: absolute; inset: 0; z-index: 0; --ar: 4/5; }
@media (min-width: 768px) {
  .hero__media { --ar: 16/9; }
}
.hero__media img { filter: brightness(0.6); }
.hero__media::after { align-items: flex-start; padding-top: 96px; color: rgba(0,0,0,0.4); background: #D9D9D9; }

/* Ролик заполняет первый экран целиком. object-fit: cover обрежет лишнее,
   но обрезать почти нечего: кадр 9:16 совпадает с пропорцией телефона.
   Затемнение — то же, что было у фото: текст лежит поверх. */
.hero__video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.6);
  background: var(--black);
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(10,10,10,0.35) 0%, rgba(10,10,10,0.1) 35%, rgba(10,10,10,0.92) 100%);
}
.hero__inner { position: relative; z-index: 2; max-width: var(--container); width: 100%; margin-inline: auto; }
/* Название на первом экране. Лёгкое начертание вместо жирного —
   правка Вероники 03.09.2026: рядом с роликом жирный заголовок спорил
   с вывеской в кадре. Строчные буквы не берём: знак и вывеска набраны
   прописными, надпись должна быть с ними одной семьёй. */
.hero__title {
  max-width: 14ch;
  font-family: var(--font-display);
  font-size: clamp(30px, 8vw, 60px);
  font-weight: 300;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.hero__eyebrow { color: #D9D9D9; margin-bottom: 20px; }
/* Строка под названием — основным шрифтом, не заголовочным: указание
   Вероники 03.09.2026. Заголовок набран Oswald прописными, эта строка
   Commissioner строчными, и разница шрифтов держит их как две разные
   ступени, а не как один длинный заголовок. */
.hero__sub {
  margin-top: 14px;
  max-width: 24ch;
  font-family: var(--font-body);
  font-size: clamp(17px, 4.3vw, 22px);
  font-weight: 400;
  line-height: 1.35;
}
.hero__place { margin-top: 16px; color: #C9C9C9; }
.hero__actions { margin-top: 32px; }

/* ⚠ ПЕРВЫЙ ЭКРАН НА ТЕЛЕФОНЕ — по референсу kate.studio, присланному
   Вероникой 04.09.2026: строка-подводка сверху, крупное название по
   центру, под ним кнопка.

   Порядок в разметке не меняется — h1 остаётся первым элементом, иначе
   поисковики получат страницу, начинающуюся с описания вместо названия.
   Меняется только порядок показа (order): так видит человек, а робот
   читает разметку.

   Название уменьшено (8vw → 7vw): по центру строка длиннее, чем при
   выключке влево, и прежний кегль разносил его на четыре строки. */
.hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* Кегль уменьшен 05.09.2026 по указанию Вероники, и ещё раз 06.09.2026
   при возврате названия студии: «только шрифтом чуть поменьше».
   На телефоне 375px было 24px, стало 21px. */
.hero__title { max-width: 15ch; font-size: clamp(21px, 5.4vw, 42px); }
.hero__sub {
  order: -1;
  margin-top: 0;
  margin-bottom: 16px;
  /* Строка должна стоять в один ряд — указание Вероники 05.09.2026.
     Ограничение по ширине снято, перенос запрещён, а кегль привязан к
     ширине экрана: на самых узких телефонах строка ужимается, но не
     ломается пополам. */
  max-width: none;
  white-space: nowrap;
  font-size: clamp(13px, 3.6vw, 21px);
  color: #E4E4E4;
}

/* ==========================================================================
   ПЕРВЫЙ ЭКРАН НА БОЛЬШОМ ЭКРАНЕ — ДВЕ КОЛОНКИ
   Решение Вероники 02.09.2026. Ролик снят вертикально, 9:16 — то есть
   под телефон. Там он и работает во весь экран: пропорция кадра совпала
   с пропорцией экрана, ничего не обрезается.

   На компьютере растягивать вертикальный кадр на всю ширину нельзя:
   либо срежет голову, либо замылит. Поэтому от 900px первый экран
   становится двухколонным — слева текст и кнопка, справа ролик в своей
   родной пропорции, высотой почти во весь экран. Ничего не теряется, и
   композиция выглядит осознанной, а не вынужденной.

   ⚠ Пока ролика нет, в правой колонке стоит нынешнее фото. Оно
   горизонтальное, поэтому в вертикальной рамке обрезано по краям —
   это временно и уйдёт вместе с появлением файла.
   ========================================================================== */
@media (min-width: 900px) {
  /* ⚠ Переделано 04.09.2026. Было: ролик стоял отдельной колонкой в своей
     пропорции 9:16, с белыми полями сверху и снизу. Вероника: «мне не
     нравится, что на компьютере видео сбоку и как в рамке», из двух
     предложенных ею вариантов взят первый — растянуть ролик на половину
     первого экрана.

     Теперь ролик занимает всю правую половину: от верха до низа экрана и
     до самого края монитора, без полей. Рамки не остаётся, потому что
     нет ни одной белой полосы вокруг кадра. Текст живёт в левой половине,
     прижатой к ширине контейнера, — на широком мониторе он не уезжает
     к краю. */
  .hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Правая половина отдана ролику, поэтому справа отступ на пол-экрана
       плюс воздух, чтобы строка не упиралась в кадр. */
    padding: calc(var(--header-h) + 32px)
             calc(50% + clamp(24px, 3vw, 64px))
             56px
             max(var(--gutter), calc((100% - var(--container)) / 2));
    background: var(--white);
    color: var(--black);
  }
  /* Тёмная вуаль поверх всего кадра больше не нужна — текст ушёл с
     картинки. Но с тех пор как ролик занял правую половину, под шапкой
     оказался кадр, и чёрные буквы меню на нём тонули. Тот же псевдоэлемент
     переиспользован под светлое смягчение вверху ролика: сверху почти
     белое, книзу сходит на нет. Меню читается, кадр не «замылен». */
  .hero::before {
    display: block;
    top: 0;
    right: 0;
    left: auto;
    bottom: auto;
    width: 50%;
    height: calc(var(--header-h) + 56px);
    background: linear-gradient(to bottom,
                rgba(255,255,255,0.92) 0%,
                rgba(255,255,255,0.75) 45%,
                rgba(255,255,255,0) 100%);
    z-index: 1;
  }

  .hero__media {
    /* Прижат к правому краю экрана и растянут по высоте. aspect-ratio
       снят намеренно: пропорцию теперь задаёт сам экран, а лишнее
       обрезается (object-fit: cover у ролика). */
    position: absolute;
    inset: 0 0 0 auto;
    width: 50%;
    height: 100%;
    aspect-ratio: auto;
  }
  /* Затемнение снято: кадр больше не подложка под текст, а самостоятельный
     объект. object-position смещён вправо — там, где на нынешнем фото
     лицо; с вертикальным роликом строка не понадобится */
  /* На компьютере ролик стоит в своей колонке и текста поверх нет —
     затемнять нечего. object-position нужен был горизонтальному фото в
     вертикальной рамке; вертикальный кадр встаёт ровно. */
  .hero__media img,
  .hero__media video { filter: none; object-position: center; }

  .hero__inner {
    max-width: 34ch;
    margin-inline: 0;
    /* Центрирование и перестановка строки — только для телефона:
       на компьютере колонка стоит слева, и порядок обычный. */
    align-items: flex-start;
    text-align: left;
  }
  /* На телефоне строка светлая — она лежит поверх тёмного ролика.
     На компьютере фон белый, и тот же светлый серый на нём почти не
     виден: возвращаем обычный серый текста. */
  .hero__sub { order: 0; margin-top: 14px; margin-bottom: 0; white-space: normal; color: var(--grey-text); }
  .hero__title { font-size: clamp(36px, 4.4vw, 64px); }
  .hero__sub { font-size: clamp(17px, 1.5vw, 21px); }
  .hero__eyebrow,
  .hero__place { color: var(--grey-text); }
  .hero__actions .btn--light { color: var(--black); }
  .hero__actions .btn--light:hover,
  .hero__actions .btn--light:focus-visible { background: var(--black); color: var(--white); }

  /* Стрелка «листать вниз» уходит из центра под левую колонку: по центру
     она оказалась бы поверх ролика */
  .hero__scroll {
    left: max(var(--gutter), calc((100% - var(--container)) / 2));
    margin-left: 0;
    color: var(--black);
  }

  /* ⚠ Шапка уезжает при прокрутке вниз и возвращается при движении вверх
     — правка Вероники 04.09.2026. Только на компьютере: на телефоне
     шапка низкая, места отнимает мало, а прыгающая полоса при инерции
     прокрутки раздражает сильнее, чем помогает.

     Класс is-hidden ставит js/main.js (раздел про шапку). */
  .header { transition: height 0.4s var(--ease), background-color 0.4s var(--ease), color 0.4s var(--ease), transform 0.35s var(--ease); }
  .header.is-hidden { transform: translateY(-100%); }

  /* Шапка стоит на белом: буквы чернеют, знак притемняется */
  .header:not(.is-scrolled):not(.menu-open) { color: var(--black); }
  .header:not(.is-scrolled):not(.menu-open) .logo__mark { filter: brightness(0.42) contrast(1.35); }
}

.hero__scroll {
  position: absolute;
  left: 50%;
  bottom: 28px;
  z-index: 2;
  width: 44px;
  height: 44px;
  margin-left: -22px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  color: var(--white);
  animation: hero-pulse 3s var(--ease) infinite;
}
.hero__scroll svg { width: 12px; height: 34px; }
@keyframes hero-pulse {
  0%, 78%, 100% { opacity: 0.5; transform: translateY(0); }
  88%           { opacity: 1;   transform: translateY(6px); }
}

/* ==========================================================================
   9. О СТУДИИ — типографика с двумя кадрами атмосферы
   Фото не собраны в отдельную галерею, а вклиниваются между смысловыми
   кусками текста: вертикальный идёт рядом с лидом (от 1024px — в правой
   колонке, до неё — сразу после списка специалистов), широкий встаёт
   паузой перед цитатой. Пропорция каждого задана через --ar прямо в
   разметке, механика заглушки общая — см. раздел 5.
   ========================================================================== */
.about__lead { max-width: 22em; }

.about__photo { margin: 0; }

/* Приветствие в начале «О студии» — бледный знак и фраза капсом.
   Собрано 06.09.2026 по описанию Вероники и её референсу (kate.studio). */
.about__welcome {
  display: grid;
  justify-items: center;
  gap: clamp(18px, 4vw, 26px);
  margin-bottom: clamp(28px, 6vw, 44px);
  text-align: center;
}
/* Знак светлый по файлу, поэтому на белом фоне его сначала притемняем тем
   же фильтром, что в шапке и подвале, и только потом гасим до бледного. */
.about__mark {
  width: clamp(72px, 18vw, 104px);
  height: auto;
  filter: brightness(0.42) contrast(1.35);
  opacity: 0.28;
}
.about__hello {
  margin: 0;
  max-width: 18em;
  font-size: clamp(17px, 4.4vw, 24px);
  font-weight: 500;
  line-height: 1.35;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Затемнение и подпись на большом кадре — как на плитках «Направлений».
   ⚠ .ph гасит оба псевдоэлемента (content: none), поэтому градиент
   возвращаем явно. z-index выше самой фотографии (у неё 3), иначе снимок
   перекроет и заливку, и подпись. */
.about__photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  /* ⚠ Затемнение усилено 06.09.2026 по просьбе Вероники. Фон этого кадра
     светло-серый, и белая подпись читалась слабее, чем на плитках
     «Направлений», где снимки темнее. Тень начинается выше (45% вместо
     55%) и к низу гуще (0,85 вместо 0,72): буквы держатся уверенно, сама
     фотография почти не темнеет. Плиток «Направлений» это не касается,
     у них своё правило ниже по файлу. */
  background: linear-gradient(180deg, rgba(10,10,10,0) 45%, rgba(10,10,10,0.85) 100%);
  pointer-events: none;
}
/* Блоки «подзаголовок капсом + абзац» — по референсу Вероники 06.09.2026.
   Заголовок набирается основным шрифтом, а не заголовочным: на референсе
   это гротеск того же семейства, что и текст, только плотнее и капсом.
   Гарнитуру не меняем, берём тот же --font-body. */
/* Отступ, который прежде давал сам абзац (.about__note, margin-top 20px),
   переехал на обёртку: внутри неё абзац идёт вплотную за подзаголовком,
   а воздух нужен перед всем блоком. Без этого подзаголовок прилипал к
   нижнему краю фотографии. */
.about__point { margin-top: clamp(26px, 5.5vw, 36px); }
.about__point + .about__point { margin-top: clamp(24px, 5vw, 34px); }
.about__point-title {
  margin: 0 0 10px;
  font-family: var(--font-body);
  font-size: clamp(15px, 3.9vw, 18px);
  font-weight: 600;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--black);
}
.about__point .about__note { margin-top: 0; }
/* Блок с подзаголовком используется и в «Обучении» — 06.09.2026. Там
   абзац размечен классом .prose, поэтому убираем и его верхний отступ:
   иначе между подзаголовком и текстом появлялся лишний зазор. */
.about__point .prose { margin-top: 0; }
/* ⚠ И даём блоку воздух снизу — только в «Обучении». После него идёт
   строка «Обучение доступно по двум направлениям», и вплотную она
   читалась как продолжение абзаца, а не как начало нового списка.
   В «О студии» такого соседа нет, поэтому правило точечное. */
.edu-text .about__point { margin-bottom: clamp(28px, 6vw, 40px); }

.about__photo-caption {
  position: absolute;
  z-index: 6;
  left: clamp(16px, 4vw, 28px);
  right: clamp(16px, 4vw, 28px);
  bottom: clamp(14px, 3.5vw, 24px);
  color: var(--white);
  font-size: clamp(15px, 3.8vw, 19px);
  line-height: 1.35;
}

/* На узких экранах колонки нет — кадр просто продолжает текст, поэтому
   ему нужен свой отступ сверху. Брейкпоинт ровно 768px: именно там
   .about__grid становится сеткой (см. «ПЛАНШЕТ — от 768px»), и с этого
   же места фото должно выравниваться по верху вместе с текстом
   (align-items: start), а не висеть на отступе */
/* Раскладка по макету, присланному Вероникой 03.09.2026: большой кадр
   слева, текст справа, под ними лента из четырёх маленьких.

   На телефоне колонки складываются в одну — сначала кадр, потом текст.
   Лента из четырёх в строку на 375px дала бы кадры по 80px, поэтому там
   она становится сеткой 2×2: кадр 160px ещё можно рассмотреть. */
.about__text { margin-top: clamp(28px, 6vw, 40px); }
/* Лид набран заголовочным шрифтом — правка Вероники 04.09.2026. Прежний
   довод («заголовочным шрифтом фраза в тридцать слов превращается в
   стену») снят вместе с самой фразой: она сократилась вдвое, и на
   полутора строках Dela Gothic читается как врез, а не как стена.

   ⚠ Dela Gothic примерно на треть шире Commissioner при том же кегле,
   поэтому рост размера умеренный: 30px вместо 24px даёт прибавку
   заметно больше, чем кажется по числам. Межстрочное ужато с 1,45 до
   1,15 — у крупного плотного шрифта прежний интервал разваливает фразу
   на отдельные строки. */
/* ⚠ 05.09.2026: лид набирается основным шрифтом в жирном начертании —
   указание Вероники. Прежде здесь стоял заголовочный Dela Gothic; рядом
   с антиквой в тексте он читался как чужой. Cormorant 700 держит ту же
   роль врезки, но остаётся одной семьёй с абзацами под ним.

   Кегль поднят: у антиквы строчные ниже, и 30px Dela Gothic по величине
   равны примерно 34px Cormorant. Межстрочное чуть просторнее — у
   антиквы длинные выносные элементы. */
.about__lead {
  font-family: var(--font-body);
  font-size: clamp(23px, 5.4vw, 34px);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0;
  text-wrap: balance;
}

/* Названия специальностей — на ступень плотнее основного текста (300),
   но не жирные: выделяем перечисление, а не кричим. */
/* У антиквы разница между 500 и 400 почти не видна — для выделения
   специальностей берём 600 (правка вслед за сменой шрифта 05.09.2026). */
.about__role { font-weight: 600; }

/* Последний абзац — тише остального текста: это не описание услуг, а
   интонация. Фиксированные 16px по указанию Вероники 04.09.2026. */
.about__note {
  margin-top: 20px;
  max-width: 36em;
  /* 16px были заданы под Commissioner. У Cormorant строчные ниже, и на
     том же кегле абзац проваливается — 17px возвращают его к прежней
     величине на глаз (правка вслед за сменой шрифта 05.09.2026). */
  /* ⚠ 05.09.2026: абзац больше не «тихий». Вероника: «сделать
     начертанием обычного текста, не таким тонким и бледным». Цвет и вес
     теперь как у остального текста, отдельным его держит только размер
     и отступ. */
  font-size: 17px;
  line-height: 1.5;
}
.about__text .prose { margin-top: 16px; }
.about__actions { margin-top: clamp(28px, 5vw, 36px); }

/* Прежний список «в студии работают» и кнопка записи убраны совсем
   03.09.2026 — вместе с ними ушло и правило, прятавшее их на телефоне.
   Новый список пришёл с текстом Вероники: это не перечень должностей, а
   часть её текста, и прятать его нельзя. */

.about__strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: clamp(40px, 8vw, 64px);
}

/* Ролики-знакомства владелиц — 28.09.2026. Приём и стили те же, что у
   роликов в «Обучении» (.edu-reels): два вертикальных кадра 9:16 рядом,
   без звука, звук по кнопке. Здесь задаются только отступы.

   ⚠ Селектор из двух классов нарочно: у .edu-reels отступы записаны
   сокращённо (margin: 0 0 …), а такая запись обнуляет и боковые, и
   верхний. Правило с одним классом она бы перебила, и ролики прилипли
   бы к тексту и к левому краю. */
/* ⚠ 28.09.2026 промежуток увеличен по правке Вероники: «сделай отступ
   побольше между текстом „Ваш комфорт — наш приоритет“ и роликами».
   Было 40 точек на телефоне и 64 на компьютере, стало 64 и 104: текст
   и ролики читались как один кусок, теперь между ними пауза. */
.edu-reels.about__reels { margin-top: clamp(64px, 13vw, 104px); }
/* ⚠ 28.09.2026: ролики знакомства — в цвете, правка Вероники «ролики
   цветные делаем». Чёрно-белый снимает общее правило .edu-reel__video,
   здесь оно отменяется. В «Обучении» ролики остаются чёрно-белыми —
   это её отдельное решение от 25.09.
   ⚠ Ролик Натальи выглядит чёрно-белым и так: он снят и смонтирован
   в этой манере, цвета в самом файле нет. */
.about__reels .edu-reel__video { filter: none; }
@media (min-width: 768px) {
  /* На компьютере два ролика во всю ширину смотрелись бы как баннер:
     держим их в половине полосы и ставим по центру. */
  .edu-reels.about__reels { max-width: 620px; margin-inline: auto; }
}
@media (min-width: 600px) {
  .about__strip { grid-template-columns: repeat(4, 1fr); gap: 16px; }
}
/* Маленькие кадры кликабельны — курсор должен об этом говорить */
.about__thumb { cursor: pointer; }

/* Цитата — отдельная пауза в тексте, а не продолжение абзаца: собственный
   отступ сверху и снизу (не зависит от margin соседних элементов).
   Курсив снят 05.09.2026: на сайте его больше нет нигде. */
.about__quote {
  /* Цитата живёт в текстовой колонке, а не отдельной полосой внизу
     блока, поэтому отступ сверху скромнее прежнего (правка 05.09.2026). */
  margin: clamp(28px, 5vw, 40px) 0 0;
  max-width: 26em;
  font-family: var(--font-body);
  /* Кегль уменьшен 04.09.2026 по указанию Вероники: было в 1,4 раза
     крупнее основного текста, цитата спорила с абзацами над ней. */
  /* Ещё мельче — правка Вероники 05.09.2026. */
  font-size: calc(var(--fs-body) * 0.95);
  font-weight: 400;
  line-height: 1.4;
  color: var(--grey-text);
}
@media (min-width: 768px) {
  .about__quote { margin: clamp(32px, 4vw, 48px) 0 0; }
}

/* ==========================================================================
   10. МАСТЕРА
   Сетка из четырёх одинаковых карточек (.masters-grid > .master-card):
   портрет 4:5, единая типографика. Раньше карточки делились на крупные
   (совладелицы) и компактные (команда) через модификаторы --lead/--compact
   на 6-колоночной сетке — после того как в блоке осталось четверо и все
   одного размера, оба модификатора стали мёртвыми и убраны вместе с
   6-колоночной раскладкой. Теперь: 2 в ряд до 1024px, 4 в ряд от 1024px.
   ========================================================================== */
.founders__label { margin-top: 4px; }
@media (min-width: 768px) {
  /* На большом экране карточки больше не делятся на крупные/компактные —
     подпись «основательницы студии» над двумя из пяти перестаёт быть
     понятной композиционно, поэтому от 768px её прячем. */
  .founders__label { display: none; }
}

/* ⚠ НА ТЕЛЕФОНЕ — ЛЕНТА, КОТОРУЮ ЛИСТАЮТ ВБОК. Правка Вероники
   04.09.2026 по референсу kate.studio: «не делать их рядами, сделать так,
   чтобы можно было листать, а ниже все три маленькие плитки мастеров».

   Раньше здесь было два столбца по 8px между ними: на 375px карточка
   выходила 175px, портрет читался с трудом, а третий мастер висел один
   во втором ряду. Теперь карточка занимает 82% ширины экрана — почти
   весь экран, но край следующей видно, и понятно, что лента листается.

   ⚠ Про «потряхивает» — замечание Вероники о прокрутке в референсе.
   Дёргает обычно из-за жёсткого прилипания (mandatory): палец ещё ведёт
   ленту, а браузер уже тащит её к ближайшей карточке, и они спорят.
   Здесь взят мягкий режим (proximity): прилипание срабатывает, только
   когда карточка и так почти на месте. Плюс overscroll-behavior — чтобы
   лента не «пробрасывала» жест на прокрутку всей страницы, отчего экран
   и подрагивает вертикально. */
.masters-grid {
  display: flex;
  gap: 10px;
  margin-top: 20px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* лента идёт от края до края экрана, а не внутри полей страницы */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scroll-padding-inline: var(--gutter);
}
.masters-grid::-webkit-scrollbar { display: none; }
.masters-grid > .master-card {
  flex: 0 0 82%;
  scroll-snap-align: start;
}

/* Полоса из трёх миниатюр под лентой: показывает, сколько всего мастеров
   и на ком ты сейчас. Активная — в полную силу, остальные приглушены. */
.masters-thumbs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 14px;
}
.masters-thumb {
  padding: 0;
  border: 0;
  background: none;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  cursor: pointer;
  opacity: 0.4;
  transition: opacity 0.35s var(--ease);
}
.masters-thumb.is-active { opacity: 1; }
.masters-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 20%;
  filter: grayscale(1);
}

/* На компьютере всё как было: обычная сетка, миниатюры не нужны —
   все карточки и так видны разом. */
@media (min-width: 768px) {
  .masters-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(32px, 4vw, 56px);
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
  .masters-grid > .master-card { flex: none; }
  .masters-thumbs { display: none; }
}
/* В ряд — только с 1024px: на планшете карточка ужимается примерно до
   145px по ширине, и портрет 4:5 перестаёт читаться. До 1024px — 2 в ряд.

   ⚠ Колонок ровно столько, сколько мастеров. Было четыре — с тех пор как
   мастеров стало трое, справа зияла пустая четверть (правка Вероники
   04.09.2026: «на десктопе смотрится плохо»). Если состав снова
   изменится, править здесь. */
@media (min-width: 1024px) {
  .masters-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Присланные портреты не все 4:5: у Яны и Валентина кадр уже (0.65 и 0.67
   против нужных 0.80), и object-fit: cover срезает по ~9% сверху и снизу —
   ровно по макушке (пучок волос и шапка соответственно). Сдвигаем точку
   кадрирования вверх: срез идёт снизу, где только пол и столешница.
   Когда портреты пересоберут строго в 4:5, правило станет безвредным —
   при совпадающей пропорции обрезать нечего. */
.master-card__media img { object-position: 50% 20%; }

/* Типографика карточки — бывшая «крупная»: после удаления --compact
   мельчить больше нечего, поэтому значения сложены в базовые правила */
.master-card__media { margin-bottom: 16px; }
.master-card__name { margin-top: 8px; font-size: clamp(16px, 4vw, 24px); font-weight: 600; line-height: 1.15; }
/* Должность стоит вплотную к имени: это подпись к нему, а не отдельная
   строка. Было margin-top 4px при line-height имени 1.25 — между ними
   набегал заметный провал (правка Вероники 04.09.2026). */
.master-card__role { margin-top: 2px; font-weight: 400; line-height: 1.3; }

@media (min-width: 768px) {
  .master-card__name { margin-top: 16px; font-size: clamp(18px, 2.5vw, 24px); }
  .master-card__role { margin-top: 3px; }
}

/* ==========================================================================
   11. УСЛУГИ — «Услуги» и «Цены» в одном блоке. Три раздела, каждый со своим
   кликабельным фото; клик раскрывает список услуг с ценами. Открыт может
   быть только один раздел одновременно (переключается в main.js).
   ========================================================================== */
/* Было 3 в ряд на любом экране. С Dela Gothic это перестало работать:
   шрифт заметно шире прежнего, и в плитке 106px названия ломались
   посередине слова — «КОЛОРИС / ТИКА», «КОСМЕТО / ЛОГИЯ». Ниже 600px
   плиток теперь две в ряд, и названия встают в строку. */
.service-cats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: start;
  gap: 10px;
  margin-top: clamp(32px, 6vw, 64px);
}
@media (min-width: 600px) {
  .service-cats { grid-template-columns: repeat(3, 1fr); gap: 16px; }
}
@media (min-width: 768px) {
  .service-cats { gap: clamp(24px, 3vw, 40px); }
}

.services__note { max-width: 34em; }

.service-cat__btn {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}
.service-cat__media { display: block; }
/* Затемняющая подложка снизу, чтобы название читалось на любом фото */
.service-cat__media::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Выше .ph img (z-index 3) — иначе загруженное фото перекроет градиент
     и подпись перестанут быть видны поверх снимка. */
  z-index: 5;
  background: linear-gradient(180deg, rgba(10,10,10,0) 55%, rgba(10,10,10,0.72) 100%);
  transition: background-color 0.3s var(--ease);
  pointer-events: none;
}
/* Лёгкое затемнение при наведении — сигнал, что фото кликабельно */
@media (hover: hover) {
  /* Заливку при наведении не меняем: круг тёмный, а фон блока светлый —
     подмена цвета делала бы его невидимым. Приглушаем целиком. */
  .soc:hover, .soc:focus-visible { opacity: 0.72; }
}
@media (hover: hover) {
  .service-cat__btn:hover .service-cat__media::before,
  .service-cat__btn:focus-visible .service-cat__media::before {
    background: linear-gradient(180deg, rgba(10,10,10,0.15) 0%, rgba(10,10,10,0.8) 100%);
  }
}
.service-cat__name {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 6;
  color: var(--white);
  font-family: var(--font-display);
  /* Шкала пересчитана под Dela Gothic: он шире Oswald примерно на треть */
  font-size: clamp(11px, 3.1vw, 22px);
  font-weight: 700;
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  overflow-wrap: break-word;
}
@media (min-width: 600px) {
  .service-cat__name { left: 12px; right: 12px; bottom: 10px; }
}
@media (min-width: 768px) {
  .service-cat__name { left: 18px; right: 18px; bottom: 16px; font-size: clamp(15px, 2vw, 22px); }
}

/* Раскрытие через grid-template-rows: 0fr → 1fr, плавно и без max-height */
.service-cat__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease);
}
.service-cat__panel.is-open { grid-template-rows: 1fr; }
.service-cat__inner { overflow: hidden; min-height: 0; }
/* Работы внутри раскрытой услуги: четыре кадра лентой над списком.
   Решение Вероники 03.09.2026 — работы уходят внутрь услуг, отдельного
   блока портфолио больше нет.

   Две в ряд на телефоне: четыре дали бы кадры по 78px даже при том, что
   панель занимает всю ширину. От 600px — четыре в ряд. */
.works-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: clamp(24px, 4vw, 32px);
}
@media (min-width: 600px) {
  .works-strip { grid-template-columns: repeat(4, 1fr); gap: 14px; }
}
.work-thumb { cursor: pointer; }

.service-cat__inner > *:first-child { margin-top: clamp(24px, 4vw, 40px); }
.service-cat__inner > *:last-child { margin-bottom: clamp(8px, 2vw, 16px); }
.service-cat__inner .link-line { margin-top: 20px; }

/* Открытая плитка: подложка темнее, чем при наведении. Список прайса
   теперь стоит не под самой плиткой, а под всей сеткой, поэтому по
   плиткам должно быть видно, чей это список. */
.service-cat__btn[aria-expanded="true"] .service-cat__media::before {
  background: linear-gradient(180deg, rgba(10,10,10,0.35) 0%, rgba(10,10,10,0.88) 100%);
}

/* Заголовок открытого раздела — та же типографика, что у названия на
   плитке, только тёмная: связывает список с плиткой, на которую нажали. */
.service-panel__title {
  font-family: var(--font-display);
  font-size: clamp(20px, 3.4vw, 28px);
  font-weight: 700;
  line-height: 1.05;
  text-transform: uppercase;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--dark);
}

/* ==========================================================================
   ОБУЧЕНИЕ ДЛЯ МАСТЕРОВ
   Карточки без фото: снимков с обучения пока нет, а серые заглушки в
   шестом блоке подряд читались бы как поломка. Держится на типографике —
   заголовок, строка условий, описание, — как блок «О студии».

   Сетка та же, что у мастеров: одна колонка на телефоне, три от 768px.
   Не четыре: курсов мало, четвёртая колонка оставила бы дыру.
   ========================================================================== */
/* Названия направлений набраны спокойно — основным шрифтом, не
   заголовочным и не прописными (правка Вероники 03.09.2026: «выделить,
   но не акцентно»). Нажимается только кнопка «Подробнее»: у неё есть
   слово, объясняющее, что произойдёт, а у названия его не было. */
/* Текст перед фотографией. Ширина шире прежних 30ch: строка стала
   длинной, а на узкой колонке абзац в три предложения вытягивался в
   лесенку (правка 04.09.2026). */
/* Текст-описание живёт в правой колонке рядом с фотографией, поэтому
   по центру его больше не выключаем и ширину не зажимаем (правка
   05.09.2026). На телефоне колонка одна — он идёт над списком. */
.edu-lead { margin-top: 0; margin-bottom: clamp(24px, 4vw, 32px); max-width: none; text-align: left; }
.edu-note { margin-top: clamp(32px, 6vw, 48px); color: var(--muted); }
.edu-list {
  list-style: none;
  margin-top: 16px;
  max-width: 30ch;
}
/* Названия направлений прописными — указание Вероники 05.09.2026.
   Межбуквенное расширено: у антиквы прописные без него сбиваются в
   плотную стену. */
.edu-list li {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
  font-size: clamp(18px, 4.4vw, 22px);
  font-weight: 400;
}
/* Верхняя линия у первого пункта — той же длины, что и остальные. */
.edu-list li:first-child { border-top: 0; }
.edu-list li:first-child::before {
  content: "";
  position: absolute;
  left: 0; right: 42%; top: 0;
  height: 1px;
  background: var(--line);
}
.edu-cta { margin-top: clamp(32px, 6vw, 48px); }
/* Кнопка «Подробнее» по центру — правка Вероники 06.09.2026 («давай по
   центру попробуем»). Прежде она стояла у левого края, и справа от неё
   оставалось пустое поле.
   Только на телефоне: на компьютере блок идёт в две колонки, там кнопка
   выравнивается по своей колонке и трогать её незачем. */
@media (max-width: 767px) {
  .edu-cta { text-align: center; }

  /* ⚠ 07.09.2026, просьба Вероники: «текст в блоке „обучение“
     сделать меньше как в блоке „о студии“».

     Сличено с .about__note: там фиксированные 17px и межстрочный 1.5.
     В «Обучении» текст шёл от --fs-body: на телефоне это 17,25px
     и межстрочный 26,7px — разница в кегле крошечная, а в межстрочном
     заметная: абзац выглядел рыхлее и оттого крупнее.

     ⚠ Только телефон. На компьютере --fs-body равен 19px, и там
     разница с «О студии» больше. Десктоп не тронут без слова
     Вероники — вопрос ей задан 07.09.2026. */
  .edu-lead,
  .edu-text .about__point .prose,
  .edu-note {
    font-size: 17px;
    line-height: 1.5;
  }
}

/* ⚠ Кадр с основательницами, добавлен 04.09.2026. На телефоне он идёт
   над текстом — блок начинается с лица, а не со строчки «обучение
   доступно по двум направлениям». На компьютере встаёт слева, текст
   справа: та же раскладка, что в «О студии», чтобы страница держала
   один ритм. */
.edu-grid { margin-top: clamp(28px, 6vw, 40px); }
.edu-photo { margin: 0 0 clamp(24px, 5vw, 32px); }
/* Кадр обучения обесцвечен 06.09.2026 по указанию Вероники («сделай фото
   на обучении в чб»). Тем же приёмом, что портреты команды: цвет снимает
   стиль, сам файл остаётся цветным — вернуть можно одной строкой. */
.edu-photo img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); }
.edu-text .edu-note { margin-top: 0; }
/* Строка «Доступно два направления» поднята к роликам 25.09.2026 по
   правке Вероники. Стоит вплотную над ними, поэтому отступ сверху
   снят, а снизу — короткий, чтобы строка читалась как подпись к паре
   роликов, а не как отдельный абзац.

   ⚠ 26.09.2026, «вариант 2» — выбран Вероникой из двух показанных
   картинками. Промежуток после заголовка «Обучение» уменьшен с 40 до
   18: в остальных блоках за заголовком сразу идёт что-то крупное, а
   здесь попадала одна короткая серая строка и висела в пустоте.
   Правило заведено только для этого блока — в соседних промежуток
   прежний, общий ритм страницы не тронут. */
.edu-reels-note { margin: 0 0 clamp(12px, 3vw, 16px); }
#education .section-head { margin-bottom: 18px; }

/* ⚠ РОЛИКИ ВМЕСТО ФОТО — 15.09.2026, решение Вероники: «без фото, будет
   два ролика с Натальей и Яной». Два вертикальных кадра 9:16 бок о бок,
   как сетка рилсов; под каждым — направление и имя. Пока ролик один
   (Яны ещё нет), модификатор --one ставит его по центру, а не в левую
   половину с пустотой справа.

   ⚠ 25.09.2026: оба ролика обесцвечены по указанию Вероники («наложи
   на видео с Натальей Ким чб фильтр, чтобы оба видео были в чб»).
   Ролик Яны чёрно-белый сам по себе, ролик Натальи — цветной, и рядом
   они спорили. Цвет снимает стиль, файлы остаются цветными: вернуть —
   убрать одну строку filter ниже, как у портретов команды. */
.edu-reels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 clamp(24px, 5vw, 32px);
}
.edu-reels--one {
  grid-template-columns: minmax(0, 280px);
  justify-content: center;
}
.edu-reel { margin: 0; }
.edu-reel__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--black);
}
.edu-reel__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
}
/* Кнопка звука — вариант «Б» (Вероника, 11.09): ролик идёт без звука,
   звук включается по кнопке. Кнопка нарочно заметная: с подписью, на
   тёмной подложке, не меньше 44 точек в высоту (правило 3 по сайту).
   Точку в углу половина людей не заметит, и звук не услышит никто. */
.edu-reel__sound {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-radius: 0;
  background: rgba(10, 10, 10, 0.72);
  color: var(--white);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  transition: background-color 0.25s var(--ease);
}
.edu-reel__sound:hover, .edu-reel__sound:focus-visible { background: var(--black); }
.edu-reel__sound[hidden] { display: none; }
.edu-reel__ico { width: 18px; height: 18px; flex: none; }
.edu-reel__ico--on { display: none; }
.edu-reel__sound.is-on .edu-reel__ico--on { display: block; }
.edu-reel__sound.is-on .edu-reel__ico--off { display: none; }
.edu-reel__caption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
}
.edu-reel__topic {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.02em;
}
@media (max-width: 419px) {
  /* На телефоне два ролика рядом — по 160–180 точек: подпись на кнопке
     ужимается, но остаётся. Прятать её нельзя — тогда это снова точка в
     углу, которую никто не нажмёт. */
  .edu-reels:not(.edu-reels--one) .edu-reel__sound {
    left: 8px;
    bottom: 8px;
    padding: 0 10px;
    font-size: 11px;
    letter-spacing: 0.04em;
    gap: 6px;
  }
}

@media (min-width: 900px) {
  .edu-grid {
    display: grid;
    grid-template-columns: 0.9fr 1fr;
    gap: clamp(40px, 5vw, 72px);
    /* Колонки выровнены по верху, а не по центру: текст-описание должен
       начинаться на одной высоте с фотографией. Список направлений и
       кнопка опускаются ниже сами — их отодвигает описание сверху
       (правка Вероники 05.09.2026). */
    align-items: start;
  }
  .edu-photo { margin: 0; }
  /* Небольшой отступ сверху у правой колонки: строка «Обучение доступно…»
     не должна упираться в верхний край кадра. */
  .edu-text { padding-top: clamp(8px, 1.5vw, 20px); }
}

/* ==========================================================================
   ПОРТРЕТЫ МАСТЕРОВ — ОДИН ВИД
   Кадры сняты в разное время и в разных местах: студия с серым фоном,
   белая стена, рабочее место с полками. Один размер и одна крупность
   лица уже приведены в самих файлах (см. ЗАДАЧИ.md). Здесь снимается
   последнее, что разваливает ряд, — цвет: у одного кадра тёплый загар,
   у другого синие баллоны на полках за спиной. На чёрно-белом сайте это
   единственные цветные пятна.

   Обесцвечивание держим в CSS, а не в файлах: откатывается одной
   строкой, а будущие портреты подхватываются сами, без обработки.
   ========================================================================== */
.master-card__media img { filter: grayscale(1); }

/* ==========================================================================
   ПРЕЛОАДЕР
   Белый экран, по центру логотип целиком. Анимируется только верхняя
   скобка: она открывается снизу вверх, потом направо. Буквы под ней не
   рисуются — появляются и гаснут вместе со скобкой.

   Открытие сделано через clip-path: inset(сверху справа снизу слева).
   Сначала правый отступ держится на 88% — видна только левая полоса, и
   верхний отступ уходит со 100% до 0: линия «растёт» снизу вверх. Потом
   правый отступ уходит до нуля — рамка раскрывается направо. Проценты
   считаются от размера самого элемента, поэтому подгонять числа под
   размер знака не нужно.

   Скрыт по умолчанию и включается только классом js на <html>: если
   скрипт не загрузился, снять белый экран будет некому.
   ========================================================================== */
.preloader { display: none; }
.js .preloader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--white);
  color: var(--black);
  transition: opacity 0.7s var(--ease), visibility 0.7s var(--ease);
}
/* Класс ставит JS после загрузки. visibility нужна вместе с opacity:
   прозрачный, но существующий экран продолжал бы ловить нажатия. */
.js .preloader.is-done { opacity: 0; visibility: hidden; }

/* ⚠ ТРЕТЬЯ СТРАХОВКА, добавлена 04.09.2026 после случая на выкладке:
   сайт открылся, а белый экран со знаком висел вечно.

   Две прежние страховки обе держались на js/main.js: он снимает экран по
   загрузке страницы и принудительно через 6 секунд. Но если самого
   main.js нет — не доехал на хостинг, упал с ошибкой, вырезан
   «ускорителем» хостинга, — снимать экран становится некому, а класс js
   уже стоит: его ставит отдельная строчка в <head>, и она отрабатывает
   всегда.

   Теперь экран уходит сам средствами CSS через 6 секунд, без всякого
   скрипта. Когда main.js жив, он снимает экран раньше, и до этой
   анимации дело не доходит. */
@keyframes preload-selfhide {
  to { opacity: 0; visibility: hidden; }
}
.js .preloader {
  animation: preload-selfhide 0.7s var(--ease) 6s forwards;
}

/* ⚠ Знак переливается металлом — правка Вероники 04.09.2026: «тем же
   эффектом, что используется на самом сайте».

   Как сделано. Контуры залиты не плоским чёрным, а градиентом с
   чередованием тёмных и светлых полос — это и читается как металл
   (заливка задана в разметке: fill="url(#kc-metal)"). Блики медленно
   едут поперёк знака, отсюда «перелив».

   ⚠ Почему не сам logo_mark.png. Пробовали залить контуры этим файлом —
   не вышло: знак нарисован в системе координат, уменьшенной в десять раз
   и отражённой по вертикали, и картинка внутри букв размножалась
   мелкими копиями. Градиент от системы координат не зависит.

   Полосы взяты тёмные: экран прелоадера белый, а металл сам по себе
   светлый — на белом он бы почти пропал. В шапке ровно та же задача
   решается притемнением через brightness. */
/* Проценты загрузки под знаком. Появились 06.09.2026 — «делаем цифры
   вместе с анимацией». Мелко и приглушённо: это служебная подпись, а не
   часть знака, и перетягивать внимание она не должна.
   Цифры набираются основным шрифтом с одинаковой шириной знаков
   (tabular-nums) — иначе строка дёргается при смене 8 на 1. */
.preloader__pct {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(48px, 12vh, 96px);
  margin: 0;
  text-align: center;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--grey-text);
  font-variant-numeric: tabular-nums;
}

.preloader__logo {
  position: relative;
  width: clamp(150px, 40vw, 260px);
  /* пропорция знака целиком: 721 к 660 */
  aspect-ratio: 721 / 660;
}
.preloader__word {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* Скобка занимает не весь квадрат, а ровно свою верхнюю часть —
   519 из 660 единиц высоты знака. Иначе проценты в clip-path считались бы
   от всего поля, и первая треть движения уходила бы на пустоту под ней. */
.preloader__frame,
.preloader__stem {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 78.6%;
}
/* ⚠ Ствол буквы «К» — это левая палочка рамки, а не часть самой буквы:
   в знаке «К» нарисована только двумя диагоналями. Пока рамка не
   дорисована, «К» стоит без ствола и читается обрубленной — замечание
   Вероники 04.09.2026.

   Поэтому левая палочка вынесена отдельным слоем и стоит всегда, а
   анимируется только то, что и должно ехать: верхняя черта и штрих
   справа. Слой — копия того же контура, обрезанная по левому краю. */
.preloader__stem {
  clip-path: inset(0 88% 0 0);
  opacity: 1;
}
/* Буквы стоят на месте всё время, мигает только скобка над ними —
   правка Вероники 03.09.2026. Так круг читается спокойнее: глазу не за
   чем гоняться, кроме одной линии. */
.preloader__word { opacity: 1; }
/* ==========================================================================
   ⚠⚠ ГЛАВНОЕ ПРАВИЛО ПРЕЛОАДЕРА, записано 05.09.2026 после ошибки:

   ЗНАК НИКОГДА НЕ РЕЖЕТСЯ. Ни одна часть контура не прячется — ни на
   мгновение, ни «пока идёт анимация».

   Что случилось. Ради движения линия рамки обрезалась по высоте, и у
   логотипа пропадала левая вертикаль: буква «К» оставалась без ствола
   (в знаке она нарисована двумя диагоналями, ствол принадлежит рамке).
   Вероника увидела это сразу: «почему ты прелоадер исказил?».

   Отсюда правило: логотип на прелоадере обязан совпадать с
   img/logo_mark.png до последней линии. Движение берётся не из
   вырезания частей, а из перелива металла — блики едут поперёк знака,
   сам знак стоит неподвижно и целиком.

   Если снова захочется «дорисовывать» линию — сначала показать Веронике
   снимок рядом с настоящим логотипом.
   ========================================================================== */
/* ⚠ Движение вернулось 05.09.2026 — правка Вероники: «линия начинает
   движение при загрузке на уровне букв КС».

   Слоя два, и это принципиально:

   • .preloader__stem — ствол буквы «К», отрезок вертикали ВДОЛЬ «КС».
     Не двигается никогда. Именно его вырезание в прошлый раз оставляло
     букву без ствола;
   • .preloader__frame — всё, что выше: вертикаль над «КС», верхняя черта
     и штрих справа. Растёт только он: сначала линия идёт вверх от уровня
     «КС», потом черта уходит вправо.

   В любой момент буква целая, дорисовывается только рамка над ней.
   38% — высота, на которой начинаются крупные буквы; при смене логотипа
   пересчитать. */
.preloader__stem {
  clip-path: inset(38% 88% 0 0);
  opacity: 1;
  animation: none;
}
.preloader__frame {
  animation: preload-frame 3.4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

/* ⚠ Переписано 06.09.2026. Правка Вероники: «когда прорастает линия над
   КС, она не должна появляться горизонтально, она должна двигаться по
   своему направлению: сначала вырастать из буквы К вверх, потом вправо,
   потом вниз».

   Прежняя анимация делала два движения из трёх: линия честно росла
   вверх, а дальше окно inset() раскрывалось вправо и открывало разом и
   верхнюю черту, и всю правую стойку. Правая стойка не рисовалась
   сверху вниз, а проявлялась целиком.

   Прямоугольным окном три поворота не описать, поэтому окно стало
   многоугольником. Он всегда из восьми точек — иначе браузер не умеет
   плавно переходить между кадрами; в первых фазах лишние точки просто
   совпадают.

   Форма окна по обходу контура:
     (0, Ytop) — (X, Ytop) — (X, Ybot) — (R, Ybot)
     — (R, T) — (L, T) — (L, 100%) — (0, 100%)
   где L — ширина левой стойки, T — высота верхней черты, R — левый край
   правой стойки. Числа сняты с самого знака: левая стойка занимает
   слева около 3%, верхняя черта — 12% высоты, правая стойка стоит на
   91–97% ширины. Взяты с запасом: 12%, 14%, 88%.

   ⚠ Здесь же убраны осколки двух старых наборов кадров: они остались
   от прежних попыток без заголовка @keyframes, и лишние скобки в них
   обрывали разбор файла — из-за этого отваливалось правило ниже, для
   тех, у кого анимации отключены. */
@keyframes preload-frame {
  /* Пауза: виден только неподвижный кусок стойки у буквы «К» */
  0%, 8% {
    clip-path: polygon(0% 38%, 12% 38%, 12% 38%, 12% 38%, 12% 38%, 12% 38%, 12% 100%, 0% 100%);
    opacity: 1;
  }
  /* 1. Вверх: стойка вырастает из буквы */
  34% {
    clip-path: polygon(0% 0%, 12% 0%, 12% 0%, 12% 0%, 12% 0%, 12% 0%, 12% 100%, 0% 100%);
    opacity: 1;
  }
  /* 2. Вправо: верхняя черта идёт от угла к правому краю */
  56% {
    clip-path: polygon(0% 0%, 100% 0%, 100% 14%, 100% 14%, 100% 14%, 12% 14%, 12% 100%, 0% 100%);
    opacity: 1;
  }
  /* 3. Вниз: правая стойка опускается вдоль края */
  78% {
    clip-path: polygon(0% 0%, 100% 0%, 100% 105%, 88% 105%, 88% 14%, 12% 14%, 12% 100%, 0% 100%);
    opacity: 1;
  }
  /* Знак постоял целиком и погас */
  88% {
    clip-path: polygon(0% 0%, 100% 0%, 100% 105%, 88% 105%, 88% 14%, 12% 14%, 12% 100%, 0% 100%);
    opacity: 1;
  }
  95% {
    clip-path: polygon(0% 0%, 100% 0%, 100% 105%, 88% 105%, 88% 14%, 12% 14%, 12% 100%, 0% 100%);
    opacity: 0;
  }
  100% {
    clip-path: polygon(0% 38%, 12% 38%, 12% 38%, 12% 38%, 12% 38%, 12% 38%, 12% 100%, 0% 100%);
    opacity: 0;
  }
}

/* Кому анимации мешают — тому просто белый экран со статичным знаком */
@media (prefers-reduced-motion: reduce) {
  /* Кому анимации мешают — тот видит знак целиком и неподвижным */
  .preloader__frame { animation: none; clip-path: none; opacity: 1; }
  /* Страховку не отключаем: без неё при мёртвом скрипте экран не уйдёт
     вовсе. Только убираем плавность. */
  .js .preloader { transition-duration: 0.01ms; animation-duration: 0.01ms; }
}

/* ==========================================================================
   БЛОК-ВЫСКАЗЫВАНИЕ
   Пауза между роликом и портфолио: одна фраза по центру, вокруг воздух.
   Высота задана в долях экрана, а не в пикселях, — блок должен читаться
   как отдельный экран, а не как абзац между двумя секциями.

   Строка узкая (18 символов в строке крупным кеглем) намеренно: короткая
   строка читается как высказывание, длинная — как описание.
   ========================================================================== */
.statement {
  display: flex;
  align-items: center;
  /* Было 72vh на телефоне и 80vh на компьютере — вокруг фразы оставалось
     слишком много пустоты (правка Вероники 03.09.2026). Теперь высота
     задаётся отступами, а не долей экрана: блок ровно такой, каким его
     делает текст. */
  padding-block: clamp(72px, 16vw, 140px);
  background: var(--white);
  color: var(--black);
  --typeon-dim: #DCDCDC;
}
.statement .container { width: 100%; }
/* Шрифт не заголовочный — прямое указание Вероники 02.09.2026. Oswald
   здесь давил: он узкий, жирный и прописной, фраза читалась как вывеска.
   Основной шрифт лёгким начертанием, строчными буквами и просторной
   строкой звучит как высказывание, а не как объявление. */
/* ⚠ Разбивка строк задана вручную 05.09.2026 — указание Вероники:
   «Место, где профессиональная» / «колористика встречается» /
   «с эстетической косметологией». Автоматический подбор (text-wrap:
   balance) давал другое деление, поэтому переносы проставлены в
   разметке тегами <br>, а сам подбор отключён. */
.statement__text {
  /* Ширина рассчитана под самую длинную из трёх групп —
     «с эстетической косметологией». При 22ch она не помещалась и
     выпирала за край. */
  max-width: 30ch;
  margin-inline: auto;
  text-align: center;
  font-family: var(--font-body);
  /* Было clamp(24px, 5.2vw, 44px). На телефоне упиралось в нижнюю
     границу 24px, и слово «профессиональная» занимало строку целиком —
     фраза складывалась пирамидкой (правка Вероники 04.09.2026). */
  font-size: clamp(23px, 5.6vw, 46px);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
}
@media (min-width: 900px) {
  .statement__text { max-width: 34ch; }
}

/* ==========================================================================
   ТЕКСТ, КОТОРЫЙ «ПЕЧАТАЕТСЯ» ОТ ПРОКРУТКИ
   Разметку на буквы делает js/main.js (раздел 7а). Двигается только
   цвет: ни размер, ни положение букв не меняются, поэтому строка не
   дёргается и высота блока не скачет.
   ========================================================================== */
/* Слово держится целым через nowrap, а не через inline-block: строчный
   элемент экранная читалка читает слитно с соседями, а inline-block
   часть читалок произносит с паузой после каждого слова. Перенос всё
   равно случится по пробелу между словами. */
.typeon__word { white-space: nowrap; }
.typeon__char {
  color: var(--typeon-dim);
  transition: color 0.5s var(--ease);
}
.typeon__char.is-lit { color: inherit; }

@media (prefers-reduced-motion: reduce) {
  .typeon__char { color: inherit; transition: none; }
}

/* ==========================================================================
   12. РАБОТЫ
   ========================================================================== */
/* Статичная сетка на любом экране — раньше здесь была горизонтальная
   карусель (overflow-x:auto), убрана: на iOS она усиливала ощущение
   болтающейся страницы при обычном вертикальном скролле. */
.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-top: clamp(40px, 6vw, 64px);
}
@media (min-width: 768px) {
  .gallery { grid-template-columns: repeat(3, 1fr); gap: 16px; }
}
@media (min-width: 1200px) {
  .gallery { grid-template-columns: repeat(4, 1fr); }
}
.gallery__item { cursor: zoom-in; }
.works__more { margin-top: 8px; }
.works__disclaimer { margin-top: 8px; max-width: 34em; }

/* ==========================================================================
   13. СТРОКА ПРАЙСА — точечное заполнение, как в меню ресторана
   Используется внутри разделов «Услуги» (раздел 11 выше).
   ========================================================================== */
.price-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 12px 0;
}
.price-line__name { font-size: 15px; }
.price-line__dots {
  flex: 1 1 auto;
  min-width: 24px;
  border-bottom: 1px dotted var(--grey-line);
  margin-bottom: 6px;
}
.price-line__time { font-size: 13px; color: var(--muted); white-space: nowrap; }

/* Подзаголовок внутри прайса. В колористике 26 строк — сплошным списком
   он не читается, глазу не за что зацепиться. Группы («тонирование»,
   «контуринг») дают точки входа: клиент ищет свою технику, а не сканирует
   весь столбец. Отбивка сверху больше, чем снизу, — заголовок должен
   принадлежать списку под собой, а не висеть между двумя. */
.price-group {
  margin-top: 28px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
}
.price-group + .price-line { padding-top: 14px; }

/* Цен на сайте нет (решение 02.09.2026). Строка теперь «название —
   длительность», и без цены она стала легче: точечная линия ведёт глаз
   к времени, а не к цифре. */
.services__price-note { margin-top: 16px; max-width: 34em; color: var(--muted); }
/* Точечная линия вела глаз от названия к цене. Цены нет — линия ведёт в
   пустоту, поэтому строки без цены её не показывают. Правило само себя
   отменит, если цены вернутся: оно смотрит на наличие ячейки цены. */
.price-line:not(:has(.price-line__cost)) .price-line__dots { display: none; }

/* На узком экране строка «название — время — цена» в одну линию не живёт:
   «30 000–60 000 ₽» не переносится, и на название остаётся 90px, отчего
   оно рвётся на четыре строки. Ниже 600px строка складывается в две:
   название сверху, время и цена под ним. */
/* Складывание в две строки нужно только там, где справа есть цена.
   Сейчас цен нет, и правило само себя не применяет — вернутся, включится
   обратно без правок. */
@media (max-width: 599px) {
  .price-line:has(.price-line__cost) { flex-wrap: wrap; row-gap: 2px; }
  .price-line:has(.price-line__cost) .price-line__name { flex: 1 1 100%; }
  .price-line__time { order: 1; }
  .price-line__dots { order: 2; }
  .price-line__cost { order: 3; }
}
.price-line__cost { font-size: 15px; font-weight: 600; white-space: nowrap; }

/* ==========================================================================
   15. КОНТАКТЫ
   ========================================================================== */
.contacts-grid { display: grid; gap: clamp(48px, 8vw, 80px); }
/* ⚠ Начертание адреса изменено 07.09.2026 по указанию Вероники:
   «адрес другим шрифтом (Geometria Medium капсом)». Гарнитура и капс
   уже были такими — менялся только вес: 800 (Bold) на 500 (Medium).
   Правило одно на все экраны, поэтому на компьютере адрес тоже стал
   легче. */
.contacts__address { margin-top: 16px; font-size: clamp(24px, 4vw, 36px); font-weight: 500; text-transform: uppercase; line-height: 1.15; }
.contacts__address-note { margin-top: 8px; font-size: 15px; color: var(--muted); text-transform: none; }
/* ⚠ Верхняя линия убрана 10.09.2026 по указанию Вероники: сразу под
   заголовком «Контакты» она выглядела лишней чертой. Разделители между
   строками остались. */
.contacts__list { margin-top: 32px; }
.contacts__row { display: flex; justify-content: space-between; gap: 20px; padding: 16px 0; border-bottom: 1px solid var(--line); }
.contacts__row dt { font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); padding-top: 3px; }
.contacts__row dd a { text-decoration: none; border-bottom: 1px solid var(--line); }

/* Контейнер под iframe 2ГИС: пропорция задана заранее, чтобы карта не
   ломала вёрстку до того, как код виджета будет вставлен. На мобильном
   занимает всю ширину секции. */
.contacts__map {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--grey-bg);
  overflow: hidden;
}
/* ⚠ Пока код карты не вставлен, контейнер пуст. Светлая заливка на
   чёрном блоке читалась как дыра в вёрстке (правка 05.09.2026):
   до появления карты оставляем только тонкую рамку — она перекликается
   со скобкой логотипа и выглядит намеренной. Комментарии внутри тега
   :empty не мешают, поэтому правило снимается само, как только карта
   встанет. */
.contacts__map:empty {
  background: none;
  /* ⚠ Цвет привязан к --line, а не задан белым: блок стал светлым
     06.09.2026 («мне не нравится, что он чёрный»), и прежняя белая рамка
     на белом фоне пропадала совсем. */
  border: 1px solid var(--line);
}
/* Значки мессенджеров: круглые, с заливкой — как на референсе, который
   Вероника прислала 06.09.2026 («давай контакты так же кружочками как на
   референсе оставим»). Квадратные пробовали в тот же день, не подошли.

   Порядок — Telegram, потом WhatsApp: как на референсе.

   ⚠ Диаметр 40px — уменьшен 06.09.2026 по просьбе Вероники («кружочки
   сделать поменьше»). Это ниже порога 44px, принятого по сайту, поэтому
   область нажатия расширена невидимым слоем ::after до 48px: круг
   выглядит меньше, а палец попадает как прежде. Уменьшать сам круг
   дальше можно, трогать ::after — нет.

   Цвета взяты от секции, а не заданы намертво: на светлом блоке круг
   тёмный со светлым значком, на чёрном — наоборот. Блок контактов сейчас
   светлый, но правило переживёт возврат к чёрному. */
.contacts__soc {
  display: flex;
  gap: 12px;
  margin-top: 28px;
  padding: 0;
  list-style: none;
}
.soc {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--black);
  color: var(--white);
  text-decoration: none;
  transition: opacity 0.3s var(--ease);
}
/* Невидимая область нажатия: круг 40px, попадать по нему нужно как по
   48px. Без этого мелкий значок промахивается на телефоне. */
.soc::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; }
.section--black .soc { background: var(--white); color: var(--black); }
.soc svg { width: 17px; height: 17px; display: block; }

/* На телефоне контакты собраны по образцу, присланному Вероникой
   06.09.2026: карта сверху, под ней группа «подпись — значение» по
   центру, обрамлённая двумя тонкими линиями.

   Порядок переставлен через order, а не в разметке: так десктопная
   раскладка в две колонки (строка с grid-template-columns ниже по
   файлу) остаётся нетронутой, и правка обратима одним правилом.

   Тексты, названия строк и сам адрес не менялись. */
@media (max-width: 767px) {
  .contacts-grid { text-align: center; }
  /* ⚠ Порядок переставлен 06.09.2026 по указанию Вероники: «логичнее
     будет поставить под заголовком „Контакты“ сами контакты, далее
     адрес и карту уже».

     Было: карта — маршрут — адрес — телефон. Человек видел карту
     раньше, чем узнавал, куда ехать.
     Стало: телефон и мессенджеры — адрес — карта — маршрут. */
  .contacts-grid > div { order: 1; }
  .contacts-grid > .contacts__map { order: 2; }
  .contacts-grid > p { order: 3; }

  /* Внутри первого столбца тоже переставляем: сперва способы связи,
     потом адрес. Отступы переезжают вместе с элементами — иначе воздух
     остаётся там, где его больше нечему разделять. */
  .contacts-grid > div { display: flex; flex-direction: column; }
  .contacts__list { order: 1; margin-top: 0; }
  .contacts__soc { order: 2; }
  .contacts__address { order: 3; margin-top: clamp(28px, 6vw, 40px); }
  .contacts__address-note { order: 4; }

  /* Подпись над значением, а не слева от него */
  .contacts__row {
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 14px 0;
    border-bottom: 0;
  }
  .contacts__row dt { padding-top: 0; }
  /* Линии только по краям группы, между пунктами их нет */
  .contacts__row:last-child { border-bottom: 1px solid var(--line); }
  .contacts__soc { justify-content: center; }
}

.contacts__map iframe,
.contacts__map img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}

/* ==========================================================================
   16. ЖУРНАЛ — УБРАН 02.09.2026
   Решение Вероники: журнал снимаем совсем. Страница списка, пять статей
   и article.css перенесены в материалы/журнал-снят-с-сайта/ — из папки
   сайта они уехали бы на хостинг. Оформление журнала удалено отсюда
   вместе с ними; вернуть можно из истории правок.
   ========================================================================== */

/* ==========================================================================
   ФУТЕР
   ========================================================================== */
/* ⚠ Подвал стал светлым 06.09.2026 («подвал делаем белым»). Цвета,
   заданные под чёрный фон, переведены на переменные секции: линия сверху
   и приглушённый текст теперь берутся из темы блока, а не прописаны
   белым напрямую. Фильтр знака трогать не нужно — он и был рассчитан на
   светлый фон, тот же, что в прокрученной шапке. */
.footer { padding: 48px 0 calc(96px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.footer__inner { display: grid; gap: 32px; }
.footer__nav { display: flex; flex-wrap: wrap; gap: 8px 24px; }
/* Прописными — правка Вероники 10.09.2026, как в меню наверху.
   Межбуквенное расширено: у антиквы прописные без него сбиваются
   в плотную строку. */
.footer__nav a {
  font-size: 15px;
  text-decoration: none;
  color: inherit;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
/* Разделы сайта в подвале — в две колонки, по просьбе Вероники
   06.09.2026: слева «направления, команда, о студии», справа «обучение,
   контакты». Раскладка по колонкам, а не по строкам: три ячейки в высоту
   и заполнение сверху вниз — тогда первые три пункта уходят в левый
   столбец, оставшиеся два в правый.

   Только на телефоне: на компьютере меню идёт строкой по центру, и это
   не трогалось. */
@media (max-width: 767px) {
  .footer__nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(3, auto);
    grid-auto-flow: column;
    gap: 12px 24px;
    justify-items: start;
  }
}
.footer__legal { display: grid; gap: 12px; }
.footer__legal a { font-size: 15px; color: inherit; }
.footer__copy { font-size: 13px; letter-spacing: 0.05em; color: var(--muted); }
.footer--plain { padding-bottom: 48px; }

/* --- Страница политики конфиденциальности --- */
/* Заголовок документа набирается мельче заголовков главной: на мониторе
   56px разносило «Политика в отношении обработки персональных данных» на
   четыре строки, и страница начиналась с плаката вместо документа.
   text-wrap: balance выравнивает строки по длине (правка 04.09.2026). */
.legal .h2 { font-size: clamp(26px, 4vw, 38px); text-wrap: balance; }
.legal__date { margin-top: 16px; }
.legal__body { max-width: 34em; margin-top: 48px; }
.legal__body .h3 { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--line); text-transform: none; }
.legal__body .h3:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.legal__body p { margin-top: 16px; }
.legal__body strong { font-weight: 600; }

/* ==========================================================================
   16. ЛИПКАЯ ПАНЕЛЬ, ЛАЙТБОКС, «НАВЕРХ»
   ========================================================================== */
.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 55;
  padding: 12px var(--gutter) calc(12px + env(safe-area-inset-bottom));
  background: var(--black);
  border-top: 1px solid rgba(255,255,255,0.2);
  transform: translateY(110%);
  transition: transform 0.4s var(--ease);
}
.sticky-cta.is-visible { transform: translateY(0); }
/* Только мобильный: на десктопе своя кнопка «Записаться» уже есть в шапке */
@media (min-width: 768px) {
  .sticky-cta { display: none; }
}
.sticky-cta__btn { width: 100%; min-height: 48px; color: var(--white); }
.sticky-cta__btn:hover, .sticky-cta__btn:focus-visible { background: var(--white); color: var(--black); }

.to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 50;
  display: none;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--grey-line);
  background: var(--white);
  color: var(--black);
  cursor: pointer;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease);
}
.to-top:hover { background: var(--black); color: var(--white); }
.to-top svg { width: 12px; height: 20px; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 72px 16px;
  background: rgba(10,10,10,0.97);
  color: var(--white);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
.lightbox.is-open { opacity: 1; }
.lightbox__stage { display: flex; align-items: center; justify-content: center; width: 100%; max-width: 900px; height: 100%; }
.lightbox__stage .ph { width: min(100%, 62vh); max-width: 100%; }
@supports (height: 1dvh) { .lightbox__stage .ph { width: min(100%, 62dvh); } }
.lightbox__close,
.lightbox__nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 0;
  background: none;
  color: var(--white);
  cursor: pointer;
}
.lightbox__close { top: 12px; right: 12px; }
.lightbox__close svg, .lightbox__nav svg { width: 18px; height: 18px; }
.lightbox__nav--prev { left: 4px; top: 50%; margin-top: -24px; }
.lightbox__nav--next { right: 4px; top: 50%; margin-top: -24px; }
.lightbox__counter {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(20px + env(safe-area-inset-bottom));
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.1em;
  color: #A6A6A6;
}

/* ==========================================================================
   17. ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ
   Подъём на 20px с прозрачностью, один раз, без повтора. Класс
   .reveal-hidden вешает только JS (js/main.js, initReveal) — без JS
   или при упавшем скрипте у .reveal нет ни одного правила в базовом
   CSS, весь контент виден сразу. Никакого transform, привязанного
   к scroll — переход запускается один раз добавлением is-visible.
   ========================================================================== */
.reveal-hidden {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
  transition-delay: var(--d, 0ms);
}
.reveal-hidden.is-visible { opacity: 1; transform: none; }

/* Вертикальная линия у номера секции дорисовывается вместе с блоком */
.section-num-line {
  display: none;
}

/* ==========================================================================
   ПЛАНШЕТ — от 768px
   ========================================================================== */
@media (min-width: 768px) {
  .hero__eyebrow, .hero__place { font-size: 13px; }

  /* Большой кадр слева заметно крупнее текстовой колонки — так он
     держит блок, а текст читается спокойным столбцом рядом */
  .about__grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: clamp(40px, 5vw, 72px); align-items: start; }
  .about__text { margin-top: 0; }
  /* ⚠ 05.09.2026 расширение «О студии» снято: правка Вероники «все блоки
     с контентом на десктопе должны быть одной ширины, не выходить за
     рамки». Блок снова живёт в общем контейнере, как остальные. */


  .contacts-grid { grid-template-columns: 1fr 1fr; }

  .footer__inner { grid-template-columns: auto 1fr auto; align-items: center; gap: 40px; }
  .footer__nav { justify-content: center; }
  .footer__legal { justify-items: end; text-align: right; }

  .to-top { display: flex; }
}

/* ==========================================================================
   ДЕСКТОП — от 1024px
   ========================================================================== */
@media (min-width: 1024px) {
  .header__inner { padding-inline: var(--gutter); }

  .burger { display: none; }
  .nav { display: flex; align-items: center; gap: 40px; }
  .nav__list { display: flex; align-items: center; gap: 32px; }
  /* Капслок — правка Вероники 04.09.2026: пункты меню набраны так же,
     как в мобильном меню и на кнопках. Межбуквенное чуть шире: прописные
     без него читаются как сплошная стена. */
  .nav__link { position: relative; display: inline-block; padding: 12px 0; font-family: var(--font-body); font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; text-decoration: none; }
  .nav__link::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 8px;
    height: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s var(--ease);
  }
  .nav__link:hover::after,
  .nav__link:focus-visible::after,
  .nav__link.is-active::after { transform: scaleX(1); }

  /* ⚠ Правки 04.09.2026 по замечанию Вероники «другие блоки на десктопе
     смотрятся плохо». Причина была одна на все блоки: вёрстка оставалась
     мобильной. Текст держал телефонный кегль, а шапка секции стояла
     узким столбиком у левого края — справа зияла пустота во весь экран. */

  /* 1. Кегль основного текста. На телефоне 15–17px — правильно, на
     мониторе те же 17px выглядят мелко и «дёшево». */
  :root {
    --fs-body: 19px;
    --fs-small: 15px;
  }

  /* 2. Шапка секции разворачивается в две колонки: слева заголовок,
     справа пояснение. Пустота справа заполняется тем, что там и должно
     быть, — текстом, а не воздухом. Секциям, где под заголовком ничего
     нет (например «Команда»), правило не мешает: вторая колонка просто
     не создаётся. */
  /* ⚠ 05.09.2026 двухколоночная шапка снята: заголовок и пояснение идут
     по центру, одно под другим. Прежнее правило разводило их по колонкам
     и оставляло заголовок у левого края. */
  .section-head__text { row-gap: 14px; }
  .section-head__text > :not(.h2) { max-width: 60ch; }

  .contacts__address { font-size: 44px; }
}

/* ==========================================================================
   РЕЖИМ «МЕНЬШЕ ДВИЖЕНИЯ»
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
  }
  .reveal-hidden { opacity: 1; transform: none; }
  .sticky-cta { transform: translateY(0); }
  .mobile-menu { opacity: 1; }
  .lightbox { opacity: 1; }
}

/* ==========================================================================
   ⚠ ДВИЖЕНИЕ И ФИРМЕННЫЙ МОТИВ. Заведено 05.09.2026 по просьбе Вероники:
   «выглядит пресно, поэкспериментировать с анимацией и паттернами,
   креатив в меру — это салон премиум-класса».

   Правило, по которому всё ниже собрано: премиум — это когда движение
   замечаешь не сразу, а на второй раз. Поэтому здесь нет ни одного
   быстрого эффекта. Всё держится на трёх приёмах:

   1) фотографии оживают медленным отъездом — кадр входит чуть крупнее
      и садится на место за секунду с лишним;
   2) линии не появляются, а прочерчиваются;
   3) фирменный мотив — незамкнутая скобка логотипа — повторяется
      водяным знаком там, где есть воздух.

   Чего сознательно нет: параллакса, вылетов сбоку, поворотов, теней,
   курсора-кружка. Всё это читается как «сайт старается понравиться», а
   салону такого уровня стараться не нужно.
   ========================================================================== */

/* 1. ФОТОГРАФИИ САДЯТСЯ НА МЕСТО
   Кадр показывается на 4,5% крупнее и за 1,2 секунды возвращается к
   своему размеру. Движение почти незаметно глазу, но снимает ощущение
   «картинка просто включилась». */
.reveal-hidden img,
.reveal-hidden .ph img {
  transform: scale(1.045);
  transition: transform 1.2s var(--ease);
  transition-delay: var(--d, 0ms);
}
.reveal-hidden.is-visible img,
.reveal-hidden.is-visible .ph img { transform: none; }

/* 2. ЛИНИИ ПРОЧЕРЧИВАЮТСЯ
   Разделители в списке направлений не проявляются вместе с текстом, а
   вырастают слева направо — как черта в логотипе. */
.edu-list li { border-bottom: 0; position: relative; }
.edu-list li::after {
  content: "";
  position: absolute;
  /* ⚠ Линия короче ширины колонки — правка Вероники 10.09.2026 по
     снимку с телефона. Во всю ширину она читалась как граница таблицы,
     а не как подчёркивание названия. */
  left: 0; right: 42%; bottom: 0;
  height: 1px;
  background: var(--line);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.9s var(--ease);
}
.edu-list li:nth-child(2)::after { transition-delay: 0.12s; }
.edu-list.is-visible li::after,
.edu-list:not(.reveal-hidden) li::after { transform: none; }

/* 3. ФИРМЕННЫЙ МОТИВ В ЧЁРНОМ БЛОКЕ
   Скобка логотипа, увеличенная во много раз и уведённая почти в фон:
   белая линия в 6% плотности на чёрном. Днём на телефоне её почти не
   видно — и это правильно, она работает как фактура, а не как рисунок.
   Угол намеренно срезан краем экрана: знак не повторяется целиком, а
   продолжается за пределы блока. */
#contacts { position: relative; overflow: hidden; }
/* ⚠ СНЯТ 07.09.2026 по просьбе Вероники: «пофиксить баг в
   последнем блоке где контакты (там какая-то вертикальная линия)».

   Это был декоративный уголок — квадрат с рамкой только сверху
   и слева, сдвинутый за правый край. Его левая стойка и давала
   вертикальную черту через весь верх блока.

   Заводился на ЧЁРНОМ блоке, где еле заметная светлая линия
   читалась как приём. После перевода контактов в светлые 06.09.2026
   линию перекрасили в тёмную — и на белом она стала выглядеть ошибкой.

   Разметка не удалена, а закомментирована — вернуть снятием скобок.

#contacts::before {
  content: "";
  position: absolute;
  right: -14%;
  top: 8%;
  width: 62%;
  aspect-ratio: 1 / 1;
  (* ⚠ Тоже перевёрнуто под светлый блок 06.09.2026: белые линии на белом
     фоне не видны. Плотность та же — еле заметный след. *)
  border-top: 1px solid rgba(10, 10, 10, 0.07);
  border-left: 1px solid rgba(10, 10, 10, 0.07);
  pointer-events: none;
  z-index: 0;
}
*/
#contacts > .container { position: relative; z-index: 1; }

/* 4. НАВЕДЕНИЕ — ТОЛЬКО НА КОМПЬЮТЕРЕ И ТОЛЬКО МЫШЬЮ
   Проверка hover: hover обязательна: без неё телефон считает наведением
   первое касание, и вместо нажатия человек получает «залипшую» плитку.
   Приближение медленное, 0,9 секунды: быстрый зум — приём распродаж. */
@media (hover: hover) and (min-width: 1024px) {
  .service-cat__media img,
  .master-card__media img,
  .about__thumb img,
  .about__photo img,
  .edu-photo img,
  .service-gallery img { transition: transform 0.9s var(--ease), opacity 0.5s var(--ease); }

  .service-cat:hover .service-cat__media img,
  .master-card:hover .master-card__media img,
  .about__thumb:hover img,
  .about__photo:hover img,
  .edu-photo:hover img,
  .service-gallery figure:hover img { transform: scale(1.05); }

  /* Подпись на плитке услуги чуть подаётся вперёд — вместе с кадром,
     но медленнее, чтобы движение читалось как одно, а не как два. */
  .service-cat__name { transition: transform 1s var(--ease); }
  .service-cat:hover .service-cat__name { transform: translateX(6px); }
}

/* Кому движение мешает — тому статика: ни отъездов, ни прочерчивания. */
@media (prefers-reduced-motion: reduce) {
  .reveal-hidden img,
  .reveal-hidden .ph img { transform: none; transition: none; }
  .edu-list li::after { transform: none; transition: none; }
  .service-cat:hover .service-cat__name { transform: none; }
}

/* ==========================================================================
   ОТДЕЛЬНАЯ СТРАНИЦА УСЛУГИ — colour.html, haircut.html и остальные
   Заведено 10.09.2026: плитка на главной ведёт на свою страницу.
   Переделано 11.09.2026 после слов Вероники «пустовато, надо докрутить».

   Порядок на странице:
     1. обложка — кадр услуги и вводный абзац, кнопка записи сразу;
     2. процедуры — на сером фоне, на компьютере группами в две колонки;
     3. работы — крупные кадры;
     4. чёрная полоса записи — единственное тёмное место, взгляд падает туда;
     5. другие направления — чтобы страница не заканчивалась тупиком.

   Страницы собираются скриптом «услуги.py» — правится шаблон в нём,
   а не сами файлы: их шесть, и они должны остаться одинаковыми.
   ========================================================================== */

/* 1. Обложка */
.usluga__hero { padding-top: calc(var(--header-h) + clamp(16px, 4vw, 40px)); }
.usluga__hero-grid { display: grid; gap: clamp(24px, 5vw, 40px); }
.usluga__cover { margin: 0; aspect-ratio: 4 / 5; overflow: hidden; }
.usluga__cover img { width: 100%; height: 100%; object-fit: cover; }
.usluga__kicker { color: var(--muted); }
.usluga__title { margin-top: 8px; }
.usluga__intro {
  margin-top: clamp(16px, 3vw, 24px);
  max-width: 34em;
  font-size: clamp(17px, 4.4vw, 21px);
  line-height: 1.55;
}
.usluga__hero-cta { margin-top: clamp(24px, 5vw, 36px); }

/* Услуга без своего кадра — обложка текстовая, по центру */
.usluga__hero--text .usluga__hero-grid { justify-items: center; text-align: center; }
.usluga__hero--text .usluga__intro { margin-inline: auto; }

@media (min-width: 900px) {
  .usluga__hero-grid {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
    gap: clamp(48px, 6vw, 96px);
    align-items: center;
  }
  /* кадр на компьютере не выше экрана, иначе текст уезжает вниз */
  .usluga__cover { max-height: calc(100vh - var(--header-h) - 80px); }
  .usluga__hero--text .usluga__hero-grid { grid-template-columns: 1fr; }
}

/* 2. Процедуры */
.usluga__list { display: grid; gap: clamp(28px, 5vw, 40px); }
@media (min-width: 900px) {
  .usluga__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(48px, 6vw, 96px);
    align-items: start;
  }
  /* одна группа в две колонки не делится — пусть идёт узкой и по центру */
  .usluga__list--single { grid-template-columns: minmax(0, 640px); justify-content: center; }
}
.usluga__block { break-inside: avoid; }
.usluga__group {
  margin-bottom: 8px;
  color: var(--muted);
}
.usluga__rows { border-top: 1px solid var(--line); }

/* Строка процедуры: название слева, длительность справа */
.usluga__row {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.usluga__name { flex: 1 1 auto; }
.usluga__time {
  flex: 0 0 auto;
  font-size: 15px;
  color: var(--muted);
  white-space: nowrap;
}

/* 3. Работы: две в ряд на телефоне, четыре на компьютере */
.usluga__works {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
@media (min-width: 768px) {
  .usluga__works { grid-template-columns: repeat(4, 1fr); gap: 16px; }
}
.usluga__shot { margin: 0; cursor: pointer; }

/* 4. Полоса записи.
   ⚠ 18.09.2026, правка Вероники: заголовок «Запишитесь на …» снят, в
   полосе остались одна тонкая строка и кнопка. Отступы сверху и снизу
   уменьшены под это: с прежними (под крупный заголовок) полоса стояла
   полупустой. Стили заголовка оставлены на случай возврата. */
.usluga__cta { padding-block: clamp(48px, 9vw, 96px); }
.usluga__cta-inner { text-align: center; display: grid; justify-items: center; gap: 14px; }
.usluga__cta-title {
  font-family: var(--font-display);
  font-size: clamp(22px, 5.4vw, 40px);
  line-height: 1.15;
  text-transform: uppercase;
  text-wrap: balance;
}
.usluga__cta-note { color: var(--muted); margin-bottom: 10px; text-wrap: balance; }

/* 5. Другие направления: лента на телефоне, ряд из пяти на компьютере */
.usluga__more-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 42%;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scroll-padding-inline: var(--gutter);
}
.usluga__more-grid::-webkit-scrollbar { display: none; }
@media (min-width: 900px) {
  .usluga__more-grid {
    grid-auto-flow: row;
    grid-template-columns: repeat(5, 1fr);
    grid-auto-columns: auto;
    gap: 16px;
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
}
/* ⚠ 18.09.2026, правка Вероники: «ниже подписи названий услуг нормально
   сделать без багов, на каждую плитку подписать». Раньше название лежало
   поверх кадра, и на плитках с фото его перекрывала сама картинка (у
   фотографий в .ph свой z-index) — подпись читалась только на пустых
   плитках. Теперь подпись стоит ПОД плиткой, чёрным, одинаково у всех —
   тем же кеглем, что подписи под роликами в «Обучении». Затемнение снято. */
.usluga__more-item {
  position: relative;
  display: block;
  color: inherit;
  text-decoration: none;
  scroll-snap-align: start;
}
.usluga__more-media { display: block; overflow: hidden; }
.usluga__more-media img { width: 100%; height: 100%; object-fit: cover; }
.usluga__more-media--empty { background: var(--grey-bg); }
.usluga__more-name {
  display: block;
  margin-top: 10px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.02em;
}
/* Затемнение под прежней подписью поверх кадра — снято 18.09.2026.
.usluga__more-item::after {
  content: "";
  position: absolute;
  inset: 45% 0 0 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.55));
  pointer-events: none;
}
.usluga__more-name { z-index: 1; }
*/

/* 3а. Мастера этой услуги — правка Вероники 11.09.2026. Стоят после
   работ и перед чёрной полосой записи: «вот что получается → вот кто
   это делает → запишитесь». Карточки те же, что в «Команде» на главной,
   чтобы мастер узнавался с первого взгляда.

   Два в ряд на телефоне, три на компьютере. Если мастер один — карточка
   одна по центру, а не прилипшая к левому краю половина экрана. */
.usluga__masters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 4vw, 40px);
}
@media (min-width: 900px) {
  .usluga__masters { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.usluga__masters--one {
  grid-template-columns: minmax(0, 320px);
  justify-content: center;
  text-align: center;
}
.usluga__masters .master-card__media { margin: 0 0 12px; }
.usluga__masters .master-card__media img { width: 100%; height: 100%; object-fit: cover; }

/* «Записаться к мастеру» под карточкой — решение Вероники 11.09.2026.
   Ссылка тонкая, в тон карточке, но область нажатия не меньше 44px:
   правило сайта для любой кнопки. */
.master-card__book { margin-top: 6px; }
.master-card__book a {
  display: inline-block;
  padding: 11px 0;
  font-size: 15px;
  /* подпись в одну строку — узкая карточка на телефоне не ломает её */
  white-space: nowrap;
}

/* Плитка на главной стала ссылкой — снимаем подчёркивание и наследуем
   цвет, чтобы она выглядела ровно как раньше. */
.service-cat__btn { display: block; color: inherit; text-decoration: none; }
