/* site-overrides/extra.css -- добавочные стили только для нового сайта (server_boardgames_calendar).
   Подключается ПОСЛЕ базового styles.css (см. каждый *.html в этой папке), поэтому здесь
   только то, что нужно добавить/переопределить -- сам styles.css не форкается, чтобы не
   тащить полную копию всего файла ради нескольких правил. */

/* ---------- whoami-banner -- заголовок+подсказка слева (whoami-banner-text, 2 строки
   заголовка + 2 строки подсказки), прямоугольная кнопка справа, растянутая на всю высоту
   текстового блока (align-items: stretch). Подсказка видна, только пока не
   идентифицировались, см. #whoAmIHint / renderWhoAmI в app.js и остальных. ---------- */
.whoami-banner { align-items: stretch; justify-content: flex-start; gap: 20px; }
.whoami-banner-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
}
.whoami-headline { margin: 0; font-size: 15px; font-weight: 600; color: var(--t1); line-height: 1.4; }
.whoami-hint { margin: 0; }
.whoami-banner .btn-primary {
  width: auto;
  border-radius: 16px;
  padding: 0 36px;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---------- ссылка "анонсировать игру" -- видна только идентифицированным, строкой
   ВНУТРИ баннера "это вы" (whoami-banner-text), под "вы вошли как..." -- см.
   #organizerLinkRow. Одинаково доступна с ЛЮБОЙ страницы сайта (index/requests/info/my/
   organizer/profile -- см. соответствующие *.html и renderWhoAmI в каждом *.js), не
   только с главной, чтобы организатору не приходилось возвращаться на календарь, чтобы
   анонсировать новую игру -- см. обсуждение с Дарьей 2026-08-14. Без своего margin-top:
   колонка .whoami-banner-text уже flex с gap: 10px между строками, свой отступ поверх
   него задвоил бы интервал ---------- */
.organizer-link-row { text-align: left; }

/* ---------- .head (тёмная плашка вверху каждой страницы, tag+заголовок+lead) -- раньше
   ощутимо "скакала" по высоте между страницами: на главной заголовок крупнее (.hero,
   44/50, в два явных ряда "настолки/для своих"), а на остальных страницах -- мельче
   (.hero-sm, 34/40, один ряд) плюс у каждой страницы свой текст-подводка разной длины
   (от одной строки на "Мой профиль" до трёх-четырёх на "Фонд клуба"). Заголовки страниц
   намеренно НЕ трогаем (крупный заголовок остаётся только у главной -- это её "лицо"),
   вместо этого: 1) чуть уменьшаем padding/отступы -- та же "шапка", но компактнее, см.
   правку с Дарьей 2026-08-14 после скриншота ("сделай шапку чуть меньше"); 2) фиксируем
   min-height и центрируем содержимое по вертикали, чтобы переход между страницами не
   дёргал вёрстку под ней. align-items: flex-start ОБЯЗАТЕЛЕН -- без него flex-контейнер
   по умолчанию растягивает детей (align-items: stretch) на всю ширину, и .tag (маленькая
   пилюля-бейдж) превращается в белую полосу на всю ширину шапки -- именно этот баг Дарья
   увидела на скриншоте после первой версии этой правки. Числа ниже -- по факту вёрстки, в
   этой песочнице нет браузера для точного замера реального рендера -- если высота всё же
   слегка "не легла" на реальном экране, поправить одно число здесь. ---------- */
.head {
  padding: 28px 32px;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
}
.head .hero { margin-top: 12px; }
.head .lead { margin-top: 10px; }
@media (max-width: 640px) {
  /* было 220px/22px 20px -- на телефоне шапка занимала непропорционально много первого
     экрана относительно самого контента (тег+заголовок+lead редко реально требуют столько
     места) -- min-height только гарантирует МИНИМУМ, реальный контент, если ему нужно
     больше, всё равно растянет блок дальше, так что это чисто уборка лишнего воздуха, не
     риск обрезать текст. Обсуждение с Дарьей 2026-08-19 "слишком много места в шапке" ---------- */
  .head { min-height: 148px; padding: 18px 16px; }
}

/* ---------- фильтры «Город»/«Жанр» на телефоне -- вместо двух блоков с чипами, каждый на
   свою ширину и часто в несколько строк (chips переносятся по .pillrow flex-wrap), --
   компактный обычный <select> (одиночный выбор, не чеклист), оба фильтра рядом в ОДНУ
   строку. Разметка под оба варианта уже в HTML (см. #cityFilterMobile/#formatFilterMobile
   в index.html, renderFilterGroup в app.js рендерит их синхронно с чипами) -- тут только
   переключение видимости по ширине экрана. Обсуждение с Дарьей 2026-08-19 "слишком много
   места под фильтры... выпадающим чеклистом в одну строку" ---------- */
.filter-select-mobile { display: none; }
@media (max-width: 640px) {
  #filters { flex-wrap: nowrap; gap: 10px; padding: 12px 0 10px; }
  #filters .filter-block { flex: 1 1 0; min-width: 0; flex-direction: row; align-items: center; gap: 6px; }
  #filters .filter-label { flex: none; white-space: nowrap; }
  #filters .pillrow { display: none; }
  #filters .filter-select-mobile {
    display: block;
    flex: 1;
    min-width: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--card);
    color: var(--t1);
    font: inherit;
    font-size: 13px;
    padding: 8px 10px;
  }
}

/* ---------- 4-я плашка в шапке (было 3: мероприятий/города/ближайшее, теперь --
   ближайшее/мероприятий/города/онлайн, см. renderStats в app.js) -- styles.css жёстко
   задаёт repeat(3, 1fr), под 4 карточки эта сетка ужалась бы неровно (3 в ряд + 1 одна на
   отдельной строке). Explicit override: 4 в ряд на широких экранах, 2x2 на средних,
   обратно в столбик на телефонах -- ПОСЛЕДНЕЕ правило (640px) должно идти именно тут,
   ПОСЛЕ 900px-правила, а не полагаться на автоматическую специфичность media-запросов:
   при узких экранах совпадают ОБА условия (max-width:900 и max-width:640), и в CSS
   каскаде побеждает то, что позже в файле, а не "более узкое" числом -- обсуждение с
   Дарьей 2026-08-19 (мобильная вёрстка) ---------- */
/* первая карточка («ближайшее») содержит дату+время+название игры -- самая «тяжёлая» по
   контенту, остальные три -- короткое число+подпись, поэтому первую делаем шире, а 2-3-4
   уже и равны между собой, вместо repeat(4, 1fr), см. просьбу Дарьи 2026-08-19 */
.stats-grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; }
@media (max-width: 900px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .stats-grid { grid-template-columns: 1fr; }
}

/* ---------- модалка "это вы": шаг 2 (имя/никнейм при первом входе с почты) ---------- */
#whoAmIStep2 h3 { margin-bottom: 8px; }

/* ---------- info.html: расширено до стандартной ширины (было wrap-narrow, 640px) --
   info-list/city-list были одноколоночными в расчёте на узкую страницу -- на 1080px
   переводим на адаптивную сетку, чтобы не было пустого места и полосок на всю ширину ---------- */
@media (min-width: 720px) {
  .info-list, .city-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 12px;
  }
}

/* ---------- info.html: Москва -- отдельный крупный блок НАД общей сеткой городов (не
   часть .city-list), остальные города -- сетка по алфавиту, без изменений ---------- */
.city-card-featured { padding: 32px 36px; gap: 10px; margin-top: 16px; }
.city-card-featured .n { font-size: 26px; }

/* ---------- несколько адресов у одного города (сейчас -- Москва, Пятигорск) -- отдельной
   строкой на каждую локацию вместо склеивания через "·", чтобы легко дописать ещё одну ---------- */
.city-meta-list { display: flex; flex-direction: column; gap: 4px; margin-top: 2px; }

/* ---------- Москва: несколько амбассадоров -- тоже city-meta-list (по одному на строку,
   имя + видимый email), тем же шрифтом/цветом, что и адреса ниже -- раньше был отдельный
   абзац city-ambassadors со ссылками цвета var(--t1), заметно темнее и "жирнее на глаз",
   чем приглушённые city-meta ниже. Ссылка внутри city-meta по умолчанию не наследует
   цвет (браузер красит <a> в синий) -- задаём явно ---------- */
.city-meta a { color: inherit; text-decoration: none; }
.city-meta a:hover { text-decoration: underline; }

/* ---------- Москва: 5 амбассадоров в одну колонку растягивали карточку по вертикали --
   раскладываем в 3 колонки (поверх city-meta-list, см. разметку в info.html). На узких
   экранах места на 3 колонки не хватает -- возвращаем в 1 колонку, как остальные города ---------- */
.city-ambassador-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px 16px;
}
@media (max-width: 640px) {
  .city-ambassador-grid { grid-template-columns: 1fr; }
}

/* ---------- requests.html/"фонд клуба": добавлен столбец "Контакты" ---------- */
.requests-table {
  grid-template-columns: minmax(130px, 1fr) minmax(170px, 1.5fr) minmax(150px, 1.3fr) minmax(140px, 1.2fr) 84px auto;
}
.req-contact {
  font-size: 12px;
  background: var(--bg);
  color: var(--t2);
  border-radius: var(--r-pill);
  padding: 5px 11px;
  line-height: 1.4;
  text-decoration: none;
  display: inline-block;
}
.req-contact:hover { background: var(--border); color: var(--t1); }
a.req-host { text-decoration: none; cursor: pointer; }
a.req-host:hover { background: var(--border); color: var(--t1); }

/* ---------- пароль на сайт: сплошной фон вместо обычного полупрозрачного затемнения --
   пока пароль не введён, сайт не должен просвечивать за модалкой вообще ---------- */
#sitePasswordOverlay { background: var(--active); }

/* ---------- организатор в карточке -- кликабельное mailto (не только hover-подсказка),
   см. metaLine()/renderContactEl() в app.js/my.js -- альтернатива вводу своей почты в
   whoami-banner. Тот же клик (mailto или выбор канала, если их несколько) -- теперь и у
   участников (.card-participants), резерва (.card-waitlist-row) и тех, кто проявил
   интерес (.card-interest), см. обсуждение с Дарьей 2026-08-14 "при клике на участников --
   так же как на организаторов". Селектор без ограничения тегом (не "a.hoverable-email", а
   просто ".hoverable-email") -- покрывает и одиночную ссылку <a>, и кнопку выбора канала
   <button class="contact-chooser-trigger"> у тех, у кого несколько контактов; без этого
   у кнопки-выбора оставалось бы пунктирное подчёркивание и cursor:help от базового
   .hoverable-email в styles.css (это для НЕкликабельных подсказок, не для наших случаев) */
.card-meta .hoverable-email,
.card-participants .hoverable-email,
.card-waitlist-row .hoverable-email,
.card-interest .hoverable-email {
  color: var(--t1);
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  border-bottom: none;
}
.card-meta .hoverable-email:hover,
.card-participants .hoverable-email:hover,
.card-waitlist-row .hoverable-email:hover,
.card-interest .hoverable-email:hover {
  text-decoration: underline;
}

/* ---------- "занять место": кнопка "без имени" отдельно от выбора зарегистрированного ---------- */
#reservedAddAnon { margin-bottom: 16px; }

/* ---------- навигация между страницами -- "закладки-корешки": скруглены только сверху,
   неактивные приглушены и как будто позади, активная -- светлая и "прорезает" линию снизу
   (тот же приём, что и обычные вкладки в интерфейсах -- контейнер несёт border-bottom,
   у каждого чипа margin-bottom: -2px и своя заливка поверх линии). Порядок и состав
   вкладок (index/requests/info/my) не меняются -- только оформление ---------- */
.top-nav.pillrow { gap: 4px; flex-wrap: nowrap; border-bottom: 2px solid var(--border); }
.top-nav .chip {
  border: none;
  border-radius: 12px 12px 0 0;
  background: #E2E6ED;
  color: #6B7A93;
  padding: 10px 20px;
  font-weight: 600;
  margin-bottom: -2px;
  white-space: nowrap;
}
.top-nav .chip:hover { background: #D3D9E2; color: var(--t1); }
.top-nav .chip.active {
  background: var(--card);
  color: var(--t1);
  font-weight: 700;
}
@media (max-width: 640px) {
  .top-nav.pillrow { border-bottom: none; gap: 8px; flex-wrap: wrap; }
  .top-nav .chip {
    border-radius: var(--r-pill);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--t1);
    font-weight: 500;
    margin-bottom: 0;
  }
  .top-nav .chip.active { background: var(--brand); font-weight: 600; }
}

/* ---------- город в строке «Где» -- раньше был первой меткой в общем облаке тегов
   (.card-tags) вперемешку с жанром/сложностью/сеттингом и терялся среди них. Теперь --
   яркий бейдж прямо в строке «Где» (см. renderWhereLine в app.js/my.js), тот же приём
   жёлтый-фон-тёмный-текст, что и у активного фильтра (.chip.active) и хедер-тега .tag ---------- */
.city-badge {
  display: inline-block;
  background: var(--brand);
  color: var(--t1);
  font-weight: 600;
  font-size: 12px;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  margin-left: 2px;
  vertical-align: middle;
}

/* ---------- сложность -- тоже была обычным серым тегом среди жанра/сеттинга, без подписи
   (просто «Лёгкая»/«Средняя»/«Сложная»). Теперь первый тег в облаке (см. renderDifficultyTag
   в app.js/my.js), с явной подписью «Сложность: ...» и цветным светофором -- палитра НЕ
   новая, те же цвета, что уже красят бейджи статуса (.badge-open/.badge-planned/
   .badge-cancelled в styles.css), просто применённые к тегу вместо статуса ---------- */
.tag-difficulty-easy { background: #E3F7ED; color: var(--ok); font-weight: 600; }
.tag-difficulty-medium { background: #FFF1DB; color: #B36B00; font-weight: 600; }
.tag-difficulty-hard { background: #FFE8DC; color: var(--err); font-weight: 600; }

/* ---------- РЕЗЕРВ: скрытый список тех, кто опоздал на основную запись, или кого
   организатор сознательно отодвинул (например, игротека для новичков, а записался опытный
   игрок). Виден только организатору/амбассадору (весь список + управление) или самому
   человеку в резерве (только своя запись) -- см. renderWaitlistBlock в app.js/my.js.
   Продвижение в основной список -- только вручную организатором. ---------- */
.card-waitlist { font-size: 12px; color: var(--t2); display: flex; flex-direction: column; gap: 4px; }
.card-waitlist-row { display: flex; align-items: center; gap: 8px; }
.link-btn {
  border: none;
  background: transparent;
  color: var(--active);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}
.link-btn:hover { opacity: 0.7; }

/* ---------- модалка «подробнее об игре» -- клик по названию игры на карточке (только у
   игр, не у «событий» -- см. card-game-clickable у renderCard в app.js/my.js) открывает
   модалку с картинкой/тегами/мета-инфо/комментарием организатора (ev.note -- поле
   «Комментарий / ссылка» в форме анонса, раньше нигде на самом сайте не показывалось,
   только в шаринг-тексте на organizer.html) и ссылками (Тесера/BGG), плюс та же кнопка
   записи, что и на карточке -- см. openGameDetailsModal. Обычный .modal рассчитан на
   заголовок+подсказку+одну форму -- контента здесь заметно больше, поэтому: заворачиваем
   картинку/теги/мету/комментарий/ссылки в свой gap-контейнер (как у .card), и разрешаем
   модалке прокручиваться, если на маленьком экране контент не помещается по высоте.
   Базовый .modal рассчитан на узкую форму (max-width: 380px) -- для этой модалки тесно
   (картинка+текст в одну узкую колонку), расширяем почти до ширины двух карточек;
   width: 100% на самом .modal уже отвечает за сужение на маленьких экранах, доп. медиа-
   запрос не нужен ---------- */
.card-game-clickable { cursor: pointer; }
.card-game-clickable:hover { text-decoration: underline; }
/* НЕСКОЛЬКО ИГР: короткая пометка "+ ещё N игр" сразу в заголовке карточки, см. app.js/
   my.js -- рядом с основным названием игры, но заметно бледнее и мельче него */
.card-game-extra-hint { font-size: 13px; font-weight: 400; color: var(--t1); }
#gameDetailsOverlay .modal { max-width: 620px; max-height: calc(100vh - 40px); overflow-y: auto; }
.game-details-body { display: flex; flex-direction: column; gap: 12px; margin-bottom: 18px; }
.modal-note {
  font-size: 13px;
  color: var(--t1);
  line-height: 1.5;
  white-space: pre-line;
  background: var(--bg);
  border-radius: var(--r-lg);
  padding: 12px 14px;
  margin-top: 4px;
}

/* ---------- ПОДЕЛИТЬСЯ: маленький круглый значок, а не полноразмерная кнопка -- рядом с
   бейджем статуса на карточке (card-top-right, см. renderCard) и рядом с заголовком в
   модалке «подробнее об игре» (modal-title-row) -- см. renderShareIconButton/
   openShareModal в app.js/my.js ---------- */
.card-top-right { display: flex; align-items: center; gap: 6px; }
.icon-btn {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: var(--bg);
  color: var(--t2);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
}
.icon-btn:hover { background: var(--border); color: var(--t1); }
.modal-title-row { display: flex; align-items: center; gap: 8px; }

/* ---------- модалки «поделиться» (ссылка) и «текст приглашения» (только организатору,
   см. openShareModal/openShareInviteModal в app.js,my.js) -- вторая содержит textarea на
   9 строк с готовым текстом поста, при базовой ширине модалки (380px) текст переносится
   почти по слову на строку и плохо читается -- расширяем обе, чтобы переход между ними не
   дёргал ширину окна ---------- */
#shareOverlay .modal, #shareInviteOverlay .modal { max-width: 480px; }
/* кнопка-переход в модалку приглашения -- .btn-ghost вне .card-actions/.result-actions по
   умолчанию не тянется на всю ширину (в отличие от .btn-primary над ней) */
#shareInviteOpenBtn { width: 100%; box-sizing: border-box; text-align: center; margin-top: 10px; }

/* ---------- дёрганье экрана при переходе между вкладками -- каждая страница сперва
   рисует пустой контейнер с короткой надписью "Загружаем...", а через мгновение (после
   ответа сервера) резко подставляет полный список -- высота страницы скачком вырастает.
   Резервируем примерный минимум высоты заранее, чтобы скачок был меньше и не так бросался
   в глаза, пока идёт загрузка (после неё min-height ничего не меняет -- реальный список
   и так обычно выше) ---------- */
#eventsGrid, #myGrid, #requestsList { min-height: 420px; }

/* ---------- ГЛАВНАЯ: #statsRow ("N мероприятий / N городов / ближайшее") -- пустой
   <section> (0px) до первого ответа сервера, потом резко вырастает на ~120px (3 карточки
   .card-s) -- это только на главной (единственная страница с этим блоком), см. жалобу
   Дарьи 2026-08-14 "при переключении на главную -- прыгает". Резервируем место так же,
   как у списков выше ---------- */
#statsRow { min-height: 120px; }

/* ---------- «Мой профиль»: до идентификации виден #notIdentifiedState (короткая строка),
   после -- вместо него разворачивается вся форма #profileForm (много полей, ощутимо
   выше) -- тот же приём, что у #statsRow выше: резервируем место под обе, чтобы переход
   не дёргал высоту страницы ---------- */
#notIdentifiedState, #profileForm { min-height: 480px; }

/* ---------- ПЕРЕНОС/ОТМЕНА мероприятия -- лейбл "на картинке" (см. renderImageRibbon в
   app.js/my.js): картинка оборачивается в .card-image-wrap (нужен только как контекст для
   position:absolute у ribbon), сама картинка ведёт себя как раньше. Полоса, не наклонная
   диагональная лента -- заметнее издалека и надёжнее в вёрстке при любой ширине карточки.
   Отменённым -- ещё и чёрно-белая картинка (.card-image-cancelled). Цвета НЕ новые: та же
   палитра, что уже красит .badge-cancelled (var(--err)) и .badge-planned (#B36B00) в
   styles.css/extra.css, просто сплошным фоном + белый текст (для контраста поверх ЛЮБОЙ
   фотографии, а не приглушённый бейджевый фон-в-цвет-текста). .badge-rescheduled -- та же
   короткая пилюля «Перенесено» рядом с обычным бейджем статуса (badgeGroup), не требует
   картинки вообще, чтобы факт переноса был виден и у мероприятий без фото. ---------- */
.card-image-wrap { position: relative; }
.card-image-wrap .card-image { display: block; }
.card-image-cancelled { filter: grayscale(1); }
.card-image-ribbon {
  position: absolute;
  left: 0;
  right: 0;
  top: 14px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  text-align: center;
  color: #fff;
}
.card-image-ribbon-cancelled { background: var(--err); }
/* «Внимание! Перенос даты» -- корпоративный жёлтый (var(--brand), тот же, что у .tag/
   .chip.active/.city-badge) с чёрной рамкой сверху и снизу, тёмный текст вместо белого
   для контраста на жёлтом фоне -- см. обсуждение с Дарьей 2026-08-19. Пилюля
   .badge-rescheduled в шапке карточки убрана (см. renderCard в app.js/my.js), этот ribbon
   на картинке -- теперь единственный визуальный индикатор переноса в списке карточек */
.card-image-ribbon-rescheduled {
  background: var(--brand);
  color: var(--t1);
  border-top: 2px solid var(--t1);
  border-bottom: 2px solid var(--t1);
}

/* ---------- ПРОФИЛЬ -- выбор канала связи (contactChooserOverlay, см. app.js/my.js:
   metaLineContact/openContactChooser) и сама страница «Мой профиль» (profile.html/js) ---------- */
/* организатор кликабелен, но это <button>, а не <a> (нужен JS-обработчик, не просто href) --
   сбрасываем стандартный вид кнопки и красим под уже привычный .hoverable-email */
.contact-chooser-trigger {
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
.contact-chooser-list { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.contact-chooser-option {
  display: block;
  text-align: center;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--t1);
  border-radius: var(--r-lg);
  padding: 12px 16px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: 0.15s;
}
.contact-chooser-option:hover { border-color: var(--t3); }

/* плашка «в разработке» -- сверху страницы «Фонд клуба» (про будущий список игр/BGA-
   библиотеку -- тематически это про каталог игр, а не про сам профиль), см. requests.html.
   Раньше была на «Мой профиль», перенесена -- см. обсуждение с Дарьей 2026-08-14 */
.wip-banner {
  background: #FFF1DB;
  color: #B36B00;
  border-radius: var(--r-lg);
  padding: 12px 16px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 18px;
}

/* форма профиля -- те же поля/лейблы, что в форме анонса на organizer.html (.field/.field-hint) */
.profile-email-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 18px; }
.profile-email-value { font-size: 16px; font-weight: 600; color: var(--t1); }
/* "напишите Дарье" -- имя вместо голого адреса, клик уже открывает mailto (тот же приём,
   что у организатора на карточке игры, см. .card-meta a.hoverable-email выше). Базовый
   .hoverable-email (styles.css) вне .card-meta красится по-другому (пунктирное подчёркивание,
   курсор "help" -- это для НЕкликабельных подсказок), здесь -- перекрываем на свой, "как на
   главной" вид: тёмный текст, подчёркивание только на hover, курсор pointer */
.profile-email-row a.hoverable-email { color: var(--t1); font-weight: 500; text-decoration: none; cursor: pointer; border-bottom: none; }
.profile-email-row a.hoverable-email:hover { text-decoration: underline; }
/* сама страница «Мой профиль» теперь стандартной ширины (.wrap, 1080px, как index/requests/
   info/my -- было wrap-narrow, см. profile.html), чтобы шапка/навигация/баннер "это вы" не
   были уже, чем на остальных страницах. Но САМА форма (.form-card) -- ограничена в ширину,
   иначе всего 2 колонки .form-grid растягиваются на весь 1080px и поля выглядят неоправданно
   широкими; тот же лимит, что и у organizer.html за счёт его wrap-narrow */
.form-card { max-width: 640px; }

/* ---------- УЧАСТНИК -- скрытое меню по правому клику (participantActionsOverlay, см.
   openParticipantActionsModal в app.js/my.js): организатор/амбассадор может удалить
   участника, перенести его в резерв или добавить/убрать гостя. Раньше кнопка "→ резерв"
   висела прямо на карточке всегда видимой -- теперь всё спрятано за правым кликом по
   имени участника (contextmenu на .card-participants .hoverable-email), см. обсуждение с
   Дарьей 2026-08-14 "спрячем это меню по правому клику". ---------- */
/* "Гостей: N" слева, счётчик справа -- те же круглые .stepper-btn, что и у "занято без
   записи" на карточке (см. renderReservedStepper), вместо прежних прямоугольных "− гость"/
   "+ гость" на var(--err) (цвет ошибки) -- красили совсем не деструктивное действие и
   выбивались из оформления сайта, см. обсуждение с Дарьей 2026-08-19 */
.participant-actions-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.participant-actions-guests-label { font-size: 13px; color: var(--t2); }
/* "→ Перенести в резерв" -- такое же нейтральное действие, как и на карточке (обычная
   кнопка без цвета ошибки), поэтому .btn-ghost (как «Указать почту»/«Анонсировать ещё
   одну»), а не .btn-secondary/var(--err); растягиваем на всю ширину модалки, как остальные
   кнопки в ней (по умолчанию .btn-ghost -- по содержимому) */
#participantActionsOverlay .btn-ghost { width: 100%; box-sizing: border-box; margin-bottom: 10px; }
/* "Удалить из списка" -- единственное по-настоящему деструктивное действие в этой модалке,
   поэтому единственное, что красится var(--err) -- сплошная заливка поверх .btn-primary,
   тот же var(--err), что уже красит .badge-cancelled и .card-image-ribbon-cancelled в этом
   файле. .btn-primary сам красит текст в var(--brand) (жёлтый) -- сочетание жёлтый-на-
   красном плохо читается и выглядит как ошибка вёрстки, поэтому явно перекрываем текст в
   белый, см. жалобу Дарьи 2026-08-19 "желтое на красном плохо" */
.btn-danger { background: var(--err); color: #fff; }
.btn-danger:hover { background: #d5420a; }

/* ---------- «показать прошедшие»: раньше актуальные и прошедшие мероприятия были просто
   одним отсортированным списком (актуальные сверху, приглушённая карточка -- единственная
   разница) -- границу легко упустить. Явный разделитель-подпись между группами, см.
   renderPastDivider в app.js, обсуждение с Дарьей 2026-08-19. Через всю ширину сетки
   (grid-column: 1 / -1, тот же приём, что и у .empty в styles.css), линия сверху -- как
   лёгкий заголовок раздела, не отдельная карточка */
.past-divider {
  grid-column: 1 / -1;
  padding-top: 14px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--t3);
}

/* ---------- АДМИНКА (admin.html/js) -- список зарегистрированных аккаунтов ----------
   Простая таблица без готового аналога в базовом styles.css (там таблиц не было вовсе) --
   минимальный набор правил, полосатые строки для читаемости длинного списка. */
.admin-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.admin-table th, .admin-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border); }
.admin-table th { color: var(--t3); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.03em; }
.admin-table tbody tr:hover { background: var(--bg); }
.admin-table select { padding: 6px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--card); color: var(--t1); font: inherit; }

/* ---------- РЕДИЗАЙН СОБЫТИЙ (organizer.html/js, app.js/my.js) -- у «события» нет попапа
   «подробнее об игре» (openGameDetailsModal не вызывается для type='event'), поэтому
   инфо/ссылки/привязанные игры показываем сразу на карточке. .card-event-note -- свободный
   текст «поле информации», .card-linked-games/.card-linked-event -- пара строк со ссылками
   на привязанные записи (см. renderCard). Ничего похожего в базовом styles.css нет. */
.card-event-info { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--t2); }
.card-event-note { white-space: pre-wrap; }
.card-linked-games, .card-linked-event {
  font-size: 13px;
  color: var(--t2);
}
.card-linked-event a { color: var(--t1); font-weight: 600; text-decoration: none; }
.card-linked-event a:hover { text-decoration: underline; }
/* СПИСОК ИГР НА СОБЫТИИ -- просьба Дарьи 2026-09-19 "они отображаются просто списком...
   рядом с игрой должна быть кнопка (записать)". Раньше .card-linked-games была одной
   строкой с именами через запятую (тот же <a> стиль, что у .card-linked-event выше) --
   теперь каждая игра -- отдельная строка (.card-linked-game-row) с названием слева и
   маленькой кнопкой «Записаться» справа (.btn-ghost из styles.css, тот же класс, что и
   «+ добавить игру» в форме организатора -- переиспользован как есть). */
.card-linked-games-title { font-weight: 600; color: var(--t1); }
.card-linked-game-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
}
.card-linked-game-name { color: var(--t1); font-weight: 600; text-decoration: none; }
.card-linked-game-name:hover { text-decoration: underline; }
.card-linked-game-signup {
  flex-shrink: 0;
  padding: 4px 12px;
  font-size: 12px;
  text-decoration: none;
}

/* ---------- АДМИНКА: список городов (admin.html/js) -- пилюля с названием + инлайн-кнопка
   удаления. .event-game-remove (styles.css) не подходит напрямую -- она через
   position:absolute привязана к своему специфичному блоку с играми, тут нужна простая
   инлайн-кнопка внутри пилюли. См. просьбу Дарьи 2026-09-15 "хочу иметь возможность
   добавлять новые города в админке". */
.city-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px 6px 14px;
  border-radius: var(--r-pill);
  background: var(--bg);
  border: 1px solid var(--border);
  font-size: 13px;
  color: var(--t1);
}
.city-pill-remove {
  border: none;
  background: none;
  color: var(--t2);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 50%;
}
.city-pill-remove:hover { color: var(--err); background: var(--card); }

/* ---------- #accountsSearch: input type="search" вместо type="text" -- см. комментарий в
   admin.html. Chrome игнорирует autocomplete="off" для полей, похожих на логин (подставляет
   сохранённые пароли/письма сайта), но не делает этого для type="search". Сбрасываем нативный
   вид поля поиска (кружок-крестик очистки, скругления Safari/Chrome), чтобы оно выглядело как
   обычный .field input, унаследованный из styles.css. ---------- */
input[type="search"] {
  -webkit-appearance: none;
  appearance: none;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration {
  -webkit-appearance: none;
}

/* ---------- КАРУСЕЛЬ картинок/описаний игр на карточке (renderGamesGallery в app.js/my.js) --
   заменяет собой .card-image-wrap только у анонсов с дополнительными играми (ev.games.length),
   см. обсуждение с Дарьей 2026-09-17 "на главной странице должна быть возможность листать
   такую карточку и посмотреть все картинки и описание игр". Слайды -- обычные <div>,
   переключаются через hidden (JS), а не через CSS-transform/scroll-snap -- проще и надёжнее
   при переменном количестве слайдов (1-6: основная игра + до 5 доп.). .card-gallery-slide
   без картинки (только название+описание) остаётся тем же по вёрстке, просто без <img>
   сверху. ---------- */
.card-gallery { position: relative; }
.card-gallery-slides { position: relative; }
.card-gallery-slide { position: relative; }
.card-gallery-slide .card-image { margin-bottom: 0; }
/* название игры -- только когда слайдов больше одного (иначе оно и так есть в .card-game
   заголовке карточки, дублировать не нужно, см. renderGamesGallery) */
.card-gallery-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--t1);
  margin-top: 8px;
}
/* ОВЕРЛЕЙ НАЗВАНИЯ ПОВЕРХ КАРТИНКИ -- просьба Дарьи 2026-09-19 "название игры отображается
   не под картинкой, как сейчас, а на самой картинке и отображает какая это игра из трёх".
   .card-gallery-image-wrap оборачивает <img> ТОЛЬКО когда у слайда есть картинка (см.
   renderGamesGallery в app.js/my.js) -- она даёт position:relative для абсолютного
   позиционирования .card-gallery-title-overlay внизу картинки, с градиентной подложкой,
   чтобы название читалось на любом фоне. Индекс «N из M» -- второй элемент того же ряда,
   мельче и полупрозрачнее названия. У слайдов БЕЗ картинки оверлею вешать не на что --
   там остаётся старый вариант: .card-gallery-title как обычный блок-заголовок над
   описанием (см. JS), поэтому базовые font-size/weight/color у класса не убираем -- их
   переопределяет только .card-gallery-title-overlay ниже. */
.card-gallery-image-wrap { position: relative; }
.card-gallery-image-wrap .card-image { display: block; }
.card-gallery-title-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px;
  padding: 20px 12px 10px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
  pointer-events: none;
}
.card-gallery-title-overlay .card-gallery-title {
  margin-top: 0;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.card-gallery-index {
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
  flex-shrink: 0;
  white-space: nowrap;
}
.card-gallery-desc {
  font-size: 13px;
  color: var(--t2);
  margin-top: 4px;
  line-height: 1.4;
  white-space: pre-wrap;
}
/* стрелки + точки -- один ряд под слайдом, тот же приём (круглые кнопки), что и у
   .stepper-btn (renderReservedStepper/участники), чтобы не заводить новый визуальный язык */
.card-gallery-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
}
.card-gallery-nav {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--t1);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: 0.15s;
  flex-shrink: 0;
}
.card-gallery-nav:hover { border-color: var(--t3); }
.card-gallery-dots { display: flex; gap: 6px; }
.card-gallery-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: none;
  background: var(--border);
  padding: 0;
  cursor: pointer;
}
.card-gallery-dot.active { background: var(--brand); }

/* ---------- «ВАЖНАЯ ИНФОРМАЦИЯ» -- КАРТОЧКИ ГОРОДОВ, редактируемые администратором
   (info.html/info.js, src/logic/infoCards.js) -- просьба Дарьи 2026-09-17 "дать мне
   (админу) возможность редактировать страничку «важная информация» прямо на сайте...
   больше никому =)". Сама карточка (.city-card/.city-card-featured) -- без изменений,
   те же классы, что были в статичной разметке раньше. Новое -- только тулбар
   ✏️/🗑 поверх карточки (виден только администратору) и форма модалки редактирования. ---------- */
.city-card { position: relative; }
.city-card-edit-toolbar {
  position: absolute;
  top: 14px;
  right: 16px;
  display: flex;
  gap: 6px;
}
.city-card-edit-toolbar button {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 15px;
  padding: 4px;
  line-height: 1;
  opacity: 0.55;
  transition: opacity 0.15s;
}
.city-card-edit-toolbar button:hover { opacity: 1; }

/* модалка редактирования карточки -- явно шире базовой (.modal рассчитан на узкую форму
   max-width:380px, см. комментарий у #gameDetailsOverlay выше в этом файле) и со своим
   скроллом -- динамических строк (контакты/заметки/ссылки) может набраться много */
#infoCardOverlay .modal { max-width: 560px; max-height: calc(100vh - 40px); overflow-y: auto; }
.ic-section { margin-bottom: 18px; display: flex; flex-direction: column; gap: 8px; }
.ic-section > .cap.mut { margin-bottom: 2px; }
/* одна строка редактора (контакт/заметка/ссылка) -- поле(я) + маленький крестик удаления
   справа, тот же приём, что и .city-pill-remove в admin.html/css у списка городов */
.ic-row { display: flex; gap: 8px; align-items: center; }
.ic-row input {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  font-size: 13px;
  font-family: inherit;
}
.ic-row-remove {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--t2);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.ic-row-remove:hover { border-color: var(--err); color: var(--err); }

/* ---------- ПЕРЕКЛЮЧАТЕЛЬ «режим показа / режим редактирования» на info.html -- просьба
   Дарьи 2026-09-17 (раскладка съехала при наборе): "можно на странице важное для админа
   просто будет режим показа/режим редактирования?" -- чтобы страница по умолчанию
   выглядела как обычный просмотр даже для администратора (без значков ✏️/кнопки
   добавления поверх карточек), а редактирование включалось явным тумблером, см.
   #infoEditModeToggle в info.js. Активное состояние -- та же заливка var(--brand), что и у
   .chip.active/.city-badge/.tag, чтобы не заводить новый цвет под "режим включён". ---------- */
.info-edit-mode-row { margin: 4px 0 4px; }
#infoEditModeToggle.active {
  background: var(--brand);
  color: var(--t1);
  border-color: var(--brand);
  font-weight: 600;
}

/* ---------- ЖИВЫЕ КОНТАКТЫ на карточках города -- имя + кнопка «Написать» рядом (просьба
   Дарьи 2026-09-19), вместо явного текста контакта. .link-btn -- уже существующий стиль
   маленькой текстовой кнопки-ссылки (см. РЕЗЕРВ выше в этом файле), переиспользуем как есть,
   тут только сама раскладка строки. ---------- */
.info-contact-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

/* ---------- БАННЕР КРУПНОГО СОБЫТИЯ -- просьба Дарьи 2026-09-19 "под блоком «вы вошли
   как» нужно создать место для анонса крупных событий - обычно его не видно, если нет ни
   одного активного события". hidden по умолчанию в разметке (index.html), показывается JS
   (renderBanner в app.js), только когда action=banner вернул не null. Картинка+заголовок
   слева, две кнопки внизу -- тот же .btn-primary/.btn-ghost, что и везде на сайте, ничего
   нового не заводим. ---------- */
.event-banner {
  display: flex;
  gap: 20px;
  align-items: center;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 20px;
  margin-top: 16px;
}
.event-banner-image {
  width: 160px;
  height: 110px;
  object-fit: cover;
  border-radius: var(--r-lg);
  flex-shrink: 0;
}
.event-banner-body { flex: 1; min-width: 0; }
.event-banner-title { margin: 4px 0 12px; font-size: 20px; }
.event-banner-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.event-banner-actions .btn-primary, .event-banner-actions .btn-ghost {
  width: auto;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
@media (max-width: 640px) {
  .event-banner { flex-direction: column; align-items: stretch; }
  .event-banner-image { width: 100%; height: 160px; }
}

/* ---------- значок настройки баннера на карточке (renderBannerIconButton в app.js) --
   тот же .icon-btn, что и «поделиться» рядом, подсветка -- когда ЭТО мероприятие сейчас
   активный баннер сайта (ev.isBanner с бэкенда), видно сразу в списке, не только открыв
   модалку ---------- */
.icon-btn-active { background: var(--brand); color: var(--t1); }
.icon-btn-active:hover { background: var(--brand); }

/* ---------- ВРЕМЕННЫЙ ЛЕНДИНГ СОБЫТИЯ (landing.html/js) -- просьба Дарьи 2026-09-19
   "нужно предусмотреть возможность создания временных лендингов событий". СКЕЛЕТ до
   реального макета, который Дарья пришлёт отдельно (см. комментарий в landing.html) --
   минимальный набор правил, картинка на всю ширину + заголовок + инфо + ссылки. ---------- */
.landing-image {
  width: 100%;
  max-height: 360px;
  object-fit: cover;
  border-radius: var(--r-lg);
  margin-top: 24px;
}
.landing-title { margin: 12px 0 8px; }
.landing-note { white-space: pre-line; color: var(--t2); line-height: 1.5; margin-bottom: 16px; }
.landing-links { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.landing-actions .btn-primary { width: auto; text-decoration: none; display: inline-flex; align-items: center; }
