/* Латинские display-шрифты (остаются для английских заголовков) */
@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Kalam:wght@400;700&family=DM+Sans:wght@400;500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,700;1,700&family=Patrick+Hand&family=DM+Sans:wght@400;500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Anton&family=Handlee&family=DM+Sans:wght@400;500&display=swap');
/* Кириллица: Russo One — брутальный condensed аналог Bebas для заголовков;
   Marck Script — рукописный с кириллицей для рукописных заметок;
   Special Elite — для classified-card (латиница, но подходит для стилизации) */
@import url('https://fonts.googleapis.com/css2?family=Russo+One&family=Marck+Script&family=PT+Sans+Narrow:wght@700&display=swap');

/* ============================================================
   Story OS — Cinematic Detective Landing
   5-сценовый scroll-driven stage. Файл изолирован: токены
   локальные, в основной index.html не импортировать.
   Структура файла:
     1. Локальные токены
     2. Сброс и базовый каркас
     3. Cinema stage + scroll track + переходы сцены
     4. Слои сцены (bg / ambient / props / threads / content)
     5. Сцена 1 — светлая пробковая доска
     6. Сцена 2 — тёмный стол
     7. Сцена 3 — светлая, тревожная (разлёт страниц)
     8. Сцена 4 — тёмный граф Story OS
     9. Сцена 5 — светлая, разрешённая
    10. Универсальные компоненты: card / copy / cta / thread
    11. Side-nav, scroll-hint
    12. Адаптив и motion-preferences
   ============================================================ */

/* ============ 1. Локальные токены =========================== */
:root {
  /* Бумага и пробка (светлые сцены) */
  --paper-cream:       #f4ecd8;
  --paper-cream-soft:  #ece2c4;
  --paper-shadow:      rgba(28, 18, 8, 0.35);
  --board-cork:        #8a6a44;
  --board-cork-dark:   #4a341c;
  --board-cork-light:  #b09060;

  /* Длина скролла */
  --scene-step-h:      90vh;

  /* Чернила и текст */
  --ink-dark:          #1a120a;
  --ink-mid:           #4a3a28;
  --ink-faint:         #7a6850;

  /* Красная нить и пины */
  --thread-red:        #b51a1a;
  --thread-red-dark:   #5a0808;
  --thread-red-soft:   #d04848;
  --pin-red:           #c92a2a;
  --pin-shadow:        rgba(0, 0, 0, 0.5);

  /* Ночные сцены (стол + граф) */
  --night-bg:          #0d0f14;
  --night-bg-deep:     #050608;
  --night-surface:     #1a1410;
  --night-text:        #e8e1d2;
  --night-text-mid:    #a8a094;
  --night-glow:        #d4a857;
  --night-cyan:        #4ec9d9;
  --night-screen:      #1a2438;

  /* Типографика */
  /* Для латинских заголовков: Bebas Neue; для кириллицы: Russo One */
  --font-display: 'Bebas Neue', 'Russo One', 'PT Sans Narrow', sans-serif;
  /* Russo One — аналог Bebas по ширине и духу, но с полной кириллицей */
  --font-display-ru: 'Russo One', 'PT Sans Narrow', sans-serif;
  /* Marck Script — кириллический рукописный; Kalam — fallback */
  --font-hand:    'Marck Script', 'Kalam', cursive;
  --font-body:    'DM Sans', sans-serif;

  /* Тайминги */
  --ease-out:     cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-in-out:  cubic-bezier(0.45, 0, 0.55, 1);
  --t-fast:       240ms;
  --t-mid:        520ms;
  --t-scene:      900ms;
}

/* ============ 2. Сброс и базовый каркас ===================== */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
img, svg { display: block; max-width: 100%; }
button, a { font: inherit; }
button {
  background: none; border: 0; color: inherit;
  cursor: pointer; padding: 0;
}

body.cinema {
  font-family: var(--font-body);
  color: var(--ink-dark);
  background: var(--ink-dark);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* ============ 3. Cinema stage + scroll track ================ */
/* Stage прижат к viewport — это «экран кинотеатра».
   Track — невидимая дорожка реальной высоты, по которой едет скролл. */
.cinema-stage {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  background: var(--ink-dark);
}

/* Все слои сцены фиксированы на минимальной ширине 1100px.
   При более широком окне растягиваются до 100%.
   Это гарантирует что % позиции карточек (--x/--y) не сдвигаются
   при сужении окна — они считаются от фиксированной базы. */
.scene__layer {
  min-width: 1100px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--paper-cream); color: var(--ink-dark);
  padding: 0.5rem 1rem; z-index: 1000;
}
.skip-link:focus { left: 1rem; top: 1rem; }

.cinema-track {
  position: relative;
  z-index: 0;
  pointer-events: none;
}
/* Каждый шаг — определен переменной. Синхронно с SCENE_STEP_VH = 1 в JS.
   Чтобы настроить чувствительность скролла: меняй оба числа одновременно.
   Меньше = агрессивнее (легче переключить). Больше = плавнее.
   Рекомендуемый диапазон: 0.4 (очень чутко) до 1.5 (очень плавно).
   Последний шаг 150vh — буфер для достижимости последней сцены. */
.cinema-track__step {
  height: var(--scene-step-h);
}
.cinema-track__step:last-child {
  height: var(--scene-step-h);
}

/* ============ 4. Сцена и слои ============================== */
/* Каждая сцена накладывается поверх предыдущей и крестфейдится.
   Сцена едет на +3vh при входе для cinematic feel. */
.scene {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(3vh) scale(0.992);
  transition:
    opacity   var(--t-scene) var(--ease-out),
    transform var(--t-scene) var(--ease-out),
    visibility 0s linear var(--t-scene);
  isolation: isolate;
}
.scene.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity   var(--t-scene) var(--ease-out),
    transform var(--t-scene) var(--ease-out),
    visibility 0s linear 0s;
}

.scene__layer {
  position: absolute;
  inset: 0;
  min-width: 1100px;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  --px: 0px; --py: 0px;
}

/* Центрирование scene__layer на узких экранах — через landing-pan.js (JS надёжнее CSS) */
.scene__layer--bg      { z-index: 0; }
.scene__layer--ambient { z-index: 1; }
.scene__layer--props   { z-index: 10; pointer-events: auto; will-change: transform; transform: translate3d(var(--px), var(--py), 0); }
.scene__layer--threads { z-index: 40; will-change: transform; transform: translate3d(calc(var(--px) * 1.4), calc(var(--py) * 1.4), 0); }
.scene__layer--content { z-index: 60; pointer-events: auto; }

/* ============ 5. Сцена 1 — светлая пробковая доска ==========
   board-base.webp — реальный арт (1536×1024). Градиенты-fallback
   сняты сверху, остался только мягкий vignette по краям для
   cinematic-освещения. Если файла не будет — рендер свалится на
   background-color (var(--board-cork)). */
.scene--1 .scene__layer--bg {
  background:
    radial-gradient(ellipse at 50% 55%, transparent 0%, transparent 45%, rgba(20, 12, 6, 0.35) 100%),
    url("assets/board/board-base.webp") center / cover no-repeat,
    var(--board-cork);
}
/* wear-01 переведён в полноценный фон сцены 5 — ambient сцены 1
   освобождён под будущую wear/grain-текстуру (например, grain-soft.webp
   по стандарту § 4). До тех пор слой пустой. */
.scene--1 .scene__layer--ambient { background-image: none; }

/* ============ 6. Сцена 2 — тёмный стол ====================
   board-wear-03.webp — реальный фон ночной сцены (1536×1024).
   Vignette нейтральный чёрный, мягкий — края у тёмного фото уже
   естественно тёмные, перебарщивать нельзя. */
.scene--2 .scene__layer--bg {
  background:
    radial-gradient(ellipse at 50% 55%, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.45) 100%),
    url("assets/board/board-wear-03.webp") center / cover no-repeat,
    var(--night-bg);
}
.scene--2 .scene__layer--ambient { background: none; }

/* ============ 7. Сцена 3 — светлая, тревожная ==============
   board-wear-02.webp — реальный фон (1536×1024). Изображение
   перенесено из ambient-слоя в bg, mix-blend убран. Vignette по
   краям мягче, чем у сцены 1, чтобы сохранить тревожную светлоту. */
.scene--3 .scene__layer--bg {
  background:
    radial-gradient(ellipse at 50% 55%, transparent 0%, transparent 50%, rgba(40, 24, 10, 0.32) 100%),
    url("assets/board/board-wear-02.webp") center / cover no-repeat,
    #d8c8a0;
}
.scene--3 .scene__layer--ambient { background-image: none; }

/* ============ 8. Сцена 4 — тёмный граф =====================
   board-wear-04.webp — реальный фон сцены графа (1536×1024).
   Vignette нейтральный чёрный, центр держим открытым для grid-board. */
.scene--4 .scene__layer--bg {
  background:
    radial-gradient(ellipse at 50% 50%, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.45) 100%),
    url("assets/board/board-wear-04.webp") center / cover no-repeat,
    var(--night-bg-deep);
}
.scene--4 .scene__layer--ambient { background: none; }

/* ============ 9. Сцена 5 — чистая светлая ==================
   board-wear-01.webp — реальный фон (1536×1024). Изображение
   перенесено из ambient-слоя в bg. Vignette мягче и теплее,
   чтобы поддержать ощущение «разрешения / выхода на свет». */
.scene--5 .scene__layer--bg {
  background:
    radial-gradient(ellipse at 50% 45%, transparent 0%, transparent 55%, rgba(60, 40, 18, 0.28) 100%),
    url("assets/board/board-wear-01.webp") center / cover no-repeat,
    var(--paper-cream);
}
.scene--5 .scene__layer--ambient { background-image: none; }

/* ============ 10. Универсальные компоненты ================ */

/* ── 10.1 Карточка (фото / заметка / папка / лист) ───────── */
.card {
  position: absolute;
  left: var(--x, 50%);
  top:  var(--y, 50%);
  width: 200px;
  padding: 1rem 1rem 1.2rem;
  background: var(--paper-cream);
  transform: rotate(var(--rot, 0deg));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 14px 28px var(--paper-shadow);
  transition: transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out);
}
.card:hover {
  transform: rotate(0deg) translateY(-6px) scale(1.04);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 24px 42px var(--paper-shadow);
  z-index: 10;
}

/* Стаггер появления карточек внутри активной сцены */
.scene:not(.is-active) .card {
  opacity: 0;
  transform: rotate(var(--rot, 0deg)) translateY(-14px);
}
.scene.is-active .card {
  opacity: 1;
  transform: rotate(var(--rot, 0deg));
  transition:
    opacity   620ms var(--ease-out),
    transform 620ms var(--ease-out);
}
/* Стаггер общий для .card и .polaroid: оба — <article> внутри
   .scene__layer--props, поэтому :nth-of-type считает их в одной
   последовательности. :where() удерживает специфичность нулевой. */
.scene.is-active :where(.card, .polaroid):nth-of-type(1) { transition-delay:  120ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(2) { transition-delay:  240ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(3) { transition-delay:  360ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(4) { transition-delay:  480ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(5) { transition-delay:  600ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(6) { transition-delay:  720ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(7) { transition-delay:  840ms; }
.scene.is-active :where(.card, .polaroid):nth-of-type(8) { transition-delay:  960ms; }

/* ── Слои пинов (новая архитектура: 4 отдельных DOM-слоя) ───
   Раньше пин жил внутри карточки как вложенный span.
   Теперь три элемента (shadow / base / head) создаются JS
   в отдельных div-ах с правильным z-index:
     .pin-layer--shadow  z:20  тени
     .pin-layer--base    z:30  основания
     .scene-threads-svg  z:40  нити (между base и head!)
     .pin-layer--head    z:50  головки поверх нитей        */

.pin-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.pin-layer--shadow { z-index: 20; }
.pin-layer--base   { z-index: 30; }
.pin-layer--head   { z-index: 50; }

.scene-threads-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 40;
  pointer-events: none;
  overflow: visible;
}

/* Каждый DOM-элемент пина позиционируется через --cx/--cy (px),
   которые JS пишет после замера getBoundingClientRect карточки. */
.pin-shadow-el,
.pin-base-el,
.pin-head-el {
  position: absolute;
  left: var(--cx, 50%);
  top:  var(--cy, 50%);
  border-radius: 50%;
  will-change: transform;
}

/* Тень — 24×12 размытый эллипс */
.pin-shadow-el {
  width: 24px;
  height: 12px;
  transform:
    translate(calc(-50% + var(--shadow-x, 6px)), calc(-50% + var(--shadow-y, 7px)))
    rotate(-8deg);
  border-radius: 999px;
  background: radial-gradient(
    ellipse at center,
    rgba(10,6,5,0.5)  0%,
    rgba(10,6,5,0.26) 48%,
    rgba(10,6,5,0)    100%
  );
  filter: blur(1.8px);
}

/* Основание — клиппированный конус */
.pin-base-el {
  width: 28px;
  height: 28px;
  transform: translate(-50%, -26%) scale(var(--pin-scale, 1));
  border-radius: 48% 52% 50% 50% / 58% 58% 42% 42%;
  clip-path: ellipse(52% 44% at 50% 63%);
  background: radial-gradient(
    circle at 34% 28%,
    #ff8b8b 0%, #df3838 34%, #991515 74%, #5d0909 100%
  );
  border: 2px solid #26120f;
  box-shadow:
    inset 1px 1px 0 rgba(255,220,220,0.28),
    inset -1px -1px 0 rgba(40,0,0,0.24),
    0 1px 0 rgba(0,0,0,0.18);
}
.pin-base-el::before {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: inherit;
  border: 1px solid rgba(33,18,14,0.32);
  transform: translate(0.4px,-0.2px) scale(0.985);
  opacity: 0.8;
  pointer-events: none;
}

/* Головка — шарик поверх нити */
.pin-head-el {
  width: 20px;
  height: 20px;
  transform:
    translate(calc(-50% + var(--head-x, 0px)), calc(-50% + var(--head-y, 0px)))
    scale(var(--pin-scale, 1));
  border-radius: 46% 54% 51% 49% / 53% 45% 55% 47%;
  background: radial-gradient(
    circle at 32% 28%,
    #ffd0d0 0%, #ff8c8c 16%, #ef4848 38%, #c91f1f 68%, #760b0b 100%
  );
  border: 2px solid #24110e;
  box-shadow:
    inset 1.5px 1px 0 rgba(255,235,235,0.48),
    inset -1px -1px 0 rgba(72,10,10,0.34),
    0 1px 0 rgba(0,0,0,0.2);
  transition: transform 80ms linear;
}
.pin-head-el::before {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: inherit;
  border: 1px solid rgba(33,18,14,0.32);
  transform: translate(0.4px,-0.2px) scale(0.985);
  opacity: 0.8;
  pointer-events: none;
}

/* ── 10.2 Polaroid (photo) ────────────────────────────────
   container-type: inline-size — подключает container queries,
   чтобы caption и другие тексты масштабировались вместе с шириной
   карточки (через cqi), а не с шириной viewport. */
.polaroid {
  --frame: 12px;
  --bottom-frame: 8px;
  --radius: 4px;
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  width: var(--w, 260px);
  padding: var(--frame) var(--frame) var(--bottom-frame);
  background: #f7f2e8;
  border-radius: var(--radius);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.6) inset, 0 18px 34px var(--paper-shadow);
  transform: rotate(var(--rot, -4deg));
  transition: transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out);
}
.polaroid:hover {
  transform: rotate(0deg) translateY(-6px) scale(1.04);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 24px 42px var(--paper-shadow);
  z-index: 10;
}

/* Контейнер фото — без фиксированного aspect-ratio: рамка
   принимает форму того, что внутри. line-height:0 убирает
   inline-baseline gap, иначе под <img> образуется ~4 px зазор. */
.polaroid__photo {
  position: relative;
  width: 100%;
  background: #d8cfbf;
  line-height: 0;
}
.polaroid__photo img {
  display: block;
  width: 100%;
  height: auto;
  filter: contrast(0.95) saturate(0.88);
}

.polaroid__caption {
  padding-top: 3px;
  font-family: var(--font-hand);
  font-size: var(--caption-size, 22px);
  line-height: 1.2;
  color: var(--ink-mid);
  text-align: center;
}

/* Polaroid-пин и галочка-резолв. Сам пин стилизован общим
   блоком выше (.card__pin, .polaroid__pin). Здесь только
   галочка. */
.polaroid--resolved { background: #fdf7e1; }
.polaroid__check {
  position: absolute;
  top: -12px; right: -10px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: #2e7d32;
  box-shadow: 0 4px 10px rgba(0,0,0,.3);
  z-index: 3;
}
.polaroid__check::after {
  content: "";
  position: absolute;
  top: 7px; left: 10px;
  width: 6px; height: 13px;
  border: solid #fff;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
}

/* Стаггер появления (зеркалит поведение .card в 10.1). */
.scene:not(.is-active) .polaroid {
  opacity: 0;
  transform: rotate(var(--rot, -4deg)) translateY(-14px);
}
.scene.is-active .polaroid {
  opacity: 1;
  transform: rotate(var(--rot, -4deg));
  transition:
    opacity   620ms var(--ease-out),
    transform 620ms var(--ease-out);
}

/* Записка от руки.
   Картинку реальной бумаги передаём инлайн через --note-bg
   (см. HTML: style="--note-bg: url('…')"). Если переменная не
   задана — fallback на старый CSS-узор разлиновки. */
.card--note {
  background-color: var(--paper-cream);
  background-image: var(--note-bg,
    repeating-linear-gradient(transparent 0 28px, rgba(74, 58, 40, 0.18) 28px 29px));
  background-size: contain;
  background-position: center center;
  background-repeat: no-repeat;
  aspect-ratio: 3 / 2;
  font-family: var(--font-hand);
  font-size: 28px;
  line-height: 1.45;
  color: var(--ink-dark);
  padding: 1.4rem 1.1rem 1.2rem;
}
.card__hand { margin: 0; }

/* Папка дела. Реальная sepia-папка передаётся через --folder-bg;
   fallback — CSS-полоска манильского tab сверху. */
.card--folder {
  background-color: transparent;
  background-image: var(--folder-bg,
    linear-gradient(180deg, #d8b87a 0 28px, var(--paper-cream) 28px));
  background-size: contain;
  background-position: center center;
  background-repeat: no-repeat;
  aspect-ratio: 3 / 4;
  padding-top: 2.2rem;
}
.card__heading {
  font-family: var(--font-display-ru);
  font-size: 18px;
  margin: 0 0 0.6rem;
  color: var(--ink-dark);
}
.card__list {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-mid);
}
.card__list li {
  padding: 0.25rem 0;
  border-bottom: 1px dashed rgba(74, 58, 40, 0.3);
}
.card__list li:last-child { border-bottom: 0; }

/* Лист бумаги (сцена 3). Реальная бумага — через --page-bg;
   без неё видна декоративная разлиновка из .card__page-lines. */
.card--page {
  width: 160px;
  aspect-ratio: 3 / 4;
  background-color: var(--paper-cream);
  background-image: var(--page-bg, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  padding: 0;
}
/* Когда задана реальная бумага — скрываем CSS-разлиновку,
   иначе линии накладываются на уже-отрисованную текстуру. */
.card--page[style*="--page-bg"] .card__page-lines { display: none; }
.card__page-lines {
  position: absolute;
  inset: 14px 12px;
  background: repeating-linear-gradient(
    transparent 0 9px,
    rgba(74, 58, 40, 0.4) 9px 10px
  );
}
.card__stamp {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-12deg);
  font-family: var(--font-hand);
  font-size: 2.6rem;
  color: var(--thread-red);
  text-shadow: 0 0 6px rgba(181, 26, 26, 0.4);
}

/* Лёгкое покачивание тревожных карточек */
.scene--3.is-active .card--page,
.scene--3.is-active .card--note {
  animation: wobble 4.4s ease-in-out infinite;
}
.scene--3.is-active .card:nth-of-type(odd)  { animation-delay: -1.2s; }
.scene--3.is-active .card:nth-of-type(even) { animation-delay: -2.6s; }
@keyframes wobble {
  0%, 100% { transform: rotate(var(--rot, 0deg)) translateY(0); }
  50%      { transform: rotate(calc(var(--rot, 0deg) - 1deg)) translateY(2px); }
}

/* Зелёная галочка резолва (сцена 5) */
.card--resolved { background: #fdf7e1; }
.card__check {
  position: absolute;
  top: -12px; right: -10px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: #2e7d32;
  box-shadow: 0 4px 10px rgba(0,0,0,.3);
  z-index: 3;
}
.card__check::after {
  content: "";
  position: absolute;
  top: 7px; left: 10px;
  width: 6px; height: 13px;
  border: solid #fff;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
}

/* ── 10.2 Стол (сцена 2) — иллюстрация на CSS ─────────────── */
.desk {
  position: absolute;
  inset: 0;
}
.desk__lamp-glow {
  position: absolute;
  top: -10%; left: 18%;
  width: 64%; height: 90%;
  background: radial-gradient(ellipse at center, rgba(212, 168, 87, 0.4) 0%, transparent 60%);
  filter: blur(40px);
}
.desk__monitor {
  position: absolute;
  top: 12%; left: 50%;
  width: 420px;
  height: 260px;
  transform: translateX(-50%) perspective(900px) rotateX(28deg);
  background: linear-gradient(180deg, var(--night-screen) 0%, #0a1020 100%);
  border: 8px solid #1a1a1a;
  border-radius: 6px;
  box-shadow: 0 30px 80px rgba(78, 201, 217, 0.2);
}
.desk__monitor::before {
  content: "";
  position: absolute;
  inset: 14% 10%;
  background:
    linear-gradient(transparent 0 4px, var(--night-cyan) 4px 5px),
    linear-gradient(transparent 0 10px, rgba(78,201,217,.3) 10px 11px),
    linear-gradient(transparent 0 18px, var(--night-text-mid) 18px 19px);
  background-size: 100% 8px, 100% 12px, 100% 20px;
  opacity: 0.65;
}

.desk__keyboard {
  position: absolute;
  top: 58%; left: 50%;
  width: 340px;
  height: 64px;
  transform: translateX(-50%);
  background: linear-gradient(180deg, #2a2a2a 0%, #161616 100%);
  border-radius: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,.6);
}
.desk__keyboard::after {
  content: "";
  position: absolute;
  inset: 8px 12px;
  background:
    repeating-linear-gradient(90deg, transparent 0 12px, rgba(255,255,255,0.06) 12px 14px),
    repeating-linear-gradient(0deg,  transparent 0 12px, rgba(255,255,255,0.06) 12px 14px);
  border-radius: 2px;
}

.desk__notebook {
  position: absolute;
  top: 58%; right: 7%;
  width: 190px;
  height: 240px;
  transform: rotate(var(--rot, 0deg));
  background: var(--paper-cream);
  box-shadow: 0 14px 28px rgba(0,0,0,.55);
}
.desk__notebook-lines {
  position: absolute;
  inset: 18px 14px;
  background: repeating-linear-gradient(transparent 0 12px, rgba(74,58,40,.4) 12px 13px);
  display: block;
}

.desk__mug {
  position: absolute;
  top: 62%; left: 7%;
  width: 100px;
  height: 100px;
  background: radial-gradient(circle at 50% 100%, #6b3a2a 0%, #2a140a 70%);
  border-radius: 50%;
  box-shadow:
    0 12px 24px rgba(0,0,0,.65),
    inset 0 0 0 6px #1a0a08,
    inset 0 -10px 0 rgba(0,0,0,.3);
}
.desk__mug::before {
  content: "";
  position: absolute;
  inset: 20%;
  background: radial-gradient(circle, #4a2a1a 0%, #1a0a04 100%);
  border-radius: 50%;
}
.desk__steam {
  position: absolute;
  top: -10%; left: 35%;
  width: 18px; height: 60px;
  background: radial-gradient(ellipse at center, rgba(232, 225, 210, 0.5) 0%, transparent 70%);
  filter: blur(8px);
  animation: steam-rise 3.6s ease-in-out infinite;
}
.desk__steam--2 {
  left: 60%;
  width: 14px;
  animation-delay: 1.4s;
}
@keyframes steam-rise {
  0%   { transform: translateY(0)    scale(1);   opacity: 0; }
  30%  { opacity: 0.85; }
  100% { transform: translateY(-120px) scale(1.6); opacity: 0; }
}

.desk__pen {
  position: absolute;
  top: 76%; left: 32%;
  width: 90px;
  height: 6px;
  background: linear-gradient(90deg, #1a1a1a 0% 70%, var(--night-glow) 70% 100%);
  transform: rotate(-18deg);
  border-radius: 3px;
  box-shadow: 0 4px 8px rgba(0,0,0,.5);
}

.desk__sticky {
  position: absolute;
  top: 22%; right: 12%;
  width: 120px;
  height: 120px;
  transform: rotate(var(--rot, 0deg));
  background: #f4d97a;
  box-shadow: 0 12px 24px rgba(0,0,0,.55);
  padding: 1rem;
  font-family: var(--font-hand);
  font-size: 1.5rem;
  color: var(--ink-dark);
  display: grid;
  place-items: center;
  text-align: center;
  line-height: 1.1;
}

/* ── 10.3 Граф-доска (сцена 4) ────────────────────────────── */
.grid-board {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 680px;
  height: min(360px, 50vh);
}
.grid-board__threads {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  z-index: 1;
}
.grid-board__node {
  position: absolute;
  left: calc((var(--gx) - 1) / 4 * 100%);
  top:  calc((var(--gy) - 1) / 2 * 100%);
  width: 110px;
  height: 110px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  display: grid;
  place-items: center;
  text-align: center;
  background:
    radial-gradient(circle at 50% 50%, rgba(78, 201, 217, 0.18) 0%, transparent 70%),
    rgba(18, 28, 56, 0.78);
  border: 1.5px solid rgba(78, 201, 217, 0.55);
  color: var(--night-text);
  box-shadow:
    0 0 24px rgba(78, 201, 217, 0.28),
    inset 0 0 12px rgba(78, 201, 217, 0.15);
  z-index: 2;
}
.grid-board__node--ai {
  border-color: var(--night-glow);
  background:
    radial-gradient(circle at 50% 50%, rgba(212, 168, 87, 0.22) 0%, transparent 70%),
    rgba(40, 28, 12, 0.78);
  box-shadow:
    0 0 32px rgba(212, 168, 87, 0.5),
    inset 0 0 16px rgba(212, 168, 87, 0.2);
}
.grid-board__label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--night-text-mid);
  display: block;
  margin-bottom: 0.2rem;
}
.grid-board__count {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--night-text);
  line-height: 1;
}
.grid-board__node--ai .grid-board__count {
  color: var(--night-glow);
  animation: ai-pulse 1.8s ease-in-out infinite;
}
@keyframes ai-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.82); }
}

/* ── 10.4 Нити (SVG-paths, общий стиль) ───────────────────── */
.scene__layer--threads { width: 100%; height: 100%; }

.thread {
  fill: none;
  stroke: var(--thread-red);
  stroke-width: 1.8;
  stroke-linecap: round;
  opacity: 0.65;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,0.3));
  stroke-dasharray: 1400;
  stroke-dashoffset: 1400;
  transition: stroke-dashoffset 1500ms var(--ease-out) 280ms;
}
.scene.is-active .thread { stroke-dashoffset: 0; }

.thread--neon {
  stroke: var(--night-cyan);
  filter: drop-shadow(0 0 4px var(--night-cyan));
  opacity: 0.75;
}
.thread--clean {
  stroke: var(--thread-red-soft);
  opacity: 0.55;
}

/* ── 10.4.1 Threads inside props (dynamic JS renderer) ────────
   SVG-слой перенесён внутрь .scene__layer--props сцен 1 и 5:
   тот же transform-родитель и stacking-context, что у карточек.
   • parallax props сдвигает SVG и пины как одно целое — paths
     не нужно пересчитывать на pointermove;
   • DOM-порядок (svg → cards) даёт честный stacking: paper
     карточки закрывает нить там, где они пересекаются, а
     .pin__head закрывает endpoint нити в точке входа в шляпку. */
.scene__layer--props > .scene__layer--threads {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  transform: none;
  pointer-events: none;
  overflow: visible;
}

/* Тройной path: тёмная подложка под основной нитью + красный core
   с лёгкой drop-shadow + dashed highlight как «шёрстка» нашитой
   нити. Отдельный stroke от статичной .thread выше, чтобы не
   наследовать draw-on transition (dashoffset пересчитывался бы
   при каждом ре-рендере). */
.thread-shadow {
  fill: none;
  stroke: rgba(20, 16, 16, 0.34);
  stroke-width: 8;
  stroke-linecap: round;
}
.thread-core {
  fill: none;
  stroke: var(--thread-red);
  stroke-width: 3.2;
  stroke-linecap: round;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,0.3));
}
.thread-highlight {
  fill: none;
  stroke: rgba(255, 170, 170, 0.28);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-dasharray: 2 12;
}

/* Fade-in группы при активации сцены */
.scene__layer--threads [data-thread-render] {
  opacity: 0;
  transition: opacity 600ms var(--ease-out) 240ms;
}
.scene.is-active .scene__layer--threads [data-thread-render] {
  opacity: 1;
}

/* ============ Classified card (сцена 1) ==================== */
@import url('https://fonts.googleapis.com/css2?family=Special+Elite&display=swap');

.classified-card {
  position: fixed;
  top: 50vh;
  left: 50vw;
  transform: translate(-50%, -50%);
  width: min(460px, calc(100vw - 24px));
  height: clamp(420px, 72vh, 620px); /* фиксированная высота — все карточки одинаковы */
  overflow: visible; /* пины торчат за верхний край */
  background: #f2ede0;
  border: 1px solid #c4b898;
  padding: clamp(14px, 4vw, 28px) clamp(12px, 4vw, 32px);
  font-family: 'Special Elite', monospace;
  z-index: 60;
  display: flex;
  flex-direction: column;
}

.classified-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 27px,
    rgba(60, 40, 20, 0.07) 27px,
    rgba(60, 40, 20, 0.07) 28px
  );
  pointer-events: none;
}

.classified-card__hole {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--board-cork);
  border: 1px solid var(--board-cork-dark);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.3);
}

.classified-card__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 14px;
  margin-top: 6px;
}

.classified-card__meta {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: #5a4a38;
  line-height: 1.7;
}

.classified-card__status { color: #8b1a1a; }

.classified-card__stamp {
  font-family: var(--font-display);
  font-size: 20px;
  letter-spacing: 0.15em;
  color: #8b1a1a;
  border: 3px solid #8b1a1a;
  padding: 2px 10px;
  transform: rotate(3deg);
  opacity: 0.85;
  line-height: 1;
  flex-shrink: 0;
}

.classified-card__title-row {
  margin-bottom: 16px;
  border-bottom: 1.5px solid #8b1a1a;
  padding-bottom: 10px;
}

.classified-card__title {
  font-family: var(--font-display-ru);
  font-size: 22px;
  letter-spacing: 0.04em;
  color: #1a1208;
  line-height: 1;
}

.classified-card__subtitle {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: #6a5a48;
  margin-top: 4px;
}

.classified-card__lines {
  display: flex;
  flex-direction: column;
  gap: 9px;
  flex: 1; /* занимает всё свободное место → footer всегда внизу */
  justify-content: space-evenly; /* строки равномерно распределяются */
}

.classified-card__line {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12px;
  color: #2a1e10;
  line-height: 1.5;
}

.classified-card__num {
  color: #6a5a48;
  font-size: 10px;
  letter-spacing: 0.06em;
  flex-shrink: 0;
}

.classified-card__sep {
  border: none;
  border-top: 1px dashed #c4b080;
  margin: 12px 0;
}

.classified-card__footer {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
}

.classified-card__sig {
  font-size: 10px;
  color: #6a5a48;
  line-height: 1.8;
}

.classified-card__sig-line {
  display: block;
  border-top: 1px solid #8a7a68;
  margin-top: 3px;
  padding-top: 2px;
  font-size: 9px;
  letter-spacing: 0.06em;
}

.classified-card__page {
  font-size: 10px;
  color: #8a7a68;
  text-align: right;
  line-height: 1.8;
}

.classified-card__fold {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 24px;
  height: 24px;
  background: linear-gradient(225deg, var(--board-cork) 50%, #e0d8c8 50%);
}

.classified-card__cta {
  margin-top: 18px;
  display: flex;
  justify-content: center;
}

/* Redact spans — переиспользуемый класс */
.redact {
  display: inline-block;
  background: #1a1208;
  height: 13px;
  vertical-align: middle;
  border-radius: 1px;
  position: relative;
  top: -1px;
}

/* CTA кнопка — flat, Special Elite, минимальное скругление */
.cta--classified {
  font-family: 'Special Elite', monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 5px 14px;
  border-radius: 2px;
  background: #2a5c3a;
  color: #dff0e6;
  border: 1px solid #1a3d26;
  box-shadow: none;
  text-decoration: none;
  display: inline-block;
  transition: background 120ms, color 120ms;
}
.cta--classified:hover { background: #1e4429; }
.cta--classified:active { background: #132d1a; }

/* ── Пины на .classified-card строятся через landing-pan.js ──
   Используют те же классы pin-shadow-el / pin-base-el / pin-head-el
   что и обычные пины сцен. position:fixed задаётся инлайн в JS.  */

/* ── Кнопка личного кабинета — верхний левый угол каждой сцены ─
   position:fixed, всегда видна поверх всего.
   Тёмная, лаконичная — не конкурирует с CTA на карточке.      */
.btn-ui {
  font-family: 'Special Elite', monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 5px 14px;
  border-radius: 2px;
  background: rgba(20, 12, 6, 0.80);
  color: rgba(232, 225, 210, 0.95);
  border: 1px solid rgba(232, 225, 210, 0.25);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: background 120ms;
  white-space: nowrap;
  display: inline-block;
}

.btn-ui:hover {
  background: rgba(20, 12, 6, 0.95);
}

.btn-cabinet {
  position: fixed;
  top: clamp(12px, 2vh, 20px);
  left: clamp(14px, 2vw, 24px);
  z-index: 200;
}

/* ── Адаптив только для .classified-card ─────────────────────
   Ширина адаптируется через min() в базовом правиле выше.
   Здесь только уменьшаем шрифты и отступы на телефонах.      */

@media (max-width: 500px) {
  .classified-card__title { font-size: 17px; }
  .classified-card__line  { font-size: 11px; gap: 4px; }
  .classified-card__lines { gap: 6px; }
  .classified-card__stamp { font-size: 15px; padding: 2px 7px; }
  .cta--classified        { font-size: 12px; padding: 10px 20px; }
  .classified-card__cta   { margin-top: 12px; }
  .classified-card__sep   { margin: 8px 0; }
}

@media (max-width: 400px) {
  .classified-card__title  { font-size: 14px; }
  .classified-card__line   { font-size: 10px; }
  .classified-card__lines  { gap: 5px; }
  .classified-card__meta   { font-size: 9px; }
  .classified-card__stamp  { font-size: 13px; padding: 1px 6px; border-width: 2px; }
  .classified-card__top    { margin-bottom: 8px; }
  .classified-card__title-row { margin-bottom: 8px; padding-bottom: 6px; }
  .cta--classified         { font-size: 11px; padding: 8px 14px; }
  .classified-card__cta    { margin-top: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .scene__layer--threads [data-thread-render] {
    transition: none;
    opacity: 1;
  }
}

/* ── 10.4.2 Folder-карточка без текстового содержимого ────────
   У .card--folder в сцене 1 теперь только пин + sticker, без
   .card__heading/.card__list — фон-фотография папки сама несёт
   смысл. Без явного aspect-ratio такой контейнер схлопнулся бы
   до padding-высоты. */
.card--folder:not(:has(.card__heading)) {
  aspect-ratio: 4 / 5;
  padding: 0;
}

/* ── 10.4.3 Sticker-наклейка поверх folder-карточки ───────────
   Маленький красный стикер с надписью, повёрнут — как наклеенный
   от руки маркер «Подозреваемые». Сидит в верхнем углу папки,
   z-index поднят над фоном карточки, чтобы текст читался поверх. */
.card__sticker {
  position: absolute;
  top: -16px;
  right: -22px;
  width: 96px;
  height: 96px;
  background-image: url("assets/props/stickers/sticker-red-03.webp");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  display: grid;
  place-items: center;
  text-align: center;
  font-family: var(--font-hand);
  color: #fff8e7;
  font-size: 0.92rem;
  line-height: 1.05;
  letter-spacing: 0.01em;
  transform: rotate(-12deg);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 6px rgba(60, 0, 0, 0.4);
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.35));
  pointer-events: none;
  z-index: 2;
  padding: 0 8px;
  box-sizing: border-box;
}

/* ── 10.5 Copy: заголовки, подзаголовки, чаптеры ──────────── */
.copy {
  position: absolute;
  max-width: 620px;
  padding: 1.2rem;
}
.copy--center {
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}
.copy--top-left  { top: 9%; left: 6%;  text-align: left; }
.copy--top-right { top: 9%; right: 6%; text-align: right; }

.copy__stamp,
.copy__chapter {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  color: var(--thread-red);
  text-transform: uppercase;
  margin: 0 0 1.2rem;
}
.copy__stamp {
  border: 2px solid var(--thread-red);
  display: inline-block;
  padding: 0.2rem 0.6rem;
}
.copy--dark .copy__chapter { color: var(--night-glow); }

.copy__headline {
  font-family: var(--font-display-ru);
  font-weight: 400;
  font-size: 3rem;
  line-height: 1.04;
  margin: 0 0 1.2rem;
  color: var(--ink-dark);
  letter-spacing: -0.01em;
}
.copy--dark .copy__headline { color: var(--night-text); }

.copy__accent {
  font-family: var(--font-hand);
  font-weight: 400;
  font-size: 1.08em;
  color: var(--thread-red-dark);
  display: inline-block;
  transform: rotate(-1deg);
}
.copy--dark .copy__accent { color: var(--night-glow); }
.copy__accent--anxious {
  color: var(--thread-red);
  text-decoration: underline wavy var(--thread-red-soft);
  text-underline-offset: 6px;
}

.copy__sub {
  font-size: 1.1rem;
  color: var(--ink-mid);
  margin: 0;
  max-width: 540px;
}
.copy--center .copy__sub { margin-left: auto; margin-right: auto; }
.copy--top-right .copy__sub { margin-left: auto; }
.copy--dark .copy__sub { color: var(--night-text-mid); }

.copy__cta {
  display: flex;
  gap: 0.8rem;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 2rem;
}

/* ── 10.6 CTA ─────────────────────────────────────────────── */
.cta {
  display: inline-block;
  padding: 0.85rem 1.6rem;
  border-radius: 4px;
  text-decoration: none;
  font-weight: 600;
  letter-spacing: 0.02em;
  transition:
    transform var(--t-fast) var(--ease-out),
    box-shadow var(--t-fast) var(--ease-out),
    background-color var(--t-fast) var(--ease-out);
}
.cta--primary {
  background: var(--ink-dark);
  color: var(--paper-cream);
  box-shadow: 0 4px 0 var(--thread-red-dark);
}
.cta--primary:hover  { transform: translateY(-2px); box-shadow: 0 6px 0 var(--thread-red-dark); }
.cta--primary:active { transform: translateY(1px);  box-shadow: 0 2px 0 var(--thread-red-dark); }

.cta--ghost {
  background: transparent;
  color: var(--ink-dark);
  border: 1.5px solid var(--ink-mid);
}
.cta--ghost:hover { background: rgba(31, 22, 16, 0.06); }

.prop-img {
  position: absolute;
  left: var(--x, 50%);
  top:  var(--y, 50%);
  width: var(--w, 20%);
  height: auto;
  transform: rotate(var(--rot, 0deg));
  transform-origin: top center;
  transition: transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out);
  filter: drop-shadow(0 8px 16px rgba(28, 18, 8, 0.4));
}

.prop-img img {
  display: block;
  width: 100%;
  height: auto;
  mix-blend-mode: multiply;
}

.prop-img__text {
  position: absolute;
  top: var(--text-top, 38%);
  left: var(--text-left, 12%);
  width: var(--text-w, 76%);
  margin: 0;
  font-family: var(--font-hand);
  font-size: var(--text-size, 18px);
  line-height: 1.55;
  color: var(--ink-dark);
  pointer-events: none;
}

.prop-img:hover {
  transform: rotate(0deg) translateY(-4px) scale(1.03);
  filter: drop-shadow(0 16px 28px rgba(28, 18, 8, 0.5));
  z-index: 15;
}

.prop-img img {
  display: block;
  width: 100%;
  height: auto;
}

/* Стаггер появления */
.scene:not(.is-active) .prop-img {
  opacity: 0;
  transform: rotate(var(--rot, 0deg)) translateY(-14px);
}

.scene.is-active .prop-img {
  opacity: 1;
  transform: rotate(var(--rot, 0deg));
  transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
}



/* ============ 11. Side-nav и scroll-hint =================== */
.scene-nav {
  position: fixed;
  right: 1.4rem;
  top: 50vh;     /* fallback для старых браузеров */
  top: 50dvh;    /* dvh = dynamic viewport height, не прыгает при появлении адресной строки */
  transform: translateY(-50%);
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.scene-nav__dot {
  position: relative;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  border: 1.5px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
  transition: transform 240ms var(--ease-out),
              background-color 240ms var(--ease-out);
}
.scene-nav__dot:hover { transform: scale(1.25); }
.scene-nav__dot.is-active {
  background: var(--thread-red);
  border-color: var(--thread-red);
  transform: scale(1.35);
  box-shadow: 0 1px 6px rgba(0,0,0,0.5);
}

.scene-nav__label {
  position: absolute;
  right: 26px; top: 50%;
  transform: translateY(-50%) translateX(6px);
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  padding: 0.2rem 0.55rem;
  font-size: 0.74rem;
  font-family: var(--font-mono);
  letter-spacing: 0.05em;
  border-radius: 3px;
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.scene-nav__dot:hover .scene-nav__label,
.scene-nav__dot:focus-visible .scene-nav__label {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Точки одинаковы на всех сценах — белые с тенью, читаются на любом фоне */

.scroll-hint {
  position: fixed;
  bottom: clamp(1rem, 3vh, 1.8rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
  transition: opacity 400ms var(--ease-out);
}

/* label скрыт — только стрелка */
.scroll-hint__label { display: none; }

.scroll-hint__arrow {
  font-size: 1.6rem;
  line-height: 1;
  display: block;
  animation: scroll-bounce 1.6s ease-in-out infinite;
  /* По умолчанию — белая с тенью (тёмные сцены 2, 4) */
  color: #fff;
  text-shadow:
    0 1px 6px rgba(0,0,0,0.8),
    0 0 16px rgba(0,0,0,0.5);
}

/* Сцены 1, 5 — светлый пробковый фон: белая стрелка с тёмной тенью */
body[data-active-scene="1"] .scroll-hint__arrow,
body[data-active-scene="5"] .scroll-hint__arrow {
  color: #fff;
  text-shadow:
    0 1px 4px rgba(20,10,0,0.85),
    0 2px 8px rgba(20,10,0,0.6);
}

/* Сцена 3 — светлый тревожный фон: чёрная стрелка с белой подсветкой */
body[data-active-scene="3"] .scroll-hint__arrow {
  color: #1a120a;
  text-shadow:
    0 0 6px rgba(255,248,230,0.95),
    0 1px 3px rgba(255,248,230,0.8),
    0 -1px 3px rgba(255,248,230,0.8);
}

@keyframes scroll-bounce {
  0%, 100% { transform: translateY(0);   opacity: 0.75; }
  50%      { transform: translateY(6px); opacity: 1; }
}
.scroll-hint.is-hidden { opacity: 0; }

/* ============ 12. Адаптив и motion ========================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 200ms !important;
  }
  .thread { stroke-dasharray: none; stroke-dashoffset: 0; }
}

/* ============ 14. Pin-anchor — якоря пинов на classified-card =
   .pin-anchor — невидимые 1×1 точки, размещённые абсолютно на
   верхнем крае карточки. JS читает их BoundingClientRect так же,
   как читает верх любой другой карточки.
   --pin-anchor-x задаётся инлайн: левый пин — около 25% ширины,
   правый — около 75%.                                           */
.classified-card {
  position: fixed; /* явно, чтобы pin-anchor считались корректно */
  /* width задана в основном блоке выше */
}

.pin-anchor {
  position: absolute;
  top: 0;
  left: var(--pa-x, 25%);
  width: 1px;
  height: 1px;
  pointer-events: none;
  display: block;
}
.pin-anchor--right {
  --pa-x: 75%;
}

/* ============ 15. Pan Mode — для узких окон и мобильных ======
   Включается автоматически ниже --pan-breakpoint (880px по
   умолчанию). В pan-mode:
     • сцена растягивается до --pan-w × --pan-h (больше viewport)
     • карточки НЕ масштабируются (сохраняют desktop-размеры)
     • пользователь перетаскивает содержимое мышью/тачем
     • инерция добавляется через CSS scroll-behavior на внутренний
       контейнер, либо через JS momentum (см. landing-detective.js)
     • scroll-hint меняется на pan-hint
     • по умолчанию сцена центрирована на classified-card          */

:root {
  --pan-w: 1400px;   /* виртуальная ширина доски в pan-mode */
  --pan-h: 900px;    /* виртуальная высота */
}

/* Обёртка pan — внутри .cinema-stage, overflow:hidden уже есть */
.scene__pan {
  position: absolute;
  inset: 0;
  /* Курсор: grab при наведении, grabbing при зажатой кнопке */
  cursor: grab;
  touch-action: none;  /* блокируем scroll браузера, обрабатываем сами */
  overflow: hidden;
  user-select: none;
}
.scene__pan.is-panning {
  cursor: grabbing;
}

/* Виртуальный холст — перемещается JS через transform: translate */
.scene__pan-canvas {
  position: absolute;
  width: var(--pan-w);
  height: var(--pan-h);
  top: 0; left: 0;
  will-change: transform;
  /* Начальная позиция центрирует холст в viewport */
  transform: translate(var(--pan-tx, 0px), var(--pan-ty, 0px));
}

/* В pan-mode отключаем % позиционирование карточек через сцену —
   теперь --x / --y работают на холсте, а не на viewport.
   Размеры карточек фиксированы (не clamp от vw). */
.scene.pan-active .scene__layer--bg,
.scene.pan-active .scene__layer--ambient {
  width: var(--pan-w);
  height: var(--pan-h);
  background-size: cover;
}
.scene.pan-active .scene__layer--props,
.scene.pan-active .scene__layer--threads,
.scene.pan-active .scene__layer--content,
.scene.pan-active .pin-layer,
.scene.pan-active .scene-threads-svg {
  width: var(--pan-w);
  height: var(--pan-h);
}

/* Pan-hint — иконка «перетащи» вместо «скролл» */
.pan-hint {
  position: fixed;
  bottom: clamp(1rem, 3vh, 2rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(26, 18, 10, 0.55);
  pointer-events: none;
  opacity: 0;
  transition: opacity 400ms var(--ease-out);
}
body.pan-mode .pan-hint { opacity: 1; }
body.pan-mode .scroll-hint { opacity: 0; }
body[data-tone="dark"] .pan-hint { color: rgba(232, 225, 210, 0.55); }

.pan-hint__icon {
  font-size: 1.4rem;
  animation: pan-hint-drift 2.4s ease-in-out infinite;
}
@keyframes pan-hint-drift {
  0%, 100% { transform: translate(0, 0); }
  25%       { transform: translate(4px, -3px); }
  75%       { transform: translate(-4px, 3px); }
}

/* Pan edge-vignette — подсказывает что доска обрезана */
.pan-edge {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 90;
  opacity: 0;
  transition: opacity 300ms var(--ease-out);
  background:
    linear-gradient(to right,  rgba(28,18,8,0.18) 0%, transparent 12%),
    linear-gradient(to left,   rgba(28,18,8,0.18) 0%, transparent 12%),
    linear-gradient(to bottom, rgba(28,18,8,0.18) 0%, transparent 10%),
    linear-gradient(to top,    rgba(28,18,8,0.18) 0%, transparent 10%);
}
body.pan-mode .pan-edge { opacity: 1; }
body[data-tone="dark"] .pan-edge {
  background:
    linear-gradient(to right,  rgba(0,0,0,0.3) 0%, transparent 12%),
    linear-gradient(to left,   rgba(0,0,0,0.3) 0%, transparent 12%),
    linear-gradient(to bottom, rgba(0,0,0,0.3) 0%, transparent 10%),
    linear-gradient(to top,    rgba(0,0,0,0.3) 0%, transparent 10%);
}

/* На desktop pan-mode не нужен */
@media (min-width: 881px) {
  body.pan-mode { /* переопределяется JS при необходимости */ }
  .pan-hint, .pan-edge { display: none; }
  .scene__pan { all: unset; position: absolute; inset: 0; cursor: default; }
  .scene__pan-canvas { all: unset; position: absolute; inset: 0; width: 100%; height: 100%; transform: none; }
}

/* ============ 13. Заметка для разработчика =================
   Все слои сцены сохраняют CSS-fallback'и: если .webp недоступен,
   рендер не падает (vignette + base-color). Карточки props
   получают реальную графику через инлайн-переменные в HTML,
   без правки CSS (см. style="…--note-bg/--folder-bg/--page-bg…").

   ── Фоны сцен (background-image внутри .scene__layer--bg) ────
     .scene--1 → assets/board/board-base.webp     (479 KB, light cork)
     .scene--2 → assets/board/board-wear-03.webp  (145 KB, dark desk)
     .scene--3 → assets/board/board-wear-02.webp  (277 KB, anxious)
     .scene--4 → assets/board/board-wear-04.webp  (49 KB,  dark graph)
     .scene--5 → assets/board/board-wear-01.webp  (392 KB, resolved)
     все .scene__layer--ambient — слот пуст, под будущий grain.

   ── Polaroid (Scene 1 и Scene 5, всего 4 шт) ─────────────────
   Компонент .polaroid использует <img>; источник прописан
   прямо в HTML, alt-текст обязателен.
     Scene 1 «Идея»       → props/photos/photo-detective-table-01.webp
     Scene 1 «Сцена 1»    → props/photos/photo-accident-01.webp
     Scene 5 «Начало»     → props/photos/photo-alley-shadow-01.webp
     Scene 5 «Кульминация» → props/photos/photo-detective-board-01.webp

   ── Notes / Folders / Pages — инлайн-переменные ──────────────
   Каждая карточка задаёт свой ассет через style:
     --note-bg   → backgroud для .card--note
     --folder-bg → background для .card--folder
     --page-bg   → background для .card--page
   Если переменная не задана — действует CSS-fallback (см. 10.1).

   Текущий проводной маппинг:
     Scene 1 note   «Кто? Зачем?…»     → notes/note-lined-01.webp
     Scene 1 folder «Дело №001»         → folders/folder-sepia-01.webp
     Scene 3 page  #1 (?? stamp)        → papers/paper-torn-01.webp
     Scene 3 page  #2                   → papers/paper-page-01.webp
     Scene 3 note  «Где улика…»         → notes/memo-card-01.webp
     Scene 3 page  #3 (!  stamp)        → papers/paper-unfolded-01.webp
     Scene 3 note  «Что знает…»         → notes/note-lined-02.webp
     Scene 3 page  #4                   → papers/paper-manila-01.webp
     Scene 3 page  #5 (?? stamp)        → papers/paper-page-01.webp
     Scene 3 note  «Ружьё…»             → notes/note-grid-01.webp
     Scene 5 folder «Финал»             → folders/folder-sepia-02.webp
     Scene 5 folder «Рукопись»          → folders/folder-sepia-03.webp

   ── Не задействовано (резерв в библиотеке) ───────────────────
     photos/photo-cellar-door-01.webp
     photos/photo-graveyard-01.webp
     photos/photo-outline-of-corpse-01.webp
     folders/folder-dark-01.webp
     folders/envelope-string-01.webp
     stickers/* (3 файла)
     desk/* (4 файла — дубль board/* по контенту)
   ============================================================ */

/* ── Pan-mode: guard для pointer-events и параллакса ─────────
   Когда pan-mode активен, pointer события на props-слое отключаем
   (пан-холст перехватывает их сам), но ссылки и кнопки остаются
   кликабельными.                                               */
body.pan-mode .scene__layer--props {
  pointer-events: none;
}
body.pan-mode .scene__layer--props a,
body.pan-mode .scene__layer--props button {
  pointer-events: auto;
}