/* Места под видео.

   Ролики появятся в отдельном плане; здесь готовы места и правила отдачи.
   Правило одно и оно определяет, проседает ли скорость страницы: LCP-элементом
   должен быть ПОСТЕР, а не видео. Постер — тот же первый кадр, что уйдёт в
   генерацию ролика; видео начинает грузиться только когда секция входит в
   экран, и не грузится вовсе на узких экранах.

   Пока роликов нет, .media показывает постер и подпись с описанием кадра —
   так видно, что именно там будет снято. */
.media{position:relative;overflow:hidden;background:var(--surface)}
.media[data-ratio="wide"]{aspect-ratio:16/9}
.media[data-ratio="tall"]{aspect-ratio:3/4}
/* Герой занимает весь экран: ролик должен встречать человека целиком,
   а не полосой в три четверти высоты.

   Высота задана в svh, а не vh. На телефоне адресная строка прячется при
   прокрутке, и 100vh считается по ВЫСОКОМУ состоянию окна - экран первого
   вида оказывается выше видимой области, и низ уезжает под строку.
   Единица svh считается по низкому состоянию, поэтому герой всегда влезает
   целиком. Строка с vh оставлена первой для браузеров, которые svh не
   знают: они возьмут её, а знающие перекроют следующей.

   Верхнего предела в пикселях нет намеренно: на большом мониторе ролик
   растягивается во весь экран - ровно тот эффект, ради которого всё
   и затевалось. */
/* У героя свой тёмный фон: заголовок и кнопка на нём светлые при любой
   теме. Раньше темноту давала картинка-заглушка из прототипа, и посадочная
   без своей картинки первого экрана в кремовой теме получила бы кремовый
   заголовок на кремовом фоне. Градиент - тот же, что был у заглушки. */
.media[data-ratio="hero"]{min-height:100vh;min-height:100svh;
  background:linear-gradient(135deg,var(--navy),var(--deep))}
.media[data-ratio="hero"] .media-over{
  min-height:100vh;min-height:100svh;display:flex;align-items:center;
  padding-top:var(--gap-5);padding-bottom:var(--gap-5)
}
/* Затемнение снизу: без него светлый край ролика съедает белый текст,
   а кнопка теряет границу. Градиент, а не сплошная плёнка, - чтобы
   верх кадра остался чистым. */
/* Тёмные цвета остаются ТОЛЬКО у прозрачной шапки, и только пока она
   прозрачна - то есть в самой верхней точке страницы.

   Причина: полоса затемнения под шапкой тёмная при любой теме (см. ниже),
   поэтому надпись и ссылки на ней обязаны быть светлыми. Как только шапка
   окрашивается при прокрутке, она возвращается к выбранной теме.

   Тёмные цвета держит и САМ ГЕРОЙ: кадр снят в темноте, и осветлять его
   под светлую тему бессмысленно - см. комментарий к затемнению ниже.
   Тема начинается ниже героя.

   Переобъявление действует потому, что пользовательское свойство, заданное
   на потомке, перекрывает унаследованное. Ни одного цвета литералом. */
/* У прозрачной шапки приглушённый цвет ссылок НЕ используется: на светлом
   пятне кадра (пламя свечи) он даёт 3.25:1 при норме 4.5. Полный кремовый
   в том же худшем случае даёт 5.85:1. Приглушённость - украшение, которое
   тут стоило бы читаемости. */
body.has-hero .media[data-ratio="hero"],
body.has-hero .site-header:not(.is-solid){
  --bg:var(--deep);
  --surface:var(--navy);
  --text:var(--cream);
  --text-soft:var(--text-muted);
  --text-dim:var(--slate);
  --line:var(--hair);
  --accent:var(--gold);
  --accent-ink:var(--ink);
  color:var(--text)
}
/* Приглушённый цвет ссылок отменяется ТОЛЬКО у шапки и объявляется ПОСЛЕ
   общего блока, иначе он перекрывался бы им. Порядок здесь несёт смысл:
   у героя приглушённый нужен (подпись под заголовком), у шапки - нет. */
body.has-hero .site-header:not(.is-solid){--text-soft:var(--cream)}

/* ЕДИНСТВЕННОЕ затемнение на герое - вверху, под шапкой.

   Оно существует ради читаемости прозрачной шапки: кадр под ней может
   оказаться светлым, и тогда ссылки пропадают. Полоса возвращает
   читаемость, не закрывая кадр сплошной плашкой.

   Нижней вуали НЕТ намеренно. Она затягивала весь экран ради заголовка,
   а заголовок и так читается: текст светлый, кадр тёмный. Плёнка во весь
   кадр съедала картинку без нужды.

   Цвет затемнения тёмный ПРИ ЛЮБОЙ ТЕМЕ и берётся напрямую, а не через
   var(--bg). Пробовали через тему: в кремовой кадр затягивало светлой
   дымкой, и ролик - снятый в темноте, со свечами и морёным деревом -
   становился блёклым. Светлая вуаль такой кадр не осветляет, а замутняет. */
.media[data-ratio="hero"]::before{content:'';position:absolute;
  left:0;right:0;top:0;height:clamp(150px,22vh,260px);
  z-index:1;pointer-events:none;
  background:linear-gradient(to bottom,
    color-mix(in srgb,var(--deep) 78%,transparent) 0%,
    color-mix(in srgb,var(--deep) 44%,transparent) 46%,
    color-mix(in srgb,var(--deep) 14%,transparent) 78%,
    transparent 100%)}
.media-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Исключение из «нижней вуали нет» - только у картинки первого экрана
   посадочной и только на телефоне. На компьютере сюжет кадра справа, а
   заголовок лежит на тёмной левой трети. На узком экране кадр 3:2 режется
   по центру, и под заголовок уходит сам сюжет - лицо, свеча, полотенце:
   золотая подпись и подзаголовок на нём не читались (15.09, после картинок
   на всех посадочных). Вуаль снизу вверх, верх кадра остаётся чистым. */
@media (max-width:760px){
  .media[data-ratio="hero"]:has(> img.media-poster)::after{content:'';position:absolute;
    inset:0;z-index:2;pointer-events:none;
    background:linear-gradient(to top,
      color-mix(in srgb,var(--deep) 92%,transparent) 0%,
      color-mix(in srgb,var(--deep) 80%,transparent) 45%,
      color-mix(in srgb,var(--deep) 30%,transparent) 72%,
      transparent 90%)}
}
.media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.media-note{position:absolute;left:var(--gap-2);bottom:var(--gap-2);z-index:2;
  font-size:var(--step--1);letter-spacing:.1em;text-transform:uppercase;
  color:var(--cream);text-shadow:0 1px 6px rgba(0,0,0,.7);
  display:flex;align-items:center;gap:8px}
.media-note small{text-transform:none;letter-spacing:.02em;color:var(--text-muted)}
.media-over{position:relative;z-index:3}
/* Две кнопки в кадре стоят в строку и переносятся на узком экране:
   вторая, уехавшая под первую на телефоне, - это не ряд, а список. */
.hero-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--gap-2)}
/* Обводка кнопки в кадре кремовая при ЛЮБОЙ температуре.
   .btn-line строится на var(--text), а он под кремовой темой тёмный -
   тёмная рамка и тёмная надпись на тёмном кадре пропадают совсем.
   Кадр снят в темноте и остаётся тёмным независимо от темы (см. выше),
   значит и кнопка на нём обязана быть светлой. Ни одного цвета
   литералом: кремовый берётся из палитры бренда. */
.media[data-ratio="hero"] .btn-line{
  border-color:color-mix(in srgb,var(--cream) 55%,transparent);
  color:var(--cream)}

/* Раньше на узком экране видео не грузилось вовсе: мегабайт ролика на
   мобильном трафике дороже эффекта, а мобильный трафик у салона основной.
   Расчёт изменился вместе с роликом. Вертикальная петля весит 218 КБ -
   меньше, чем обычная фотография-обложка, - поэтому телефон получает её,
   а не заглушку. Выбор источника делает скрипт: разные <source media> для
   видео браузеры соблюдают ненадёжно, а два <video> скачали бы оба файла.

   Три случая, когда ролик НЕ запускается, и постер остаётся один:
   отключённая анимация в системе, режим экономии трафика и отсутствие JS.
   Во всех трёх постер - полноценная картинка, а не серый прямоугольник. */
.hero-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* Кнопка звука. Звук выключен по умолчанию и включается только руками:
   сайт, заигравший сам, закрывают. */
/* Кнопка звука: круг со значком и маленькая подпись под ним.

   Одного значка мало: треугольник в круге читается как «включить видео»,
   а не «включить звук» - видео на герое и так играет. Подпись снимает
   этот вопрос за одно слово и меняется вместе с состоянием.

   Подпись видимая, а не только для читалки экрана: она нужна всем
   одинаково. Отдельного aria-label поэтому нет - имя кнопке даёт сам
   текст, и дублировать его значило бы рискнуть, что они разойдутся.

   Значок меняется по состоянию: треугольник, когда звук выключен,
   две черты, когда играет. Привычная пара, объяснять не надо. */
.sound-toggle{position:absolute;left:50%;bottom:clamp(24px,5vh,56px);
  transform:translateX(-50%);z-index:4;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  background:transparent;border:0;padding:0;cursor:pointer;color:var(--cream)}
.sound-dot{width:62px;height:62px;border-radius:50%;display:grid;place-items:center;
  background:color-mix(in srgb,var(--deep) 52%,transparent);
  border:1px solid color-mix(in srgb,var(--gold) 45%,transparent);
  backdrop-filter:blur(10px);
  transition:border-color var(--dur-1) var(--ease),background var(--dur-1) var(--ease),transform var(--dur-1) var(--ease)}
.sound-toggle svg{width:19px;height:19px;fill:currentColor;
  /* Треугольник тяжелее слева: без сдвига он смотрится съехавшим к краю
     круга, хотя геометрически стоит по центру. */
  margin-left:3px}
.sound-toggle[aria-pressed="true"] svg{margin-left:0}
.sound-toggle .icon-pause{display:none}
.sound-toggle[aria-pressed="true"] .icon-play{display:none}
.sound-toggle[aria-pressed="true"] .icon-pause{display:block}
/* У подписи своя подложка, а не только тень. Она стоит внизу по центру
   кадра, куда боковое затемнение уже не достаёт, и на светлом участке
   (пламя свечи) приглушённый цвет давал 1.81:1 при норме 4.5. Тень
   помогает глазу, но контраста не создаёт.

   Подложка повторяет круг: тот же затемнённый фон и то же размытие, -
   поэтому знак и подпись читаются как одна кнопка, а не как надпись
   рядом с ней. */
.sound-caption{font:600 10px/1 var(--ui);letter-spacing:.14em;
  text-transform:uppercase;color:var(--cream);
  padding:6px 11px;
  background:color-mix(in srgb,var(--deep) 62%,transparent);
  border:1px solid color-mix(in srgb,var(--gold) 22%,transparent);
  backdrop-filter:blur(10px);
  transition:color var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease)}
/* Пока звук играет, вокруг круга идёт медленная волна - тихий признак
   включённого состояния. */
.sound-toggle[aria-pressed="true"] .sound-dot{
  animation:sound-pulse var(--breath) var(--ease-breath) infinite}
@keyframes sound-pulse{
  0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--gold) 30%,transparent)}
  100%{box-shadow:0 0 0 22px transparent}
}
@media (hover:hover){
  .sound-toggle:hover .sound-dot{border-color:var(--gold);
    background:color-mix(in srgb,var(--deep) 68%,transparent);
    transform:scale(1.06)}
  .sound-toggle:hover .sound-caption{color:var(--cream)}
}

/* Компактная копия той же кнопки - в фиксированном виджете связи.

   Она нужна на страницах без кадра: звук общий для всего сайта, и
   выключать его человек должен там, где он играет, а не возвращаясь
   на главную. Класс .sound-toggle оставлен намеренно - значки,
   состояния и волна вокруг круга приходят оттуда, здесь меняются
   только размер, привязка и цвета.

   Цвета - как у соседней кнопки связи: она стоит в потоке страницы,
   а не поверх затемнённого кадра, и полупрозрачный тёмный круг из
   кадра на кремовом фоне выглядел бы пятном. */
.sound-mini{position:static;transform:none;color:var(--text)}
.sound-mini .sound-dot{width:46px;height:46px;
  background:var(--surface);
  border-color:var(--line);
  box-shadow:0 12px 30px rgba(0,0,0,.28)}
.sound-mini svg{width:16px;height:16px}
@media (hover:hover){
  .sound-mini:hover .sound-dot{border-color:var(--accent)}
}

@media (max-width:900px){
  .media-note{display:none}
  .sound-toggle{bottom:clamp(18px,4vh,36px)}
  .sound-dot{width:54px;height:54px}
}

/* Плитки ритуалов: у каждой свой зацикленный ролик.

   Пять роликов сразу - это пять параллельных декодеров, и на слабом
   телефоне страница от этого дёргается. Поэтому preload="none", а
   воспроизведение включается, только когда плитка попала в экран,
   и выключается, когда ушла.

   До этого виден кадр-картинка .tile-poster - тот же первый кадр. Атрибут
   poster для этого не годится: на iPhone клиента 15.09 плитки с ним стояли
   пустыми серыми.

   Картинка лежит ПОВЕРХ ролика и исчезает, когда пошли кадры (класс
   is-hidden ставит home.js по событию playing). Сначала было наоборот -
   прозрачный ролик под картинкой, - и на Android мини-видео перестали
   запускаться вовсе: браузер не заводит беззвучный автозапуск у ролика,
   который считает невидимым, а ролик оставался невидимым, потому что не
   запускался. Ролик теперь всегда видим для браузера.

   Затемнения плиток (::after) подняты на тот же слой, что и картинка, и
   идут после неё - иначе картинка легла бы поверх градиента. */
img.tile-poster{z-index:1;transition:opacity var(--dur-2) var(--ease)}
img.tile-poster.is-hidden{opacity:0}
video.ritual-media{object-fit:cover}
