/* ==========================================================================
   Сетка плиток, галерея внутри плитки и просмотр фото.
   ========================================================================== */

/* Сетка на шесть колонок: треть = 2, половина = 3, вся строка = 6 */
.projects-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    column-gap: var(--gap-grid);
    row-gap: clamp(3rem, 5vw, 4.5rem);
    margin-top: var(--space-8);
    align-items: start;
    /* Плитка меньшего размера подтягивается в пустой хвост строки,
       иначе при смешении ширин в ряду остаются дыры */
    grid-auto-flow: row dense;
}

.card--small {
    grid-column: span 2;
}

.card--medium {
    grid-column: span 3;
}

.card--large {
    grid-column: span 6;
}

/* Чем шире плитка, тем спокойнее пропорции кадра */
.card--small .project-image {
    aspect-ratio: var(--card-ar, 3/4);
}

.card--medium .project-image {
    aspect-ratio: var(--card-ar, 1/1);
}

.card--large .project-image {
    aspect-ratio: var(--card-ar, 16/9);
}

.card--large .project-title {
    font-size: clamp(1.6rem, 3vw, 2.4rem);
}

/* ------------- выравнивание подписей по строке (subgrid) ------------------
   У каждой фотографии своя пропорция, поэтому раньше заголовки в одном ряду
   прыгали по высоте. Теперь плитка — подсетка из двух строк (кадр и подпись),
   общих для всего ряда: кадры стоят на одной нижней линии, как на полке,
   а подписи начинаются на одной высоте. В режиме правки у плитки
   есть служебные кнопки, поэтому там раскладка остаётся прежней. */
/* Только когда плитки стоят рядом (от 600 px). На телефоне они идут по одной,
   выравнивать нечего, а Safari на iPhone считал подсетку с пропорциями кадров
   неверно: сплющивал картинки и разрывал подпись. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 600px) {
    body:not(.is-editing) .projects-grid > .project-card {
        display: grid;
        grid-row: span 2;
        grid-template-rows: subgrid;
        row-gap: 0;
    }

    body:not(.is-editing) .projects-grid > .project-card > .project-image {
        grid-row: 1;
        align-self: end;
    }

    body:not(.is-editing) .projects-grid > .project-card > .project-meta {
        grid-row: 2;
        align-self: start;
    }

    /* Текстовая карточка без кадра: подпись с самого верха */
    body:not(.is-editing) .projects-grid > .card--plain {
        grid-row: span 1;
        grid-template-rows: auto;
    }

    body:not(.is-editing) .projects-grid > .card--plain > .project-meta {
        grid-row: 1;
    }
  }
}

/* ---------------------------- плитки брендов ------------------------------ */

/* Ширину ячейки считает сервер (--span): строка всегда заполнена целиком */
.brand-cell {
    grid-column: span var(--span, 3);
    min-width: 0;
}

.brand-cell .project-card {
    grid-column: auto;
}

/* Форма плитки бренда задаётся отдельно от ширины */
.brand-card.tile--portrait .project-image { aspect-ratio: 3/4; }
.brand-card.tile--square .project-image { aspect-ratio: 1/1; }
.brand-card.tile--wide .project-image { aspect-ratio: 16/9; }
.brand-card.tile--strip .project-image { aspect-ratio: 5/1; }

/* Плитки брендов в одном ряду — одной высоты: общую пропорцию ряда
   считает сервер (--row-ar, см. rowRatios в site.ts). Только на широком
   экране, где бренды стоят рядом; ниже каждая обложка в своей пропорции. */
@media (min-width: 1025px) {
    .projects-grid .brand-cell[style*="--row-ar"] .brand-card .project-image {
        aspect-ratio: var(--row-ar);
    }
}

.brand-card .project-image {
    /* Не выше экрана: портретная обложка во всю ширину иначе тянется на два экрана */
    max-height: 86svh;
}

/* Обложка бренда заполняет плитку целиком: поля тут были бы дырой в сетке */
.brand-card .project-image img,
.brand-card .project-image video {
    backface-visibility: hidden;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition:
        filter var(--dur-slow) var(--ease-out),
        transform var(--dur-slow) var(--ease-out);
}

/* «Сюда можно нажать»: при наведении обложка чуть темнеет, а поверх
   проявляется стеклянная плашка «Подробнее» — настоящее стекло: размытая
   и насыщенная подложка, световая кромка, блик и (в Chromium) преломление.

   Важно: прозрачность (opacity) анимируется у самой плашки, а не у слоя
   над ней. Слой с opacity < 1 становится для стекла «корнем подложки»,
   и размывать ему нечего — раньше из-за этого стекло на «Подробнее»
   не работало и выглядело плоской тёмной плашкой. */
.brand-card__cta {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: grid;
    place-items: center;
    background: rgb(12 12 12 / 0);
    transition: background-color var(--dur-base) var(--ease-out);
    pointer-events: none;
}

.brand-card__chip {
    display: inline-flex;
    align-items: center;
    min-height: 48px;
    padding: 0 var(--space-6);
    border-radius: var(--radius-pill);
    border: 1px solid rgb(255 255 255 / 0.5);
    background:
        linear-gradient(180deg, rgb(255 255 255 / 0.32) 0%, rgb(255 255 255 / 0.08) 55%, rgb(255 255 255 / 0.14) 100%),
        rgb(255 255 255 / 0.08);
    -webkit-backdrop-filter: blur(12px) saturate(185%) brightness(1.06);
    backdrop-filter: blur(12px) saturate(185%) brightness(1.06);
    box-shadow:
        inset 0 1px 0 rgb(255 255 255 / 0.7),
        inset 0 -1px 0 rgb(0 0 0 / 0.12),
        inset 0 10px 18px -12px rgb(255 255 255 / 0.6),
        0 12px 32px -12px rgb(0 0 0 / 0.5);
    color: #fff;
    text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);
    font-size: clamp(0.8rem, 1.2vw, 0.95rem);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
    opacity: 0;
    transform: translateY(8px) scale(0.96);
    transition:
        opacity var(--dur-base) var(--ease-out),
        transform var(--dur-base) var(--ease-emph);
}

/* Преломление по кромке — там, где браузер его умеет (см. glass.js) */
.glass-refract .brand-card__chip {
    -webkit-backdrop-filter: url(#glass-lens) blur(10px) saturate(185%) brightness(1.06);
    backdrop-filter: url(#glass-lens) blur(10px) saturate(185%) brightness(1.06);
}

a.brand-card:hover .brand-card__cta,
a.brand-card:focus-visible .brand-card__cta {
    background: rgb(12 12 12 / 0.16);
}

a.brand-card:hover .brand-card__chip,
a.brand-card:focus-visible .brand-card__chip {
    opacity: 1;
    transform: none;
}

/* Браузер без размытия: плашка плотнее, чтобы надпись читалась */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .brand-card__chip {
        background: rgb(20 20 20 / 0.72);
    }
}

@media (hover: hover) {
    /* Обложка слегка темнеет и приближается. Размытие убрано: вместе
       с подъёмом плитки и стеклянной плашкой оно перерисовывало слой
       на каждом кадре, и при наведении всё «дрожало». */
    a.brand-card:hover .project-image :is(img, video),
    a.brand-card:focus-visible .project-image :is(img, video) {
        filter: brightness(0.78);
        transform: scale(1.03);
    }

    /* Плитка бренда не подпрыгивает: реагирует только обложка */
    .brand-cell .project-card:hover {
        transform: none;
    }
}

/* Наведения нет — подсказка видна всегда, но плашкой в углу, а не во весь кадр */
@media (hover: none) {
    .brand-card__cta {
        background: transparent;
        place-items: end start;
        padding: clamp(0.6rem, 3vw, 1rem);
    }

    /* Плашка на обложке уже говорит «Подробнее» — второй такой же строке под текстом не место */
    .brand-card__more {
        display: none;
    }

    .brand-card__chip {
        min-height: 2.25rem;
        padding: 0 var(--space-4);
        font-size: var(--text-xs);
        letter-spacing: 0.08em;
        opacity: 1;
        transform: none;
    }
}

/* ================================ галерея ================================= */

.gallery {
    position: relative;
    isolation: isolate;
    /* Пока палец тянет кадр, галерея не должна прокручивать страницу вбок */
    touch-action: pan-y;
    cursor: zoom-in;
}

.gallery__slide {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    transition: opacity 0.7s var(--ease-in-out);
    pointer-events: none;
}

.gallery__slide.is-active {
    opacity: 1;
    pointer-events: auto;
}

/* Кадр показывается целиком, а не подрезается под коробку плитки.
   Фон плитки прозрачный — поля сливаются со страницей, ни голова модели,
   ни низ вещи не срезаются. */
.gallery__slide img,
.gallery__slide video {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Подпись кадра: название цвета у вещи, показанной в нескольких вариантах */
.gallery__cap {
    position: absolute;
    left: var(--space-3);
    bottom: var(--space-3);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    max-width: calc(100% - 1.5rem);
    min-height: 1.75rem;
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
    border: 1px solid var(--glass-dark-edge);
    background: var(--glass-dark-tint);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.18);
    color: #fafaf8;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Управление галереей: тёмное стекло поверх фото, одна форма для всех кнопок */
.gallery__arrow,
.gallery__zoom,
.gallery__add,
.gallery__drop {
    position: absolute;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border-radius: var(--radius-pill);
    border: 1px solid var(--glass-dark-edge);
    background:
        linear-gradient(180deg, rgb(255 255 255 / 0.14) 0%, rgb(255 255 255 / 0) 55%),
        var(--glass-dark-tint);
    box-shadow:
        inset 0 1px 0 rgb(255 255 255 / 0.22),
        inset 0 -1px 0 rgb(0 0 0 / 0.2),
        0 4px 16px -4px rgb(0 0 0 / 0.35);
    color: #fafaf8;
    font-family: var(--font-main);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    /* Проявляется при наведении на плитку; что кадров несколько, видно по точкам */
    opacity: 0;
    transition:
        opacity var(--dur-base) var(--ease-out),
        background-color var(--dur-base) var(--ease-out),
        border-color var(--dur-base) var(--ease-out),
        transform var(--dur-fast) var(--ease-out);
}

.gallery__arrow {
    top: 50%;
    margin-top: -20px;
}

.gallery__arrow--prev {
    left: var(--space-3);
}

.gallery__arrow--next {
    right: var(--space-3);
}

.gallery__zoom {
    top: var(--space-3);
    right: var(--space-3);
}

.gallery__add {
    bottom: var(--space-3);
    right: var(--space-3);
    font-size: 1.25rem;
}

.gallery__drop {
    bottom: var(--space-3);
    right: calc(var(--space-3) + 48px);
    font-size: 0.95rem;
}

.gallery:hover :is(.gallery__arrow, .gallery__zoom, .gallery__add, .gallery__drop),
.gallery:focus-within :is(.gallery__arrow, .gallery__zoom, .gallery__add, .gallery__drop) {
    opacity: 1;
}

:is(.gallery__arrow, .gallery__zoom, .gallery__add):hover {
    background:
        linear-gradient(180deg, rgb(255 255 255 / 0.18) 0%, rgb(255 255 255 / 0) 55%),
        rgb(10 10 10 / 0.7);
    border-color: rgb(255 255 255 / 0.45);
}

:is(.gallery__arrow, .gallery__zoom, .gallery__add, .gallery__drop):active {
    transform: scale(0.92);
}

.gallery__drop:hover {
    background: rgb(150 30 30 / 0.85);
    border-color: rgb(255 170 170 / 0.6);
}

/* Точки — индикатор кадра. Активная вытягивается в черту: видно и где ты, и сколько всего */
.gallery__dots {
    position: absolute;
    left: 50%;
    bottom: var(--space-3);
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 0 var(--space-1);
    border-radius: var(--radius-pill);
    border: 1px solid rgb(255 255 255 / 0.14);
    background: var(--glass-dark-tint);
    transform: translateX(-50%);
}

/* Сама точка маленькая, но область нажатия — 24 пикселя */
.gallery__dot {
    position: relative;
    width: 18px;
    height: 24px;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}

.gallery__dot::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 6px;
    height: 6px;
    margin: -3px 0 0 -3px;
    border-radius: var(--radius-pill);
    background: rgb(250 250 248 / 0.45);
    transition: width var(--dur-base) var(--ease-emph), margin var(--dur-base) var(--ease-emph), background-color var(--dur-base) var(--ease-out);
}

.gallery__dot.is-active::before {
    width: 14px;
    margin-left: -7px;
    background: #fafaf8;
}

.gallery__dot:focus-visible {
    outline-offset: -2px;
}

/* Подпись слева — точки уходят вправо, чтобы не наезжать на неё */
.gallery:has(.gallery__slide.is-active .gallery__cap) .gallery__dots {
    left: auto;
    right: var(--space-3);
    transform: none;
}

/* Наведения нет — кнопки видны всегда, но тише, чтобы не спорить с вещью */
@media (hover: none) {
    .gallery {
        cursor: default;
    }

    .gallery__arrow,
    .gallery__zoom,
    .gallery__add,
    .gallery__drop {
        opacity: 0.85;
    }

    .gallery__arrow {
        width: 44px;
        height: 44px;
        margin-top: -22px;
    }

    /* В две колонки (600–1024) плитка узкая — там листают пальцем, стрелки
       только закрывали бы вещь. На телефоне плитка во всю ширину: стрелки видны. */
    @media (min-width: 600px) {
        .card--small .gallery__arrow {
            display: none;
        }
    }
}

/* Картинки без фона (прозрачный PNG, WebP, GIF): вписываются целиком,
   сквозь плитку виден фон сайта, вырезанный предмет не обрезается */
.gallery__slide.is-cutout img,
.project-image.is-cutout img {
    object-fit: contain;
    padding: 2%;
}

/* Наведение не «наезжает» на прозрачную картинку */
.project-card:hover .gallery__slide.is-cutout img,
.project-card:hover .project-image.is-cutout img {
    transform: none;
}

/* Видео-обложка ведёт себя как картинка */
.project-image > video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ============================= просмотр фото ============================== */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(4rem, 8vh, 6rem) clamp(1rem, 6vw, 6rem);
    background: rgb(8 8 8 / 0.78);
    -webkit-backdrop-filter: blur(24px) saturate(130%);
    backdrop-filter: blur(24px) saturate(130%);
    opacity: 0;
    transition: opacity var(--dur-base) var(--ease-out);
    overscroll-behavior: contain;
}

.lightbox[hidden] {
    display: none;
}

.lightbox.is-open {
    opacity: 1;
}

.lightbox__figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
    max-width: min(100%, 1400px);
    max-height: 100%;
    margin: 0;
    transform: scale(0.97);
    transition: transform var(--dur-slow) var(--ease-emph);
}

.lightbox.is-open .lightbox__figure {
    transform: none;
}

.lightbox__stage {
    position: relative;
    display: grid;
    place-items: center;
    min-width: min(60vw, 480px);
    min-height: min(50vh, 360px);
}

/* Пока кадр грузится — пульсирующая подложка вместо пустоты */
.lightbox.is-loading .lightbox__stage::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--radius-sm);
    background: rgb(255 255 255 / 0.06);
    animation: pulse 1.4s var(--ease-in-out) infinite;
}

.lightbox__image {
    max-width: 100%;
    max-height: calc(100svh - 12rem);
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 2px;
    box-shadow: 0 30px 80px -30px rgb(0 0 0 / 0.8);
    transition: opacity var(--dur-base) var(--ease-out);
}

.lightbox.is-loading .lightbox__image {
    opacity: 0;
}

.lightbox__caption {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-2) var(--space-5);
    color: rgb(250 250 248 / 0.72);
    font-size: var(--text-sm);
    text-align: center;
}

.lightbox__label {
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-size: var(--text-xs);
}

.lightbox__label:empty {
    display: none;
}

.lightbox__original {
    color: rgb(250 250 248 / 0.72);
    text-underline-offset: 3px;
    transition: color var(--dur-fast) var(--ease-out);
}

.lightbox__original:hover {
    color: #fafaf8;
}

.lightbox__close,
.lightbox__arrow {
    position: absolute;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background-color var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.lightbox__close:hover,
.lightbox__arrow:hover {
    background:
        linear-gradient(180deg, rgb(255 255 255 / 0.2) 0%, rgb(255 255 255 / 0) 55%),
        rgb(255 255 255 / 0.12);
}

.lightbox__close:active,
.lightbox__arrow:active {
    transform: scale(0.94);
}

.lightbox__close {
    top: calc(var(--space-5) + env(safe-area-inset-top));
    right: calc(var(--space-5) + env(safe-area-inset-right));
    width: var(--control-h);
    height: var(--control-h);
}

.lightbox__arrow {
    top: 50%;
    width: 52px;
    height: 52px;
    margin-top: -26px;
}

.lightbox__arrow[hidden] {
    display: none;
}

.lightbox__arrow--prev {
    left: calc(var(--space-5) + env(safe-area-inset-left));
}

.lightbox__arrow--next {
    right: calc(var(--space-5) + env(safe-area-inset-right));
}

.lightbox__counter {
    position: absolute;
    bottom: calc(var(--space-5) + env(safe-area-inset-bottom));
    left: 50%;
    transform: translateX(-50%);
    color: rgb(250 250 248 / 0.6);
    font-size: var(--text-sm);
    letter-spacing: 0.08em;
    font-variant-numeric: tabular-nums;
}

body.lightbox-open {
    overflow: hidden;
}
