/* Полноэкранный просмотр фотографии. Общий слой для лендинга и страницы зала:
   разметку плиток обобщает атрибут data-lightbox, скрипт — app/frontend/lib/gallery.ts.
   Правила жили в landing.css, пока лайтбокс был только на главной. Собственных
   токенов не используют, поэтому файл подключается к любой странице. */

/* Lightbox: полноэкранный слой поверх страницы, открывается кликом по плитке. */
.lightbox { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
  background: rgba(0, 0, 0, .82); padding: 24px; }
.lightbox[hidden] { display: none; }
.lightbox img { max-width: 100%; max-height: 82vh; border-radius: 12px; transition: opacity .15s; }
/* Пока новый кадр не декодирован, старый не показываем: иначе при переходе между
   фото на мгновение виден предыдущий снимок. min-height у figure держит коробку
   на месте, чтобы модалка не схлопывалась в ноль и не прыгала. */
.lightbox img.is-loading { opacity: 0; }
.lightbox figure { position: relative; margin: 0; min-height: 50vh; display: grid; place-content: center; }
/* Спиннер живёт ровно то время, пока кадр гасится: иначе на медленной сети посетитель
   видит тёмный слой с крестиком и пустоту внутри. Рисуем его на figure (сама картинка
   в этот момент прозрачна) по классу, а не по :has(): класс ставит скрипт, и состояние
   проверяется юнит-тестом. Светлый — подложка тёмная. */
.lightbox figure.is-loading::after { content: ""; position: absolute; left: 50%; top: 50%;
  width: 38px; height: 38px; margin: -19px 0 0 -19px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .28); border-top-color: #fff;
  animation: lightbox-spin .8s linear infinite; }
@keyframes lightbox-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .lightbox figure.is-loading::after { animation: none; } }
.lightbox-caption { margin-top: 12px; color: #fff; font-size: 14px; text-align: center; }
/* z-index у кнопок обязателен: figure тоже позиционирована (ради спиннера) и идёт в
   разметке слоя ПОСЛЕ них, так что при z-index:auto порядок отрисовки решает DOM и
   кадр ложится поверх кнопок. На узком экране коробка figure дотягивается до отступа
   слоя и съедала клик по стрелкам — жали видимую кнопку, не происходило ничего. */
.lightbox-close { position: absolute; z-index: 1; top: 16px; right: 20px; width: 44px; height: 44px;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, .16); color: #fff; font-size: 24px; cursor: pointer; }

/* Стрелки листания. Габарит 44px — минимальная комфортная цель для пальца. */
.lightbox-nav{ position: absolute; z-index: 1; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .16); color: #fff; font-size: 28px; line-height: 1; cursor: pointer; }
.lightbox-prev { left: 16px; }
.lightbox-next { right: 16px; }
.lightbox-nav[hidden] { display: none; }
