/* ==========================================================================
   DEYA MUSIC — страничные раскладки
   ========================================================================== */

/* ---------- Общая шапка страницы ---------- */

.page-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
  padding-block: var(--sp-6) var(--sp-5);
}
@media (min-width: 1024px) { .page-head { padding-block: var(--sp-7) var(--sp-6); } }

/* ---------- Главная ---------- */

.home-filters {
  position: sticky;
  top: 68px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding-block: var(--sp-4);
  /* В потоке страницы строка прозрачная (правка заказчика 2026-08-18): подложка
     там ни от чего не защищает, а лишний прямоугольник виден. Появляется она
     ровно на то время, пока строка прилипла к шапке, — класс `is-stuck` вешает
     `initStickyFilters()` в `js/ui.js`, как и у самой шапки. */
  background: none;
}
/* Подложка — отдельным слоем, а не сменой `background` у самой строки: градиент
   с `none` не интерполируется, и фон возникал бы рывком. Слой уходит под
   содержимое строки (`z-index: -1` внутри её же контекста наложения), книзу
   сходит на нет — лента уезжает под строку плавно, а не обрезается линией. */
.home-filters::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom, var(--c-bg) 68%, transparent);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease);
  pointer-events: none;
}
.home-filters.is-stuck::before { opacity: 1; }

@media (min-width: 1024px) { .home-filters { top: 80px; } }

/* Воздух между лентой дат и первой меткой месяца. */
.home-filters + [data-feed] { margin-top: var(--sp-3); }

.home-filters__row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.home-filters__row .scroller { flex: 1; min-width: 0; }
/* Город не должен сжимать ленту дат: у него своя ширина, лента забирает остаток.
   На узких экранах строка переносится, и селект встаёт под лентой. */
.home-filters__row { flex-wrap: wrap; }
.home-filters__row .filters { flex: 0 0 auto; }
@media (max-width: 559.98px) {
  .home-filters__row .filters { width: 100%; }
  .home-filters__row .city-select { width: 100%; }
}

/* Строка фильтров «год + город» (правка заказчика 08.09, мобильный документ:
   «добавляем сортировку: год, город»).

   На мобильном оба селекта делят строку поровну — так она не прыгает, когда
   в городе выбрано длинное название («Нижний Новгород» вместо «Все города»).
   Селекты выглядят одинаково намеренно: это один и тот же тип управления,
   и разный вид означал бы разную природу. */
.home-filters__top {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.home-filters__top .city-select,
.home-filters__top .year-select { flex: 1 1 0; min-width: 0; }
.home-filters__top select { width: 100%; }

/* Строка «год + город» (правка заказчика 08.09, мобильный документ).

   На широком экране фильтр ГОДА не нужен: вся афиша и так видна лентой, а
   лишний селект только занимает место — поэтому он скрыт. Город остаётся, и
   строка из двух элементов превращается в строку из одного, прижатого вправо:
   ровно там он и стоял до правки. */
@media (min-width: 1024px) {
  .home-filters__top { justify-content: flex-end; }
  .home-filters__top .year-select { display: none; }
  /* Ширину город получает по содержимому, а не половину строки: растянутый на
     пол-экрана селект выглядел бы полем ввода, а не фильтром. */
  .home-filters__top .city-select { flex: 0 0 auto; }
}

/* Вход в прошлое над лентой — МОБИЛЬНАЯ механика (правка заказчика 08.09,
   мобильный документ: «прошедшие мероприятия у нас находятся как бы выше по
   ленте»). На десктопе прошедшие живут в отдельном разделе «Архив», и второй
   вход в них с главной только путал бы: там для этого есть пункт меню. */
@media (min-width: 1024px) {
  .feed-past,
  .feed-past__more { display: none; }
}

.feed__more { display: flex; justify-content: center; margin-top: var(--sp-6); }

/* Блоки главной («Ближайшие мероприятия» → «О нас» → «Контакты») стоят вплотную,
   и их вертикальные отступы складываются. Верхний отступ следующей секции задан
   одним значением на обеих ширинах: в сумме с нижним отступом предыдущей выходит
   64px на мобильном и 80px на десктопе. На мобильном это ровно столько же, сколько
   без правила (32+32), — там шаг и так был нормальным; правило работает на десктопе,
   где иначе набегает 96px. */
[data-page='home'] .section--tight + .section--tight { padding-top: var(--sp-6); }

/* ---------- Страница мероприятия ---------- */

.event-layout {
  display: grid;
  gap: var(--sp-6);
  align-items: start;
}
@media (min-width: 1024px) {
  .event-layout {
    grid-template-columns: minmax(0, 1.5fr) minmax(320px, 0.85fr);
    gap: var(--sp-8);
  }
}

/* ---------- Шапка мероприятия: афиша фоном, описание поверх ----------
   Правка заказчика 08.09 (мобильный документ): «по дизайну делаем, как и в
   странице тура (афиша на заднем фоне, поверх неё описание)».

   Устроено ровно как .tour-head, и намеренно: два макета одной сущности
   («страница с афишей и текстом») расходились бы при каждой следующей правке.
   Отличие одно — кадр здесь принадлежит мероприятию, а не туру.

   `margin-inline: calc(50% - 50vw)` растягивает кадр во всю ширину экрана
   поверх полей контейнера; страница от этого не едет вбок, потому что у body
   стоит `overflow-x: clip` (base.css). */
.event-hero {
  position: relative;
  isolation: isolate;
  z-index: 0;
  margin-inline: calc(50% - 50vw);
  margin-top: var(--sp-5);
  /* Верхний отступ — это и есть видимая часть афиши: плашка с названием лежит
     ниже, и без него кадр был бы закрыт ею целиком. Значение в vh, а не в
     пикселях: на высоком экране афише достаётся больше, на низком меньше, но
     плашка в обоих случаях остаётся на виду. */
  padding-block: clamp(var(--sp-6), 22vh, 260px) var(--sp-6);
  background-size: cover;
  background-position: center 30%;
}

/* Вуаль: кадры афиш тёмные и вертикальные, тема светлая. Без засветления текст
   на плашке читался бы, а вот края кадра резали бы страницу пополам. */
.event-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom,
    var(--c-bg) 0%,
    var(--c-veil) 16%,
    var(--c-veil) 76%,
    var(--c-bg) 100%);
}

/* Текст возвращается на сетку контейнера — те же поля, что у всех страниц. */
.event-hero__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.event-hero__panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  max-width: 820px;
  padding: var(--sp-5);
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft);
}
@media (min-width: 1024px) {
  .event-hero { padding-block: clamp(var(--sp-7), 26vh, 320px) var(--sp-7); }
  .event-hero__panel { padding: var(--sp-6); gap: var(--sp-4); }
}

/* Отдельного блока обложки на странице мероприятия больше нет: афиша стала
   фоном шапки (.event-hero выше) — правка заказчика 08.09. Стили .event-cover
   удалены вместе с разметкой, чтобы не оставлять правил, которые ничего не
   оформляют и при следующей правке будут приняты за действующие. */

.event-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  color: var(--c-text-2);
}
.event-meta__item { display: flex; align-items: center; gap: var(--sp-2); }
.event-meta__item svg { width: 17px; height: 17px; color: var(--c-teal); flex-shrink: 0; }

/* Боковая панель покупки */
.buy-panel {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
@media (min-width: 1024px) { .buy-panel { position: sticky; top: 104px; } }

.buy-panel__list { display: flex; flex-direction: column; gap: var(--sp-2); }
.buy-panel__row { display: flex; justify-content: space-between; gap: var(--sp-4); }
.buy-panel__row dt { color: var(--c-text-3); }
.buy-panel__row dd { margin: 0; text-align: right; }

/* Реквизиты организатора: служебная подпись, отделена от списка тонкой линией
   и набрана самым мелким стилем — она обязательна, но не спорит с кнопкой. */
.buy-panel__org {
  margin-top: calc(var(--sp-1) * -1);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--c-border-soft);
  color: var(--c-text-3);
}

/* Блок покупки под описанием мероприятия. Заголовка у секции нет (правка
   заказчика 2026-08-18) — окошко виджета говорит за себя; для скринридеров
   секция подписана `aria-label`. Отступ сверху больше внутреннего шага колонки:
   блок отделён от текста описания, но остаётся частью той же страницы. */
.ticket-section { display: flex; flex-direction: column; gap: var(--sp-4); margin-top: var(--sp-4); }

.event-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* ---------- Страница тура ---------- */

/* Шапка тура: название и описание, а обложка — фоном страницы под ними
   (правка заказчика 2026-08-18; до неё кадр жил в плашке-баннере со скруглением).

   Блок разворачивается во всю ширину экрана отрицательными полями, а текст внутри
   остаётся на сетке контейнера — поэтому фон уходит под края страницы, а строки
   стоят там же, где на остальных страницах. Высоту диктует сам текст: фон
   привязан к блоку, а не задан числом, и не обрежется на длинном описании. */
.tour-head {
  position: relative;
  isolation: isolate;
  margin-inline: calc(50% - 50vw);
  margin-top: var(--sp-5);
  /* Снизу кадр тянется до самого блока «Предстоящие даты» (правка заказчика
     2026-08-18): нижнее поле шапки взяло на себя воздух следующей секции,
     а у секции своё верхнее поле обнулено — иначе между кадром и заголовком
     оставалась бы полоса пустого фона страницы. */
  padding-block: var(--sp-7) var(--sp-9);
  /* Сам адрес обложки подставляется инлайновым `background-image` из `tour.js`:
     через промежуточную переменную относительный путь резолвился от css-файла
     (`css/img/events/…`), и картинка не находилась. */
  background-size: cover;
  background-position: center 35%;
  background-repeat: no-repeat;
}
/* Засветление кадра до фона страницы: плотнее сверху и снизу, чтобы блок
   не обрывался границей, и ровное посередине, где лежит текст. Обложки в данных
   вертикальные и тёмные, а тема светлая: без вуали строки на кадре не прочесть. */
.tour-head::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom,
    var(--c-bg) 0%,
    var(--c-veil) 16%,
    var(--c-veil) 76%,
    var(--c-bg) 100%);
}

@media (min-width: 1024px) { .tour-head { padding-block: var(--sp-8) calc(var(--sp-9) + var(--sp-6)); } }
/* Секция дат начинается сразу за кадром, своего верхнего отступа у неё нет. */
.tour-head + .section { padding-top: 0; }

/* Текст возвращается на сетку контейнера: слева и справа те же поля, что у всех
   страниц, а на широких экранах — ещё и по краю колонки в 1280px. */
.tour-head__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

/* Полупрозрачная плашка поверх фотографии (правка заказчика 2026-08-18): название
   и описание лежат на ней, а не прямо на кадре. Она же и держит контраст, поэтому
   вуаль на самом кадре ослаблена — фотография видна, а строки читаются. */
.tour-head__panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  max-width: 820px;
  padding: var(--sp-5);
  /* Плашка приспущена до 80% (правка заказчика 2026-08-18): сквозь неё
     проглядывает кадр. Своё значение, а не `--c-glass` (0.72) и не
     `--c-glass-strong` (0.92): у шапки и липких панелей за спиной страница,
     а здесь фотография, и порог читаемости другой. */
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft);
}
@media (min-width: 1024px) { .tour-head__panel { padding: var(--sp-6); gap: var(--sp-4); } }

/* Длинные строки читаются хуже — держим их короче ширины самой плашки. */
.tour-head__panel .prose { max-width: 62ch; }

.tour-dates { display: flex; flex-direction: column; }

.tour-date {
  position: relative;
  display: grid;
  gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--c-border-soft);
  grid-template-columns: 1fr;
  transition: background var(--dur-fast) var(--ease);
}
@media (min-width: 768px) {
  .tour-date {
    grid-template-columns: 132px minmax(0, 1fr) auto;
    gap: var(--sp-5);
    padding-inline: var(--sp-3);
    border-radius: var(--r-md);
  }
  .tour-date:hover { background: var(--c-surface); }
}
.tour-date__date { color: var(--c-text); font-family: var(--font-display); font-weight: 600; }
.tour-date__place { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.tour-date__action { display: flex; gap: var(--sp-3); }
/* «Группа ВК» в строке даты — с белой заливкой, а не прозрачная (правка заказчика
   2026-08-18): строки разделены только тонкими линиями, и контурная кнопка
   на пустом фоне читалась слабее соседней «Подробнее», у которой заливка есть.
   Правило точечное: в других местах `btn-secondary` остаётся контурной. */
.tour-date .btn-secondary { background: var(--c-surface); }
.tour-date .btn-secondary:hover { background: var(--c-teal-dim); }
.tour-date--past { opacity: 0.62; }
.tour-date--past:hover { opacity: 1; }

/* ---------- Архив ---------- */

/* Архивная полоса теперь построена на .home-filters (как на главной), поэтому
   собственная раскладка ей больше не нужна — иначе flex-column из старого
   правила ломал бы строку «годы + город» (правка заказчика 08.09).
   Класс сохранён как крючок для точечных отличий архива. */
.archive-bar { padding-block: var(--sp-4) var(--sp-5); }

/* ---------- Фотоотчёт ---------- */

.photo-head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-4); }

.photo-external {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-7) var(--sp-5);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
}

/* Ссылка на внешний альбом ПОД галереей (правка заказчика 08.09, C9): когда
   свои фото есть, альбом — их продолжение, а не замена. Поэтому блок становится
   строкой: текст слева, кнопка справа, высота вдвое меньше «пустого» состояния,
   где он занимает страницу один. */
.photo-external--inline {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-5);
  margin-top: var(--sp-5);
}
.photo-external--inline .btn { flex-shrink: 0; }

/* На узком экране строка всё равно складывается в столбик: кнопка рядом с
   двумя строками текста на 360px не помещается. */
@media (max-width: 639.98px) {
  .photo-external--inline { flex-direction: column; align-items: flex-start; }
}

/* ---------- Блоки «О нас» и «Контакты» на главной ----------
   Отдельных страниц нет: пункты меню ведут якорями вниз главной. */

/* Якорь не должен упираться в липкую шапку — иначе заголовок блока
   оказывается под ней. Запас чуть больше высоты шапки (68 / 80px). */
#about, #contacts { scroll-margin-top: 88px; }
@media (min-width: 1024px) { #about, #contacts { scroll-margin-top: 104px; } }

.text-layout {
  display: grid;
  gap: var(--sp-6);
  align-items: start;
  /* minmax(0, 1fr), а не auto: колонка `auto` не сжимается уже минимальной
     ширины содержимого, и одна длинная неразрывная строка (почта) растягивала
     её шире контейнера — все блоки страницы уезжали за правое поле. */
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 1024px) { .text-layout { grid-template-columns: minmax(0, 1.4fr) minmax(280px, 0.7fr); gap: var(--sp-8); } }

.contact-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
}
.contact-card__row { display: flex; flex-direction: column; gap: var(--sp-1); }
/* Почта и телефон — строки без пробелов: на узком экране им нужно разрешить
   перенос, иначе они торчат из карточки (booking@deyamusic.ru — это 261px). */
.contact-card a, .contact-card address { overflow-wrap: anywhere; }


/* ---------- 404 ---------- */

.error-page {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-5);
  padding-block: var(--sp-9) var(--sp-8);
  max-width: 640px;
}
.error-page__code {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(4.5rem, 2rem + 11vw, 9rem);
  line-height: 0.9;
  letter-spacing: -0.04em;
  background: linear-gradient(100deg, var(--c-teal-ink), var(--c-coral));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.error-page__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
