/* ============================================================================
   test-projects.css — «Проекты» (lp /projects → будущий боевой /portfolio) и
   страницы объектов (/projects/<slug>). Стили боевого сайта: палитра slate +
   синий акцент, Inter, радиусы 0.75 / 1.2 / 1.5rem, тени и easing из output.css
   (токены @theme: --shadow-panel-light, --ease-out-expo, --color-surface-base).
   Шапка, футер, форма заявки и FAQ — боевые партиалы, здесь их стилей нет.
   Скоуп: .pj-page и .pj-dialog. Боевые файлы не задеты.

   Кладка «Все фото» — нативный CSS без JS: grid + единицы контейнера (cqi) +
   round(). Контейнер объявлен на ОБЁРТКЕ .pj-cq (cqi в свойствах самого
   контейнера считались бы от предка). Высота плитки = ширина колонки ÷ пропорция
   кадра (--ar из данных), поэтому раскладка известна до загрузки картинок.
   Браузеры без round() получают многоколоночный fallback (@supports not).
   ============================================================================ */

.pj-body {
  --pj-bg: #f8fafc;        /* surface-base боевого */
  --pj-card: #ffffff;
  --pj-muted: #eef2f7;     /* surface-muted */
  --pj-dark: #020617;      /* slate-950, тёмные секции и hero */
  --pj-dark-2: #0f172a;    /* slate-900 */
  --pj-ink: #0f172a;       /* заголовки на светлом */
  --pj-ink-2: #475569;     /* текст, slate-600 */
  --pj-ink-3: #64748b;     /* мета, slate-500 */
  --pj-on-dark: #ffffff;
  --pj-on-dark-2: #94a3b8; /* slate-400 */
  --pj-on-dark-3: #cbd5e1; /* slate-300, лид на тёмном */
  --pj-line: #e2e8f0;      /* slate-200 */
  --pj-line-2: #cbd5e1;    /* slate-300 */
  --pj-line-dark: rgba(255, 255, 255, .10);
  --pj-blue: #2563eb;      /* blue-600, кнопки и активные чипы */
  --pj-blue-2: #1d4ed8;    /* blue-700, hover */
  --pj-blue-text: #3b82f6; /* blue-500, акцент в заголовке */
  --pj-blue-soft: #eff6ff; /* blue-50 */
  --pj-r-s: .75rem;        /* rounded-xl: кнопки, плитки */
  --pj-r-m: 1.2rem;        /* карточки боевого */
  --pj-r-l: 1.5rem;        /* панели */
  --pj-ease: var(--ease-out-expo, cubic-bezier(.16, 1, .3, 1));
  --pj-shadow: var(--shadow-panel-light, 0 26px 50px -34px rgba(15, 23, 42, .26));
  --pj-shadow-hover: 0 26px 46px -24px rgba(15, 23, 42, .34), var(--shadow-panel-light, 0 26px 50px -34px rgba(15, 23, 42, .26)); /* панельная тень плюс плотный слой — состояние наведения */
  --pj-glow: 0 18px 45px -18px rgba(59, 130, 246, .55);
  --pj-gutter: 1rem;                                          /* боковое поле .pj-wrap */
  --pj-sec: 4rem;                                             /* ритм секций боевого: py-16 → py-24 с 768px */
  --pj-col: calc(640px + 380px + clamp(3rem, 6vw, 6rem));     /* колонка чтения: проза + колонка расчёта + зазор; по ней выровнена вся страница объекта */
  font-family: 'Inter', system-ui, sans-serif;
  background: var(--pj-bg);
  color: var(--pj-ink-2);
  -webkit-font-smoothing: antialiased;
}
.pj-page [hidden], .pj-dialog [hidden] { display: none !important; }
/* Сброс кнопок через :where() — нулевой вес селектора. С весом (0,2,1) он перебивал сами кнопки:
   у «Показать всё» текст становился серым на синем (контраст 1.5:1), у остальных слетал жирный. */
:where(.pj-page, .pj-dialog) button { font: inherit; color: inherit; cursor: pointer; }
/* кольцо фокуса — боевое (input.css: blue-400, отступ 2px, радиус 4px) */
.pj-page :is(button, a, summary):focus-visible, .pj-dialog :is(button, a):focus-visible { outline: 2px solid #60a5fa; outline-offset: 2px; border-radius: 4px; }
.pj-page img { display: block; max-width: 100%; }

/* ---------- Общие примитивы боевого ---------- */
.pj-wrap { max-width: 1600px; margin-inline: auto; padding-inline: var(--pj-gutter); }
@media (min-width: 640px) { .pj-body { --pj-gutter: 1.5rem; } }
@media (min-width: 1024px) { .pj-body { --pj-gutter: 2rem; } }
@media (min-width: 768px) { .pj-body { --pj-sec: 6rem; } }
.pj-section { padding-block: var(--pj-sec); }
.pj-section--light { background: var(--pj-bg); }
.pj-section--white { background: var(--pj-card); }
.pj-h1 { font-size: clamp(2.25rem, 1.2rem + 3.4vw, 3.75rem); font-weight: 700; line-height: 1.08; letter-spacing: -.02em; color: var(--pj-on-dark); margin: 0; text-wrap: balance; }
/* акцент в заголовке — боевой градиент H1 (blue-400 → cyan-400 → blue-500); тень снимаем, иначе она проступает сквозь прозрачные буквы */
.pj-h1 .pj-accent { background: linear-gradient(90deg, #60a5fa 0%, #22d3ee 55%, #3b82f6 100%); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: none; }
.pj-h2 { font-size: clamp(1.875rem, 1rem + 2.4vw, 3rem); font-weight: 700; line-height: 1; letter-spacing: -.025em; color: var(--pj-ink); margin: 0; text-wrap: balance; }
.pj-h3 { font-size: clamp(1.25rem, 1rem + .8vw, 1.5rem); font-weight: 700; line-height: 1.25; letter-spacing: -.01em; color: var(--pj-ink); margin: 0; }
.pj-lead { font-size: clamp(1.0625rem, .95rem + .5vw, 1.25rem); line-height: 1.6; color: var(--pj-ink-2); margin: 0; text-wrap: pretty; }
.pj-kicker { display: inline-flex; align-items: center; gap: .6rem; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .2em; color: var(--pj-ink-3); }
.pj-kicker::before { content: ""; width: 8px; height: 8px; border-radius: 999px; background: var(--pj-blue); }
.pj-kicker--pill { padding: .35rem .85rem; border-radius: 999px; border: 1px solid #3b82f6; background: rgba(37, 99, 235, .9); color: #fff; letter-spacing: .1em; backdrop-filter: blur(4px); box-shadow: 0 0 20px rgba(37, 99, 235, .35); } /* как пилюля в hero боевой главной: bg-blue-600/90 + border-blue-500 + shadow-glow */
.pj-kicker--pill::before { display: none; }
/* кнопки: первичная = hero боевого (синий градиент), вторичная на тёмном = стекло, на светлом = контур */
.pj-btn { display: inline-flex; align-items: center; justify-content: center; gap: .75rem; min-height: 52px; padding: .9rem 2rem; border-radius: .5rem; font-weight: 700; font-size: 1rem; line-height: 1.2; border: 2px solid transparent; transition: transform .3s var(--pj-ease), box-shadow .3s var(--pj-ease), background-color .3s ease, color .3s ease, border-color .3s ease; }
.pj-btn i { font-size: .9em; }
.pj-btn--primary { background: linear-gradient(90deg, #2563eb, #1d4ed8); color: #fff; box-shadow: 0 10px 15px -3px rgba(30, 58, 138, .3), 0 4px 6px -4px rgba(30, 58, 138, .3); }
.pj-btn--primary:hover { transform: scale(1.02); box-shadow: 0 20px 25px -5px rgba(30, 58, 138, .4), 0 8px 10px -6px rgba(30, 58, 138, .4); }
.pj-btn--ghost { background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .30); color: #fff; backdrop-filter: blur(8px); }
.pj-btn--ghost:hover { background: #fff; color: var(--pj-ink); }
.pj-btn:active { transform: scale(.97); } /* ниже правил :hover — при равном весе побеждает последнее, иначе нажатие не отзывается */
.pj-btn--sm { min-height: 44px; padding: .65rem 1.25rem; font-size: .9375rem; }
.pj-link { display: inline-flex; align-items: center; gap: .5rem; min-height: 44px; border: 0; background: none; padding: 0; color: var(--pj-blue); font-size: .9375rem; font-weight: 700; }
.pj-link i { font-size: .85em; transition: transform .3s var(--pj-ease); }
.pj-link:hover { color: var(--pj-blue-2); text-decoration: underline; text-underline-offset: 5px; }
.pj-link:hover i { transform: translateX(4px); }

/* ---------- HERO галереи: мозаика лучших кадров на светлом фоне, текст сбоку ----------
   Владелец 28.09.2026: первый экран — «лицо компании», эффект на фото. Кадры яркие, без тёмной вуали;
   шапка сайта белым текстом, поэтому на этой странице она сразу на тёмной подложке (как после прокрутки). */
.pj-body:has(.pj-hero) #navbar { background: var(--pj-dark-2); }
.pj-hero { background: var(--pj-card); padding-top: 104px; }
.pj-hero__grid { display: grid; gap: 1.5rem; padding-block: 1.5rem; }
.pj-hero__text { display: flex; flex-direction: column; align-items: flex-start; }
.pj-hero .pj-crumbs { border-color: var(--pj-line); background: var(--pj-bg); backdrop-filter: none; color: var(--pj-ink-3); }
.pj-hero .pj-crumbs li + li::before { color: var(--pj-line-2); }
.pj-hero .pj-crumbs a:hover { color: var(--pj-ink); }
.pj-hero .pj-crumbs [aria-current] { color: var(--pj-blue); }
.pj-hero .pj-h1 { color: var(--pj-ink); max-width: 14ch; margin-bottom: 1.25rem; }
.pj-hero .pj-accent { color: var(--pj-blue); }
.pj-hero .pj-lead { max-width: 46ch; margin-bottom: 1.75rem; }
.pj-hero__cta { display: flex; flex-wrap: wrap; gap: .75rem 1rem; margin-bottom: 1.75rem; }
/* цифры — строкой с разделителями: три крупных числа читаются быстрее пилюль */
.pj-hero-meta { display: flex; flex-wrap: wrap; gap: .5rem 1.75rem; margin: 0; font-size: .9375rem; color: var(--pj-ink-3); }
.pj-hero-meta b { display: block; font-size: 1.75rem; line-height: 1.1; font-weight: 700; letter-spacing: -.02em; color: var(--pj-ink); font-variant-numeric: tabular-nums; }
.pj-hero__clients { margin-top: 1.25rem; display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem .75rem; }
.pj-hero__clients p { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--pj-ink-3); }
.pj-hero__clients ul { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: .25rem .5rem; font-size: .9375rem; color: var(--pj-ink-2); }
.pj-hero__clients li:not(:last-child)::after { content: " ·"; color: var(--pj-ink-3); } /* разделитель у предыдущего имени, иначе при переносе вторая строка начиналась с точки */
/* мозаика: большой кадр и пять поменьше (компьютер), большой и два под ним (телефон); мозаика на телефоне
   идёт первой. Все ячейки горизонтальные, как сами кадры банка: вертикальная ячейка резала снимок в полосу */
.pj-mosaic { order: -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
.pj-mosaic__cell { position: relative; display: block; min-width: 0; overflow: hidden; border-radius: var(--pj-r-s); background: var(--pj-muted); aspect-ratio: 4 / 3; }
.pj-mosaic__cell:first-child { grid-column: 1 / -1; aspect-ratio: 16 / 10; }
.pj-mosaic__cell:nth-child(n + 4) { display: none; }
.pj-mosaic__cell img { width: 100%; height: 100%; display: block; object-fit: cover; transition: transform .6s var(--pj-ease); }
.pj-mosaic__cell:hover img, .pj-mosaic__cell:focus-visible img { transform: scale(1.04); }
/* название объекта — только при наведении: кадр остаётся чистым, но видно, куда ведёт ссылка */
.pj-mosaic__cap { position: absolute; inset: auto 0 0 0; padding: 2rem .875rem .75rem; background: linear-gradient(0deg, rgba(15, 23, 42, .75), rgba(15, 23, 42, 0)); color: var(--pj-on-dark); font-size: .875rem; font-weight: 700; opacity: 0; transition: opacity .3s ease; }
.pj-mosaic__cell:hover .pj-mosaic__cap, .pj-mosaic__cell:focus-visible .pj-mosaic__cap { opacity: 1; }
@media (hover: none) { .pj-mosaic__cap { display: none; } }
@media (min-width: 1024px) {
  .pj-hero__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: center; gap: clamp(2rem, 4vw, 4rem); padding-block: 2rem; }
  /* большой кадр — две колонки на две строки, справа два, снизу три; высоту строк задают малые ячейки 16:10 */
  .pj-mosaic { order: 0; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; }
  .pj-mosaic__cell { aspect-ratio: 16 / 10; }
  .pj-mosaic__cell:first-child { grid-column: 1 / 3; grid-row: 1 / 3; aspect-ratio: auto; }
  .pj-mosaic__cell:nth-child(n + 4) { display: block; }
}
.pj-btn--line { background: var(--pj-card); border-color: var(--pj-line-2); color: var(--pj-ink); }
.pj-btn--line:hover { border-color: var(--pj-blue); color: var(--pj-blue); }
.pj-aud { display: flex; flex-wrap: wrap; gap: .75rem; padding-block: 1.25rem 2rem; border-top: 1px solid var(--pj-line); }
.pj-aud a { display: inline-flex; align-items: center; gap: .75rem; min-height: 44px; padding: .6rem 1.1rem; border-radius: 999px; border: 1px solid var(--pj-line); background: var(--pj-bg); color: var(--pj-ink); font-size: .875rem; font-weight: 600; transition: border-color .3s ease, color .3s ease, transform .3s var(--pj-ease); }
.pj-aud a:hover { border-color: var(--pj-blue); color: var(--pj-blue); }
.pj-aud a:active { transform: translateY(1px); }
.pj-aud i { font-size: 12px; color: var(--pj-ink-3); transition: transform .35s var(--pj-ease), color .3s ease; }
.pj-aud a:hover i { transform: translateX(3px); color: var(--pj-blue); }

/* ---------- КАТАЛОГ: шапка секции, режимы, фильтры ---------- */
.pj-catalog { scroll-margin-top: 96px; }
.pj-bar { display: flex; align-items: end; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.pj-bar__title .pj-kicker { margin-bottom: 1rem; }
.pj-bar__right { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.pj-count { margin: 0; font-size: .9375rem; color: var(--pj-ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* переключатель режимов: пилюля, активный сегмент синий (как pf-filter-active боевого) */
.pj-seg { display: inline-flex; gap: 4px; padding: 4px; border-radius: 999px; background: var(--pj-card); border: 1px solid var(--pj-line); box-shadow: 0 1px 2px rgba(15, 23, 42, .04); }
.pj-seg button { display: inline-flex; align-items: center; gap: .5rem; min-height: 40px; padding: 0 1.1rem; border: 0; border-radius: 999px; background: transparent; color: var(--pj-ink-2); font-size: .875rem; font-weight: 700; white-space: nowrap; transition: background-color .25s ease, color .25s ease, box-shadow .25s ease, transform .25s var(--pj-ease); }
.pj-seg button span { font-size: 12px; font-weight: 600; color: var(--pj-ink-3); font-variant-numeric: tabular-nums; } /* без opacity: полупрозрачный счётчик на синем не проходил 4.5:1 */
.pj-seg button:hover { color: var(--pj-blue); }
.pj-seg button[aria-pressed="true"] { background: var(--pj-blue); color: #fff; box-shadow: 0 4px 14px -4px rgba(37, 99, 235, .45); }
.pj-seg button[aria-pressed="true"] span { color: #fff; }
/* активный сегмент тоже отзывается: без этих строк наведение и нажатие на нём были неотличимы от покоя */
.pj-seg button[aria-pressed="true"]:hover { background: var(--pj-blue-2); }
.pj-seg button:active { transform: scale(.97); }
/* фильтр по продукции: чипы боевого .pf-filter-btn / .pf-filter-active (класс переключает скрипт), второй ряд — типы */
.pj-filter { border-top: 1px solid var(--pj-line); border-bottom: 1px solid var(--pj-line); padding: 1rem 0; margin-bottom: clamp(1.5rem, 3vw, 2rem); }
.pj-filter summary { display: none; }
.pj-filter summary::-webkit-details-marker { display: none; }
.pj-filter-body { display: grid; gap: .75rem; }
.pj-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; }
/* У боевого чипа `.pf-filter-btn:hover` (вес 0,2,0) перебивает `.pf-filter-active` (0,1,0), и активный
   чип под курсором остаётся синим текстом на синей заливке — подпись исчезает. То же и на боевом
   /portfolio; там лечится в input.css, здесь — локальным модификатором, чтобы не трогать общий компонент. */
.pj-chips .pf-filter-active:hover, .pj-chips .pf-filter-active:focus-visible { color: #fff; border-color: var(--pj-blue); }
.pj-chips .pf-filter-btn { min-height: 40px; } /* боевой чип как есть (11px uppercase, синяя заливка активного); локально только высота под палец ≥40px */
.pj-chips--types { padding-left: 1rem; border-left: 2px solid var(--pj-line-2); }
.pj-selection { display: flex; align-items: center; gap: 1rem; margin: -.75rem 0 1.5rem; font-size: .9375rem; color: var(--pj-ink-3); }
.pj-selection button { border: 0; background: none; padding: 0; min-height: 44px; color: var(--pj-blue); font-weight: 600; text-decoration: underline; text-underline-offset: 4px; }
.pj-selection button:hover { color: var(--pj-blue-2); } /* как у .pj-link: наведение темнит синий */
.pj-note { font-size: .9375rem; color: var(--pj-ink-3); margin: 0 0 1.5rem; }

/* ---------- КЛАДКА ---------- */
.pj-cq { container-type: inline-size; }
.pj-masonry {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 1.5cqi; row-gap: 0;
  grid-auto-rows: 0.25cqi;
  grid-auto-flow: row dense;
  align-items: start;
  margin: 0 0 -1.5cqi; padding: 0; list-style: none;
}
.pj-masonry > * { --ar: 1; min-width: 0; margin-bottom: 1.5cqi; grid-row-end: span round(nearest, calc((32.3333 / var(--ar) + 1.5) / 0.25)); }
/* кадр банка: широкий на компьютере, вертикальный 4:5 на телефоне — пропорция плитки меняется вместе
   с картинкой из <picture>, граница та же 767px, что у <source> */
.pj-masonry > .pj-tile--m { --ar: var(--ar-w); }
@media (max-width: 767px) { .pj-masonry > .pj-tile--m { --ar: var(--ar-m); } }
@media (max-width: 1000px) {
  .pj-masonry { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 2cqi; margin-bottom: -2cqi; }
  .pj-masonry > * { margin-bottom: 2cqi; grid-row-end: span round(nearest, calc((49 / var(--ar) + 2) / 0.25)); }
}
/* браузеры без round() в span: лента многоколоночным потоком, пропорции те же, порядок по колонкам */
@supports not (grid-row-end: span round(nearest, calc(3.4))) {
  .pj-masonry { display: block; columns: 3; column-gap: 24px; margin-bottom: 0; }
  .pj-masonry > * { break-inside: avoid; margin-bottom: 24px; }
  @media (max-width: 1000px) { .pj-masonry { columns: 2; column-gap: 16px; } .pj-masonry > * { margin-bottom: 16px; } }
}
/* Точные ряды там, где браузер умеет делить длину на длину. Дробный ряд (0.25cqi) браузер округляет
   до 1/64px, ошибка копится на сотнях рядов и вертикальный зазор уплывал: 4.9px вместо 7.2px
   на 393px и разброс 2.2–4.9px между плитками. Ряд ровно 1px — накопления нет, остаётся ±0.5px. */
@supports (grid-row-end: span round(nearest, calc(10cqi / 1px))) {
  .pj-masonry { grid-auto-rows: 1px; }
  .pj-masonry > * { grid-row-end: span round(nearest, calc((32.3333cqi / var(--ar) + 1.5cqi) / 1px)); }
  @media (max-width: 1000px) {
    .pj-masonry > * { grid-row-end: span round(nearest, calc((49cqi / var(--ar) + 2cqi) / 1px)); }
  }
}

/* плитка фото: естественная пропорция, подпись всегда видна на градиенте боевого (from-slate-900/80) */
.pj-tile { position: relative; display: block; border-radius: var(--pj-r-s); overflow: hidden; background: var(--pj-muted); isolation: isolate; cursor: zoom-in; color: var(--pj-on-dark); box-shadow: 0 1px 2px rgba(15, 23, 42, .06); transition: transform .35s var(--pj-ease), box-shadow .35s var(--pj-ease); }
.pj-tile img { width: 100%; height: auto; display: block; transition: transform .5s var(--pj-ease); user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; } /* длинный тап на iOS иначе открывает системное «сохранить изображение» */
/* наведение одной грамматики с карточкой объекта: подъём на 3px и тень; иначе режимы ленты ведут себя по-разному */
.pj-tile:hover, .pj-tile:focus-visible { transform: translateY(-3px); box-shadow: var(--pj-shadow-hover); }
.pj-tile:hover img, .pj-tile:focus-visible img { transform: scale(1.03); }
.pj-tile__cap {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  padding: clamp(2rem, 14%, 4.5rem) 1rem 1rem;
  background: linear-gradient(0deg, rgba(15, 23, 42, .82) 0%, rgba(15, 23, 42, .45) 50%, rgba(15, 23, 42, 0) 100%);
  display: grid; gap: 2px; font-size: .875rem; line-height: 1.35;
  transition: padding .45s var(--pj-ease);
}
.pj-tile__cap b { font-weight: 700; }
.pj-tile__cap span { font-size: 12px; color: var(--pj-on-dark-3); }
.pj-tile:focus-visible { outline-offset: 2px; }

/* Сетка галереи: все плитки одного размера, кадр на всю плитку, подпись поверх (владелец 28.09.2026:
   «плитки одинаковые, меньше пустого места, эффект на фото»). Компьютер 4:3 по широкому кадру,
   телефон 4:5 по вертикальному кадру банка из <picture> (та же граница 767px). */
.pj-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(.75rem, 1.2vw, 1.25rem); margin: 0; padding: 0; }
.pj-grid > .pj-tile { aspect-ratio: 4 / 3; }
.pj-grid > .pj-tile picture, .pj-grid > .pj-tile img { width: 100%; height: 100%; display: block; object-fit: cover; }
.pj-tile--obj { cursor: pointer; }
.pj-grid .pj-tile__cap { padding: 3rem 1.125rem 1rem; gap: 4px; }
.pj-grid .pj-tile__cap b { font-size: 1.0625rem; line-height: 1.3; }
.pj-grid .pj-tile__cap span { font-size: 13px; }
@media (max-width: 1000px) { .pj-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) { .pj-grid > .pj-tile { aspect-ratio: 4 / 5; } }
/* телефон: объекты в одну колонку крупно, лента фото — в две */
@media (max-width: 560px) {
  .pj-projects { grid-template-columns: 1fr; }
  .pj-projects .pj-tile__cap { padding: 3rem 1rem 1rem; font-size: .9375rem; }
  .pj-projects .pj-tile__cap b { white-space: normal; }
  .pj-projects .pj-tile__cap span { display: block; }
  .pj-photos .pj-tile__cap { padding: 1.75rem .625rem .625rem; }
  .pj-photos .pj-tile__cap b { font-size: 13px; }
  .pj-photos .pj-tile__cap span:not(.sr-only) { display: none; }
}

.pj-empty { text-align: center; padding: clamp(3rem, 8vw, 6rem) 1.25rem; border: 1px dashed var(--pj-line-2); border-radius: var(--pj-r-m); background: var(--pj-card); }
.pj-empty h3 { margin: 0 0 .75rem; }
.pj-empty p { max-width: 50ch; margin: 0 auto; color: var(--pj-ink-2); }
.pj-empty div { display: flex; justify-content: center; align-items: center; gap: 1.25rem; flex-wrap: wrap; margin-top: 1.5rem; }
.pj-catalog-end { display: flex; justify-content: space-between; align-items: center; gap: 1.5rem; flex-wrap: wrap; margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1.5rem; border-top: 1px solid var(--pj-line); font-size: .9375rem; color: var(--pj-ink-3); }

/* ---------- Контекст объекта над формой: правила в photo-lightbox.css ---------- */

/* ---------- ЛАЙТБОКС: правила вынесены в photo-lightbox.css — он общий с блоком «Лучшее» на страницах изделий ---------- */
/* защита от «сохранить как»: контекстное меню и перетаскивание гасятся скриптом, тут — только курсор/выделение */
/* защита кадра — одним правилом на весь раздел, иначе каждый новый компонент выходит без неё */
.pj-page img, .pj-dialog img { -webkit-user-drag: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }

/* ---------- СТРАНИЦА ОБЪЕКТА ---------- */
/* тёмная шапка как у боевых страниц: под прозрачной фиксированной навигацией всегда графит */
/* Шапка объекта, обложка и тело живут в одной колонке чтения (та же формула, что у .pj-obj-body),
   иначе левый край страницы шагал 32 → 167 → 32. Полноширинные остаются только галереи кадров. */
.pj-obj-col { max-width: var(--pj-col); margin-inline: auto; }
.pj-obj-head { position: relative; isolation: isolate; background: var(--pj-dark); color: var(--pj-on-dark); padding-top: clamp(130px, 16vh, 180px); padding-bottom: clamp(2.5rem, 5vw, 4rem); overflow: hidden; }
/* Подложка шапки — обложка объекта приглушённой, как фото под hero боевого /portfolio (opacity-30):
   без неё правая половина экрана стояла пустым градиентом. Сверху — скрим слева направо под текст. */
.pj-obj-head__bg { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; opacity: .3; pointer-events: none; }
.pj-obj-head::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(90deg, rgba(2, 6, 23, .94) 0%, rgba(2, 6, 23, .7) 50%, rgba(2, 6, 23, .3) 100%), radial-gradient(60% 80% at 85% 20%, rgba(37, 99, 235, .22), transparent 60%); } /* только slate + blue: бирюзовый оставлен боевым партиалам */
.pj-obj-head .pj-kicker--pill { margin-bottom: 1.25rem; }
/* крошки — боевая пилюля из hero /portfolio: 11px, заглавные, разрядка .2em, текущий пункт синий */
.pj-crumbs { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .75rem; max-width: 100%; margin: 0 0 1.5rem; padding: .5rem 1rem; list-style: none; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .1); background: rgba(2, 6, 23, .45); backdrop-filter: blur(12px); font-size: 11px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: #94a3b8; }
.pj-crumbs li + li::before { content: "/"; margin-right: .75rem; color: #475569; }
.pj-crumbs a { transition: color .3s ease; }
.pj-crumbs a:hover { color: #fff; }
.pj-crumbs [aria-current] { color: #60a5fa; }
/* на телефоне пилюля не переносится: иначе вторая строка начиналась со слэша.
   Длинное имя объекта подрезаем многоточием — путь всё равно читается. */
@media (max-width: 560px) {
  .pj-crumbs { flex-wrap: nowrap; max-width: 100%; }
  .pj-crumbs li { white-space: nowrap; }
  .pj-crumbs li:last-child { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
}
.pj-obj-head .pj-h1 { max-width: 24ch; margin: 0 0 1rem; } /* H1 объекта длинный (изделие + помещение + заказчик, до 65 знаков): 2–3 строки на десктопе, как H1 боевых внутренних страниц */
.pj-obj-head .pj-lead { max-width: 60ch; color: var(--pj-on-dark-3); }
.pj-obj-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; margin: 1.5rem 0 0; padding: 0; list-style: none; font-size: .9375rem; color: var(--pj-on-dark-2); }
.pj-obj-meta li { display: inline-flex; align-items: center; gap: .5rem; }
.pj-obj-meta i { font-size: .85em; color: #60a5fa; }
.pj-obj-tags { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0 0; padding: 0; list-style: none; }
.pj-obj-tags a { display: inline-flex; align-items: center; gap: .5rem; min-height: 40px; font-size: 13px; font-weight: 600; color: #fff; border: 1px solid var(--pj-line-dark); background: rgba(255, 255, 255, .05); border-radius: 999px; padding: 6px 14px; transition: border-color .25s ease, background-color .25s ease; }
.pj-obj-tags a:hover { border-color: rgba(96, 165, 250, .6); background: rgba(59, 130, 246, .12); }
.pj-obj-tags i { font-size: 11px; color: #93c5fd; }
/* обложка: без обрезки, ограничение по высоте, кадр по центру на светлом; подпись по ширине кадра */
/* Обложка живёт в той же колонке, что текст и колонка расчёта (та же формула ширины, что у .pj-obj-body),
   и прижата к её левому краю. Раньше кадр центрировался по своей натуральной ширине, и левый край страницы
   шагал 226 → 167 → 32: текст торчал за края обложки на 59px с каждой стороны.
   Отступ сверху вместе с отступом шапки даёт 96px на десктопе и 64px на телефоне. */
.pj-obj-cover { margin-inline: auto; max-width: var(--pj-col); padding-top: clamp(1.5rem, 2.5vw, 2rem); display: grid; justify-items: start; }
.pj-obj-cover a { display: block; cursor: zoom-in; }
.pj-obj-cover img { display: block; width: auto; max-width: 100%; height: auto; max-height: min(82vh, 900px); margin: 0; border-radius: var(--pj-r-m); background: var(--pj-muted); box-shadow: var(--pj-shadow); }
.pj-obj-cover figcaption { margin-top: .75rem; font-size: 13px; line-height: 1.5; color: var(--pj-ink-3); }
.pj-obj-cover .pj-credit::before { content: " · "; } /* источник фото в той же строке, а не отдельной служебной строкой */
.pj-obj-cover .pj-credit { white-space: nowrap; }
/* Кадры банка сразу под обложкой: по два в ряд в колонке обложки, нечётный последний — во всю ширину.
   Все кадры банка одной пропорции, поэтому ровная сетка без обрезки. Подписей на кадрах нет — имя объекта в шапке. */
.pj-obj-shots { max-width: var(--pj-col); margin: clamp(1.5rem, 2.5vw, 2rem) auto 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(.75rem, 1.5vw, 1.25rem); }
.pj-obj-shots > a:last-child:nth-child(odd) { grid-column: 1 / -1; }
.pj-obj-shots a { display: block; cursor: zoom-in; border-radius: var(--pj-r-m); overflow: hidden; background: var(--pj-muted); box-shadow: var(--pj-shadow); }
.pj-obj-shots img { display: block; width: 100%; height: auto; }
/* Без текста объекта колонка расчёта становится полосой на всю колонку: слева призыв, справа кнопка и телефон */
.pj-obj-body.pj-obj-body--solo { grid-template-columns: minmax(0, var(--pj-col)); }
.pj-obj-body--solo .pj-aside { position: static; display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 320px); grid-template-areas: "k btn" "h btn" "l phone" "n n"; column-gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.pj-obj-body--solo .pj-aside > .pj-kicker { grid-area: k; }
.pj-obj-body--solo .pj-aside > h2 { grid-area: h; }
.pj-obj-body--solo .pj-aside > .pj-aside__lead { grid-area: l; margin-bottom: 0; }
.pj-obj-body--solo .pj-aside > .pj-btn { grid-area: btn; align-self: end; }
.pj-obj-body--solo .pj-aside > .pj-aside__phone { grid-area: phone; justify-self: center; margin-top: 0; }
.pj-obj-body--solo .pj-aside > .pj-aside__note { grid-area: n; margin-top: 1.25rem; }
/* текст объекта + липкая колонка */
.pj-obj-body { display: grid; grid-template-columns: minmax(0, 640px) minmax(280px, 380px); justify-content: center; column-gap: clamp(3rem, 6vw, 6rem); row-gap: 2rem; align-items: start; } /* текст и колонка расчёта собраны к центру, без пустоты в 360px между ними */
.pj-obj-text { max-width: 640px; }
.pj-obj-text h2 { font-size: clamp(1.375rem, 1.1rem + .9vw, 1.75rem); font-weight: 700; letter-spacing: -.01em; color: var(--pj-ink); margin: 0 0 .75rem; }
.pj-obj-text h2 + p { margin: 0; color: var(--pj-ink-2); font-size: 1.0625rem; line-height: 1.7; }
.pj-obj-text section + section { margin-top: clamp(2rem, 4vw, 3rem); padding-top: clamp(1.5rem, 3vw, 2rem); border-top: 1px solid var(--pj-line); }
/* Статья: тематический разбор на тёмной секции, формула — стеклянная панель */
.pj-article { background: var(--pj-dark); }
.pj-article__wrap { max-width: 920px; }
.pj-article .pj-kicker { color: var(--pj-blue-text); }
.pj-article .pj-h2 { color: var(--pj-on-dark); }
.pj-article__lead { margin: clamp(1.5rem, 3vw, 2.25rem) 0 0; font-size: clamp(1.125rem, 1rem + .4vw, 1.3rem); line-height: 1.7; color: var(--pj-on-dark-3); text-wrap: pretty; }
.pj-article__body { margin-top: clamp(1.5rem, 3vw, 2rem); }
.pj-article__body > * { margin: 0; }
.pj-article__body > * + * { margin-top: 1.5rem; }
.pj-article__h3 { font-size: clamp(1.1875rem, 1.05rem + .45vw, 1.375rem); font-weight: 700; line-height: 1.3; letter-spacing: -.01em; color: var(--pj-on-dark); text-wrap: balance; }
.pj-article__body > .pj-article__h3 { margin-top: clamp(2rem, 4vw, 2.5rem); }
.pj-article__body > .pj-article__h3 + .pj-article__text { margin-top: .625rem; }
.pj-article__text {font-size: 1.0625rem; line-height: 1.8; color: var(--pj-on-dark-2); text-wrap: pretty; }
.pj-article__formula { padding: clamp(1.5rem, 3vw, 2rem); border: 1px solid rgba(59, 130, 246, .35); border-radius: var(--pj-r-l); background: linear-gradient(135deg, rgba(37, 99, 235, .16), rgba(34, 211, 238, .07)); color: #fff; font-weight: 600; font-size: clamp(1.125rem, 1rem + .5vw, 1.375rem); line-height: 1.4; box-shadow: var(--pj-glow); }
.pj-article__outro { font-size: 1rem; line-height: 1.7; color: var(--pj-on-dark-3); text-wrap: pretty; }
.pj-specs { margin: 1.5rem 0 0; font-size: .9375rem; display: grid; }
.pj-specs > div { display: grid; grid-template-columns: minmax(120px, .8fr) 2fr; gap: 1.25rem; padding: 10px 0; border-bottom: 1px solid var(--pj-line); }
.pj-specs dt { color: var(--pj-ink-3); }
.pj-specs dd { margin: 0; color: var(--pj-ink); font-weight: 500; }
.pj-aside { position: sticky; top: 112px; background: var(--pj-card); border: 1px solid var(--pj-line); border-radius: var(--pj-r-l); padding: clamp(1.5rem, 2.4vw, 2rem); box-shadow: var(--pj-shadow); }
.pj-aside .pj-kicker { margin-bottom: .875rem; }
.pj-aside h2 { font-size: 1.375rem; font-weight: 700; margin: 0 0 .75rem; letter-spacing: -.01em; color: var(--pj-ink); }
/* абзацам колонки — свой класс, а не «.pj-aside p»: селектор по тегу перебивал кикер и оговорку, и те лечились !important */
.pj-aside__lead { margin: 0 0 1.5rem; font-size: .9375rem; color: var(--pj-ink-2); line-height: 1.55; }
.pj-aside .pj-btn { width: 100%; }
.pj-aside__phone { display: inline-flex; align-items: center; gap: .75rem; margin-top: 1.25rem; font-weight: 700; font-size: 1.125rem; color: var(--pj-ink); }
.pj-aside__phone i { font-size: .85em; color: var(--pj-blue); }
.pj-aside__note { margin: .75rem 0 0; font-size: 13px; color: var(--pj-ink-3); }
/* главы фотографий, соседние объекты, «ещё объекты»: один ритм — секции равными шагами */
/* один левый край на всю страницу: главы, соседние объекты и «Ещё объекты» идут той же колонкой,
   что крошки, обложка и проза — иначе посреди страницы шов в 135px */
.pj-obj-after .pj-wrap { max-width: calc(var(--pj-col) + 2 * var(--pj-gutter)); }
.pj-obj-after > section { padding-block: var(--pj-sec) 0; }
.pj-obj-after > section:first-child { padding-top: 0; } /* отступ от текста даёт нижний padding секции тела; иначе 86 + 86 = дыра в 170px */
.pj-obj-after > section:last-child { padding-bottom: var(--pj-sec); }
.pj-chapter__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; margin-bottom: 1.5rem; }
.pj-chapter__head .pj-kicker { margin-bottom: .875rem; } /* у секции глав такой же кикер, как у остальных секций страницы */
.pj-chapter__head span { font-size: .9375rem; color: var(--pj-ink-3); font-variant-numeric: tabular-nums; }
.pj-obj-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--pj-line); border: 1px solid var(--pj-line); border-radius: var(--pj-r-m); overflow: hidden; }
.pj-obj-nav a { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1rem; align-items: center; padding: 1.25rem 1.5rem; background: var(--pj-card); transition: background .3s ease; }
.pj-obj-nav a:hover { background: var(--pj-blue-soft); }
.pj-obj-nav a + a { grid-template-columns: minmax(0, 1fr) auto; text-align: right; }
.pj-obj-nav a + a img { order: 2; }
/* высота одна, ширина по кадру: квадратная обрезка съедала до 55 % вертикального снимка.
   contain — страховка на случай панорамного кадра шире 96 px */
.pj-obj-nav img { height: 72px; width: auto; max-width: 96px; object-fit: contain; justify-self: center; border-radius: .75rem; }
.pj-obj-nav small { display: block; font-size: 11px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--pj-blue); margin-bottom: 4px; }
.pj-obj-nav b { font-weight: 700; font-size: 1rem; color: var(--pj-ink); }
.pj-related__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
/* «Ещё объекты»: колонки в долях пропорций кадров (--pj-related-cols из данных) — все превью
   выходят одной высоты, каждое в своей пропорции. Равные колонки давали вертикальный кадр
   на 989px рядом с горизонтальным на 631px; обрезать нельзя, это фотография работы. */
.pj-masonry.pj-related { display: grid; grid-template-columns: var(--pj-related-cols, repeat(3, minmax(0, 1fr))); grid-auto-rows: auto; row-gap: 1.5cqi; margin-bottom: 0; }
.pj-masonry.pj-related > * { grid-row-end: auto !important; margin-bottom: 0; cursor: pointer; }


/* ---------- RESPONSIVE ---------- */
@media (max-width: 1000px) {
  .pj-obj-body { grid-template-columns: 1fr; }
  .pj-aside { position: static; }
}
@media (max-width: 767px) {
  .pj-hero__cta .pj-btn { width: 100%; }
  .pj-hero { padding-top: 76px; }
  .pj-catalog { scroll-margin-top: 72px; }
  .pj-bar { align-items: start; flex-direction: column; gap: 1rem; }
  .pj-bar__right { width: 100%; justify-content: space-between; }
  .pj-seg { flex: 1; }
  .pj-seg button { flex: 1; justify-content: center; padding: 0 .75rem; }
  .pj-filter summary { display: flex; align-items: center; gap: .75rem; min-height: 44px; font-size: .9375rem; font-weight: 700; color: var(--pj-ink); cursor: pointer; list-style: none; }
  .pj-filter summary > span { margin-left: auto; font-weight: 500; color: var(--pj-ink-3); font-size: 13px; max-width: 60%; text-align: right; }
  .pj-filter summary i { font-size: 11px; color: var(--pj-blue); transition: transform .3s var(--pj-ease); }
  .pj-filter[open] summary i { transform: rotate(180deg); }
  .pj-filter-body { padding-top: 1rem; }
  .pj-filter:not([open]) .pj-filter-body { display: none; }
  .pj-tile__cap { padding: 1.5rem .75rem .75rem; font-size: 13px; }
  /* на телефоне ничего мельче 12px: 11px читается хуже и на боевом мобильном шаблоне таких размеров нет */
  .pj-crumbs, .pj-kicker, .pj-hero__clients p, .pj-obj-nav small,
  .pj-page .pf-filter-btn { font-size: 12px; }
  .pj-chapter__head > span { white-space: nowrap; flex-shrink: 0; } /* «3 кадра» вставало в две строки в 45px */
  .pj-obj-head { padding-top: 112px; }
  .pj-obj-cover { display: block; }
  .pj-obj-shots { grid-template-columns: 1fr; }
  .pj-obj-body--solo .pj-aside { display: block; }
  .pj-obj-body--solo .pj-aside > .pj-aside__lead { margin-bottom: 1.5rem; }
  .pj-obj-body--solo .pj-aside > .pj-aside__phone { margin-top: 1.25rem; }
  .pj-obj-cover a { width: 100%; } /* без этого ссылка ужималась по натуральной ширине кадра и обложка была уже подписи на 32px */
  .pj-obj-cover img { width: 100%; max-height: none; } /* обложка во всю ширину колонки, вровень с заголовком */
  /* на узкой колонке подпись автора отдельной строкой и мельче основной: иначе две фразы
     без разделителя читаются как одна */
  /* подпись автора остаётся в той же строке и тем же начертанием, что на компьютере: nowrap не даёт
     разорвать её посреди фразы, а при нехватке места она целиком переносится на следующую строку */
  .pj-obj-nav { grid-template-columns: 1fr; }
  .pj-obj-nav a { padding: 1rem; }
  .pj-obj-nav a + a { grid-template-columns: minmax(0, 1fr) auto; }
  .pj-masonry.pj-related { grid-template-columns: minmax(0, 1fr); row-gap: 1rem; }
}
/* На телефоне плитка ленты 177px, а подпись занимала 54–66 % её высоты и переносилась на три строки —
   от снимка оставалась треть. Имя объекта — не больше двух строк (в одну обрезалось почти каждое,
   01.10.2026), список категорий убираем: на этом экране категории показывает фильтр, а не каждая плитка. */
@media (max-width: 560px) {
  .pj-tile__cap { padding: 1.125rem .5rem .5rem; font-size: 12px; line-height: 1.25; }
  .pj-tile__cap b { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
  .pj-masonry:not(.pj-related) .pj-tile__cap > span:not(.sr-only) { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pj-page *, .pj-dialog * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
/* «Поделиться» в шапке объекта — между строкой адреса/фото и метками продукции */
.pj-obj-share { margin: 1.25rem 0 0; }
