/**
 * Каркас истории-витрины: первый экран, на котором стоят чертёж и текст,
 * а прокрутка меняет сцены. Общий для историй-витрин, грузится только на их
 * главных. Цвета, шрифты и отступы задаёт само демо.
 *
 * Переменные:
 *   --story-paper  фон экрана истории, задаёт демо
 *   --story-step   сколько прокрутки уходит на одну сцену
 *   --story-steps  число сцен, ставит разметка
 *   --story-top    высота липкой шапки, --story-lead - плашка демо над
 *                  историей; обе меряет story.js, здесь только оценка
 *                  на время, пока он грузится
 *
 * Два вида:
 *   готовый лист - без скриптов, при reduced motion и если движок не
 *     загрузился (.is-static). Заголовок, готовый чертёж, текст всех сцен
 *     подряд. Ничего не прячется.
 *   живая история - экран стоит, сцены меняются. Раскладка включается
 *     сразу, по has-js из <head>, ещё до загрузки GSAP: иначе страница
 *     сначала показала бы готовый лист, а потом перепрыгнула. Чертёж
 *     проявляется, когда story.js поставил .is-live.
 *
 * Правила живой истории начинаются с длинного префикса
 * `.has-js:not(.js-failed) .story:not(.is-static)` и лежат внутри
 * prefers-reduced-motion: no-preference. Префикс заодно перебивает
 * правила готового листа из файлов демо.
 */

.story {
  --story-top: 4rem;
  --story-lead: 2.5625rem;
  --story-steps: 6;
  --story-step: 80svh;
}

/* На узком экране плашка демо в две строки. */
@media (max-width: 47.99rem) {
  .story {
    --story-lead: 4rem;
  }
}

.story__stage {
  display: grid;
  gap: 2rem;
}

.story__drawing {
  display: block;
  width: 100%;
  height: auto;
}

.story__scenes {
  display: grid;
  gap: 2rem;
  padding: 0;
  list-style: none;
}

/* Подпись и полоса хода нужны только живой истории. */
.story__nav {
  display: none;
}

/*
 * Готовый лист: то, что по ходу истории уходит, в итоговом чертеже не
 * нужно. У живой истории это правило снято, и уход рисует GSAP.
 */
.story:not(.is-live) [data-until] {
  display: none;
}

.story__counter {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.story__bar {
  flex: 1;
  height: 2px;
  overflow: hidden;
  background-color: color-mix(in srgb, currentColor 15%, transparent);
}

.story__bar > span {
  display: block;
  height: 100%;
  background-color: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
}

/* --- Живая история --------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  /*
   * Высота секции - это запас прокрутки: экран плюс шаг на каждую сцену.
   * Сам экран прилипает под шапкой и стоит, пока запас не кончится.
   * Закрепление делает position: sticky, а не GSAP: экран не прыгает,
   * даже если скрипт задумался.
   */
  .has-js:not(.js-failed) .story:not(.is-static) {
    --story-screen: calc(100svh - var(--story-top) - var(--story-lead));
    height: calc(var(--story-screen) + var(--story-steps) * var(--story-step));
    padding-block: 0;
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__stage {
    position: sticky;
    top: var(--story-top);
    height: var(--story-screen);
    overflow: hidden;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(9rem, 1fr) auto auto;
    grid-template-areas:
      "visual"
      "text"
      "nav";
    align-items: stretch;
    gap: 1rem;
    padding-block: 1rem;
    background-color: var(--story-paper, transparent);
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__visual {
    grid-area: visual;
    min-height: 0;
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__drawing {
    width: 100%;
    height: 100%;
  }

  /* Пока движок грузится, чертежа нет: иначе мелькнул бы готовый дом. */
  .has-js:not(.js-failed) .story:not(.is-static):not(.is-live) .story__visual {
    opacity: 0;
  }

  .has-js:not(.js-failed) .story.is-live .story__visual {
    transition: opacity var(--dur-base) var(--ease-out);
  }

  /*
   * Первый текст и все сцены лежат в одной клетке: текст меняется на
   * месте. Клетка высотой с самый длинный текст, на телефоне короткий
   * текст сцены прижат к чертежу, а не висит посередине.
   */
  .has-js:not(.js-failed) .story:not(.is-static) .story__intro,
  .has-js:not(.js-failed) .story:not(.is-static) .story__scenes {
    grid-area: text;
    align-self: start;
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__scenes {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__scene {
    grid-area: 1 / 1;
  }

  /* Видим только текст с .is-active. Первый экран помечен в разметке. */
  .has-js:not(.js-failed) .story:not(.is-static) .story__intro,
  .has-js:not(.js-failed) .story:not(.is-static) .story__scene {
    opacity: 0;
    visibility: hidden;
    transform: translateY(1rem);
    transition:
      opacity var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-out),
      visibility 0s linear var(--dur-base);
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__intro.is-active,
  .has-js:not(.js-failed) .story:not(.is-static) .story__scene.is-active {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
  }

  .has-js:not(.js-failed) .story:not(.is-static) .story__nav {
    grid-area: nav;
    display: flex;
    align-items: center;
    gap: 1rem;
  }

  /* Телефон: меньше одновременных эффектов, украшения на маленьком
     чертеже только мешают. В готовом листе они на месте. */
  @media (max-width: 47.99rem) {
    .has-js:not(.js-failed) .story:not(.is-static) [data-desktop] {
      display: none;
    }
  }

  /*
   * Низкий телефон, 568-700 px: заголовок, чертёж, главная кнопка и
   * подпись «листайте» в экран не влезают. Жертвуем тем, что помечено
   * .story__optional - подводкой и второй ссылкой. В готовом листе
   * они на месте.
   */
  @media (max-width: 47.99rem) and (max-height: 44rem) {
    .has-js:not(.js-failed) .story:not(.is-static) .story__optional {
      display: none;
    }
  }

  /* Широкий экран: текст слева, чертёж справа во всю высоту экрана. */
  @media (min-width: 48rem) {
    .has-js:not(.js-failed) .story:not(.is-static) .story__stage {
      grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
      grid-template-rows: minmax(0, 1fr) auto;
      grid-template-areas:
        "text visual"
        "nav visual";
      column-gap: clamp(2rem, 5vw, 5rem);
      padding-block: 1.5rem;
    }

    .has-js:not(.js-failed) .story:not(.is-static) .story__intro,
    .has-js:not(.js-failed) .story:not(.is-static) .story__scenes {
      align-self: center;
    }
  }
}
