/* Названия заказчиков теперь написаны прямо в сцене — на ярлыках, к которым
   сходятся лучи. Меню их дублирует, поэтому в покое оно уходит в фон и не
   спорит с работами; нужно оно только чтобы прыгнуть к заказчику, чей
   ярлык уехал за край экрана. Разворачивается по наведению. */
#menu {
  /* absolute, НЕ fixed. position: fixed сам по себе создаёт стекающий
     контекст (как transform или opacity<1), и mix-blend-mode пунктов
     смешивался бы внутри пустого меню, а не с работами — белое на белом.
     Проверено попиксельно: проба в #stage инвертируется, та же проба
     внутри fixed-меню — нет. Геометрия не меняется: #stage сам fixed
     с inset: 0, так что absolute внутри него — те же координаты экрана.
     (.contacts может оставаться fixed: там blend стоит на самом
     элементе, а сам fixed-элемент наружу смешиваться умеет.) */
  position: absolute;
  left: 0;
  /* Центрируем распоркой сверху и снизу, а не translateY(-50%):
     transform создаёт стекающий контекст, и mix-blend-mode пунктов
     смешивался бы внутри меню, а не с работами под ним. */
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  /* z-index здесь НЕ ставить. position: fixed + z-index делает меню
     самостоятельным стекающим контекстом, и mix-blend-mode пунктов
     смешивается с фоном самого меню, а не с работами под ним — текст
     остаётся белым на белом. Порядок держит место в разметке: меню
     идёт после #world внутри #stage, значит рисуется поверх работ. */
  padding: 18px var(--pad) 18px var(--pad);
  transition: opacity .32s ease;
  /* распорка во всю высоту не должна ловить клики мимо самого списка */
  pointer-events: none;
}
.menu-list, .menu-item, #menu::after { pointer-events: auto; }

/* Пока меню спит, виден только активный заказчик: зритель не теряет,
   где он находится, а сцена не перекрыта списком из десяти строк. */
#menu .menu-item { transition: color .28s ease, transform .28s ease,
                               opacity .32s ease; }
#menu:not(:hover):not(:focus-within):not(.is-awake) .menu-item {
  opacity: 0;
}
#menu:not(:hover):not(:focus-within):not(.is-awake) .menu-item.is-active {
  opacity: 1;
}

/* Полоска-«язычок» у самого края: подсказывает, что здесь что-то есть. */
#menu::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 2px;
  height: 42px;
  margin-top: -21px;
  background: var(--fg-mute);
  opacity: 1;
  transition: opacity .32s ease;
}
#menu:hover::before,
#menu:focus-within::before,
#menu.is-awake::before { opacity: 0; }

/* Зона захвата шире самого меню: целиться в узкую колонку неудобно. */
#menu::after {
  content: '';
  position: absolute;
  inset: -12px -40px -12px 0;
  z-index: -1;
}

.menu-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.menu-item {
  display: block;
  border: 0;
  background: none;
  padding: 3px 0;
  /* Inter, как везде на сайте: моноширинный был здесь единственным чужим
     шрифтом и читался как элемент другого интерфейса. Кегль чуть крупнее
     (Inter при 12px мельче моно того же размера), трекинг слабее —
     моноширинному он был нужен, пропорциональному нет. */
  font-family: var(--font);
  font-size: 13px;
  letter-spacing: .01em;
  line-height: 1.35;
  /* Цвет — чистый белый: exclusion считает от него, и результат равен
     инверсии фона. Приглушённый серый дал бы грязный полутон вместо
     негатива, поэтому «тише» список делает opacity, а не цвет. */
  color: #fff;
  opacity: .55;
  cursor: pointer;
  text-align: left;
  transition: color .28s ease, transform .28s ease;
  transform-origin: left center;
  white-space: nowrap;
  /* Инверсия относительно подложки, как у ярлыков сцены (scene.css):
     на чёрном список белый, на светлой работе — чёрный. Плашка за
     списком тут стояла и была убрана: её край обрывался поперёк работы.
     Тень — слабая страховка на среднесерых кадрах. */
  mix-blend-mode: exclusion;
  /* Собственный composited-слой — ради настоящего Safari: он блендит
     только слой с слоем, и не-композитный пункт смешивался с тайлом
     страницы, а не с работами. Отсюда же было и мигание: transition
     opacity промоутит пункт на время анимации — пока идёт переход,
     слой есть и инверсия видна, в покое слоя нет и она пропадает.
     Контекст возникает на самом пункте, а не на предке — безопасно
     (см. tools/SAFARI-BLEND.md). ВАЖНО: transform здесь занят под сдвиг
     активного пункта, поэтому translateZ дописан в обе ветки —
     одиночное правило transform их перезаписывало бы. */
  transform: translateZ(0);
  text-shadow:
    0 0 3px rgba(0, 0, 0, .35),
    0 0 12px rgba(0, 0, 0, .25);
}

.menu-item:hover { opacity: .8; }

/* Активный кластер: сдвиг вправо читается лучше, чем просто цвет —
   взгляд ловит движение на периферии, не отрываясь от сцены */
.menu-item.is-active {
  opacity: 1;
  transform: translateX(6px) translateZ(0);   /* слой сохраняем, см. .menu-item */
}

.menu-item.is-disabled {
  color: #2e2d2b;
  cursor: default;
  font-style: italic;
}

.menu-item:focus-visible {
  outline: 1px solid var(--fg-dim);
  outline-offset: 3px;
}

/* На телефоне навигации нет вовсе: экран маленький, лента снизу отъедала
   полосу под работами, а названия заказчиков и так написаны в сцене на
   ярлыках. Пробуем, как читается сцена без списка; вернуть — снять
   display: none (прежняя горизонтальная лента лежит в git-истории). */
@media (max-width: 760px) {
  #menu { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  #menu, #menu .menu-item, #menu::before { transition-duration: .01ms; }
}
