/* ==========================================================================
   PHOTO — галерея «Фото» (TASK-289)
   Стили сетки и полноэкранного оверлея. Не копия team.css: слайд
   SPA-секции и флаг скрытия лого живут в main.css (рядом с блоком
   vrk-no-logo / vrk-team-open), здесь — только собственно галерея.
   ========================================================================== */

/* ─── Шапка фрагмента: диагностика «M не показано» + пустое состояние ───
   Внутри .photo-section — АБСОЛЮТНО над зоной карточек (как team
   page-header в team.css — тоже вне потока): #photo-grid растягивается
   на секцию ИМЕННО как team-grid (та же clientHeight → тот же расчёт
   карточек в js). На photo.html секции нет — шапка в потоке. */
.photo-section .photo-header {
    position: absolute;
    top: var(--header-h);
    right: 40px;
    left: 40px;
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding: 6px 0 0;
    min-height: 30px;
    box-sizing: border-box;
    pointer-events: none;
    z-index: 10;
}

.photo-section .photo-header > * {
    pointer-events: auto;
}

.photo-counter {
    font-family: Arial, sans-serif;
    font-size: 13px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.45);
    white-space: nowrap;
}

/* ─── Сетка материалов (плоский манифест старого формата) ─── */
.photo-cards-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    padding: 8px 40px 24px;
    margin: 0 auto;
    max-width: 1600px;
    width: 100%;
    box-sizing: border-box;
}

/* Отступ от лого (fixed, слева по центру, z-index 999): только там,
   где лого реально отрисован — html.vrk-photo-has-logo ставит
   js/photo.js (page-logo-link в DOM И logo !== false в конфиге).
   На photo.html лого нет → отступа нет, сетка на всю ширину
   (дефект Tester'а v2: пустое поле 26.5% без лого). */
@media (min-width: 769px) {
    html.vrk-photo-has-logo .photo-cards-grid,
    html.vrk-photo-has-logo .photo-albums-row {
        padding-left: 26.5%;
    }
}

/* TASK-294: тот же инсет в ПРЕВЬЮ АЛЬБОМА — сдвиг вправо sticky-шапки
   (стрелка «← Все альбомы» + заголовок) и сетки ячеек, слева лого.
   Флор max(…, 210px): правый край лого 38+168=206px, чистый 26.5% на
   769–792px даёт 203.7–209.9px (подлезание под лого) — 210px держит
   зазор ≥4px, с 793px процент сам становится больше флора.
   top/right/bottom наследуют базовые правила (в т.ч. десктопные
   padding-bottom:60px шапки v27 и padding-top:0 сетки v27 — v26/v27
   TASK-293 не затронуты); число колонок держит targetColumnWidth
   (альбомные константы CELLS в js/photo.js, шаг 2). */
@media (min-width: 769px) {
    html.vrk-photo-has-logo .photo-album-view-header,
    html.vrk-photo-has-logo .photo-album-view .photo-cells {
        padding-left: max(26.5%, 210px);
    }
}

/* Низ скроллящегося блока (секция выше); высота зоны = team-grid (
   команда): паддинг-низ не добавляем — иначе ритм уезжает */
#photo-grid {
    overflow-y: auto;
    flex: 1 1 auto;
}

.photo-card {
    position: relative;
    margin: 0;
    aspect-ratio: 1 / 1;
    background: #0d0d0d;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    transition: border-color 0.2s ease, transform 0.2s ease;
}

.photo-card:hover,
.photo-card:focus-visible {
    border-color: rgba(255, 255, 255, 0.3);
    transform: translateY(-2px);
}

.photo-card:active {
    transform: translateY(0) scale(0.98);
}

.photo-card img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.photo-card.is-loaded img {
    opacity: 1;
}

/* Лоадер — классы команды (.team-card-loader из team.css):
   спиннер/позиция/скрытие через .hidden; в photo-контейнерах жёстко
   display:none при .hidden или .is-loaded (team.css оставляет
   полупрозрачным — на обложке/ячейке он должен уйти сам). */
.photo-card-loader,
.photo-card-loader .photo-card-spinner,
.team-card-loader,
.team-card-loader .team-card-spinner {
    display: inherit;
}

.is-loaded .team-card-loader,
.is-loaded .photo-card-loader,
.team-card-loader.hidden,
.photo-card-loader.hidden {
    display: none !important;
}

.photo-card-spinner {
    width: 26px;
    height: 26px;
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-top-color: #ff0000;
    border-radius: 50%;
    animation: photoSpin 0.8s linear infinite;
}

@keyframes photoSpin {
    to { transform: rotate(360deg); }
}

/* Плейсхолдер видео без постера: круг с треугольником play */
.photo-card--no-poster::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 50%;
}

.photo-card--no-poster::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-38%, -50%);
    border-style: solid;
    border-width: 9px 0 9px 15px;
    border-color: transparent transparent transparent rgba(255, 255, 255, 0.85);
    z-index: 1;
}

/* Значок видео в правом верхнем углу карточки */
.photo-video-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 26px;
    height: 22px;
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 5px;
    z-index: 2;
}

.photo-video-badge::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-40%, -50%);
    border-style: solid;
    border-width: 5px 0 5px 8px;
    border-color: transparent transparent transparent #fff;
}

/* Подпись (имя файла или title) */
.photo-card figcaption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 18px 10px 6px;
    font-family: Arial, sans-serif;
    font-size: 11px;
    line-height: 1.3;
    color: rgba(255, 255, 255, 0.85);
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0));
    pointer-events: none;
}

/* ─── Пустое состояние ─── */
.photo-empty {
    margin: 0;
    padding: 40px 20px;
    font-family: Arial, sans-serif;
    font-size: 15px;
    color: rgba(255, 255, 255, 0.6);
    letter-spacing: 0.5px;
}

.photo-empty[hidden] {
    display: none;
}

/* ==========================================================================
   КАТАЛОГ АЛЬБОМОВ — карточки как на «Команде» (v3)
   Горизонтальная прокрутка (.photo-albums-row) по подходу .team-grid
   из team.css; стрелки .team-arrow (team.css) — кламп на границах;
   точки-индикаторы на мобайле — подход .team-dots.
   ========================================================================== */
/* ─── Стрелки каталога — классы команды (.team-page-header/.team-nav-arrows
   из team.css): позиции и ритм совпадают; отдельного блока больше нет.
   Команда держит шапку-стрелки АБСОЛЮТНОЙ (вне потока, team.css:216) —
   подсказываю то же здесь, иначе ряд уезжает вниз на высоту блока.
   pointer-events у команды: блок none, стрелки auto. */
.photo-albums-view .team-page-header {
    pointer-events: none;
    z-index: 10;
}

.photo-albums-view .team-nav-arrows {
    pointer-events: auto;
}

/* Ряд карточек альбомов = .team-grid из team.css (та же высота зоны,
   тот же JS-пересчёт). Скроллбар — командный (team.css: thin,
   rgba(255,255,255,0.2), webkit 6px, hover красный; на мобайле скрыт
   media ≤768 team.css) — v7 отменил скрытие v6, своих правил нет. */

/* Вертикальный скролл превью альбома — как горизонтальный ряд
   списка альбомов (team-grid, team.css 353-381): тонкая полоса,
   бледный скруглённый бегунок, красный на hover. */
#photo-grid {
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
}

#photo-grid::-webkit-scrollbar {
    width: 6px;
}

#photo-grid::-webkit-scrollbar-track {
    background: transparent;
}

#photo-grid::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.2);
    border-radius: 3px;
}

#photo-grid::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 0, 0, 0.5);
}

/* Вид каталога альбомов — растянуть на секцию (родитель ряда):
   иначе .team-grid flex:1 не работает, и ритм расходится с командой */
.photo-albums-view {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.photo-albums-view.hidden {
    display: none;
}

/* Точки на десктопе не должны занимать высоту (как team-dots) */
@media (min-width: 769px) {
    .photo-dots {
        display: none;
    }
}

/* Фото-специфика карточки альбома: обложка cover.jpg.
   Ритм/размер/шрифты карточки — из .team-card/.team-card-photo/.team-card-name
   (team.css). Исключение: name-блок альбома — одна строка (название),
   но фактическая высота выравнивается с командной (77px на десктопе —
   3 строки: 16+26+26), иначе карточки в ряду на разных y. */
.photo-album-card-name {
    min-height: 77px;
}

@media (max-width: 768px) {
    .photo-album-card-name {
        min-height: 55px;
    }
}

/* Плейсхолдер отсутствующей обложки: видимый признак.
   album.flat («Материалы») — нейтральный; альбом без cover.jpg —
   с восклицанием, владелец не должен пропустить. */
.photo-album-cover-ph {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 12px;
    box-sizing: border-box;
    font-family: Arial, sans-serif;
    font-size: 13px;
    letter-spacing: 0.5px;
    color: rgba(255, 255, 255, 0.55);
    background:
        linear-gradient(135deg, rgba(255,255,255,0.04) 25%, transparent 25%,
            transparent 50%, rgba(255,255,255,0.04) 50%,
            rgba(255,255,255,0.04) 75%, transparent 75%);
    background-size: 28px 28px;
}

.photo-album-cover-ph--warn {
    color: rgba(255, 255, 255, 0.85);
}

.photo-album-cover-ph--warn::before {
    content: "!";
    display: block;
    position: absolute;
    top: 26%;
    left: 50%;
    transform: translateX(-50%);
    width: 34px;
    height: 34px;
    border: 2px solid #ff0000;
    border-radius: 50%;
    color: #ff0000;
    font-size: 22px;
    font-weight: bold;
    line-height: 30px;
    text-align: center;
}

/* Точки-индикаторы (мобайл): класс команды .team-dots даёт общий блок —
   сами точки красим фото-классом (team.css не знает .photo-dot) */
.photo-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
    transition: background 0.3s ease;
}

.photo-dot.active {
    background: #ff0000;
}

/* ==========================================================================
   ПРЕВЬЮ АЛЬБОМА — 500px-стиль (v3)
   Крупная сетка с минимальными отступами; картинки ВПИСАНЫ в ячейку
   (object-fit: contain) — обрезки в чужие пропорции нет. Раскладка —
   TASK-292 v2: колонки одинаковой ширины «как 500px»: кадры друг под
   другом, высоты колонок независимы. Пиксельную геометрию считает
   js/photo.js (единая функция, без aspect-ratio); стабильно до загрузки —
   место под кадр резервируется сразу по известному AR.
   ========================================================================== */
.photo-album-view {
    display: none;
}

.photo-album-view.active {
    display: block;
}

/* Шапка уровня альбома. v26, TASK-293 (правка владельца): стрелка «← Все
   альбомы» СЛЕВА перед названием (v6 было: название слева, стрелка справа);
   justify-content: flex-start + order:-1 у стрелки — DOM-порядок (заголовок
   первым) сохранён для скринридера/Tab. Sticky/фон/z-index не менялись. */
.photo-album-view-header {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 16px;
    padding: 10px 40px 0;
    box-sizing: border-box;
    /* v14: закреплённая шапка превью — не уезжает с миниатюрами при
       прокрутке (#photo-grid — ближайший скроллящийся предок, sticky сработает;
       топ 0 = верх его видимой области: на мобайле 148 от окна — под общей
       шапкой сайта (128+20), на десктопе 113 — как сейчас в потоке).
       Фон непрозрачный — миниатюры не видны сквозь, «дыры» сверху нет
       (шапка в потоке до приклейки занимает своё место). */
    position: sticky;
    top: 0;
    background: #080808;
    z-index: 20;
}

/* v9: «Все альбомы» — иконка-стрелка (класс .team-arrow из team.css,
   вид/поведение как в ряду и в оверлее); photo-класс остался хуком JS.
   v26, TASK-293: стрелка визуально слева перед заголовком (order:-1). */
.photo-album-back {
    flex-shrink: 0;
    order: -1;
}

.photo-album-view-title {
    /* v26: защита от длинных имён альбомов — обрезка с эллипсисом
       (заголовок в flex-строке со стрелкой, min-width:0 обязателен). */
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: Arial, sans-serif;
    font-size: 28px;
    color: #fff;
    letter-spacing: 1px;
}

/* v26, TASK-293 (ПК ≥769px): шрифт заголовка и стрелки — как у карточек
   списка альбомов (Helvetica Neue, 400, ls −0.03em, lh 1.1), но 38px;
   стрелка масштабируется под заголовок (38×38; svg перебивает width/height
   атрибуты innerHTML). Мобайл ≤768 не трогается: 20px и 44×44 (тач-таргет). */
/* v27, TASK-293 (владелец: «начинаешь скроллить — зазор пропадает, должно
   оставаться»): зазор 60px перенесён В САМИ sticky-шапку (padding-bottom).
   Полоса непрозрачного #080808 (фон секции тот же — шва нет) едет вместе
   с шапкой: фото уходят ПОД неё при скролле и появляются у её кромки —
   зазор «заголовок → фото» держится 60px в любом положении скролла.
   Вариант v26 (padding-top сетки) уезжал с контентом и схлопывался.
   .photo-cells в альбоме обнулён по паддингу-сверху (иначе 60+16=76);
   layoutCells читает 0 и пересчитывает высоту сам (JS не тронут).
   Геометрия в покое не изменилась против v26: title.bottom → фото = 60. */
@media (min-width: 769px) {
    .photo-album-view-title {
        font-family: "Helvetica Neue", sans-serif;
        font-size: 58px;
        font-weight: 400;
        letter-spacing: -0.03em;
        line-height: 1.1;
    }
    .photo-album-back svg {
        width: 48px;
        height: 48px;
    }
    .photo-album-view-header {
        padding-bottom: 60px;
    }
    .photo-album-view .photo-cells {
        padding-top: 0;
    }
}

/* Видимое сообщение, когда все ячейки альбома скрыты (файлы недоступны) */
.photo-album-note {
    margin: 18px 40px;
    font-family: Arial, sans-serif;
    font-size: 14px;
    color: rgba(255, 255, 255, 0.6);
}

.photo-album-note[hidden] {
    display: none;
}

/* Сетка ячеек альбома — TASK-292 v2: вертикальная раскладка колонками
   «как 500px»: кадры идут друг под другом во всю ширину колонки, колонки
   по горизонтали на независимой высоте. Пиксельную геометрию (число
   колонок, x/y каждой ячейки, ширины/высоты) считает js/photo.js —
   единая функция раскладки; контейнер — relative-холст, ячейки
   позиционируются абсолютно (DOM-порядок не трогается). aspect-ratio не
   используется (JS-геометрия на любом движке); gap синхронен с CELLS
   в js/photo.js (десктоп 24 / мобайл 16 — v3:owner ×4). */
.photo-cells {
    position: relative;
    gap: 24px; /* TASK-292 v3 (владелец): ×4 от 6px; синхронно с CELLS.gap */
    padding: 16px 40px 40px;
    box-sizing: border-box;
}

/* Плоская сетка старого формата (манифест без альбомов) — прежний вид:
   квадраты. aspect-ratio возвращён скоупом на неё (общему .photo-cell
   размер теперь задаёт JS-раскладка). */
.photo-cards-grid .photo-cell {
    aspect-ratio: 1 / 1;
}

.photo-cell {
    position: absolute; /* TASK-292 v2: x/y задаёт JS-раскладка колонок */
    margin: 0;
    background: #0d0d0d;
    border: none;
    border-radius: 4px;
    overflow: hidden;
    cursor: pointer;
    transition: filter 0.2s ease;
    box-sizing: border-box;
}

.photo-cell:hover,
.photo-cell:focus-visible {
    filter: brightness(1.18);
}

.photo-cell img {
    width: 100%;
    height: 100%;
    object-fit: cover; /* TASK-292 v2: размер ячейки задаёт раскладка колонок */
    display: block;
    opacity: 0;
    transition: opacity 0.25s ease;
}

/* Плоская сетка старого формата — как было: вписывание в квадрат */
.photo-cards-grid .photo-cell img {
    object-fit: contain;
}

.photo-cell.is-loaded img {
    opacity: 1;
}

.photo-cell.is-loaded .team-card-loader,
.photo-cell.is-loaded .photo-card-loader,
.photo-cell.photo-card--no-poster .team-card-loader,
.photo-cell.photo-card--no-poster .photo-card-loader {
    display: none;
}

.photo-cell .photo-cell-cap {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 14px 8px 4px;
    font-family: Arial, sans-serif;
    font-size: 10px;
    line-height: 1.3;
    color: rgba(255, 255, 255, 0.85);
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.photo-cell:hover figcaption,
.photo-cell:focus-visible figcaption {
    opacity: 1;
}

/* ==========================================================================
   ПОЛНОЭКРАННЫЙ ОВЕРЛЕЙ ПРОСМОТРА
   z-index 100000 — конвенция .team-popup-overlay (team.css);
   выше секции 998 и лого 999. Лого на время просмотра прячется
   через html.vrk-photo-overlay (main.css, блок в конце файла).
   ========================================================================== */
.photo-overlay {
    position: fixed;
    inset: 0;
    z-index: 100000;
    background: rgba(0, 0, 0, 0.92);
    display: none;
    align-items: center;
    justify-content: center;
}

.photo-overlay.active {
    display: flex;
}

.photo-overlay-stage {
    max-width: 94vw;
    max-height: 92vh;
    max-height: 92dvh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.photo-overlay-stage img {
    max-width: 94vw;
    max-height: 92vh;
    max-height: 92dvh;
    width: auto;
    height: auto;
    display: block;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
}

.photo-overlay-stage video {
    max-width: 94vw;
    max-height: 92vh;
    max-height: 92dvh;
    width: auto;
    height: auto;
    display: block;
    background: #000;
}

/* Крестик — правый верхний угол; hit-зона ≥ 44px (мобайл-гайд) */
.photo-overlay-close {
    position: fixed;
    top: 14px;
    right: 14px;
    width: 44px;
    height: 44px;
    padding: 0;
    background: transparent;
    /* v17: рамка снята (правка владельца) — тап-зона 44×44 осталась;
       индикатор фокуса клавиатуры — :focus-visible ниже */
    border: none;
    color: #fff;
    font-size: 30px;
    line-height: 1;
    cursor: pointer;
    z-index: 100001;
    transition: color 0.2s ease;
}

/* Читаемость крестика на светлых участках фото: мягкая тень-подложка
   (не рамка) + на hover — красный крестик */
.photo-overlay-close {
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.8);
}

.photo-overlay-close:hover {
    color: #ff0000;
}

/* «Скачать» — левый верхний угол; v11: иконка (стрелка в лоток)
   вместо текста на обеих платформах; имя — aria-label/title (JS).
   Рамка/фон бывшей pill-кнопки сохранены (позиция не менялась). */
.photo-overlay-download {
    position: fixed;
    top: 24px;
    left: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    text-decoration: none;
    color: #fff;
    /* v17: плашка и рамка сняты; тап-зона 44×44; читаемость — тень
       на svg (правило ниже) */
    background: transparent;
    border: none;
    border-radius: 999px;
    z-index: 100001;
    transition: color 0.2s ease;
}

.photo-overlay-download svg {
    display: block;
    /* Читаемость на светлых участках фото: тень, не рамка */
    filter: drop-shadow(0 1px 5px rgba(0, 0, 0, 0.85));
}

.photo-overlay-download:hover {
    color: #ff0000;
}

.photo-overlay-download:hover svg * {
    stroke: #ff0000;
}

/* «3 / 40» сверху по центру */
.photo-overlay-count {
    position: fixed;
    top: 30px;
    left: 50%;
    transform: translateX(-50%);
    font-family: Arial, sans-serif;
    font-size: 14px;
    letter-spacing: 1px;
    color: rgba(255, 255, 255, 0.7);
    z-index: 100001;
    pointer-events: none;
}


/* Стрелки листания (десктоп) — вид .team-arrow из team.css
   (прозрачные, красный hover на SVG), позиция — по краям экрана
   на середине высоты, как у карточек команды */
.photo-overlay-nav {
    position: fixed;
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
    padding: 0;
    background: none;
    border: none;
    outline: none;
    cursor: pointer;
    z-index: 100001;
}

.photo-overlay-prev { left: 24px; }
.photo-overlay-next { right: 24px; }

/* ─── Мобайл ─── */
@media (max-width: 768px) {
    /* v18: отступ уменьшен 148 → 128 (высота общей мобильной шапки).
       Больше запаса не нужно: закреплённая шапка альбома (sticky,
       непрозрачный фон) приклеивается на top: 0 видимой области —
       то есть ровно под общую шапку (128), без пустой полосы, через
       которую просвечивали миниатюры. Командный 100px при этой
       прозрачной шапке оставил бы щель 100–128 — поэтому 128. */
    .photo-section {
        padding-top: 128px;
    }

    .photo-section .photo-header {
        top: 128px; /* синхронно с padding-top выше */
        right: 20px;
        left: 20px;
        padding: 4px 0 0;
        min-height: 26px;
    }

    /* Отступ под лого — только десктоп: на мобайле сетка на всю ширину */
    .photo-cards-grid,
    .photo-cells {
        padding-left: 20px;
        padding-right: 20px;
    }

    .photo-cards-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
    }

    /* TASK-292 v2: сетка альбома одна на всех брейкпоинтах — колонки
       (геометрию считает js/photo.js по цели конфига: мобайл — фактически
       2 колонки). Остаются только мобильные отступы и gap. */
    .photo-cells {
        gap: 16px; /* TASK-292 v3 (владелец): ×4 от 4px; синхронно с CELLS.gapMobile */
    }

    /* Ряд карточек — классы команды: их мобильный блок (team.css) даёт
       75vw/300 + паддинги; photo-правило не нужно —
       повторяет team.css, дубль убран (v6) */

    /* Шапка альбома на мобайл.
       v28, TASK-293 (владелец: «отступ верный, но уменьшается при
       скролле»): зазор 16px перенесён В САМИ sticky-шапку (padding-bottom),
       как v27 на десктопе — variant с padding-top у .photo-cells уезжал
       с контентом и схлопывался. Геометрия в покое не меняется:
       title.bottom → первое фото = 26 (10 в шапке + 16 полоса). */
    .photo-album-view-header {
        padding: 8px 20px 16px;
    }
    .photo-album-view .photo-cells {
        padding-top: 0;
    }

    /* Название альбома на мобайл — размер как .name-white у команды */
    /*.photo-album-view-title {
        font-size: 20px;
    }*/

    .photo-album-note {
        margin: 14px 20px;
    }

    /* Стрелки оверлея на мобайле прячем — жест/край экрана, кнопки теснят кадр
       (как у «Команды»: .team-arrow скрыт на мобайле) */
    .photo-overlay-nav {
        display: none;
    }

    /* v11: «Скачать» — левый верхний угол (иконка), тап-зона ≥ 44px;
       с крестиком (правый верх) в углы не пересекаются */
    .photo-overlay-download {
        top: 14px;
        left: 14px;
        bottom: auto;
        transform: none;
        width: 44px;
        height: 44px;
        padding: 0;
    }

    .photo-overlay-count {
        top: 20px;
    }

}

/* ≤480 — как у «Команды»: карточка 80vw, name-строки мельче (v4) */
/* ≤480 — правило из team.css (80vw / name 20px) работает на
   .team-card/.name-white напрямую — дубль убран (v6) */

/* ─── Standalone photo.html ─── */
body.photo-page {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    margin: 0;
    padding: 0;
    background-color: #080808;
    color: #fff;
    font-family: Arial, sans-serif;
}

/* Ссылка "← Главная" для standalone photo.html (образец .team-back-link) */
.photo-back-link {
    position: fixed;
    top: 20px;
    left: 20px;
    z-index: 100;
    color: #fff;
    text-decoration: none;
    font-weight: bold;
    font-size: 13px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 6px 14px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.3);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: color 0.3s ease, border-color 0.3s ease;
}

.photo-back-link:hover {
    color: #ff0000;
}

.photo-page .photo-section-title {
    text-align: center;
    font-size: 44px;
    margin: 18px 0 0;
    color: #fff;
    letter-spacing: 1px;
}

/* На standalone-странице заголовок слева (как шапка фрагмента) */
.photo-page .photo-header {
    justify-content: center;
}
/* Кнопка «вниз»: скрытие по [hidden] (у .team-collapse-btn display:flex,
   без правила атрибут hidden не прячет кнопку и она перехватывает клики). */
.photo-bottom-btn[hidden] {
    display: none;
}
/* v9: в превью альбома кнопки «вверх/вниз» не нужны (правка владельца
   v9). «Вверх» в альбоме была показана в 2b7259e, возвращена к исходному
   по решению владельца TASK-293: «в сетке с фото она не нужна». Вместе с
   правилом снят запас 72px из 2b7259e — он существовал только под кнопку
   (иначе внизу альбома оставался пустой хвост). Класс photo-album-open
   ставит photo.js при открытии превью. */
body.photo-album-open .photo-collapse-btn,
body.photo-album-open .photo-bottom-btn {
    display: none;
}
/* v10, мобайл: возврат к списку альбомов. Командное .team-arrow скрыто
   на ≤768 (стрелки ряда на мобайле не нужны) — для photo-back это
   правило перебиваем скоупленно (два класса = специфичность выше
   командного media-правила и file позже); на «Команду» не влияет. */
@media (max-width: 768px) {
    .photo-album-back.team-arrow {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
    }
}
/* v12: hover-зум превью альбома — масштабируется САМА картинка внутри
   контейнера (overflow hidden), сетка не дёргается. Тач-устройства:
   hover нет (media hover:none) — и «залипания» при тапе нет. */
.photo-cell {
    overflow: hidden;
}

.photo-cell img {
    transition: transform 0.25s ease;
}

@media (hover: hover) {
    .photo-cell:hover img {
        transform: scale(1.06);
    }
}

@media (prefers-reduced-motion: reduce) {
    .photo-cell img {
        transition: none;
    }

    @media (hover: hover) {
        .photo-cell:hover img {
            transform: none;
        }
    }
}
/* v13: «Без альбома» — НЕ настоящий альбом: пунктирная рамка обложки и
   приглушённый плейсхолдер; исчезает, когда в манифесте нет записей
   без альбома (сборка по реальным папкам). */
.photo-album-card--flat .photo-album-cover {
    background: repeating-linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.06) 0px,
        rgba(255, 255, 255, 0.06) 4px,
        transparent 4px,
        transparent 8px
    );
    border: 1px dashed rgba(255, 255, 255, 0.25);
    border-radius: 14px;
}

.photo-album-card--flat .photo-album-cover-ph {
    font-style: italic;
    color: rgba(255, 255, 255, 0.55);
}
/* v17: индикатор фокуса с клавиатуры (рамка снята в обычном/hover —
   фокус остаётся видимым): скоуп на оба контрола оверлея */
.photo-overlay-close:focus-visible,
.photo-overlay-download:focus-visible {
    outline: 2px solid rgba(255, 255, 255, 0.7);
    outline-offset: 2px;
    border-radius: 6px;
}
/* v19: скрытый хост кэш-контейнеров альбомов — держит узлы в DOM-дереве
   (Chrome сохраняет декодированные картинки, lazy не перезагружается при
   возврате в альбом). Вне видимой области и без кликов. */
.photo-cache-host {
    position: absolute;
    left: -9999px;
    top: 0;
    width: 1px;
    height: 1px;
    overflow: hidden;
    visibility: hidden;
    pointer-events: none;
}
/* v22: обратная связь по клику на альбом:
   — нажатое состояние карточки сразу (поднимается/приглушается);
   — спиннер появляется ТОЛЬКО если отрисовка не уложилась в 150 мс
     (кэшированные открытия не мигают — замер: вставка 1,6–30 мс);
   — снятие по отрисовке (rAF×2 внутри photo.js). */
.photo-card-pressed {
    opacity: 0.75;
    transform: scale(0.985);
    transition: opacity 0.12s ease, transform 0.12s ease;
}

.photo-card-loader-press {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
}
