/* Список — второй вид тех же работ, для Telegram и вообще для чтения.
   Общий чёрный фон и Inter из base.css; своих цветов не заводит.

   Отличие от сцены принципиальное: тут страница действительно прокручивается.
   В base.css у html/body стоит overflow: hidden — прокрутка страницы там
   отдана зуму сцены. Класс list-mode на body возвращает её обратно, ровно
   на время, пока список открыт. */

/* Прокручивается сам .list — фиксированный слой поверх сцены; body и html
   остаются нескроллящимися, как в base.css. Так сцена под списком не
   уезжает и возвращается в той же точке, где её оставили. */

.list {
  position: fixed;
  inset: 0;
  z-index: 40;                   /* над сценой, под лайтбоксом и чатом */
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--bg);
  -webkit-overflow-scrolling: touch;
  /* Внутри Telegram потягивание вниз на самом верху закрывает WebApp.
     Свайп мы не отменяем — это нативный жест оболочки, из веба им не
     управляют; но цепочку прокрутки обрываем, чтобы жест, начатый внутри
     ленты или списка, не всплывал наружу лишний раз. */
  overscroll-behavior-y: contain;
  /* Снизу — место под закреплённую строку контактов: она лежит поверх
     списка, и без запаса последний заказчик уезжал бы ей под низ. */
  padding: calc(var(--pad) + env(safe-area-inset-top))
           var(--pad)
           calc(var(--pad) + var(--contacts-clear));
  /* Список читают, а не таскают: запрет выделения из base.css тут снимаем —
     адрес почты и название работодателя должны копироваться. */
  user-select: text;
  -webkit-user-select: text;
}

/* ── шапка: имя автора и чем он занимается ──────────────────────────── */

.list-head {
  max-width: 42rem;
  margin: 0 auto;
  padding: clamp(24px, 8vh, 72px) 0 clamp(28px, 7vh, 60px);
}

.list-name {
  margin: 0 0 1.1em;
  font-size: clamp(30px, 8.5vw, 52px);
  font-weight: 400;
  letter-spacing: -.02em;
  line-height: 1.05;
}

/* ── строки описания ─────────────────────────────────────────────────
   Разметка общая с ярлыками сцены (.cyc из scene.css отвечает за саму
   анимацию смены фразы), здесь только кегль и раскладка строки. */

.list-lines {
  display: flex;
  flex-direction: column;
  gap: .5em;
  color: var(--fg-dim);
  font-size: clamp(13px, 3.4vw, 15px);
  line-height: 1.35;
}

.list-lines-root {
  font-size: clamp(13px, 3.6vw, 16px);
}

/* Строка описания: подпись группы сверху, содержимое под ней.
 *
 *  Раньше тут стоял flex-wrap: wrap, и подпись с пунктами делили одну
 *  строку — перенос случался, только когда не влезало. Короткий список
 *  («A/B Testing, CustDev, CJM») оставался справа от заголовка, длинный
 *  уезжал вниз, и колонка выглядела собранной наугад. Раскладка не должна
 *  зависеть от длины текста: подпись всегда сверху. */
.list-line {
  display: flex;
  flex-direction: column;
  gap: .15em;
}

/* Подпись группы — тише содержимого: она называет раздел, а читают
   то, что под ней. */
.list-line-label {
  color: var(--fg-mute);
}

/* Статичная строка читается наравне с перечислениями: это такой же факт,
   а не сноска под ним. */
.list-line-text { color: var(--fg); }

/* Исключение — чем занимается компания. У заказчика статичная строка —
   это род его деятельности («Салон итальянской мебели»), фон для главного:
   что для него сделано. Белым она спорила с этим перечислением за внимание,
   хотя читают строку ниже. Приглушаем до серого — порядок чтения
   восстанавливается: имя, чем занимаются, что сделано. */
.list-item .list-line-text { color: var(--fg-dim); }

/* Перечисление того, чем занимался: в сцене крутится по одному пункту,
   здесь напечатано целиком через запятую. Белым — это главное, что
   читают в строке, и оно должно весить столько же, сколько соседние
   перечисления, а не выглядеть примечанием. */
.list-line-items {
  color: var(--fg);
  min-width: 0;
}

/* ── работодатели ────────────────────────────────────────────────────── */

.list-items {
  max-width: 42rem;
  margin: 0 auto;
}

/* Разделителей между заказчиками нет: линия через весь экран режет список
   на карточки и спорит с чёрной пустотой, на которой всё держится. Границу
   держит воздух — отступ между блоками больше, чем между строками внутри
   блока, и группировка читается сама. */
.list-item {
  padding: clamp(22px, 5.5vw, 34px) 0;
}

.list-item-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  width: 100%;
  margin-bottom: .55em;
  padding: 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  /* Тап по заголовку — цель размером с палец: заголовок и есть кнопка
     раскрытия, отдельной иконки-мишени нет. */
  min-height: 44px;
  -webkit-tap-highlight-color: transparent;
}

div.list-item-head { cursor: default; }   /* кластер без работ не раскрывается */

.list-title {
  font-size: clamp(20px, 5.4vw, 27px);
  font-weight: 400;
  letter-spacing: -.01em;
  /* Название заказчика не ломаем по словам — «Viner / Design / Group»
     читается как три слова, а не как имя (то же правило в сцене). */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.list-chev {
  flex: none;
  width: 11px;
  height: 11px;
  margin-right: 2px;
  border-right: 1.5px solid var(--fg-dim);
  border-bottom: 1.5px solid var(--fg-dim);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .3s cubic-bezier(.4, 0, .2, 1), border-color .2s ease;
}

.list-item.is-open .list-chev {
  transform: rotate(-135deg) translate(-3px, -3px);
  border-color: var(--fg);
}

/* ── гармошка ─────────────────────────────────────────────────────────
   Высоту анимируем через max-height: height: auto не интерполируется,
   а считать точный height джаваскриптом значит пересчитывать его на каждый
   resize и на каждую догрузившуюся картинку. Значение — заведомо больше
   реальной высоты ленты; скорость раскрытия от этого не зависит, потому
   что переход идёт по фактической высоте содержимого до предела. */
.list-panel {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height .42s cubic-bezier(.4, 0, .2, 1), opacity .3s ease;
}

.list-item.is-open .list-panel {
  /* Больше, чем реальная высота полосы (BAND_H ≤ 520 + отступы): предел
     только ограничивает переход, а не задаёт размер. Занижение обрезало бы
     ленту, поэтому запас взят с избытком. */
  max-height: 680px;
  opacity: 1;
}

/* ── лента работ ──────────────────────────────────────────────────────
   Не полка с превью, а кусок пространства: карточки висят на разной
   глубине, разного размера и едут с разной скоростью (раскладка и
   параллакс — в buildStrip, js/list.js). Отсюда высокая полоса: глубине
   нужно место по вертикали, иначе разница планов не читается.

   Прокрутка родная, overflow-x: жест внутри скролл-контейнера Telegram
   не перехватывает — он отбирает только потягивание от края экрана.
   Самописная карусель тут была бы хуже во всём. */
.list-strip {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  /* Полоса тянется во всю ширину экрана, а не в колонку текста: работы
     должны уезжать за край, иначе пространство упирается в поля. */
  margin: 0 calc(var(--pad) * -1);
  /* Сверху почти без отступа: полоса начинается сразу под описанием, и
     пустая чёрная лента между текстом и работами читалась бы как разрыв
     блока, а не как воздух. */
  padding: 4px var(--pad) 8px;
  /* Жест внутри ленты не должен доводить до вертикальной прокрутки
     страницы и тем более до жеста закрытия WebApp. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .22) transparent;
}

.list-strip::-webkit-scrollbar { height: 3px; }
.list-strip::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .22);
  border-radius: 2px;
}

/* Трек задаёт скроллируемую ширину; карточки внутри стоят absolute,
   потому что каждая на своей глубине и высоте — потоком это не выразить. */
.list-track {
  position: relative;
}

.list-card {
  position: absolute;
  top: 0;
  left: 0;
  padding: 0;
  border: 0;
  border-radius: 3px;
  overflow: hidden;
  background: #0d0d0d;           /* пока превью не догрузилось */
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: filter .2s ease;
  /* Тень отделяет карточку от соседки там, где они рядом: без неё две
     работы на чёрном сливаются в одну рваную картинку. */
  box-shadow: 0 6px 24px rgba(0, 0, 0, .5);
}

/* will-change здесь НЕ ставим. Он был нужен параллаксу, который переписывал
   transform на каждый кадр прокрутки; теперь карточки стоят неподвижно, и
   постоянный хинт держал бы GPU-текстуру у каждой из полусотни (набор
   выложен трижды) — ровно та беда, из-за которой мигал текст. */

.list-card:active { filter: brightness(.75); }

.list-card img,
.list-card-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Видео лежит поверх постера и проявляется, когда пошло: подмена картинки
   на первый кадр видео иначе читается как моргание. */
.list-card-video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .3s ease;
}

.list-card.has-video .list-card-video { opacity: 1; }

/* Серия: уголок объясняет, что за карточкой не один кадр. Числа больше
   нет — превью само перелистывает слайды, и счётчик дублировал бы то,
   что зритель и так видит. */
.list-card.is-post::after {
  content: '';
  position: absolute;
  right: 7px;
  bottom: 7px;
  width: 14px;
  height: 14px;
  border: 1.5px solid rgba(255, 255, 255, .85);
  border-radius: 2px;
  box-shadow: -4px -4px 0 -1.5px rgba(0, 0, 0, .5),
              -4px -4px 0 0 rgba(255, 255, 255, .55);
  pointer-events: none;
}

/* Подвала со своими контактами у списка больше нет: строка одна на все
   три вида и закреплена в углу (.contacts в base.css). Место под неё
   держит нижний padding .list — см. --contacts-clear выше. */

/* Правило браузера [hidden] { display: none } слабее любого класса, а у
   #chat стоит display: flex — без этой строки скрытая кнопка чата
   продолжала бы висеть поверх списка. Селектор повторяет id, иначе
   не перебить #chat из chat.css. */
#chat[hidden] { display: none; }

/* ── верхняя панель ───────────────────────────────────────────────────
   Выбор вида и услуги. Стоит наверху, потому что низ занят чатом и
   контактами, а третий элемент там отвоёвывал бы пиксели у сцены.

   Живёт снаружи #stage: инверсия mix-blend-mode ей не нужна, а внутри она
   пряталась бы вместе со сценой при переходе в список. */
/* Градиент под панелью: список прокручивается под ней, и заголовок
   заказчика иначе читается сквозь кнопки. Не сплошная плашка — она
   отрезала бы панель от чёрного фона, на котором всё держится. */
.topbar::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(0, 0, 0, .92) 0%,
    rgba(0, 0, 0, .72) 55%,
    rgba(0, 0, 0, 0) 100%);
  pointer-events: none;
}

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: calc(10px + env(safe-area-inset-top)) var(--pad) 22px;
  pointer-events: none;          /* фон панели кликов не ловит */
}

.topbar-nav {
  position: relative;            /* над градиентом ::before */
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(20, 20, 20, .78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  pointer-events: auto;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}

.topbar-nav::-webkit-scrollbar { display: none; }

.topbar-btn {
  flex: none;
  padding: 8px 15px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--fg-dim);
  font-size: 13px;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color .2s ease, background-color .2s ease;
}

.topbar-btn:hover { color: var(--fg); }

/* Активный вид залит, а не подчёркнут: заливка читается на чёрном
   с любого расстояния, тонкая линия под текстом — нет. */
.topbar-btn.is-active {
  background: rgba(255, 255, 255, .12);
  color: var(--fg);
}

.topbar-sep {
  flex: none;
  width: 1px;
  height: 16px;
  margin: 0 4px;
  background: rgba(255, 255, 255, .16);
}

/* ── подсказка ────────────────────────────────────────────────────────
   Выезжает из-под панели и указывает на её пункт: подсказка учит
   пользоваться меню, а не живёт сама по себе. Показывается один раз
   (arkheya:hint-seen), только на телефоне. */
.topbar-hint {
  position: relative;            /* над градиентом ::before */
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: min(100%, 30rem);
  padding: 9px 10px 9px 16px;
  border-radius: 999px;
  background: rgba(238, 238, 238, .95);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: #111;
  font-size: 13px;
  line-height: 1.25;
  pointer-events: auto;
  /* Стартовое состояние — не в @keyframes: подсказка появляется по
     таймеру из JS, и анимация, начатая при загрузке, отыграла бы впустую. */
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity .26s ease, transform .26s cubic-bezier(.4, 0, .2, 1);
}

.topbar-hint.is-in {
  opacity: 1;
  transform: none;
}

.topbar-hint[hidden] { display: none; }

.topbar-hint-close {
  flex: none;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .08);
  color: #111;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.topbar-hint-close:hover { background: rgba(0, 0, 0, .16); }

/* Список начинается ниже панели, иначе имя автора уезжает под неё. */
body.list-mode .list {
  padding-top: calc(var(--pad) + env(safe-area-inset-top) + 52px);
}

@media (prefers-reduced-motion: reduce) {
  .topbar-hint { transition-duration: .01ms; }
}

/* ── услуги: отдельный вид ────────────────────────────────────────────
   Не секция списка, а третий экран наравне с ним и с доской: услуги
   отвечают на другой вопрос — что можно заказать, а не что уже сделано. */
.services {
  position: fixed;
  inset: 0;
  z-index: 40;                   /* над сценой, под панелью и лайтбоксом */
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--bg);
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  /* Снизу — то же место под закреплённые контакты, что и у списка:
     стрелка «Объём, сроки, стоимость» указывает как раз на них. */
  padding: calc(var(--pad) + env(safe-area-inset-top) + 52px)
           var(--pad)
           calc(var(--pad) + var(--contacts-clear));
  user-select: text;
  -webkit-user-select: text;
}

.services[hidden] { display: none; }

.services-head {
  max-width: 42rem;
  margin: 0 auto;
  padding: clamp(24px, 8vh, 72px) 0 clamp(24px, 6vh, 52px);
}

.services-title {
  margin: 0;
  font-size: clamp(30px, 8.5vw, 52px);
  font-weight: 400;
  letter-spacing: -.02em;
  line-height: 1.05;
}

.services-list {
  max-width: 42rem;
  margin: 0 auto;
}

.service {
  padding: clamp(20px, 5vw, 30px) 0;
}

.service-name {
  margin: 0 0 .7em;
  font-size: clamp(17px, 4.6vw, 21px);
  font-weight: 400;
  letter-spacing: -.01em;
}

/* Пункты в строку, а не буллетами: маркированный список на чёрном читается
   как техдокументация, а это витрина умений. Разделитель — тонкая точка:
   держит пункты отдельными, не сливая их в предложение. */
.service-items {
  color: var(--fg-dim);
  font-size: clamp(14px, 3.6vw, 16px);
  line-height: 1.5;
}

/* Подвала у услуг нет: строка «↓ Объём, сроки, стоимость» убрана вместе
   со своими правилами. Контакты закреплены в углу и видны с любого места
   страницы — указывать на них стрелкой значило подписывать очевидное. */


/* Подсвеченный пункт — тот, о котором говорит подсказка.
   Пульсация, а не заливка: заливкой отмечен активный вид, и статичная
   подсветка читалась бы как «список уже открыт». Мигание же однозначно
   значит «сюда», и гаснет вместе с подсказкой. */
.topbar-btn.is-hinted {
  color: var(--fg);
  animation: topbar-hinted 1.5s ease-in-out infinite;
}

@keyframes topbar-hinted {
  0%, 100% { background: rgba(255, 255, 255, 0); }
  50%      { background: rgba(255, 255, 255, .22); }
}

@media (prefers-reduced-motion: reduce) {
  .topbar-btn.is-hinted {
    animation: none;
    background: rgba(255, 255, 255, .18);
  }
}
