/* Оформление приложения панели.
 *
 * ── Из чего считались размеры ───────────────────────────────────────────────
 *
 * Целевое устройство по ТЗ: сенсорная панель 3840×2160, горизонтальная
 * ориентация. При диагонали 65 дюймов это полотно 1440×810 мм, то есть
 * 2,67 пикселя на миллиметр.
 *
 * 1. Расстояние взаимодействия. Посетитель не рассматривает панель издалека —
 *    он её касается, а значит стоит на расстоянии вытянутой руки, 45–70 см.
 *    Верстать «чтобы читалось с двух метров» здесь неправильно: текст
 *    раздувается, на экран перестаёт помещаться содержимое, и интерфейс
 *    выглядит как презентация, а не как справочник.
 *    Базовый кегль: 17 px на макете 1920 и 26 px на панели 3840 — при 2,67 px/мм
 *    это около 10 мм высоты строки, комфортно для чтения с полуметра.
 *
 * 2. Размер сенсорной цели. ISO 9241-400 и практика публичных киосков:
 *    не меньше 9–10 мм, для терминалов общего доступа — от 15 мм.
 *    15 мм × 2,67 = 40 px на панели. Отсюда --цель: 2.4rem, что при кегле 26 px
 *    даёт 62 px (23 мм) — с запасом, включая пользователей в перчатках зимой.
 *
 * 3. Зона досягаемости. Панель такого размера ставят так, что её верхняя
 *    кромка оказывается примерно на 180 см от пола. Дотянуться туда, не задирая
 *    руку, нельзя, а для человека в коляске недосягаема и верхняя половина
 *    (ГОСТ Р 51671: органы управления до 120 см). Поэтому вся навигация
 *    вынесена в нижнюю панель — «пульт», а верх экрана только показывает.
 *
 * 4. Контраст. WCAG 2.1 AA (ГОСТ Р 52872-2019): не ниже 4.5:1 для основного
 *    текста. Цвета подобраны с запасом: --текст на --фон даёт 14:1,
 *    --текст-2 на --фон — 7:1.
 */

/* ── Шрифт ────────────────────────────────────────────────────────────────────
 *
 * Golos Text, лицензия SIL Open Font License 1.1 (файл шрифты/OFL.txt),
 * авторы Александра Королькова и Виталий Кузьмин. Гарнитура сделана
 * для интерфейсов и имеет родную кириллицу.
 *
 * Раньше здесь стоял Segoe UI, то есть шрифт операционной системы. Это плохо
 * по трём причинам сразу. Он проприетарный, лицензия Microsoft разрешает его
 * только внутри Windows — передать заказчику дизайн, построенный на нём,
 * нельзя. На панели под Android его нет вовсе, и та же самая вёрстка выглядит
 * там иначе: другая ширина букв, другие переносы, поехавшие подписи на плитках.
 * И, наконец, техническое задание требует, чтобы концептуальный дизайн задавал,
 * «какие шрифты, цвета и графические решения следует использовать», — шрифт,
 * который выбирает за нас устройство, такому требованию не отвечает.
 *
 * Файлы лежат рядом, а не тянутся с внешнего сервера: панель обязана работать
 * без интернета, и подгружаемый шрифт при пропаже сети подменился бы системным
 * посреди работы. Наборы разделены по unicode-range — при русском тексте
 * латинский файл не загружается вовсе.
 */
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/шрифты/golos-400-cyr.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/шрифты/golos-400-lat.woff2') format('woff2');
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/шрифты/golos-500-cyr.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/шрифты/golos-500-lat.woff2') format('woff2');
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/шрифты/golos-600-cyr.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/шрифты/golos-600-lat.woff2') format('woff2');
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/шрифты/golos-700-cyr.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Голос'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/шрифты/golos-700-lat.woff2') format('woff2');
}

:root {
  --фон: #0f1c2e;
  --фон-2: #16273d;
  --карточка: #1d3550;
  --акцент: #d4a24c;
  --акцент-2: #e8bd6d;
  --текст: #f2f5f8;
  --текст-2: #9fb0c2;
  --радиус: .8rem;

  /* Минимальная сторона сенсорной цели — см. пункт 2 выше */
  --цель: 2.4rem;
  --поле: 1.6rem;          /* поля экрана */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* Атрибут hidden прячет элемент через display:none из стилей браузера,
   а любое наше правило с display перебивает его по специфичности.
   Восстанавливаем приоритет явно. */
[hidden] { display: none !important; }

html {
  /* 17 px при ширине 1920, 26 px при 3840 — линейно между ними */
  font-size: clamp(15px, 0.47vw + 8px, 26px);
}

body {
  /* Запасные — только на случай, если файл шрифта не отдался: панель должна
     показать текст в любом случае, пусть и не той гарнитурой. */
  font-family: 'Голос', 'Segoe UI', Roboto, sans-serif;
  background: var(--фон);
  color: var(--текст);
  height: 100vh;
  overflow: hidden;
  /* Панель — не сайт: выделять текст и вызывать меню посетитель не должен */
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ── Каркас экрана ────────────────────────────────────────────────────────── */

.экран {
  display: none;
  position: fixed; inset: 0;
  grid-template-rows: auto 1fr auto;   /* шапка · полотно · пульт */
  animation: появление .18s ease;
}
.экран.активен { display: grid; }

@keyframes появление {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.полотно { overflow-y: auto; overscroll-behavior: contain; }

/* ── Заставка ─────────────────────────────────────────────────────────────── */

/* Единственный экран, который смотрят издалека: он должен позвать человека
   через зал. Здесь крупный кегль оправдан. */
.заставка { align-items: center; justify-content: center; text-align: center; cursor: pointer; }
.заставка.активен { display: flex; }

.заставка-фон {
  position: absolute; inset: 0;
  background: linear-gradient(160deg, #0f1c2e 0%, #1b3350 55%, #2a4a6e 100%);
  background-size: cover; background-position: center;
}
.заставка-фон::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, transparent 30%, rgba(15,28,46,.85) 100%);
  z-index: 1;                       /* затемнение поверх кадров, но под текстом */
}

/* Материалы загрузочного экрана: кадры слайд-шоу и видеоряд. */
.заставка-фон-медиа { background: #0b1421; }
.заставка-фон img, .заставка-фон video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
/* Кадры сменяются мягко: резкая подмена на большом экране бьёт по глазам. */
.кадр-заставки { opacity: 0; transition: opacity 1.2s ease; }
.кадр-заставки.виден { opacity: 1; }

.заставка-текст { position: relative; z-index: 1; padding: 2rem; }
.заставка-текст h1 {
  font-size: 4rem; font-weight: 700; letter-spacing: -0.02em;
  margin-bottom: 1rem; text-shadow: 0 2px 20px rgba(0,0,0,.4);
}
.заставка-текст p { font-size: 1.7rem; color: var(--текст-2); margin-bottom: 2.5rem; }

.кнопка-старт {
  font: inherit; font-size: 1.8rem; font-weight: 600;
  padding: 1.2rem 4rem; min-height: calc(var(--цель) * 1.6);
  color: #17202e; background: var(--акцент);
  border: none; border-radius: 4rem; cursor: pointer;
  box-shadow: 0 8px 30px rgba(212,162,76,.35);
  animation: пульс 2.4s ease-in-out infinite;
}
@keyframes пульс {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* ── Шапка: только сведения, ничего нажимаемого ───────────────────────────── */

.шапка {
  display: flex; align-items: center; gap: 1.2rem;
  padding: 1rem var(--поле);
  background: var(--фон-2);
  border-bottom: 1px solid rgba(255,255,255,.07);
}
.шапка-название { font-size: 1.35rem; font-weight: 600; flex: 1; }
.шапка-погода { font-size: 1rem; color: var(--текст-2); }
.шапка-счёт {
  font-size: 1rem; font-weight: 600; color: var(--акцент-2);
  padding: .3rem .9rem; border-radius: 2rem; background: rgba(212,162,76,.14);
  white-space: nowrap;
}

/* Пояснение о том, что действие сейчас недоступно. Разворачиваем в несколько
   строк: одной строкой такой текст в шапку не помещается. */
.шапка-счёт.предупреждение {
  color: #ffd9a8; background: rgba(214,116,54,.2);
  white-space: normal; max-width: 26rem; font-weight: 500; line-height: 1.3;
}

/* ── Пульт: всё управление у нижней кромки, в зоне досягаемости ───────────── */

.пульт {
  display: flex; align-items: center; gap: .8rem;
  padding: .9rem var(--поле);
  background: var(--фон-2);
  border-top: 1px solid rgba(255,255,255,.09);
}
.пульт-разрыв { flex: 1; }

.кнопка {
  font: inherit; font-size: 1.05rem; cursor: pointer;
  min-height: var(--цель);
  padding: 0 1.4rem;
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--текст); background: rgba(255,255,255,.09);
  border: none; border-radius: calc(var(--цель) / 2);
  white-space: nowrap;
  transition: transform .1s ease;
}
.кнопка:active { transform: scale(.97); background: rgba(255,255,255,.16); }
.кнопка-основная { background: var(--акцент); color: #17202e; font-weight: 600; }
.кнопка-основная:disabled { background: #33475e; color: var(--текст-2); }

/* Кнопка, которой пока нечего делать: выглядит приглушённо, но нажатие
   принимает и объясняет, чего не хватает. Полностью отключённая кнопка
   на киоске молчит в ответ на палец, и человек считает панель сломанной. */
.кнопка-основная.кнопка-ждёт { background: #33475e; color: var(--текст-2); }
.кнопка-фильтр { background: rgba(212,162,76,.16); color: var(--акцент-2); }
.кнопка-сброса {
  background: transparent; color: var(--акцент-2);
  border: 1px solid rgba(212,162,76,.45);
}

/* ── Плитки главного меню ─────────────────────────────────────────────────── */

/* Разделов тринадцать. На панели они должны помещаться на один экран целиком:
   меню, которое приходится прокручивать, посетитель у киоска просто
   не пролистает — он уйдёт.
 *
 * Раскладка — гибкий ряд, а не грид с автозаполнением. Причина в последнем
 * ряду: тринадцать на пять не делится, и грид прижимал остаток к левому краю,
 * оставляя справа пустое место шириной в две плитки. Ряд с выключкой по центру
 * ставит остаток посередине, и меню выглядит собранным.
 *
 * Плитки все одного размера. Раньше отдельные разделы занимали две клетки —
 * задумка была «выделить главный», а на экране получалась мешанина из широких
 * и узких прямоугольников без всякой системы. */
.плитки {
  display: flex; flex-wrap: wrap; justify-content: center; align-content: flex-start;
  gap: 1rem;
  padding: var(--поле);
}

.плитка {
  position: relative;
  /* Пять в ряд: сто процентов ширины минус четыре промежутка между ними */
  flex: 0 0 calc((100% - 4rem) / 5);
  min-height: 8.5rem;
  padding: 1.2rem;
  background: linear-gradient(145deg, #1d3550 0%, #24425f 100%);
  border-radius: var(--радиус);
  border: 1px solid rgba(255,255,255,.06);
  display: flex; flex-direction: column; justify-content: flex-end;
  cursor: pointer; overflow: hidden;
  transition: transform .1s ease;
}

/* На узких экранах пять плиток в ряд превращаются в марки: держим
   их крупными, уменьшая число в ряду. */
@media (max-width: 1400px) {
  .плитка { flex-basis: calc((100% - 3rem) / 4); }
}
@media (max-width: 1000px) {
  .плитка { flex-basis: calc((100% - 2rem) / 3); }
}
@media (max-width: 700px) {
  .плитка { flex-basis: calc((100% - 1rem) / 2); }
}
.плитка:active { transform: scale(.98); }
.плитка::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--акцент), transparent);
}
.плитка-название { font-size: 1.25rem; font-weight: 600; }

/* Значок раздела: наш векторный знак, загруженное изображение или символ,
   вписанный в CMS. Крупный — на плитке он опознавательный знак, а не
   украшение. Цвет знака задаётся здесь: файлы нарисованы currentColor,
   поэтому меняются вместе с темой, а не остаются намертво белыми. */
.плитка-значок {
  font-size: 2.2rem; line-height: 1; margin-bottom: auto;
  color: var(--акцент-2);
}
.плитка-значок img { width: 3.2rem; height: 3.2rem; object-fit: contain; display: block; }
.плитка-значок .знак {
  display: block; width: 3.2rem; height: 3.2rem;
  background: currentColor;
  mask: var(--файл) center / contain no-repeat;
  -webkit-mask: var(--файл) center / contain no-repeat;
}

/* ── Баннер главного экрана ───────────────────────────────────────────────── */

.баннер {
  margin: var(--поле) var(--поле) 0;
  padding: 1.6rem 1.8rem;
  border-radius: var(--радиус);
  background: linear-gradient(120deg, #1d3550 0%, #24425f 100%);
  background-size: cover; background-position: center;
  position: relative; overflow: hidden;
}
/* С фоновым снимком текст читается только по затемнению — иначе заголовок
   теряется на светлых участках кадра. */
.баннер-с-фоном::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(15,28,46,.88) 0%, rgba(15,28,46,.45) 100%);
}
.баннер-текст { position: relative; }
.баннер-заголовок { font-size: 1.7rem; font-weight: 700; }
.баннер-подпись { font-size: 1.05rem; color: var(--текст-2); margin-top: .4rem; max-width: 46rem; }

/* ── Карточки материалов ──────────────────────────────────────────────────── */

/* Карточки вертикальные — под пропорции снимков портала (см. .карточка-фото).
   Ширина задана так, чтобы на панели 3840 вставало семь столбцов, а на
   ноутбуке заказчика (1920) — шесть: снимок остаётся размером с открытку,
   и на экран помещается больше одного ряда. */
.карточки {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  grid-auto-rows: min-content;   /* без этого overflow:hidden схлопывает строки */
  padding: var(--поле);
  align-content: start;
}

.карточка {
  background: var(--фон-2);
  border-radius: var(--радиус);
  overflow: hidden;
  cursor: pointer;
  border: 2px solid transparent;
  transition: transform .1s ease, border-color .1s ease;
}
.карточка:active { transform: scale(.985); }
.карточка.выбрана { border-color: var(--акцент); }
.карточка.недоступна { opacity: .5; cursor: default; }

/* Кадрирование.
 *
 * Замер шестидесяти случайных снимков портала: 87 % из них вертикальные,
 * типовой размер 865×1200. Горизонтальная карточка под такие фотографии
 * не годится — при кадре 3:2 выбрасывалось 46 % снимка, при 4:3 — 41 %.
 * Соотношение 4:5 оставляет за кадром 9 %.
 *
 * Точка кадрирования — у верхнего края. При любом другом значении избыток
 * делится между верхом и низом, и у вертикальных фотографий срезается
 * верхушка: памятники оставались без голов, у церквей пропадали купола.
 * Со значением top верх не обрезается никогда, а низ у таких снимков почти
 * всегда занят газоном, асфальтом или оградой. */
.карточка-фото {
  width: 100%; aspect-ratio: 4 / 5;
  object-fit: cover; object-position: center top;
  display: block; background: #22344a;
}
/* Подпись поверх снимка.
 *
 * Затемнение снизу обязательно: белый текст на светлом кадре — это не
 * «немного бледно», а нечитаемо, и на панели 65 дюймов, где смотрят под
 * углом, ещё хуже. Градиент внизу плотный (до 92% непрозрачности), поэтому
 * контраст держится и на снежных, и на небесных снимках.
 *
 * Карточка при этом остаётся ровным прямоугольником: подпись лежит внутри,
 * а не добавляет высоту. */
.карточка { position: relative; }

.карточка-подпись {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 2.5rem .9rem .8rem;
  background: linear-gradient(to top,
    rgba(9, 17, 28, .92) 0%,
    rgba(9, 17, 28, .78) 40%,
    rgba(9, 17, 28, .35) 72%,
    rgba(9, 17, 28, 0) 100%);
  pointer-events: none;                 /* нажатие принимает сама карточка */
}

.карточка-заголовок {
  font-size: 1.05rem; font-weight: 600; line-height: 1.3;
  /* Длинные названия обрезаем двумя строками: третья строка съедает снимок,
     ради которого карточка и существует. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .55);
}
.карточка-метка {
  font-size: .85rem; color: var(--акцент-2); margin-top: .2rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .55);
}

/* Карточки экскурсий и роликов: подпись под снимком, с описанием. Они ведут
   не к странице объекта, а сразу к записи или плееру — прочитать, о чём речь,
   больше будет негде. */
.карточка-с-описанием .карточка-фото { aspect-ratio: 3 / 2; }
.карточка-тело { padding: .8rem .9rem 1rem; }
.карточка-с-описанием .карточка-заголовок { text-shadow: none; -webkit-line-clamp: 3; }
.карточка-с-описанием .карточка-метка { text-shadow: none; color: var(--акцент); }
.карточка-анонс {
  font-size: .9rem; color: var(--текст-2); margin-top: .4rem; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* ── Подбор: выдвижная панель снизу ───────────────────────────────────────── */

/* Отборы жили в потоке над карточками и занимали половину экрана: двенадцать
   городов и десяток видов переносились на пять строк, а до самих карточек
   очередь доходила уже за нижней кромкой. Выдвижная панель открывается по
   кнопке, накрывает содержимое и закрывается — на экране остаётся то, за чем
   посетитель пришёл. */
.штора {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(9, 17, 28, .6);
  animation: появление .15s ease;
}

.подбор {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  max-height: 62vh;
  display: flex; flex-direction: column;
  background: var(--фон-2);
  border-top: 1px solid rgba(255,255,255,.12);
  border-radius: 1.2rem 1.2rem 0 0;
  box-shadow: 0 -12px 40px rgba(0,0,0,.45);
  animation: выдвижение .2s ease;
}
@keyframes выдвижение {
  from { transform: translateY(100%); }
  to   { transform: none; }
}

.подбор-шапка {
  display: flex; align-items: center; gap: 1rem;
  padding: 1rem var(--поле);
  border-bottom: 1px solid rgba(255,255,255,.07);
}
.подбор-название { font-size: 1.2rem; font-weight: 600; flex: 1; }
.подбор-тело { overflow-y: auto; padding: 1.2rem var(--поле) var(--поле); display: grid; gap: 1.2rem; }

.отбор-группа { display: grid; gap: .6rem; }
.отбор-подпись { font-size: .95rem; color: var(--текст-2); }
.отбор-кнопки { display: flex; flex-wrap: wrap; gap: .6rem; }
.отбор-кнопка {
  font: inherit; font-size: 1rem; cursor: pointer;
  min-height: var(--цель); padding: 0 1.2rem;
  color: var(--текст); background: rgba(255,255,255,.07);
  border: 2px solid transparent; border-radius: calc(var(--цель) / 2);
  white-space: nowrap;
}
.отбор-кнопка.выбран { border-color: var(--акцент); color: var(--акцент-2); background: rgba(212,162,76,.12); }
.отбор-кнопка:active { transform: scale(.97); }

/* ── Карточка объекта ─────────────────────────────────────────────────────── */

.материал { padding: var(--поле); max-width: 68rem; }
/* На самой карточке объекта фотографию не обрезаем вовсе: место есть, а объект
   посетитель уже выбрал — он пришёл его рассмотреть. Ограничиваем высоту,
   чтобы снимок не выталкивал описание за пределы экрана, а ширину отдаём
   пропорциям: снимки портала вертикальные, и растянутый на всю колонку
   вертикальный кадр выглядел бы полосой с пустыми полями по бокам. */
.материал > img {
  max-height: 46vh; max-width: 100%; width: auto;
  border-radius: var(--радиус); background: #16273d;
}
.материал h2 { font-size: 1.7rem; margin: 0 0 .6rem; }
.материал h3 { font-size: 1.2rem; margin: 1.4rem 0 .7rem; }
.материал p { font-size: 1.05rem; line-height: 1.6; color: var(--текст-2); margin-bottom: .8rem; }

.материал-шапка { margin: 1.2rem 0 1rem; }
.материал-метки { display: flex; flex-wrap: wrap; gap: .5rem; }
.метка {
  font-size: .9rem; padding: .3rem .9rem; border-radius: 2rem;
  background: rgba(212,162,76,.16); color: var(--акцент-2);
}

.удобства {
  list-style: none; display: grid; gap: .45rem 1.4rem;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}
.удобства li { font-size: 1rem; color: var(--текст-2); padding-left: 1.4rem; position: relative; }
.удобства li::before { content: '✓'; position: absolute; left: 0; color: var(--акцент); }

.контакты {
  margin-top: 1.4rem; padding: 1.1rem 1.3rem;
  background: var(--фон-2); border-radius: var(--радиус);
  display: grid; gap: .6rem;
}
.контакт { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
/* Кнопка «Открыть на телефоне» стоит в строке контакта — ниже нормы касания
   она быть не может, поэтому высоту держим прежней, уменьшая только поля. */
.кнопка-мелкая-действие { font-size: .95rem; padding: 0 1rem; min-height: var(--цель); }

/* Ссылки на сторонние ресурсы из текста: группа ВКонтакте, сайт фестиваля.
   Кнопки в ряд с переносом — их бывает и одна, и пять. */
.ссылки { display: flex; flex-wrap: wrap; gap: .7rem; }
.кнопка-ссылка { font-size: 1rem; padding: 0 1.2rem; }
.контакт-подпись { font-size: .9rem; color: var(--текст-2); min-width: 6rem; flex-shrink: 0; }
.контакт-значение { font-size: 1.05rem; }

.галерея {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
}
.галерея img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover; object-position: center top;
  border-radius: .6rem; background: #22344a;
}

/* ── Экран с QR-кодом ─────────────────────────────────────────────────────── */

.qr-обёртка {
  min-height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1.2rem; padding: var(--поле);
}
.qr-подпись { font-size: 1.15rem; color: var(--текст-2); }
#qr {
  background: #fff; padding: 1rem; border-radius: var(--радиус);
  display: flex; align-items: center; justify-content: center;
}
/* Код рисуется по одному пикселю на модуль и растягивается до нужного размера.
   Сглаживание при растяжении размывает границы модулей — для камеры это шум,
   поэтому оно отключено. Размер задан с запасом: у маршрута из десяти точек
   сетка кода мельче, чем у короткой ссылки, а читаться он обязан одинаково. */
#qr img, #qr canvas {
  display: block; width: 18rem; height: 18rem;
  image-rendering: pixelated;
}
/* Ссылку показываем и текстом: если камера не срабатывает, короткий адрес
   можно набрать руками — ради этого он и короткий. */
.qr-ссылка { font-size: 1.2rem; font-weight: 600; letter-spacing: .04em; color: var(--акцент-2); }
.qr-точки { font-size: .95rem; color: var(--текст-2); text-align: center; }

/* Порядок обхода под кодом. Читают его стоя, поэтому список набран крупнее
   обычной подписи, а номера вынесены в кружки — так видно, что это
   последовательность, а не просто перечисление выбранного. */
.порядок-заголовок {
  font-size: 1.05rem; font-weight: 600; color: var(--акцент-2);
  margin-bottom: .6rem;
}
.порядок {
  list-style: none; counter-reset: шаг;
  display: flex; flex-direction: column; gap: .45rem;
  max-width: 34rem; margin: 0 auto; padding: 0; text-align: left;
}
.порядок li {
  counter-increment: шаг;
  display: flex; align-items: baseline; gap: .7rem;
  font-size: 1.05rem; color: var(--текст);
}
.порядок li::before {
  content: counter(шаг);
  flex: 0 0 1.7rem; height: 1.7rem; line-height: 1.7rem;
  border-radius: 50%; text-align: center;
  background: rgba(212,162,76,.18); color: var(--акцент-2);
  font-size: .9rem; font-weight: 600;
}

/* ── Просмотр стороннего сайта ────────────────────────────────────────────── */

/* Сайт слева, код для телефона справа: посетитель видит страницу и сразу
   понимает, как забрать её с собой, не отходя от панели. */
.сайт-полоса { display: flex; gap: var(--поле); padding: var(--поле); height: 100%; }
.сайт-рамка {
  /* min-width обязателен: без него на узком экране рамка схлопывается в ноль,
     уступая всю ширину панели с QR-кодом, — и сайт просто не виден.
     На панели 3840 места хватает с избытком, но проверять вёрстку приходится
     и в окне поменьше. */
  flex: 1 1 auto; min-width: 22rem; min-height: 60vh;
  background: #fff; border-radius: var(--радиус); overflow: hidden;
}
.сайт-окно { width: 100%; height: 100%; border: none; display: block; }

.сайт-код {
  width: 20rem; flex-shrink: 0;
  display: flex; flex-direction: column; align-items: center; gap: 1rem;
  padding: 1.4rem; background: var(--фон-2); border-radius: var(--радиус);
  text-align: center;
}
.сайт-код-подпись { font-size: 1rem; color: var(--текст-2); line-height: 1.45; }
#сайт-qr { background: #fff; padding: .8rem; border-radius: var(--радиус); }
#сайт-qr canvas { display: block; width: 14rem; height: 14rem; image-rendering: pixelated; }
.сайт-код-адрес { font-size: .9rem; color: var(--акцент-2); word-break: break-all; }

/* Снимок сайта на месте рамки. Показываем его целиком, вписывая по ширине:
   обрезать первую страницу нельзя — именно она и объясняет, что за место. */
.сайт-снимок {
  height: 100%; display: flex; flex-direction: column;
  background: #fff;
}
.сайт-снимок img {
  flex: 1 1 auto; min-height: 0;
  width: 100%; object-fit: contain; object-position: center top;
  display: block;
}
.сайт-снимок-подпись {
  flex: 0 0 auto;
  padding: .8rem 1.2rem;
  font-size: .95rem; line-height: 1.4; color: #4a5c70;
  background: #eef2f6; border-top: 1px solid #d7dee6;
}

/* Сайт запретил показ в рамке, а снимка ещё нет — тогда объяснение. */
.сайт-нельзя {
  height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .8rem;
  padding: 2rem; text-align: center; color: #4a5c70;
}
.сайт-нельзя-заголовок { font-size: 1.3rem; font-weight: 600; color: #22344a; }
.сайт-нельзя-текст { font-size: 1.05rem; max-width: 32rem; line-height: 1.5; }

/* ── Просмотр документа ───────────────────────────────────────────────────── */

/* Просмотрщик занимает всё полотно: документ на панели читают, а не
   разглядывают в углу экрана. */
.документ { height: 100%; padding: var(--поле); }
.документ-просмотр {
  width: 100%; height: 100%; min-height: 60vh;
  border: none; border-radius: var(--радиус); background: #fff;
}
.кнопка-документа { margin-top: 1.4rem; }

/* ── Календарь мероприятий ────────────────────────────────────────────────── */

.календарь { padding: var(--поле); max-width: 62rem; }
.календарь-шапка { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.календарь-месяц { font-size: 1.4rem; font-weight: 600; flex: 1; text-align: center; }

.дни-недели, .сетка-дней { display: grid; grid-template-columns: repeat(7, 1fr); gap: .5rem; }
.дни-недели { font-size: .95rem; color: var(--текст-2); text-align: center; margin-bottom: .4rem; }

.день {
  min-height: var(--цель); padding: .5rem;
  background: var(--фон-2); border-radius: .6rem;
  border: 2px solid transparent;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--текст-2);
}
.пусто-день { background: transparent; }
/* День с событиями — единственный, по которому есть смысл нажимать,
   поэтому он и выглядит нажимаемым. */
.день.есть-события { color: var(--текст); cursor: pointer; background: #1d3550; }
.день.есть-события:active { transform: scale(.96); }
.день.сегодня { border-color: var(--текст-2); }
.день.выбран { border-color: var(--акцент); }
.день-число { font-size: 1.1rem; font-weight: 600; }
.день-счёт { font-size: .8rem; color: var(--акцент); }

.события-дня { margin-top: 1.2rem; color: var(--текст-2); font-size: 1.05rem; }
.события-дня-заголовок { font-size: 1.2rem; font-weight: 600; color: var(--текст); margin-bottom: .8rem; }
.событие-строка {
  padding: .8rem 1rem; margin-bottom: .6rem;
  background: var(--фон-2); border-radius: var(--радиус); cursor: pointer;
  border-left: 3px solid var(--акцент);
}
.событие-строка:active { transform: scale(.99); }
.событие-название { font-size: 1.05rem; color: var(--текст); }
.событие-место { font-size: .9rem; color: var(--текст-2); margin-top: .2rem; }

/* ── Поиск и экранная клавиатура ──────────────────────────────────────────── */

.поиск-строка { padding: var(--поле) var(--поле) 0; }
.поиск-поле {
  min-height: calc(var(--цель) * 1.2);
  padding: .7rem 1.1rem;
  font-size: 1.5rem; letter-spacing: .01em;
  background: var(--фон-2); border: 2px solid var(--акцент);
  border-radius: var(--радиус);
  display: flex; align-items: center;
}
/* Мигающая черта на месте набора: поле не системное, и без неё непонятно,
   куда попадают буквы. */
.поиск-курсор {
  display: inline-block; width: 2px; height: 1.4em;
  background: var(--акцент); animation: мигание 1s step-end infinite;
}
@keyframes мигание { 50% { opacity: 0; } }

.клавиатура {
  flex-shrink: 0; padding: .6rem var(--поле);
  background: var(--фон-2); border-top: 1px solid rgba(255,255,255,.07);
  display: grid; gap: .4rem;
}
.клавиатура-ряд { display: flex; gap: .4rem; justify-content: center; }
.клавиша {
  font: inherit; font-size: 1.15rem; cursor: pointer;
  min-width: var(--цель); min-height: var(--цель);
  flex: 1; max-width: 4.5rem;
  color: var(--текст); background: rgba(255,255,255,.09);
  border: none; border-radius: .5rem;
}
.клавиша:active { background: var(--акцент); color: #17202e; }
.клавиша-пробел { max-width: 22rem; flex: 4; font-size: 1rem; color: var(--текст-2); }
.клавиша-стереть { max-width: 6rem; flex: 1.5; }

/* Найденный раздел в поиске — карточка без снимка, поэтому подпись у неё
   обычная, под текстом, а не поверх фотографии. */
.карточка-раздел {
  border: 2px solid var(--акцент);
  display: flex; align-items: center; min-height: 7rem;
}
.карточка-раздел .карточка-заголовок { text-shadow: none; }
.карточка-раздел .карточка-метка { text-shadow: none; color: var(--акцент); }

/* ── Формы ────────────────────────────────────────────────────────────────── */

.форма { padding: var(--поле); max-width: 56rem; }
.форма h3 { font-size: 1.2rem; margin: 1.2rem 0 .8rem; }
.форма h3:first-child { margin-top: 0; }

/* Поля в два столбца: на широком экране колонка ввода во всю ширину панели
   выглядит нелепо и заставляет вести взгляд через полтора метра. */
.поля { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }

.поле { display: block; margin-bottom: .9rem; }
.поле > span { display: block; font-size: .95rem; color: var(--текст-2); margin-bottom: .35rem; }
.поле > span em { color: var(--акцент); font-style: normal; }
.поле input, .поле textarea {
  font: inherit; font-size: 1.05rem; width: 100%;
  min-height: var(--цель); padding: .6rem .9rem;
  color: var(--текст); background: var(--фон-2);
  border: 2px solid rgba(255,255,255,.09); border-radius: .6rem;
  resize: none;
}
.поле input:focus, .поле textarea:focus { outline: none; border-color: var(--акцент); }
.поле input::placeholder, .поле textarea::placeholder { color: #5d7086; }

.подсказка { font-size: .95rem; color: var(--текст-2); margin-bottom: 1rem; line-height: 1.45; }

.согласие {
  display: flex; gap: .9rem; align-items: flex-start;
  padding: 1rem 1.2rem; margin-bottom: 1rem;
  background: var(--фон-2); border-radius: var(--радиус);
  font-size: .95rem; line-height: 1.45; color: var(--текст-2);
  cursor: pointer;
}
.согласие input { width: 1.5rem; height: 1.5rem; flex-shrink: 0; accent-color: var(--акцент); }

.сообщение { font-size: 1rem; color: var(--текст-2); min-height: 1.4em; }
.сообщение.успех { color: #7dd08f; }
.сообщение.ошибка { color: #f0a0a0; }

.слоты {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  margin-bottom: 1.2rem;
}
.слот {
  font: inherit; text-align: left; cursor: pointer;
  min-height: var(--цель); padding: .7rem 1rem;
  color: var(--текст); background: var(--фон-2);
  border: 2px solid transparent; border-radius: var(--радиус);
  display: grid; gap: .2rem;
}
.слот.выбран { border-color: var(--акцент); }
.слот:disabled { opacity: .45; cursor: default; }
.слот-время { font-size: 1.05rem; font-weight: 600; }
.слот-детали { font-size: .9rem; color: var(--текст-2); }

/* ── Детский раздел ───────────────────────────────────────────────────────── */

.плеер { height: 100%; display: flex; flex-direction: column; padding: var(--поле); gap: 1rem; }
.плеер video { width: 100%; flex: 1; min-height: 0; background: #000; border-radius: var(--радиус); }
.ролик-описание { font-size: 1.05rem; color: var(--текст-2); }

/* ── Погода ───────────────────────────────────────────────────────────────── */

.погода-обёртка { min-height: 100%; display: flex; align-items: center; justify-content: center; padding: var(--поле); }
.погода-карточка { text-align: center; padding: 2.2rem 3rem; background: var(--фон-2); border-radius: var(--радиус); }
.погода-город { font-size: 1.3rem; color: var(--текст-2); }
.погода-градусы { font-size: 4rem; font-weight: 300; line-height: 1.1; margin: .4rem 0; }
.погода-описание { font-size: 1.3rem; }
.погода-обновлено { font-size: .9rem; color: var(--текст-2); margin-top: 1.1rem; }

/* ── Служебное ────────────────────────────────────────────────────────────── */

.пусто { padding: 2.5rem var(--поле); font-size: 1.05rem; color: var(--текст-2); }

/* Область скрытого выхода: невидимый угол, срабатывает на удержание 5 секунд. */
.угол-выхода { position: fixed; top: 0; right: 0; width: 5rem; height: 5rem; z-index: 100; opacity: 0; }

/* Служебный вход в CMS: различим, только если знаешь, где искать. Размер
   меньше сенсорной нормы намеренно — посетитель не должен попадать по нему
   случайно, а сотрудник нажмёт прицельно.
 *
 * Угол выбран левый верхний: там шапка, в которой нет ни одной нажимаемой
 * области. Внизу иконка стояла бы вплотную к кнопке «Назад» на пульте,
 * и промах по ней уводил бы посетителя в панель управления. */
.вход-в-cms {
  position: fixed; left: .25rem; top: .25rem; z-index: 101;
  width: 1.2rem; height: 1.2rem; padding: 0;
  font: inherit; font-size: .75rem; line-height: 1;
  color: var(--текст-2); background: transparent;
  border: none; border-radius: 50%; cursor: pointer;
  opacity: .16;
}
.вход-в-cms:active { opacity: .7; }

/* Признак отсутствия связи */
body.нет-связи .шапка-погода::before { content: '⚠ '; color: var(--акцент); }

::-webkit-scrollbar { width: .5rem; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,.15); border-radius: 1rem; }
