:root{--bg:#fff;--fg:#161616;--muted:#6b6b6b;--line:#e6e6e6;--card:#fafafa;
/* Голубой из фавикона (#00aaed) — фирменный, но для текста и кнопок его мало:
   белый на нём даёт контраст 2.63 при норме 4.5. Поэтому рабочий акцент —
   затемнённый тон того же цвета, а чистый фирменный живёт в --brand. */
--brand:#00aaed;--accent:#0179a8;--on-accent:#ffffff}
@media(prefers-color-scheme:dark){:root{--bg:#121212;--fg:#ececec;--muted:#9a9a9a;
--line:#2a2a2a;--card:#1b1b1b;
/* На тёмном фоне чистый фирменный читается сам (7.11), затемнять нечего.
   Текст на кнопке при этом должен стать тёмным, иначе контраст падает до 2.63. */
--brand:#00aaed;--accent:#00aaed;--on-accent:#06212c}}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);font:16px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif}
a{color:inherit}
/* 1440 вместо прежних 1080: сетка карточек auto-fill, и на широком мониторе лишние
   360px давали ещё две колонки вместо пустых полей. Читаемость не страдает — длинные
   тексты ограничены отдельно (.lead и .descr по 70ch), а не шириной макета. */
.wrap{max-width:1440px;margin:0 auto;padding:0 16px}
header{border-bottom:1px solid var(--line);padding:14px 0;margin-bottom:24px}
.brand{font-weight:700;font-size:20px;text-decoration:none}
.brand span{color:var(--accent)}
nav{display:flex;flex-wrap:wrap;gap:14px;margin-top:10px;font-size:15px}
nav a{color:var(--muted);text-decoration:none}
/* Цифра у раздела — подсказка о размере, а не часть названия: мельче и приглушённее,
   иначе она спорит с самим названием. Курсив снимаем: <i> здесь выбран как самый
   короткий тег, смысла наклона в нём нет. */
nav i{margin-left:5px;font-style:normal;font-size:12px;opacity:.65;
font-variant-numeric:tabular-nums}
nav a:hover{color:var(--accent)}
/* Сам переключатель не показываем никогда: это приём вёрстки, а не элемент. */
/* Переключатель закреплён на месте, а не лежит в начале документа: фокус на нём
   при нажатии «бутерброда» уводил ленту в самое начало, и человек терял место. */
.nav-toggle{position:fixed;top:0;left:0;opacity:0;width:0;height:0;pointer-events:none}
/* Кнопка установки нужна только там, где приложение вообще ставят — на телефоне.
   На десктопе она сбивает с толку, в уже установленном приложении бессмысленна. */
.install{display:none;padding:8px 14px;border:1px solid var(--accent);border-radius:8px;
color:var(--accent);font-size:14px;font-weight:600;text-decoration:none;flex:0 0 auto}
@media(max-width:860px){.install{display:inline-block}}
@media(display-mode:standalone){.install{display:none!important}}
/* Кнопки мессенджеров в шапке. Показываем их только там, где боковой панели не видно
   в начале страницы, — на широком экране она стоит слева, и вторая пара кнопок была бы
   дублем. Подписаны словами: у MAX узнаваемого значка нет, и без надписи его не
   опознают. */
.head-line{display:contents}
.head-bots{display:none;gap:6px;flex:0 0 auto}
.head-bots a{padding:5px 11px;border:1px solid var(--line);border-radius:999px;
font-size:13px;font-weight:600;text-decoration:none;white-space:nowrap}
.head-bots a:hover,.head-bots a:focus-visible{border-color:var(--accent);color:var(--accent)}
.burger{display:none;flex-direction:column;justify-content:center;gap:5px;width:44px;height:44px;
padding:10px;cursor:pointer;border:1px solid var(--line);border-radius:9px;flex:0 0 auto}
.burger span{display:block;height:2px;background:var(--fg);border-radius:2px}
.burger:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.nav-close{display:none;position:fixed;top:12px;right:14px;z-index:95;
width:44px;height:44px;align-items:center;justify-content:center;cursor:pointer;
border:1px solid var(--line);border-radius:9px;font-size:22px;line-height:1;
background:rgba(11,16,32,.9);color:var(--fg)}
/* До 860px семнадцать разделов занимали шесть рядов и весь первый экран. */
@media(max-width:860px){
  .burger{display:flex}
  nav{display:none}
  /* Первая строка шапки: название слева, мессенджеры справа. Занимает всю ширину,
     поэтому поиск с «Установить» переносятся строкой ниже. */
  .head-line{display:flex;flex:0 0 100%;align-items:center;justify-content:space-between;gap:10px}
  .head-bots{display:flex}
  /* Крупные плашки ботов на телефоне убраны: те же ссылки теперь в шапке, а блок
     стоял перед афишей и занимал 227 px — до первого события приходилось мотать
     полтора экрана (замер 31.08.2026 на 360×640). Пояснение про личную афишу не
     удалено, а уехало под ленту: сверху оно ничего не объясняло человеку, который
     ещё не увидел ни одного события. */
  /* Через `.sidebar`, а не просто `.applink`: правило `.applink{display:block}` стоит
     ниже по файлу, и при равной силе побеждало бы оно — медиазапрос веса не добавляет. */
  .sidebar .applink{display:none}
  .sidebar{order:2}
  main{order:1}
  /* Описание витрины уходит под ленту событий (31.08.2026, решение владельца). Замер
     на 360×640: заголовок и описание занимали 242 px первого экрана, из них 104 px —
     отступы двух стеклянных карточек вокруг четырёх строк текста, и первое событие
     начиналось на 806-м пикселе. Текст не удалён и не обрезан: он виден целиком, но
     после ленты — человеку, выбирающему, куда сходить, он не нужен, а робот читает
     разметку, где абзац стоит на прежнем месте.

     Перестановка требует flex, а он отменяет схлопывание отступов между блоками,
     поэтому включаем его только там, где переносить действительно есть что. Браузеру
     без :has (iOS до 15.4) правило не достанется — страница останется прежней, а не
     сломанной. */
  main:has(>.lead-below){display:flex;flex-direction:column}
  .lead-below{order:99}
  /* Заголовок остаётся первым, но без собственной карточки: её отступы стоили больше,
     чем сам текст. Размер задан через `main>h1`, а не просто `h1`: базовые 28px
     объявлены ниже по файлу, и при равной силе селектора побеждали бы они. */
  body.glass main>h1{background:none;border:0;padding:0;margin-bottom:10px}
  main>h1{font-size:21px;line-height:1.25}
  /* Меню — накладка поверх страницы, а не блок внутри шапки: шапка остаётся вверху
     документа, и раскрытое в ней меню человек, ушедший в середину ленты, не увидит.
     Прокрутка внутри: разделов семнадцать, в высоту телефона они не помещаются. */
  /* Фон плотнее, пока меню открыто: под накладкой шапки всё равно ничего не видно.
     Снятия размытия здесь больше нет — у шапки его нет вовсе. Если оно когда-нибудь
     вернётся, вернуть и `backdrop-filter:none`: размытие делает шапку точкой отсчёта
     для закреплённых потомков, и накладка меню прибивалась к ней вместо экрана. */
  #nav-toggle:checked~header{background:rgba(11,16,32,.94)}
  #nav-toggle:checked~header nav{display:flex;flex-direction:column;gap:0;
    /* nowrap обязателен: у колонки с заданной высотой перенос раскладывает разделы
       во вторую колонку, и половина списка уезжает вбок. */
    flex-wrap:nowrap;
    position:fixed;left:0;right:0;top:0;bottom:0;z-index:90;overflow-y:auto;
    padding:64px 18px calc(24px + env(safe-area-inset-bottom));
    background:rgba(11,16,32,.86);backdrop-filter:blur(20px);
    -webkit-backdrop-filter:blur(20px)}
  #nav-toggle:checked~header nav a{padding:13px 2px;border-bottom:1px solid var(--line);font-size:17px}
  /* Крестик поверх накладки: без него закрыть меню можно только тем же «бутербродом»,
     который накладка и закрывает. */
  #nav-toggle:checked~.nav-close{display:flex}
}
/* Нижняя панель — только в установленном приложении: в браузере снизу уже есть своя,
   с адресом и кнопкой «назад», и вторая мешала бы. */
.tabbar{display:none}
@media(display-mode:standalone){
  .tabbar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:50;
  background:var(--bg);border-top:1px solid var(--line);
  padding-bottom:env(safe-area-inset-bottom)}
  .tabbar a,.tabbar label{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:8px 4px;font-size:11px;color:var(--muted);text-decoration:none;cursor:pointer}
  .tabbar svg{width:23px;height:23px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
  .tabbar a:active,.tabbar label:active{color:var(--accent)}
  /* Текущий раздел фирменным цветом — панель должна отвечать на вопрос «где я». */
  .tabbar a.active{color:var(--accent);font-weight:600}
  .tabbar a.active svg{stroke-width:2.1}
  /* «Ещё» — не раздел, а выдвижное меню. Подсвечиваем её, только пока меню открыто,
     и подсветку текущего раздела при этом не снимаем: страница-то не поменялась. */
  #nav-toggle:checked~.tabbar label{color:var(--accent);font-weight:600}
  #nav-toggle:checked~.tabbar label svg{stroke-width:2.1}
  /* Панель висит поверх страницы — иначе она закрывает низ футера. */
  body{padding-bottom:62px}
}
h1{font-size:28px;line-height:1.2;margin:0 0 8px}
h2{font-size:21px;margin:32px 0 12px}
.lead{color:var(--muted);margin:0 0 24px;max-width:70ch}
/* 230px, а не 260: на странице площадки боковая панель съедает 238px, и при 260
   третья колонка не влезала на распространённом экране 1280 (и на 1440 при зуме 125%).
   С 230 три карточки встают начиная с 1010px ширины контента. */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:18px}
/* Кликабельна вся плашка. Не оборачиваем карточку в <a>: внутри заголовок, а ссылка
   вокруг заголовка — плохая разметка и лишняя ссылка для поисковика. Вместо этого
   растягиваем невидимый слой от единственной ссылки на всю карточку. */
.card{background:var(--card);border:1px solid var(--line);border-radius:10px;overflow:hidden;
display:flex;flex-direction:column;position:relative;transition:border-color .15s}
.card:hover{border-color:var(--brand)}
/* Не inset: сокращённая запись появилась только в Safari 14.1, а до неё
   перестаёт работать не оформление, а сам клик по плашке. */
.card h3 a::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0}
.card img{width:100%;height:170px;object-fit:cover;display:block;background:var(--line);
transition:transform .45s cubic-bezier(.2,.6,.3,1)}
/* Наведение приближает афишу. Карточка с overflow:hidden держит её в своих границах,
   поэтому «выезжает» только само изображение — получается движение внутри рамки.
   Только там, где есть курсор: на телефоне hover залипает после тапа, и картинка
   осталась бы увеличенной до перехода на другую страницу. */
@media (hover:hover){
  .card:hover img{transform:scale(1.06)}
  .shot img{transition:transform .45s cubic-bezier(.2,.6,.3,1)}
  .shot:hover img{transform:scale(1.03)}
}
/* На телефоне курсора нет, а отклик нужен. Одного :active мало: браузер снимает его,
   как только начинается прокрутка, — а палец в этот момент как раз и скользит по
   карточкам. Поэтому класс ставит скрипт по касанию и держит, пока палец на экране. */
/* Стандартная серая вспышка при касании только мешает: свой отклик у нас уже есть. */
.card,.vibe-card,.wall-card{-webkit-tap-highlight-color:transparent}
/* Кому движение мешает — тому его не показываем: настройка системная, и её
   уважают все браузеры. */
@media (prefers-reduced-motion:reduce){
  .card img,.shot img{transition:none}
  .card:hover img,.shot:hover img{transform:none}
}
/* Пометка поверх афиши. Человек должен увидеть «мест нет» в списке и не тратить клик:
   до карточки он доходит, уже зная, что сюда не попасть. */
.shot-wrap{position:relative;display:block}
.badge{position:absolute;top:10px;right:10px;padding:5px 10px;border-radius:6px;
background:rgba(17,17,17,.86);color:#fff;font-size:13px;font-weight:600;letter-spacing:.01em}
/* Приглушаем саму афишу: цветная картинка кричит «иди сюда», а идти некуда. */
.card:has(.badge):not(:has(.badge-free)):not(:has(.badge-now)) img{filter:grayscale(.55) brightness(.92)}
/* Тело карточки — колонка во всю высоту: так цена прижимается к низу независимо от
   того, в одну строку название или в три. Карточки в ряду тянутся до общей высоты,
   поэтому цены выстраиваются по одной линии. */
.card-body{padding:12px 14px 16px;display:flex;flex-direction:column;flex:1}
.card h3{font-size:17px;margin:0 0 6px;line-height:1.3}
.card h3 a{text-decoration:none}
.card h3 a:hover{color:var(--accent)}
.meta{font-size:14px;color:var(--muted);margin:2px 0}
.price{font-size:14px;font-weight:600;margin-top:auto;padding-top:10px;text-align:right}
/* Цена стоит в каждой карточке. Когда её нет в источнике — приглушаем, иначе
   «Не указана» выглядит важнее самой цены. */
.price-unknown{font-weight:400;color:var(--muted)}
.empty{color:var(--muted);padding:32px 0}
.pager{display:flex;gap:10px;margin:28px 0;align-items:center;font-size:15px}
.pager a{padding:7px 13px;border:1px solid var(--line);border-radius:7px;text-decoration:none}
footer{border-top:1px solid var(--line);margin-top:48px;padding:20px 0 40px;color:var(--muted);font-size:14px}
.layout{display:grid;grid-template-columns:minmax(0,1fr);gap:28px}
@media(min-width:960px){.layout{grid-template-columns:210px minmax(0,1fr)}
.sidebar{position:sticky;top:20px;align-self:start;order:-1}}
/* На узком экране ссылки в боты идут в один ряд: столбиком они съедали верх экрана,
   и до самой афиши приходилось прокручивать. Пояснение под ними — отдельной строкой
   во всю ширину, поэтому ряд с переносом, а не сетка. */
.sidebar{display:flex;flex-wrap:wrap;gap:12px}
.sidebar .applink{flex:1 1 0;min-width:0}
.sidebar-note{flex:1 0 100%}
@media(min-width:860px){.sidebar{flex-direction:column;flex-wrap:nowrap}}
.applink{display:block;padding:12px 14px;border:1px solid var(--line);border-radius:10px;
background:var(--card);text-decoration:none;transition:border-color .15s}
.applink:hover{border-color:var(--brand)}
.applink b{display:block;font-size:16px}
.applink span{font-size:13px;color:var(--muted)}
.sidebar-note{font-size:13px;color:var(--muted);line-height:1.4}
.event-head{display:grid;grid-template-columns:minmax(0,1fr);gap:20px}
@media(min-width:720px){.event-head{grid-template-columns:360px minmax(0,1fr)}}
.event-head img{width:100%;height:auto;display:block;border-radius:10px;background:var(--line)}
.shot{display:block;cursor:zoom-in}
.photo-toggle{position:fixed;top:0;left:0;opacity:0;width:0;height:0;pointer-events:none}
.lightbox{display:none}
#photo:checked~.lightbox{display:flex;position:fixed;top:0;right:0;bottom:0;left:0;z-index:60;padding:16px;cursor:zoom-out;
background:rgba(0,0,0,.92);align-items:center;justify-content:center}
.lightbox img{width:auto;height:auto;max-width:96vw;max-height:96vh;border-radius:8px}
.facts{list-style:none;padding:0;margin:16px 0}
.facts li{padding:7px 0;border-bottom:1px solid var(--line)}
.facts b{font-weight:600}
/* Главное целевое действие карточки. Раньше это была ссылка с классом .pager —
   выглядела как «Назад/Дальше» и терялась среди фактов. */
.buy{display:inline-flex;align-items:baseline;gap:8px;margin:4px 0 8px;padding:12px 22px;
border-radius:9px;background:var(--accent);color:var(--on-accent);font-size:17px;font-weight:600;
text-decoration:none;transition:filter .15s}
.buy:hover{filter:brightness(1.12)}
.buy:focus-visible{outline:3px solid var(--fg);outline-offset:2px}
.buy span{font-weight:400;font-size:15px;opacity:.85}
/* Продажи нет. Не «серая кнопка»: неактивная кнопка провоцирует клик, а человеку
   надо сразу понять, что билет здесь не купить — и уйти смотреть другие даты. */
.sold-out{margin:4px 0 8px;padding:11px 16px;border:1px solid var(--line);border-radius:9px;
background:var(--card);font-weight:600;display:inline-block}
.sold-out a{font-weight:400;color:var(--accent)}
/* «Поделиться». Раньше кнопка была серой и проявлялась только под курсором —
   владелец 17.08.2026: «её вообще не видно». Теперь она сразу в цвете фавикона,
   но рамкой, а не заливкой: спорить за внимание с кнопкой покупки она не должна.
   Под курсором заливается — отклик остаётся, просто идёт на шаг дальше. */
.share{margin:2px 0 10px;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.share button{padding:9px 16px;font-size:15px;cursor:pointer;background:none;
border:1px solid var(--accent);border-radius:8px;color:var(--accent)}
.share button:hover,.share button:focus-visible{background:var(--accent);
color:var(--on-accent);border-color:var(--accent)}
.share-links{display:none;flex-wrap:wrap;gap:8px}
.share-links.open{display:flex}
.share-links a{padding:9px 14px;border:1px solid var(--accent);border-radius:8px;
font-size:15px;text-decoration:none;color:var(--accent)}
.share-links a:hover,.share-links a:focus-visible{background:var(--accent);
color:var(--on-accent)}
.descr{margin-top:24px;max-width:70ch;white-space:pre-line}
/* Карта места. Кликабельна целиком: тот, кому нужен маршрут, всё равно уйдёт в
   приложение карт, и лишний раз искать ссылку не должен. */
.venue-map{display:block;margin:24px 0 0;max-width:768px;text-decoration:none}
.venue-map img{width:100%;height:auto;display:block;border:1px solid var(--line);
border-radius:10px;background:var(--card)}
.venue-map span,.venue-map figcaption{display:block;margin-top:6px;font-size:14px;color:var(--muted)}
/* Подсветка при наведении осталась только у ссылки на странице места: в событии карта
   не кликается, и намёк на нажатие там обманывал бы. */
a.venue-map:hover img{border-color:var(--accent)}
a.venue-map:hover span{color:var(--accent)}
/* Текст раздела — под списком: человек пришёл за событиями, а не за чтением, но
   поисковику нужно уникальное содержание, иначе страница = один список карточек. */
.steps{max-width:70ch;line-height:1.7}
.steps li{margin:8px 0}
.collections{margin-top:28px;font-size:15px;color:var(--muted)}
.collections a{color:var(--accent);text-decoration:none}
.collections a:hover{text-decoration:underline}
.intro{margin-top:36px;padding-top:20px;border-top:1px solid var(--line);max-width:70ch;color:var(--muted);font-size:15px}
.faq{margin-top:28px;max-width:70ch}
/* Фильтр мест — теми же сегментами, что и переключатель вида: оба отвечают на
   вопрос «что показать», и вести себя должны одинаково. */
/* Слежение за артистом — рамкой, как «Поделиться» и календарь: это обещание на
   будущее, а не действие прямо сейчас. */
.watch-line{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 20px}
.watch{padding:9px 16px;font:inherit;font-size:15px;cursor:pointer;background:none;
border:1px solid var(--accent);border-radius:8px;color:var(--accent)}
.watch:hover,.watch:focus-visible{background:var(--accent);color:var(--on-accent)}
.watch[data-on="1"]{background:var(--accent);color:var(--on-accent);font-weight:600}
.watch-line small{color:var(--muted);font-size:13px}
.seats-filter{display:flex;flex-wrap:wrap;gap:4px;align-items:center;margin:0 0 16px;
padding:4px;border:1px solid var(--line);border-radius:22px;width:fit-content;font-size:15px}
.seats-filter a,.seats-filter b{padding:7px 15px;border-radius:18px;text-decoration:none}
.seats-filter a{color:var(--accent)}
.seats-filter a:hover,.seats-filter a:focus-visible{background:var(--card)}
.seats-filter b{background:var(--accent);color:var(--on-accent);font-weight:600}
.daterange{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 18px;position:relative}
.cal-open{padding:8px 16px;border:1px solid var(--accent);border-radius:8px;background:none;
color:var(--accent);font:inherit;cursor:pointer}
.cal-open:hover,.cal-open:focus-visible{background:var(--accent);color:var(--on-accent)}
.cal-pop{position:absolute;z-index:30;top:calc(100% + 6px);left:0;padding:12px;
background:var(--bg);border:1px solid var(--line);border-radius:12px;
box-shadow:0 10px 30px rgba(0,0,0,.16);min-width:280px}
.cal-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
.cal-head button{border:0;background:none;color:inherit;font:inherit;cursor:pointer;
padding:4px 10px;border-radius:6px}
.cal-head button:hover{background:var(--line)}
.cal-head b{font-size:15px}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cal-grid span{text-align:center;color:var(--muted);font-size:12px;padding:4px 0}
.cal-grid button{border:0;background:none;color:inherit;font:inherit;cursor:pointer;
padding:7px 0;border-radius:6px}
.cal-grid button:hover{background:var(--line)}
.cal-grid button[disabled]{color:var(--muted);opacity:.45;cursor:default}
.cal-grid button.on{background:var(--accent);color:var(--on-accent)}
.cal-grid button.mid{background:color-mix(in srgb, var(--accent) 18%, transparent)}
.cal-hint{margin:8px 0 0;color:var(--muted);font-size:13px}
.daterange label{display:flex;gap:6px;align-items:center;color:var(--muted);font-size:15px}
.daterange [hidden]{display:none}
.daterange input{padding:7px 10px;border:1px solid var(--line);border-radius:8px;
font:inherit;color:inherit;background:none}
.daterange button{padding:8px 16px;border:1px solid var(--accent);border-radius:8px;
background:none;color:var(--accent);font:inherit;cursor:pointer}
.daterange button:hover,.daterange button:focus-visible{background:var(--accent);color:var(--on-accent)}
.daterange-reset{color:var(--muted);font-size:14px}
/* Подпись факта остаётся в разметке, но не на виду: иконка её заменяет зрячему,
   а экранному диктору и поисковику слово по-прежнему нужно. */
.fact-label{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
clip:rect(0 0 0 0);white-space:nowrap;border:0}
.facts li{display:flex;gap:10px;align-items:flex-start}
.facts li>*:not(.fact-icon):not(.fact-label){min-width:0}
.fact-value{flex:1 1 auto;min-width:0}
.fact-icon{flex:0 0 auto;margin-top:2px;color:var(--muted)}
/* «Вайб»: лента-коллаж. Высота строк не общая — каждая афиша встаёт в своих
   пропорциях, и хаос берётся из самой формы картинок, а не из случайных чисел:
   случайные заставляли бы ленту прыгать при каждом обновлении.

   Колонки собирает скрипт и раскладывает карточки по кругу — первая влево, вторая
   в середину, третья вправо, четвёртая снова влево. Так порядок читается слева
   направо, но ряды не выравниваются по высоте. Родные CSS-колонки этого не умеют:
   они заполняют столбец сверху донизу, и хронология уходила вертикально.

   Без скриптов остаётся вариант на CSS-колонках — порядок там вертикальный, зато
   лента цела. */
.vibe{columns:4 240px;column-gap:12px}
.vibe.laid{columns:auto;display:flex;gap:12px;align-items:flex-start}
.vibe-column{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:12px}
.vibe.laid .vibe-card{margin:0}
.vibe-card{display:block;position:relative;margin:0 0 12px;border-radius:12px;
overflow:hidden;text-decoration:none;color:#fff;break-inside:avoid}
.vibe-card img{display:block;width:100%;height:auto}
/* Затемнение снизу: без него белые буквы теряются на светлой афише. Прозрачность
   самого текста тут не помогает — нужен контраст под ним. */
/* Цена в правом верхнем углу. Первый вариант — белая плашка — забирал слишком много
   внимания: белое пятно в углу перетягивало взгляд с самой афиши.
   Теперь тёмная полупрозрачная подложка: цена остаётся видной, но перестаёт спорить
   с картинкой. Размытие под ней было убрано 28.08.2026 вместе со всем прочим — оно
   роняло листание до 12 кадров в секунду, — и плотность подложки взяла его роль. */
.vibe-price{position:absolute;top:9px;right:9px;padding:4px 9px;border-radius:999px;
background:rgba(20,20,20,.62);color:#fff;font-size:13px;font-weight:600;
letter-spacing:.01em;text-shadow:0 1px 2px rgba(0,0,0,.5)}
/* Бесплатное — единственное, что выделяем цветом: это довод прийти, а не справка.
   Но тоже приглушённо, иначе вернёмся к тому же кричащему пятну. */
.vibe-price-free{background:rgba(12,120,12,.5)}
/* Название — в самый низ, к плотному краю затемнения: там оно читается лучше всего.
   Порядок задаём стилями, в разметке название остаётся первым для экранного диктора. */
.vibe-meta{order:1}
.vibe-text b{order:2}
.vibe-text{position:absolute;left:0;right:0;bottom:0;padding:34px 12px 12px;
display:flex;flex-direction:column;gap:2px;
background:linear-gradient(to top,rgba(0,0,0,.86) 0%,rgba(0,0,0,.62) 45%,transparent 100%)}
.vibe-text b{font-size:16px;line-height:1.25;text-shadow:0 1px 3px rgba(0,0,0,.6);
margin-top:2px}
.vibe-meta{font-size:13px;opacity:.92;text-shadow:0 1px 3px rgba(0,0,0,.6)}
.vibe-price{font-size:14px;font-weight:600;text-shadow:0 1px 3px rgba(0,0,0,.6)}
.vibe-now{position:absolute;top:10px;left:10px;padding:4px 9px;border-radius:6px;
background:#0ca30c;color:#fff;font-size:12px;font-weight:600}
@media (hover:hover){.vibe-card:hover img{transform:scale(1.05)}}
.vibe-card img{transition:transform .45s cubic-bezier(.2,.6,.3,1)}
@media (max-width:640px){.vibe{columns:2 150px;column-gap:8px}
  .vibe-card{margin-bottom:8px}.vibe-text{padding:26px 9px 9px}
  .vibe-text b{font-size:14px}}
/* Переключатель вида. Текущий — жирным без ссылки: на него незачем нажимать. */
/* «Стена»: события широкими полосами, одна под другой — образец прислал владелец
   17.08.2026 (лента DoStuff). Здесь форма у всех одна, а разной остаётся только
   картинка: она обрезается по центру.

   Обрезка по центру не косметика. Полоса низкая и широкая, и при обрезке по краю в
   кадр попадал бы угол афиши, где обычно пусто, а название с самого постера — срезано. */
.wall{display:flex;flex-direction:column;gap:4px}
/* Полосы идут без отступов по бокам — так на образце: картинка работает фоном, а не
   карточкой. Растягиваем на боковые поля обёртки (16px), а не до края экрана: у
   страницы слева колонка со ссылками, поэтому приём «во всю ширину окна» уводил
   ленту вправо и добавлял горизонтальную прокрутку на 119 пикселей — замерено. */
.wall{margin-left:-16px;margin-right:-16px}
.wall-card{position:relative;display:block;height:170px;overflow:hidden;
text-decoration:none;color:#fff;background:#111}
.wall-card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
object-position:center;transition:transform .5s cubic-bezier(.2,.6,.3,1)}
/* Затемнение поверх всей полосы, а не только снизу: текст стоит по центру, и под ним
   может оказаться самая светлая часть афиши. */
.wall-card::after{content:"";position:absolute;inset:0;background:rgba(0,0,0,.46)}
.wall-text{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;
align-items:center;justify-content:center;gap:5px;padding:14px 18px;text-align:center}
.wall-title{font-size:24px;line-height:1.15;font-weight:700;letter-spacing:.01em;
text-shadow:0 2px 6px rgba(0,0,0,.6)}
.wall-meta{font-size:14px;letter-spacing:.08em;text-transform:uppercase;opacity:.94;
text-shadow:0 1px 4px rgba(0,0,0,.6)}
.wall-when{font-size:13px;opacity:.86;text-shadow:0 1px 4px rgba(0,0,0,.6)}
.wall-now{position:absolute;top:10px;left:10px;z-index:2;padding:4px 9px;border-radius:6px;
background:rgba(12,120,12,.72);color:#fff;font-size:12px;font-weight:600}
@media (hover:hover){.wall-card:hover img{transform:scale(1.06)}}
@media (max-width:640px){.wall-card{height:140px}.wall-title{font-size:19px}
  .wall-meta{font-size:12px}}
/* Пока подгрузка работает, кнопки листания не нужны — но и не удалены: при сбое
   сети мы их возвращаем. */
.endless-quiet{opacity:0;height:0;overflow:hidden;margin:0;padding:0}
.endless-note{color:var(--muted);text-align:center;margin:18px 0}
/* Появление новых карточек: плавно, но коротко — долгое проявление читается как
   тормоза, а не как плавность. */
.endless-new{opacity:0}
.vibe-card,.card{transition:opacity .35s ease}
/* «Назад» была приглушённым текстом и терялась — владелец её просто не находил.
   Теперь кнопка с рамкой, но не с заливкой: заливка спорила бы с главным действием
   страницы — покупкой. Тот же приём, что у кнопки «Поделиться». */
.back{display:inline-flex;align-items:center;gap:7px;margin:0 0 16px;
padding:8px 15px 8px 12px;border:1px solid var(--line);border-radius:999px;
color:var(--fg);text-decoration:none;font-size:15px;line-height:1;
transition:border-color .15s,background .15s,color .15s}
.back::before{content:"←";font-size:17px;line-height:1;color:var(--accent)}
.back:hover,.back:focus-visible{border-color:var(--accent);background:var(--accent);
color:var(--on-accent)}
.back:hover::before,.back:focus-visible::before{color:var(--on-accent)}
/* Надпись о свободных местах — белым по глубокому бирюзовому. Светлый бирюзовый фон
   тут не годится ни с каким текстом: белый на нём даёт 1.34, тёмный спорит с меткой
   «Идёт сейчас». Цвет из того же семейства, что акцент, — плашка остаётся «нашей». */
.badge-free{background:#0a7d82;color:#ffffff}
/* «Идёт сейчас» — зелёный: он про состояние, а голубым мы показываем места.
   Две метки на одной плитке не должны спорить друг с другом цветом. */
.badge-now{background:#0ca30c;color:#fff;left:10px;right:auto}
.now{color:#0ca30c;font-weight:600;margin:2px 0 10px}
.seats-free{color:var(--accent)}
/* Календарь — рамкой, как «Поделиться»: он про «потом», а спорить за внимание
   с кнопкой покупки не должен. */
.calendar,.to-organizer{margin:18px 0 0}
.to-organizer a,.to-calendar{display:inline-flex;align-items:center;gap:8px;padding:9px 16px;
border:1px solid var(--accent);border-radius:8px;color:var(--accent);
text-decoration:none;font-size:15px}
.to-organizer a::before{content:"✉️";font-size:15px;line-height:1}
.to-calendar::before{content:"📅";font-size:15px;line-height:1}
.to-organizer a:hover,.to-organizer a:focus-visible,.to-calendar:hover,.to-calendar:focus-visible{background:var(--accent);color:var(--on-accent)}
.app-map{display:flex;flex-wrap:wrap;gap:8px;margin:24px 0 10px}
.app-map a{padding:9px 16px;border:1px solid var(--accent);border-radius:8px;
color:var(--accent);text-decoration:none;font-size:15px}
.app-map a:hover,.app-map a:focus-visible{background:var(--accent);color:var(--on-accent)}
.rassylka{max-width:56ch}
.rassylka h2{font-size:17px;margin:30px 0 10px}
.rassylka form{display:flex;flex-direction:column;gap:14px}
.rassylka label{display:flex;flex-direction:column;gap:5px;font-weight:600;font-size:15px}
.rassylka label small{font-weight:400;color:var(--muted)}
.rassylka input[type=text],.rassylka textarea{padding:10px 12px;font:inherit;
border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--fg)}
.rassylka button{padding:11px 18px;font:inherit;font-weight:600;border:0;border-radius:8px;
background:var(--accent);color:var(--on-accent);cursor:pointer;align-self:flex-start}
/* Отправка выделена цветом тревоги намеренно: отозвать уведомление нельзя, и кнопка
   не должна выглядеть как обычное действие рядом с безобидным предпросмотром. */
.rassylka button.danger{background:#c0392b}
.rassylka .confirm{margin:14px 0 6px;padding:14px;border:1px solid #c0392b;border-radius:10px}
.rassylka .confirm label{flex-direction:row;align-items:flex-start;gap:9px;font-weight:400}
.rassylka .problems{margin:0 0 18px;padding:12px 12px 12px 30px;border-radius:8px;
background:rgba(192,57,43,.09);color:#c0392b}
.rassylka .warning{padding:11px 13px;border-radius:8px;background:rgba(230,160,20,.13)}
.rassylka .ok{padding:11px 13px;border-radius:8px;background:rgba(40,150,90,.13)}
.notif{display:flex;gap:11px;padding:13px;border:1px solid var(--line);border-radius:12px;
box-shadow:0 2px 10px rgba(0,0,0,.08);background:var(--card)}
.notif img{border-radius:8px;flex-shrink:0}
.notif div{display:flex;flex-direction:column;gap:3px;min-width:0}
.notif b{font-size:15px}
.notif span{font-size:14px;color:var(--fg)}
.notif small{color:var(--muted);font-size:12px}
.rassylka fieldset.where{border:1px solid var(--line);border-radius:10px;padding:12px 13px;margin:0}
.rassylka fieldset.where legend{font-weight:600;font-size:15px;padding:0 5px}
.rassylka .chips{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:10px}
.rassylka .chips button{padding:7px 12px;font-size:14px;font-weight:400;border:1px solid var(--line);
background:var(--card);color:var(--fg);border-radius:20px;align-self:auto}
.rassylka .chips button:hover{border-color:var(--accent);color:var(--accent)}
.rassylka fieldset.where input{width:100%;box-sizing:border-box}
.rassylka fieldset.where small{display:block;margin-top:7px;color:var(--muted);font-size:13px}
.rassylka table{width:100%;border-collapse:collapse;font-size:14px}
.rassylka th,.rassylka td{padding:7px 10px;text-align:left;border-bottom:1px solid var(--line)}
.rassylka .num{text-align:right}
/* ── Стеклянный облик: пока только Пешеходный Любинский (образец 19.08.2026) ──
   Порядок слоёв снизу вверх: цветные пятна → затемнение → содержимое на подложке.
   Оба слоя закреплены на месте (fixed): при прокрутке фон стоит, а содержимое едет
   поверх него — на этом и держится ощущение глубины. */
/* Переопределяем сами переменные, а не отдельные правила: цветом акцента покрашены
   ссылки, рамки кнопок, иконки и метки — перечислять их по одному значит однажды
   забыть про какую-нибудь кнопку, и она останется нечитаемой на тёмном. */
body.glass{--bg:transparent;--fg:#f2f4f8;--muted:#b9c6da;--line:rgba(255,255,255,.20);
  --card:rgba(255,255,255,.07);--accent:#7ef0f4;--on-accent:#06212c;
  background:#0b1020;color:#f2f4f8}
.glass-bg,.glass-dim{position:fixed;inset:0;z-index:-2;pointer-events:none;overflow:hidden}
.glass-dim{z-index:-1;background:linear-gradient(180deg,rgba(8,10,22,.30),rgba(8,10,22,.62))}
/* Каждое пятно — отдельный слой, а не часть общего градиента. Так их можно двигать
   поодиночке и по-разному, и картинка остаётся заполненной: увозить фон целиком
   нельзя — к концу ленты цвет ушёл бы за край, ради чего всё и затевалось.
   Положения и размеры те же, что были у общего градиента: облик обеих страниц
   обязан совпадать. */
.glass-bg{background:#0b1020}
.glass-bg i{position:absolute;display:block;transform:translate(-50%,-50%);border-radius:50%}
.glass-bg .b1{width:140vw;height:140vw;left:10%;top:6%;
  background:radial-gradient(closest-side,rgba(0,214,220,.95),transparent 62%)}
.glass-bg .b2{width:130vw;height:130vw;left:92%;top:10%;
  background:radial-gradient(closest-side,rgba(134,92,255,.92),transparent 64%)}
.glass-bg .b3{width:120vw;height:120vw;left:80%;top:86%;
  background:radial-gradient(closest-side,rgba(255,74,150,.80),transparent 62%)}
.glass-bg .b4{width:110vw;height:110vw;left:14%;top:94%;
  background:radial-gradient(closest-side,rgba(196,214,0,.60),transparent 64%)}
/* Пятна стоят на месте. Двигать их пробовали дважды, и оба раза это стоило кадров.

   25.08.2026: четыре бесконечные анимации роняли отрисовку до 4–5 кадров в секунду
   там, где нет аппаратного ускорения. Их заменили ходом от доли прокрученного.
   28.08.2026: замер на ленте показал, что и этот ход дорог — 39 кадров против 52
   без него, и вдвое больше долгих задач. Причина та же, что и в первый раз: пятна
   огромные, на телефоне каждое крупнее экрана, и любое смещение перерисовывает
   больше площади, чем видно человеку. Мешал и переход в .35s: значение сдвига
   менялось каждый кадр, переход перезапускался, и пятна вечно «догоняли» — это и
   читалось как рывки.

   Неподвижные пятна при этом почти бесплатны: в замере без них вышло столько же,
   сколько с ними стоящими. Поэтому фон остался, а движение ушло совсем — вместе с
   will-change, который держал под них слои в памяти. */
/* Размытие создаёт свой контекст наложения, и выпадающие блоки перестают всплывать
   над соседями: календарь ушёл под ленту и стал ненажимаемым. Поднимаем тех, у кого
   есть что показать поверх соседнего блока. */
body.glass .daterange{position:relative;z-index:20}
/* Всплывающий календарь красился «фоном страницы», а он в этом облике прозрачный:
   сквозь даты просвечивала лента, и разобрать их было нельзя. Здесь подложка должна
   быть плотной — это не украшение, а поверхность для чтения. */
body.glass .cal-pop{background:rgba(9,13,26,.92);border-color:rgba(255,255,255,.24);
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  box-shadow:0 18px 44px rgba(0,0,0,.55)}
body.glass .cal-grid button:hover{background:rgba(255,255,255,.14)}
body.glass .cal-head button:hover{background:rgba(255,255,255,.14)}
body.glass .share{position:relative;z-index:15}
/* Само стекло — светлой плёнкой, без размытия. Разница на глаз почти нулевая, а в
   кадрах огромная.

   Замер 28.08.2026: blur(18px) на всех этих блоках давал 12 кадров в секунду при
   листании вместо шестидесяти. Под размытие попадали 36–48 карточек, крупные блоки,
   шапка и подвал; фон закреплён, поэтому подложка под каждым стеклом при прокрутке
   меняется и пересчитывается каждый кадр. Уменьшать радиус бесполезно — при blur(6px)
   вышло 9 кадров: платит площадь, а не резкость.

   Ключ к решению: под карточками нет ничего, кроме мягких радиальных градиентов
   фона. Размывать градиент незачем — он и так размытый, и вид стекла даёт сама
   полупрозрачность. Настоящее размытие оставлено там, где под стеклом едет резкий
   контент и таких элементов единицы: шапка (ниже), календарь и накладка меню. */
body.glass main>*,body.glass .intro,body.glass .card,body.glass .daterange,
body.glass .applink,body.glass footer>.wrap{
  background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.16);border-radius:16px}
body.glass main>*{padding:18px 20px;margin-bottom:16px}
body.glass .card{padding:0;overflow:hidden}
body.glass .card img{border-radius:0}
body.glass h1,body.glass h2,body.glass .card b,body.glass .applink b{color:#fff}
/* Не «любой span в карточке»: плашки поверх афиши красятся сами, и приглушённый
   цвет делал надпись о местах нечитаемой — светло-серым по светло-бирюзовому. */
body.glass .lead,body.glass .muted,body.glass .card span:not(.badge),
body.glass .card small,body.glass .applink span,body.glass .sidebar-note{color:var(--muted)}
/* Шапка плотная, без размытия. Она закреплена и всегда на экране, поэтому её
   размытие пересчитывается на каждый кадр листания — и это дороже, чем кажется на
   быстрой машине. Замер 28.08.2026 с торможением процессора вчетверо (так ведёт
   себя телефон): 36 кадров против 49. Без торможения разница была в три кадра, и
   по такому замеру размытие ошибочно сочли дешёвым — методическая ошибка.

   Плотность .97 обязательна: при .92 текст ленты читался сквозь шапку насквозь и
   наезжал на название. Размытие это мылило, теперь мылить нечем. */
body.glass header,body.glass .head-bar{background:rgba(11,16,32,.97);
  border-color:rgba(255,255,255,.14)}
body.glass .tabbar{background:rgba(11,16,32,.86);border-color:rgba(255,255,255,.14)}
/* Серая рамка светлой темы на тёмной шапке не видна — кнопкам мессенджеров нужна своя. */
body.glass .head-bots a{color:#fff;border-color:rgba(255,255,255,.24);
  background:rgba(255,255,255,.08)}
body.glass input,body.glass .search input{background:rgba(255,255,255,.10);
  color:#f2f4f8;border-color:rgba(255,255,255,.22)}
/* Серый текст светлой темы (#6b6b6b) на тёмном стекле почти не виден: подвал и
   служебные подписи перекрашиваем целиком, а не по одному классу. */
body.glass footer,body.glass footer p,body.glass footer b,body.glass .owner{color:var(--muted)}
/* Размытия нет на старых машинах и в экономном режиме — тогда просто плотный фон,
   иначе текст оказался бы на голом градиенте и стал нечитаемым. */
@supports not (backdrop-filter:blur(1px)){
  body.glass .cal-pop{background:rgba(9,13,26,.995)}}
@media(prefers-reduced-transparency:reduce){
  body.glass main>*,body.glass .card{background:rgba(11,16,32,.9)}}
.help{max-width:72ch}
.help .lead{color:var(--muted);font-size:16px;margin:0 0 28px}
.help h2{font-size:19px;margin:34px 0 10px}
.help dt{font-weight:600;margin-top:20px;font-size:16px}
.help dd{margin:6px 0 0;color:var(--muted)}
.help dd a{color:var(--accent)}
.faq h2{font-size:17px;margin:0 0 12px}
.faq dl{margin:0}
.faq dt{font-weight:600;margin-top:14px}
.faq dd{margin:4px 0 0;color:var(--muted)}
.owner{margin:14px 0 0;font-size:14px;color:var(--muted)}
.counters{margin-top:14px}
.hub{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px}
.hub li{padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--card)}
.hub a{font-weight:600;text-decoration:none}
.hub a:hover{color:var(--accent)}
.hub .meta{margin-left:6px}
.hub-note{display:block;font-size:13px;color:var(--muted);margin-top:2px}
/* Название и поиск закреплены сверху: к ним возвращаются из любого места ленты, а
   она бесконечная — доматывать до верха ради поиска пришлось бы долго.
   Липнет только эта строка; разделы ниже уезжают, иначе на телефоне закреплённая
   шапка съедала бы половину экрана. */
.head-bar{position:sticky;top:0;z-index:40;background:var(--bg)}
.head-top{display:flex;flex-wrap:wrap;gap:12px;align-items:center;
justify-content:space-between;padding:12px 0}
/* Тень появляется только когда под шапкой что-то проехало: в покое линия ни к чему. */
.head-bar::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
background:var(--line);opacity:0;transition:opacity .2s}
.head-bar.stuck::after{opacity:1}
.search{display:flex;gap:6px;flex:1 1 240px;max-width:380px}
.search input,.search-page input{flex:1;min-width:0;padding:8px 12px;font-size:15px;
  border:1px solid var(--line);border-radius:8px;background:#fff;color:inherit}
.search input:focus,.search-page input:focus{outline:2px solid var(--accent);outline-offset:1px}
.search button,.search-page button{padding:8px 16px;font-size:15px;cursor:pointer;
  border:1px solid var(--accent);border-radius:8px;background:var(--accent);color:var(--on-accent)}
.search-page{display:flex;gap:8px;margin:0 0 20px;max-width:520px}
.found{list-style:none;padding:0;margin:0 0 18px;line-height:1.9}
.found .meta{color:var(--muted);font-size:14px}
.foot-venues{margin:10px 0 0;line-height:1.9}
.foot-venues a{color:var(--muted);text-decoration:none}
.foot-venues a:hover{color:var(--accent)}
@media (hover:none){
  /* Плавность задаём здесь же и всем видам сразу: раньше переход был прописан только
     плитке, а «вайб» и «стена» меняли масштаб рывком — картинка дёргалась.
     Наезд медленнее возврата: так движение читается как отклик, а не как мигание. */
  .card img,.vibe-card img,.wall-card img{
    transition:transform .32s cubic-bezier(.22,.61,.36,1)}
  .card:active img,.vibe-card:active img,.wall-card:active img,
  .touched img{transform:scale(1.12);transition-duration:.22s}
  .touched{z-index:2}
}
/* Приглашение поставить значок на домашний экран. Крупный образец значка сверху:
   человек должен увидеть, что именно появится у него на экране, до установки. */
.invite-shot{display:flex;flex-direction:column;align-items:center;gap:8px;margin:0 0 22px}
.invite-shot img{width:120px;height:120px;border-radius:26px;display:block;
box-shadow:0 10px 30px rgba(0,0,0,.35)}
.invite-shot b{font-size:15px;font-weight:600}
.invite .steps{max-width:60ch;padding-left:22px}
.invite .steps li{margin:10px 0}
.invite-list{list-style:none;padding:0;display:grid;gap:12px;
grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.invite-list a{display:grid;grid-template-columns:72px 1fr;gap:14px;align-items:center;
padding:12px;border:1px solid var(--line);border-radius:14px;text-decoration:none}
.invite-list a:hover{border-color:var(--brand)}
.invite-list img{border-radius:16px;grid-row:span 2}
.invite-list b{font-size:16px}
.invite-list span{font-size:13px;color:var(--muted)}
/* Предупреждение «вы не в Safari» — показывается скриптом только там, где значок
   поставить нельзя. Остальные его не видят вовсе: hidden снимается кодом. */
.wrong-browser{border:1px solid var(--brand);border-radius:12px;padding:12px 14px;
margin:0 0 20px;font-size:15px}
.wrong-browser button{margin-left:8px;padding:7px 12px;font:inherit;font-size:14px;
cursor:pointer;background:var(--accent);color:var(--on-accent);border:0;border-radius:8px}
.wrong-browser .to-safari{display:inline-block;margin-left:8px;padding:7px 12px;
border:1px solid var(--brand);border-radius:8px;font-size:14px;text-decoration:none}
/* Кнопка установки на Android: до сигнала браузера её нет вовсе. */
.install-offer{display:none}
body.can-install .install-offer{display:block;margin:0 0 18px}
.install-offer button{padding:11px 18px;font:inherit;font-size:16px;font-weight:600;
cursor:pointer;background:var(--accent);color:var(--on-accent);border:0;border-radius:10px}
/* Кнопка «Следить» с лицом артиста (облик выбран владельцем 25.08.2026): круг с
   афишей выступает за левый край и виден раньше подписи. Радиус кнопки равен
   половине её высоты — левый торец полукруглый, круг садится ровно в него. */
.watch{display:inline-flex;align-items:center;gap:12px;padding:6px 18px 6px 6px;
border-radius:34px;text-align:left}
/* Кадр берём выше середины: на афишах человек стоит в полный рост, и центр
   квадрата приходится на пояс, а не на лицо. */
.watch-face{width:56px;height:56px;border-radius:50%;object-fit:cover;
object-position:50% 26%;display:block;
background:var(--line);box-shadow:0 0 0 2px var(--brand)}
.watch-text{display:flex;flex-direction:column;line-height:1.25}
.watch-title{font-size:12px;color:var(--muted)}
.watch-name{font-size:16px;font-weight:600}
.watch:hover .watch-title,.watch:focus-visible .watch-title,
.watch[data-on="1"] .watch-title{color:inherit}
/* Служебный лист вычитки портретов: кадр, имя и ссылка на событие. */
.portrait-list{list-style:none;padding:0;display:grid;gap:14px;
grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.portrait-list li{display:grid;grid-template-columns:96px 1fr;gap:12px;align-items:center;
padding:10px;border:1px solid var(--line);border-radius:12px}
.portrait-list img{border-radius:50%;grid-row:span 3;object-fit:cover}
.portrait-list b{font-size:15px}
.portrait-list a{font-size:13px;color:var(--accent);text-decoration:none}
.portrait-list span{font-size:12px;color:var(--muted)}
