/* alexv.ru — страница проекта «Солдат будущего».
   Общая основа (шапка, подвал, поля, ленты) — в site.css; здесь только сама страница.
   Сценарий взят с нынешней страницы: на каждом экране своё спокойное действие. */

/* ---------- 1. Характер проекта ---------- */
.b-prj { background: #000; }
.prj {
  --ink: #f1f1f1;
  --khaki: #9d9a71;   /* цвет названия и слогана */
  --glow: #0057f9;    /* синее свечение названия */
  --star: #0085de;    /* звёзды-метки */
  --star-on: #eaf6ff; /* нажатая звезда */
  /* основной текст страницы проекта: три ступени на общих порогах сайта (1024 и 1280);
     у каждой ступени один интерлиньяж — шаг текста проекта */
  --p-text: 18px;
  --p-s: 23px;
  background: #000;
  color: var(--ink);
  font-family: 'Roboto', 'Helvetica Neue', Arial, sans-serif;
  font-size: var(--p-text);
  font-weight: 300;
  line-height: var(--p-s);
}
@media (min-width: 1024px) { .prj { --p-text: 22px; --p-s: 28px; } }
@media (min-width: 1280px) { .prj { --p-text: 26px; --p-s: 32px; } }

/* колонка текста по центру страницы: не шире 32 кеглей — в строке 6–7 слов */
.prose { max-width: calc(32em + var(--fl) + var(--fr)); margin: 0 auto; padding: 0 var(--fr) 0 var(--fl); }
.prose p { margin: 0 0 var(--p-s); text-wrap: pretty; }
.prose p:last-child { margin-bottom: 0; }
/* вводная фраза перечня: первый пункт идёт сразу за ней, расстояние есть только между пунктами */
.prose p.pre-list { margin-bottom: 0; }
.prose ul { margin: 0 0 var(--p-s); padding: 0; list-style: none; }
.prose li { position: relative; margin-bottom: .45em; padding-left: 1em; }
.prose li::before { content: "•"; position: absolute; left: 0; }
.prose a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em; }
/* Тексты страниц проектов (13.10.2026, переверстка по образцу «Удачи»): заголовок раздела — крупное название сайта
   (34 / 40 / 48 / 56 / 64), полужирное, по левому краю колонки; высказывание, на котором поворачивает сценарий, —
   тем же кеглем обычного начертания; основной текст — текст проекта (18 / 22 / 26). */
.s-h2, .prose p.s-say { margin: 0; font-size: var(--t-big); line-height: 1.05; letter-spacing: -.01em; text-wrap: balance; }
.s-h2 { font-weight: 700; }
.prose p.s-say { font-weight: 400; }
.s-gap { padding-top: calc(2 * var(--p-s)); }
.s-gap-s { padding-top: var(--p-s); }
.s-end { padding-bottom: calc(2 * var(--p-s)); }
@media (min-width: 1024px) { .s-gap { padding-top: calc(3 * var(--p-s)); } .s-end { padding-bottom: calc(3 * var(--p-s)); } }

/* то, что проявляется при прокрутке: без скрипта и при отключённом движении просто видно */
.fx [data-fade], .fx .wave { will-change: opacity; }

/* ---------- 2. Первый экран: две фигуры уходят в затемнение, текст проявляется ---------- */
.s-hero { position: relative; overflow: hidden; }
.s-stage {
  container-type: inline-size;
  position: relative;
  width: var(--sw);
  margin: 0 auto;
  aspect-ratio: 334 / 482;
}
/* ширина сцены — до 1600, как раньше: фигуры того же размера, что на Readymag; картинки фигур целиком,
   поэтому на широком мониторе их спины видны, а не срезаны по краю (решение владельца 13.10.2026) */
.s-hero { --sw: min(100vw, 1600px); }
.s-stage img { position: absolute; height: auto; max-width: none; mix-blend-mode: lighten; }
/* фигуры целиком (без обрезки Readymag): окно прежней обрезки стоит на прежнем месте, остальное уходит за края */
.s-hero-l { left: -36.62%; top: 10.2%; width: 83.32%; }
.s-hero-r { left: 42.09%; top: 10.6%; width: 93.92%; }
.s-title {
  position: absolute;
  left: 0;
  right: 0;
  top: 2%;
  z-index: 1;
  margin: 0;
  color: var(--khaki);
  font-size: 8cqw;
  font-weight: 700;
  line-height: 1.17;
  letter-spacing: .015em;
  text-align: center;
  text-transform: uppercase;
  text-shadow: 0 0 .7em var(--glow);
}
.s-title span { display: block; }
.s-intro { position: relative; z-index: 2; padding-top: 1.5em; }
/* со скриптом текст вступления стоит поверх нижней части фигур — к этому моменту они уже погасли */
.fx .s-intro { margin-top: calc(var(--sw) * -0.47); padding-top: 0; }
@container page (min-width: 640px) {
  .s-stage { aspect-ratio: 1024 / 1222; }
  .s-hero-l { left: var(--l); top: 0.4%; width: var(--w); }
  .s-hero-r { left: var(--l); top: 1.7%; width: var(--w); }
  .s-title { top: 3.7%; font-size: 6.74cqw; }
  .fx .s-intro { margin-top: calc(var(--sw) * -0.373); }
}

/* ---------- 3. Фигура, которая поворачивается при прокрутке, и текст рядом ---------- */
.s-duo { display: grid; row-gap: clamp(20px, 4cqw, 40px); max-width: 1920px; margin: 0 auto; padding: 0 var(--fr) 0 var(--fl); }
.seq { position: relative; width: 100%; max-width: 420px; margin: 0 auto; aspect-ratio: 3 / 4; }
.seq > img { width: 100%; height: 100%; object-fit: contain; }
/* холст с кадрами лежит поверх первой картинки и точно её закрывает; без скрипта остаётся картинка */
.seq > canvas { position: absolute; inset: 0; display: none; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
.seq.drawn > canvas { display: block; }
.s-duo .prose { max-width: 21em; margin: 0 auto; padding: 0; }
@container page (min-width: 800px) {
  .s-duo { grid-template-columns: minmax(0, 46fr) minmax(0, 54fr); column-gap: clamp(24px, 5cqw, 96px); align-items: center; padding-left: max(var(--fl), 6cqw); padding-right: max(var(--fr), 6cqw); }
  .seq { max-width: 660px; margin: 0 0 0 auto; }
  .s-duo .prose { margin: 0; }
}

/* ---------- 4. Фигуры со звёздами: подпись появляется по нажатию и держится,
   пока не нажата другая звезда или фигура не ушла с экрана ---------- */
.fig { background: var(--figbg, #4f4f4f); }
/* фигура со звёздами целиком помещается в экран по высоте: звезда и её подпись видны вместе.
   На низком и широком окне фигура не становится мельче 70 % ширины страницы */
.fig-in { container-type: inline-size; position: relative; max-width: min(1920px, max(calc((100vh - 84px) * var(--r, 1.45)), 70cqw)); margin: 0 auto; }
@supports (height: 100svh) { .fig-in { max-width: min(1920px, max(calc((100svh - 84px) * var(--r, 1.45)), 70cqw)); } }
.fig-in > img { display: block; width: 100%; height: auto; }
.star {
  position: absolute;
  z-index: 2;
  width: clamp(34px, 4.4cqw, 48px); /* зона нажатия больше самой звезды */
  aspect-ratio: 1;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  transform: translate(-50%, -50%);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.star i {
  display: block;
  /* на узком экране звезда на 30 % крупнее, чем по пропорции макета: её лучше видно и по ней проще попасть */
  width: clamp(17px, 1.86cqw, 34px);
  aspect-ratio: 1;
  margin: auto;
  background: var(--star);
  /* синие звёзды в полную силу цвета: при прозрачности 0,6 их было плохо видно (замечание владельца 11.10.2026) */
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  transition: opacity .2s, transform .2s, background-color .2s;
}
/* нажатая звезда «горит»: почти белая, крупнее, с синим свечением вокруг. Остальные звёзды остаются как были —
   их по-прежнему хорошо видно (замечание владельца 11.10.2026: приглушённые соседние звёзды видно плохо) */
.star.on i { background: var(--star-on); transform: scale(1.35); }
.star::before {
  content: "";
  position: absolute;
  inset: -20%;
  background: radial-gradient(circle, color-mix(in srgb, var(--star) 80%, transparent) 0, color-mix(in srgb, var(--star) 34%, transparent) 38%, transparent 70%);
  opacity: 0;
  transition: opacity .2s;
  pointer-events: none;
}
.star.on::before { opacity: 1; }
.star i { position: relative; }
.star:disabled { cursor: default; }
@media (hover: hover) {
  .star:not(:disabled):not(.on):hover i { animation: star-pulse 1.2s ease-out infinite alternate; }
}
/* звёзды сами слабо пульсируют, пока на одну из них не нажали: так видно, что они нажимаются.
   И на телефоне, и на мониторе (решение владельца 11.10.2026) */
.fx .fig:not(.used) .star i,
.fx .helm:not(.used) .star:not(:disabled) i { animation: star-pulse 1.2s ease-out infinite alternate; }
@keyframes star-pulse { to { transform: scale(1.2); } }
.star:focus-visible { outline: 2px solid var(--ink); outline-offset: -6px; }
/* подписи на своих местах рядом с фигурой — когда им хватает ширины */
.cap-s {
  position: absolute;
  z-index: 1;
  margin: 0;
  font-size: clamp(13px, 1.32cqw, 24px);
  font-weight: 600;
  line-height: 1.14;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  min-width: min-content; /* блок подписи не уже её самого длинного слова */
}
.js .cap-s { opacity: 0; transition: opacity .5s; }
.js .cap-s.on { opacity: 1; transition-duration: .1s; }
/* на узком экране подпись показывается строкой под фигурой: рядом со звездой ей не хватает места */
.fig-line { display: none; }
@container page (max-width: 899.98px) {
  .cap-s { position: static; width: auto !important; padding: 0 var(--fr) .7em var(--fl); font-size: var(--t-small); font-weight: 500; line-height: var(--l-small); }
  .cap-s:first-of-type { padding-top: 14px; }
  .js .cap-s { display: none; }
  /* строка подписи: под фигурой отведено место по самой длинной подписи.
     Если фигура выше экрана (телефон горизонтально), строка держится у нижнего края экрана, пока фигура на экране:
     подпись видна сразу после нажатия на звезду. Пустая строка прозрачна и нажатий не перехватывает */
  .js .fig-line {
    display: block;
    position: sticky;
    bottom: env(safe-area-inset-bottom, 0px);
    z-index: 3;
    min-height: 6.4em; /* точную высоту под самую длинную подпись ставит скрипт */
    margin: 0;
    padding: 0;
    font-size: var(--t-small);
    font-weight: 500;
    line-height: var(--l-small);
    background: var(--figbg, #000); /* у нижнего края экрана строка ложится поверх фигуры — ей нужен свой фон */
    opacity: 0;
    pointer-events: none;
    transition: opacity .5s;
  }
  .fig-line-t { display: block; padding: 12px var(--fr) 0 var(--fl); background: var(--figbg, #000); }
  .js .fig-line.on { opacity: 1; transition-duration: .1s; }
}

/* На телефоне фигуры спереди и сзади увеличены: пустые края картинки обрезаны, руки стоят у полей страницы
   (решение владельца 11.10.2026). Где у фигур края, сборка измеряет по самой картинке: --bx, --bw — левый край и ширина,
   --by, --by1 — верх и низ, в долях картинки. Место под подпись ниже отведено по самой длинной подписи */
@container page (max-width: 639.98px) {
  .fig { overflow: hidden; }
  .fig-in {
    --wd: calc((100% - var(--fl) - var(--fr)) / var(--bw, 1));
    width: var(--wd);
    max-width: none;
    margin: calc(16px - var(--by, 0) * var(--wd) / var(--r, 1.45)) 0 calc(4px - (1 - var(--by1, 1)) * var(--wd) / var(--r, 1.45)) calc(var(--fl) - var(--bx, 0) * var(--wd));
  }
}

/* ---------- 5. Крупный план шлема ----------
   Широкий экран: звёзды и подписи проявляются и гаснут по прокрутке, нажимать не нужно;
   звезда «горит», пока её подпись проявлена.
   Узкий экран: как у фигур выше — по нажатию на звезду подпись появляется строкой под картинкой. */
.helm { position: relative; background: var(--figbg, #000); }
.helm-pic { container-type: inline-size; position: relative; max-width: 1920px; margin: 0 auto; }
.helm-pic > img { display: block; width: 100%; height: auto; }
/* без скрипта на узком экране подписи стоят списком под картинкой */
.helm-labs { display: grid; row-gap: .9em; margin: 0; padding: 18px var(--fr) 8px var(--fl); list-style: none; font-size: var(--t-small); font-weight: 500; line-height: var(--l-small); }
@container page (max-width: 899.98px) {
  .js .helm-labs { display: none; }
  /* под подписью шлема остаётся воздух: чёрное поле увеличено, текст не упирается в серое поле ниже */
  .js .helm .fig-line-t { padding-top: 16px; padding-bottom: 22px; }
}
@container page (min-width: 900px) {
  .helm-labs { position: absolute; left: 50%; top: 0; bottom: 0; display: block; width: min(100%, 1920px); padding: 0; transform: translateX(-50%); container-type: inline-size; pointer-events: none; }
  .helm-labs li { position: absolute; left: var(--x); top: var(--y); width: var(--w); min-width: min-content; font-size: clamp(13px, 1.32cqw, 24px); font-weight: 600; line-height: 1.14; }
}

/* ---------- 6. Фигура, которая вращается вслед за мышью (на телефоне — за пальцем) ---------- */
.seq2 { position: relative; overflow: hidden; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.seq2 .seq { width: 124cqw; max-width: none; margin: 0 0 0 -12cqw; }
.seq2 .seq > img { pointer-events: none; }
@container page (min-width: 640px) {
  .seq2 .seq { width: min(68cqw, 1000px); margin: 0 auto; }
}
@media (hover: hover) { .seq2 { cursor: ew-resize; } }
/* подсказка «рука»: только там, где нет мыши; качается три раза и гаснет */
.hand { position: absolute; left: 11%; top: 4%; z-index: 2; display: none; width: clamp(29px, 8.7cqw, 44px); height: auto; opacity: .35; pointer-events: none; }
@media (hover: none) {
  .js .hand { display: block; }
  .fx .hand.go { animation: hand-swing 5s linear both, hand-out .5s linear 5s forwards; }
  .hand.gone { display: none; }
}
@keyframes hand-swing { 0%, 40%, 80% { transform: translateX(0); } 20%, 60%, 100% { transform: translateX(10px); } }
@keyframes hand-out { to { opacity: 0; } }

/* ---------- 7. «Армия-2022» и заключение ---------- */
.s-army { display: block; }
.s-army img { display: block; width: 100%; height: auto; max-height: calc(1920px / 2.503); object-fit: cover; }
.s-closing { container-type: inline-size; position: relative; overflow: hidden; background: #000; }
.closing-bg { position: absolute; left: 50%; bottom: 0; width: min(100%, 1920px); height: auto; transform: translateX(-50%); }
.s-slogan {
  position: relative;
  margin: 0;
  padding-top: clamp(40px, 8cqw, 130px);
  color: var(--khaki);
  font-size: clamp(30px, 6.74cqw, 124px);
  font-weight: 700;
  line-height: 1.17;
  letter-spacing: .015em;
  text-align: center;
  text-transform: uppercase;
  text-shadow: 0 0 .7em var(--glow);
}
.s-slogan span { display: block; }
/* слоган слабо пульсирует: от полной яркости до половины и обратно */
.fx .s-slogan { animation: slogan 1.3s ease-out infinite alternate; }
@keyframes slogan { from { opacity: .5; } to { opacity: 1; } }
.credits {
  position: relative;
  display: grid;
  /* список авторов стоит в колонке текста, по три в ряд (на телефоне по два) */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--p-s) var(--gap);
  max-width: calc(32 * var(--p-text) + var(--fl) + var(--fr));
  margin: 0 auto;
  /* поправка на силу тяготения (правило владельца 12.10.2026): под слоганом воздуха больше, чем над ним, —
     в 1,4 раза; при равных отступах слоган кажется сползшим к списку авторов */
  padding: clamp(56px, 11.2cqw, 182px) var(--fr) clamp(40px, 7cqw, 110px) var(--fl);
}
@media (max-width: 639.98px) { .credits { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* теги проекта под списком авторов: вид работы, заказчик, год — ссылки на главную, где показаны работы с тем же тегом.
   Теги вдвое бледнее имён и отбиты от списка: это не продолжение списка авторов (замечание владельца 11.10.2026) */
.credits:has(+ .tags) { padding-bottom: clamp(28px, 4cqw, 56px); }
.tags { position: relative; display: flex; flex-wrap: wrap; column-gap: 32px; max-width: calc(32 * var(--p-text) + var(--fl) + var(--fr)); margin: 0 auto; padding: 0 var(--fr) clamp(28px, 6cqw, 98px) var(--fl); list-style: none; font-size: var(--t-small); line-height: var(--l-small); }
.tags a { display: block; padding: 12px 0; opacity: .5; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; transition: opacity .33s; }
.tags a:focus-visible { opacity: 1; }
@media (hover: hover) { .tags a:hover { opacity: 1; transition: none; } }
/* роль — мелким приглушённым, имя — основным кеглем сайта (16 / 18 / 20); две роли в одной ячейке разделены полшага */
.credits div { margin: 0; }
.credits dt { opacity: .6; font-size: var(--t-small); line-height: var(--l-small); }
.credits dd { margin: 0 0 calc(var(--p-s) / 2); font-size: var(--t-text); line-height: var(--s); font-weight: 500; }
.credits dd:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .tags a { transition: none; }
  .star:hover i { animation: none; }
}
