/* ═══════════════════════════════════════════════════════════════════════════
   gallery-lightbox.css — оформление лайтбокса товарных галерей.
   Работает в паре с template/js/gallery-lightbox.js, который собирает панель
   и подпись. Правила цепляются через :has(.gl-cap), поэтому чужие лайтбоксы
   (ручки, плакетки, статьи) не задеваются.
   Живой разбор раскладки: designs/gallery-lightbox.html
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
   ЛАЙТБОКС ТОВАРНЫХ ГАЛЕРЕЙ — бейджи, таблички, шильды, номерки

   Язык взят у лайтбокса ручек: кадр-карточка со скруглением и тенью, тёмный
   бар под ней (та же поверхность, что у тостов и дока сайта), стрелки прижаты
   к карточке, а не к краям экрана.

   Селектор через :has(.gl-cap) — как у ручек через :has(.pen-lb-cap): правила
   цепляются только к нашему лайтбоксу и не трогают чужие.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Поля панели. ⚠️ Порог узкой панели ставит JS классом .gl-narrow, а не
   container query: элемент не может отвечать на собственный контейнерный
   запрос, и правило молча не срабатывало — на телефоне под стрелки всё равно
   резервировалось 232px, фотографии оставалось 158px вместо 366. */
.uk-lightbox:has(.gl-cap){
  --gl-gap:14px;   /* зазор между фотографией и баром */
  --gl-pad:16px;   /* минимальное поле от краёв экрана */
  /* Поля под стрелки. 116px (как у ручек) съедали 232px ширины фотографии, и
     на ноутбучных окнах 900–1050px карточка выходила уже собственного бара —
     плашка торчала из-под картинки. 72px хватает: область попадания 64px во
     всю высоту карточки, промахнуться по ней трудно. */
  --gl-gutter:72px}
.uk-lightbox.gl-narrow:has(.gl-cap){--gl-gutter:12px;--gl-gap:12px;--gl-pad:12px}

/* Кадр. Бар прибит к низу экрана, фотография центрируется в поле над ним.
   ⚠️ display у кадров НЕ трогаем: UIkit прячет неактивные через display:none,
   активному ставит flex и сам центрует картинку. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-items>*{
  top:var(--gl-pad);
  bottom:calc(var(--gl-pad) + var(--gl-cap-h,140px) + var(--gl-gap));
  left:0;right:0}

/* Карточка одного размера для ВСЕХ фотографий. Размер приходит из JS в
   --gl-w/--gl-h: в галереях почти всё снято 3:2, но попадаются 1200×805 и
   1200×896, и кадр от этого менял ширину — вместе с ним ездили стрелки и
   бар. Прямоугольник считается по самому частому соотношению набора,
   остальные вписываются в него через object-fit:contain. Обрезать нельзя:
   у табличек по краям бывает нужная часть вывески. Поля вписывания красим
   в тон карточки, чтобы они читались как паспарту, а не как дыра. */
/* ⚠️ Запасной путь — auto с ограничениями по полю кадра, а НЕ фиксированные
   vw. Если JS почему-то не успел выставить --gl-w, картинка должна просто
   вписаться в кадр, а не превратиться в марку. Когда переменные есть, они
   меньше ограничений и те ни на что не влияют. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-items img{
  width:var(--gl-w,auto);height:var(--gl-h,auto);
  max-width:calc(100% - 2 * var(--gl-gutter));max-height:100%;object-fit:contain;
  background:#0e0f14;
  border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.45);
  cursor:default}
/* Превью из сетки (480px, уже в кэше браузера) показывает фотографию сразу,
   пока едет оригинал.
   ⚠️⚠️ Оно ОБЯЗАНО быть псевдоэлементом, а не дочерним узлом. UIkit грузит
   кадр так: `this.getSlide(item).childElementCount || trigger('itemload')` —
   то есть у кадра, в котором уже есть хоть один элемент, оригинал не
   запрашивается ВООБЩЕ. С подложкой-<img> первые два кадра (их UIkit успевает
   взять на упреждение) приезжали в полном размере, а все следующие навсегда
   оставались размытым превью. Псевдоэлемент в childElementCount не считается.
   Размер прямоугольника приходит из JS в --gl-ph-w/--gl-ph-h: он равен тому,
   в который встанет оригинал, поэтому подмена не заметна. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-items>*::before{
  content:'';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:var(--gl-ph-w,0);height:var(--gl-ph-h,0);
  background-image:var(--gl-ph,none);background-size:contain;background-position:center;
  background-repeat:no-repeat;background-color:#0e0f14;
  border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.45);
  z-index:0;pointer-events:none}
.uk-lightbox:has(.gl-cap) .uk-lightbox-items img{position:relative;z-index:1}
/* ⚠️ touch-action:none на области кадров — без него щипок забирает себе
   браузер (у .uk-lightbox от UIkit стоит touch-action:pinch-zoom) и
   увеличивает всю страницу вместе с баром и шапкой. Прокручивать внутри
   лайтбокса нечего, так что терять нечего. Подпись не трогаем: там обычные
   ссылки и кнопки. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-items{touch-action:none}
/* Пока приближено, стрелки убираем: они перекрывают увеличенный кадр, а
   листать в этот момент всё равно не нужно. */
.uk-lightbox.gl-zoomed:has(.gl-cap) .uk-lightbox-slidenav{display:none}

/* Спиннер не нужен: пока идёт оригинал, фотография уже видна из превью,
   а крутилка поверх неё читается как дефект. */
.uk-lightbox:has(.gl-cap) .uk-spinner{display:none}

/* Нижний док сайта на время открытого лайтбокса убираем: он живёт в том же
   углу экрана, что и бар, и сквозь затемнение читался вторым, призрачным
   рядом тех же мессенджеров. Класс на <html> ставит JS. */
/* ⚠️ !important обязателен: видимостью дока командует скрипт сайта — он
   ставит display инлайновым стилем при прокрутке, и правило из файла его
   не перебивает. */
/* Якоря, куда уводит кнопка из бара: калькулятор раздела (/bejdzhi/#calc-bdg),
   цены плакеток и цены тейбл-тентов. Без запаса страница встаёт так, что верх
   секции уезжает под липкую шапку (99px на десктопе, 60px на телефоне).
   Внутри своей страницы прокручивает JS с той же поправкой. */
.box-calc [id^="calc-"],#ceny,#razmery-i-ceny,#stoimost{scroll-margin-top:72px}
@media (min-width:960px){.box-calc [id^="calc-"],#ceny,#razmery-i-ceny,#stoimost{scroll-margin-top:112px}}

.gl-open #footer_button_container{display:none!important}

/* Счётчик — в левом верхнем углу, напротив крестика. В баре он отбирал
   ширину у названия, а по важности он последний элемент. */
/* Счётчик на своей плашке: он лежит поверх притушенной страницы, и на светлом
   логотипе сайта белые цифры без подложки не читались. */
.gl-count{position:absolute;top:14px;left:14px;z-index:2;
  font-family:'Open Sans',system-ui,sans-serif;font-size:12px;font-weight:600;letter-spacing:.02em;
  color:rgba(255,255,255,.72);font-variant-numeric:tabular-nums;
  padding:5px 10px;border-radius:999px;background:rgba(16,17,23,.66)}

/* ─── стрелки ───────────────────────────────────────────────────────────────
   Прижаты к карточке: её ширину JS отдаёт в --gl-w. Область попадания во всю
   высоту карточки, но всего 96px шириной — клик мимо карточки закрывает
   лайтбокс, и эту возможность нельзя съедать целиком. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav{
  top:var(--gl-pad);
  bottom:calc(var(--gl-pad) + var(--gl-cap-h,140px) + var(--gl-gap));
  height:auto;transform:none;width:96px;padding:0;margin:0;
  display:flex;align-items:center;justify-content:center}
/* ⚠️ Кликает не блок, а вложенная <a class="uk-slidenav"> 46×54 — растягиваем её */
.uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav>.uk-slidenav{
  width:100%;height:100%;display:flex;align-items:center;justify-content:center;padding:0}
.uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav svg{width:26px;height:44px;opacity:.75;
  transition:transform 140ms cubic-bezier(.23,1,.32,1),opacity 140ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){
  .uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav:hover svg{opacity:1;transform:scale(1.12)}
}
.uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav:active svg{transform:scale(.96);transition-duration:90ms}
/* Привязка по краю, обращённому К карточке: зазор не зависит от ширины кнопки.
   min() не даёт стрелке уехать за край экрана на широкой фотографии. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav.uk-position-center-left{
  left:auto;right:min(calc(50% + var(--gl-w,60vw) / 2 + 12px),calc(100% - 72px))}
.uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav.uk-position-center-right{
  right:auto;left:min(calc(50% + var(--gl-w,60vw) / 2 + 12px),calc(100% - 72px))}

/* Узкая панель: стрелки закрывают карточку по краям, а листается свайпом */
.uk-lightbox.gl-narrow:has(.gl-cap) .uk-lightbox-slidenav{display:none}
.uk-lightbox.gl-narrow:has(.gl-cap) .uk-lightbox-items img{border-radius:14px}
.gl-narrow .gl-count{top:14px;left:16px}

/* ─── бар ───────────────────────────────────────────────────────────────────
   Поверхность — та же, что у тостов и дока: плотный градиент БЕЗ
   backdrop-filter (постоянный слой размытия роняет частоту кадров всей
   страницы, замер 23.07).
   Бар прибит намертво: UIkit вешает на подпись uk-transition-slide-bottom
   (--uk-translate-y:100%) и uk-transition-opaque, которыми умеет её прятать. */
.uk-lightbox:has(.gl-cap) .uk-lightbox-caption:not(.gl-mount){display:none}
.uk-lightbox:has(.gl-cap) .uk-lightbox-caption{
  background:none;padding:0 12px;bottom:calc(var(--gl-pad) + env(safe-area-inset-bottom,0px));
  opacity:1;visibility:visible;transform:none;--uk-translate-y:0;transition:none}

/* Оболочка держит доступную ширину и служит контейнером для порогов
   раскладки бара.
   ⚠️ Ширина НЕ должна зависеть от ширины фотографии. Так было — и получалось
   кольцо: шире бар → ниже карточка → уже карточка → другой порог → другая
   высота бара. На границе порога это раскачивалось и обрывалось на пятом
   проходе в разнобое: CSS считал бар в 152px, а нарисован был 92px, и под
   фотографией зияли лишние 60px. Теперь зависимость односторонняя:
   панель → бар → фотография.
   ⚠️ Ширина задана явно: контейнер с inline-size не имеет права зависеть
   от своего содержимого. */
.gl-shell{width:min(1080px,100%);margin:0 auto;
  display:flex;justify-content:center;
  container-type:inline-size;container-name:glbar}

/* Бар обнимает своё содержимое и не растягивается до края карточки. На
   растянутом баре композиция разваливалась на три острова с провалами между
   ними — ровно то, на чём уже обожглись в баре ручек.
   Сверху он ограничен шириной фотографии: плашка шире картинки читается как
   ошибка вёрстки. Но не уже, чем нужно текущей раскладке (--gl-floor), иначе
   на низком широком окне карточка выходит узкой и трёхзонный ряд в неё не
   влезает. ⚠️ Ограничение стоит на самом баре, а не на оболочке: оболочка —
   контейнер для порогов, и её ширина не должна зависеть от фотографии. */
/* Бар постоянного размера на всех кадрах: ширина равна ширине карточки (а она
   теперь одна для всех фотографий), высота задана min-height, который JS
   считает по самой «толстой» карточке набора. Опознание прижато к левому краю,
   действия — к правому; лишняя ширина уходит в средний столбец, где от неё
   польза: значения характеристик реже переносятся. */
.gl-cap{width:min(100%,var(--gl-w,100%));min-height:var(--gl-cap-h,0);
  box-sizing:border-box;
  /* ⚠️ align-content:center обязателен вместе с min-height. По умолчанию сетка
     растягивает строки, и запас высоты (он рассчитан на самую «толстую»
     карточку набора) расползался щелями между зонами. Так он становится
     симметричным полем сверху и снизу и читается как поля плашки.
     На телефоне min-height снят (см. порог 620), и правило работает вхолостую. */
  display:grid;align-items:center;align-content:center;gap:10px 0;
  padding:14px 18px;
  background:linear-gradient(180deg,#1d1e28,#16171f);
  border:1px solid rgba(255,255,255,.08);border-radius:16px;
  color:#fff;box-shadow:0 18px 50px rgba(0,0,0,.5);text-align:left;
  font-family:'Open Sans',system-ui,sans-serif}
.gl-cap *{box-sizing:border-box}

.gl-head{display:flex;flex-direction:column;gap:3px;min-width:0}
/* Текст нигде не обрезается: высоту бара держит min-height, посчитанный
   по самой «толстой» карточке набора, поэтому переносы её не меняют. */
.gl-name{font-size:16px;font-weight:700;line-height:1.3;min-width:0}
.gl-art{font-size:12px;font-weight:600;letter-spacing:.02em;color:rgba(255,255,255,.5);
  font-variant-numeric:tabular-nums;white-space:nowrap}

/* Характеристики: подпись приглушена, значение белое. Набор полей у галерей
   разный (у бейджей «Тип бейджа», у табличек «Толщина», у шильдов
   «Назначение»), поэтому строки строятся из того, что реально есть в desc.
   ⚠️ Значения в одну строку с многоточием: «прозрачный акрил с цветной
   печатью» иначе разносит колонку на три строки и бар прыгает по высоте от
   кадра к кадру. Полный текст остаётся в title. */
.gl-specs{display:grid;grid-template-columns:var(--gl-lab,auto) minmax(0,1fr);gap:3px 12px;
  font-size:13px;line-height:1.42;margin:0;min-width:0}
/* ⚠️ Подпись переносится, а не режется: ширину колонки считает JS по самой
   длинной подписи набора, но у неё есть потолок в долях зоны. Когда потолок
   срабатывает (узкий бар, редкая длинная подпись вроде «Толщина верхней
   части»), nowrap выкладывал текст поверх значения. */
.gl-specs dt{color:rgba(255,255,255,.45)}
.gl-specs dd{margin:0;color:rgba(255,255,255,.92);
  /* страховка от неразрывного слова вроде «сублимационная» в узкой колонке */
  overflow-wrap:break-word}
.gl-more.is-blank{visibility:hidden}

/* Действия. Раскладка взята у нижнего дока сайта (#footer_button_container):
   ряд без переносов, иконки фиксированной ширины впритык слева, оранжевая
   кнопка забирает остаток. Разносить кнопки по ширине нельзя — на телефоне
   они выглядели раскиданными.
   Каналов четыре, а не шесть — ровно как в доке. Шесть иконок занимали треть
   бара, и на ширину названия с характеристиками уже не хватало. Почта и
   телефон есть в шапке, подвале и в самом доке.
   ⚠️ Никакого min-width:0 на этой зоне: он снимает автоматический минимум
   грид-колонки, и колонка ужимается НИЖЕ содержимого — кнопка расчёта
   вылезала за плашку на 84px. */
/* Кнопка расчёта уходит под ряд мессенджеров: в одну строку зона занимает
   420px из тысячи, и на имя с характеристиками не остаётся — они начинали
   переноситься на две-три строки и бар вырастал сильнее, чем от этого
   переноса кнопки. */
.gl-actions{display:flex;flex-direction:column;align-items:stretch;gap:10px}
.gl-actions .msg-buttons{justify-content:center}
.gl-actions .gl-calc{width:100%}
/* ⚠️ Размер, радиус и --mvr правим только вместе: у обводки .msg-btn::before
   радиус считается как --mvr + --mvring. У .msg-icons по умолчанию --mvr:9px
   при радиусе кнопки 14px, то есть кольцо поджато. Ставим 14 — ровно так же
   поступает #footer_button_container. */
.gl-cap .msg-icons .msg-btn{--mvr:14px}
.gl-actions .msg-buttons{gap:6px;flex-wrap:nowrap}
.gl-actions .msg-icons .msg-btn{flex:0 0 48px}

/* Кнопка расчёта — тот же градиент, что у .msg-cta-link в тостах сайта */
.gl-calc{display:inline-flex;align-items:center;justify-content:center;text-decoration:none;
  height:48px;padding:0 20px;border:0;border-radius:14px;
  background:linear-gradient(135deg,#ff6b35,#e84510);color:#fff;
  font-family:inherit;font-size:13px;font-weight:700;white-space:nowrap;cursor:pointer;
  box-shadow:0 4px 16px rgba(232,69,16,.25);
  transition:transform 160ms cubic-bezier(.23,1,.32,1),box-shadow 160ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){
  .gl-calc:hover{transform:scale(1.03);box-shadow:0 8px 24px rgba(232,69,16,.35)}
}
.gl-calc:active{transform:scale(.97);transition-duration:90ms}
/* ⚠️ Свой цвет на всех состояниях. На главной кнопка расчёта — ссылка на
   калькулятор раздела, а у UIkit есть a:hover{color:#0f6ecd;
   text-decoration:underline} — он весомее одноклассового правила, и текст
   кнопки синел под курсором. Ссылке «Все такие» тем же правилом
   дорисовывалось подчёркивание. */
.gl-calc,.gl-calc:hover,.gl-calc:focus,.gl-calc:active,
.gl-more,.gl-more:hover,.gl-more:focus{text-decoration:none}
.gl-calc:hover,.gl-calc:focus,.gl-calc:active{color:#fff}
.gl-calc:focus-visible,.gl-more:focus-visible,.uk-slidenav:focus-visible{
  outline:2px solid #fff;outline-offset:3px}

/* Ссылка в категорию — третье по важности действие, поэтому текстом.
   Текст в отдельном span: ужимать надо его, а стрелка должна остаться целой. */
.gl-more{display:inline-flex;align-items:center;gap:7px;align-self:flex-start;
  max-width:100%;min-width:0;
  font-size:13px;font-weight:600;color:rgba(255,255,255,.7);text-decoration:none;
  transition:color 140ms ease}
.gl-more svg{width:16px;height:16px;flex:0 0 16px;
  transition:transform 180ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){
  .gl-more:hover{color:#fff}
  .gl-more:hover svg{transform:translateX(3px)}
}

/* Разделители зон — волосяная линия, а не воздух: так пауза между зонами
   читается как решение, а не как провал в композиции. */
.gl-rule{width:1px;align-self:stretch;justify-self:center;
  background:rgba(255,255,255,.10)}

/* Широкий бар: три зоны в один ряд.
   ⚠️ Все колонки заданы ДОЛЯМИ, ни одной auto. Из auto-колонок при
   justify-content:normal сетка раздаёт остаток поровну, а базой каждой служит
   её содержимое — поэтому от кадра к кадру ездило всё сразу: колонка имени
   289→510px, разделители 29→91px, зона действий 210→272px, то есть оранжевая
   кнопка меняла и место, и ширину. Доли считаются от свободного места, а оно
   зависит только от ширины бара (она одна для всех кадров) и от зоны действий
   (её содержимое одинаково на всех карточках). Значит опознание всегда
   начинается на одном x, кнопки всегда прижаты к правому краю, а разделители
   стоят на месте.
   min-колонок 0, а не auto: автоминимум грид-колонки — это тоже содержимое,
   и длинное название снова растащило бы ряд. */
.gl-cap{grid-template-columns:minmax(0,.9fr) minmax(0,.2fr) minmax(0,1.1fr) minmax(0,.2fr) auto;
  grid-auto-flow:column}

/* Зонд для замеров: тот же бар, но по содержимому и без оформления. */
.gl-probe{display:block;width:max-content;min-height:0;padding:0;
  border:0;background:none;box-shadow:none}

/* ─── пороги по ширине САМОГО бара ─────────────────────────────────────────
   860px: зона действий (шесть кнопок мессенджеров и кнопка расчёта) перестаёт
   помещаться рядом с характеристиками — уводим её отдельным рядом. */
@container glbar (max-width:900px){
  .gl-cap{grid-auto-flow:row;grid-template-columns:minmax(0,1fr) minmax(0,.2fr) minmax(0,1.15fr);
    gap:12px 0}
  .gl-actions{grid-column:1/-1}
  .gl-rule:last-of-type{display:none}
}
/* 620px: и характеристики рядом с именем уже не встают — всё в столбик */
@container glbar (max-width:620px){
  /* На телефоне плашка во всю ширину: бар по содержимому оставлял бы поля
     по бокам, а фотография и так упирается в ширину экрана.
     ⚠️ Высота здесь ПО СОДЕРЖИМОМУ (min-height снят). На узком экране запас
     под самую «толстую» карточку из ста — это треть экрана наполовину пустой
     плашки. Фотография при этом не ездит: место под бар в кадре всё равно
     резервируется по --gl-cap-h, просто сам бар им не растягивается. */
  .gl-cap{width:100%;min-height:0;grid-template-columns:minmax(0,1fr);gap:10px}
  /* Имя в две строки. На узком экране кадр упирается в ширину, а не в высоту,
     поэтому лишняя строка бара его не уменьшает — только чуть сдвигает. На
     десктопе имя оставляем в одну строку: там высота бара задаёт высоту кадра,
     и от длины названия прыгала бы сама фотография. Подсказки по наведению
     на тач нет, поэтому обрезать имя здесь особенно нечестно. */
  /* Имя переносится сколько нужно: высоту бара держит min-height, посчитанный
     по самой «толстой» карточке набора. */
  .gl-rule{display:none}
  .gl-actions{grid-column:1}
}
/* 500px: ряд дока целиком — иконки впритык слева, кнопка забирает остаток.
   Кнопки чуть меньше (44px): на 366px четыре штуки по 48 не оставляют места
   под подпись «Рассчитать». Слово «стоимость» здесь лишнее — что считают,
   видно по фотографии над баром. */
@container glbar (max-width:500px){
  .gl-cap{padding:12px 14px}
  /* Ряд дока: иконки впритык слева, кнопка забирает остаток */
  .gl-actions{flex-direction:row;align-items:center}
  .gl-actions .msg-icons .msg-btn{flex:0 0 44px;height:44px;width:44px}
  .gl-actions .msg-icons .msg-btn svg{width:20px;height:20px}
  .gl-calc{flex:1 1 auto;min-width:0;height:44px;padding:0 12px}
  .gl-calc-tail{display:none}
}

@media (prefers-reduced-motion:reduce){
  .uk-lightbox:has(.gl-cap) .uk-lightbox-slidenav svg,
  .gl-calc,.gl-more,.gl-more svg,.msg-buttons .msg-btn,.msg-buttons .msg-btn svg{transition:none}
  .gl-calc:hover,.gl-calc:active,.gl-more:hover svg,
  .msg-icons .msg-btn:hover,.msg-buttons .msg-btn:hover svg{transform:none}
  .msg-buttons .msg-btn:hover::before{animation:none}
}
