

/* ==========================================================================
   css/pages/scene.css
   страничные стили
   ========================================================================== */
/* ===========================================================================
   3D-сцена конфигуратора (js/modules/configurator-3d.js).

   Контракт с разметкой (см. tools/gen_product.py, scene_block):

     <div class="scene-box" data-scene>              ← обёртка страницы
       <div class="scene" data-scene-stage>          ← НАШ контейнер
         <svg class="scene-art scene__fallback">     ← превью без JS и WebGL
       </div>
       <div class="scene__toolbar scene-box__tools">…кнопки .scene__tool…</div>
     </div>

   Владение: .scene, .scene__canvas, .scene__hint, .scene__toolbar,
   .scene__tool — этот файл вместе с configurator-3d.js. Обёртка .scene-box
   и её кнопки-переключатели — css/pages/product.css. Кнопки лежат этажом
   выше контейнера потому, что SVG-фолбэк переписывает его содержимое целиком.

   mount() дописывает в контейнер .scene__canvas и .scene__hint, ставит на нём
   классы .scene и .is-3d (по нему прячется превью) и атрибут data-time.

   Своих цветов здесь нет: всё через токены из css/tokens.css.
   =========================================================================== */

.scene {
  position: relative;
  display: block;
  overflow: hidden;
  /* Пропорция из макета: сцена там 1066×569. 16/10 давало кадр выше нужного,
     и правая колонка (панель + смета) висела над пустотой. */
  aspect-ratio: 15 / 8;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* Слой изолируем: перестройка сцены не должна перерисовывать всю страницу. */
  contain: layout paint;
}

.scene[data-time="night"] { background: var(--navy-900); }

/* Холст занимает контейнер целиком; размер буфера ставит renderer.setSize(). */
.scene__canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* Без этого браузер на телефоне забирает жест себе и сцена не крутится. */
  touch-action: none;
  cursor: grab;
}

.scene__canvas:active { cursor: grabbing; }

.scene__canvas:focus { outline: 0; }

.scene__canvas:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: -3px;
}

/* Статичный постер: видно без JS, без WebGL и пока грузится Three.js. Это либо
   фотография объекта, либо схема (см. scene_poster в tools/gen_product.py).
   Правило про > svg, > img и > picture — для любого превью, которое страница
   положила внутрь контейнера: без absolute оно оттолкнуло бы холст вниз. */
.scene__fallback,
.scene > svg,
.scene > img,
.scene > picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Фотография приходит в <picture> (WebP + запасной JPEG), поэтому картинка —
   внук контейнера, а не ребёнок: object-fit надо задать ей отдельно, иначе
   кадр 16:9 растянулся бы по рамке 15:8. */
.scene > picture { display: block; }
.scene > picture > img { width: 100%; height: 100%; object-fit: cover; }

/* Сцена поднялась — постер убираем. Именно убираем, а не перекрываем: холст
   лежит в том же контейнере, и оставленная под ним фотография просвечивала бы
   сквозь прозрачные пиксели неба. */
.scene.is-3d .scene__fallback,
.scene.is-3d > svg,
.scene.is-3d > img,
.scene.is-3d > picture { display: none; }

/* Слой SVG-фолбэка. Он рисует в свой контейнер, а не поверх всего, поэтому
   постер под ним нужно скрыть так же, как это делает 3D классом is-3d. */
.scene__svg { position: absolute; inset: 0; }
.scene__svg > svg { width: 100%; height: 100%; display: block; }
.scene.is-svg .scene__fallback,
.scene.is-svg > svg,
.scene.is-svg > img,
.scene.is-svg > picture { display: none; }

/* Возврат к фотографии.
   Сцена запускается по касанию кадра, и обратной дороги не было: подняв
   модель, человек больше не мог посмотреть на снимок реального забора — а
   именно снимок и продаёт. Ракурс «Фото» возвращает постер и прячет холст,
   не разбирая сцену: следующее переключение на «Улицу» показывает её мгновенно,
   без повторной загрузки Three.js. */
.scene.is-photo > .scene__canvas,
.scene.is-photo > canvas,
.scene.is-photo > .scene__svg,
.scene.is-photo > .scene__hint { display: none; }
.scene.is-photo.is-3d .scene__fallback,
.scene.is-photo.is-3d > svg,
.scene.is-photo.is-3d > img,
.scene.is-photo.is-svg .scene__fallback,
.scene.is-photo.is-svg > svg,
.scene.is-photo.is-svg > img { display: block; }
.scene.is-photo.is-3d > picture,
.scene.is-photo.is-svg > picture { display: block; }

/* Подсказка про управление. Гаснет, как только сценой начали пользоваться
   (класс is-quiet ставит сам модуль) — постоянная плашка мешает смотреть. */
.scene__hint {
  position: absolute;
  left: var(--s-3);
  bottom: var(--s-3);
  max-width: min(46ch, calc(100% - var(--s-8)));
  margin: 0;
  padding: 7px 11px;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--ink-2);
  /* Полупрозрачная подложка собирается из токена, а не из сырого rgba;
     первая строка — запасная для браузеров без color-mix. */
  background: var(--white);
  background: color-mix(in srgb, var(--white) 82%, transparent);
  border-radius: var(--radius-pill);
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}

.scene[data-time="night"] .scene__hint {
  color: var(--white);
  background: var(--navy-900);
  background: color-mix(in srgb, var(--navy-900) 70%, transparent);
}

.scene.is-quiet .scene__hint { opacity: 0; }

/* --- панель управления сценой (кнопки рисует страница) ---
   Здесь только то, что делает панель панелью. Куда её положить и в каком
   направлении разложить, решает страница (.scene-box__tools в product.css):
   правила равной силы, и порядок склейки css/pages/*.css решал бы спор
   случайным образом — поэтому координат тут нет. */

/* Панель — одна белая карточка на три пункта: так она нарисована в макете
   карточки товара. Раньше это были три отдельные плашки, и правый верхний угол
   сцены выглядел россыпью кнопок. */
.scene__toolbar {
  position: absolute;
  display: flex;
  gap: 2px;
  z-index: 2;
  padding: 5px;
  background: var(--white);
  background: color-mix(in srgb, var(--white) 94%, transparent);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}

/* Пункт панели: иконка сверху, подпись под ней. */
.scene__tool {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-width: 66px;
  min-height: 44px;
  padding: 4px 6px;
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.scene__tool:hover { background: var(--bg-2); color: var(--ink); }
.scene__tool:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.scene__tool[aria-pressed="true"] { background: var(--bg-2); color: var(--ink); }
.scene__tool[aria-pressed="true"] svg { color: var(--orange); }
.scene__tool svg { width: 20px; height: 20px; flex: none; color: var(--ink-2); }

/* --- полноэкранный режим ---
   Нативный :fullscreen работает везде, кроме iPhone, поэтому у сцены есть
   запасной режим на классе: тот же вид, но контейнер растянут поверх страницы. */
.scene:fullscreen,
.scene.is-fullscreen {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  width: 100%;
  height: 100%;
  max-height: none;
  aspect-ratio: auto;
  border: 0;
  border-radius: 0;
}

.scene:fullscreen .scene__toolbar,
.scene.is-fullscreen .scene__toolbar {
  top: calc(var(--s-4) + env(safe-area-inset-top, 0px));
  right: calc(var(--s-4) + env(safe-area-inset-right, 0px));
}

/* --- адаптив --- */

@media (max-width: 900px) {
  .scene { aspect-ratio: 4 / 3; }
  .scene__hint { font-size: 11px; }
}

@media (max-width: 560px) {
  .scene {
    aspect-ratio: 1 / 1;
    max-height: 62vh;   /* сцену видно целиком вместе с ценой под ней */
  }
  .scene__toolbar { gap: 0; padding: 4px; }
  .scene__tool { min-width: 40px; padding: 0 8px; }
  .scene__tool .scene__tool-text { display: none; }   /* на узком экране только иконки */
}

@media (prefers-reduced-motion: reduce) {
  .scene__hint, .scene__tool { transition: none; }
}

/* На печать уходит статичное превью: холст в PDF отдаётся пустым. */
@media print {
  .scene { aspect-ratio: 16 / 10; border-color: var(--line); }
  .scene__canvas, .scene__hint, .scene__toolbar { display: none !important; }
  .scene.is-3d .scene__fallback,
  .scene.is-3d > svg,
  .scene.is-3d > img,
  .scene.is-3d > picture { display: block; }
}
