/*
 * Главная страница. ТЗ §18.
 *
 * Страница не рассказывает про бланк вскрытия — она им является. Заполненный
 * протокол, поля с отточием, штамп, бирка с номером. Отсюда всё остальное:
 * скруглений нет, теней нет, глубина только линиями и фоном, шесть цветов.
 *
 * §18.2 перечисляет признаки шаблонной генерации, которых здесь нет:
 * ни мягких теней под одинаковыми скруглёнными карточками, ни разрядки
 * ALL CAPS над каждым заголовком, ни стрелок, приклеенных к кнопкам,
 * ни нумерации 01/02/03 там, где содержимое не является последовательностью.
 * Единственная нумерация на странице — очерёдность запуска модулей,
 * которая в ТЗ прямо зафиксирована и потому является последовательностью.
 *
 * §18.4: движение — только как ответ на действие пользователя. Здесь этим
 * ответом является прокрутка и наведение; ничего не крутится само по себе.
 * При prefers-reduced-motion всё показывается сразу в конечном состоянии.
 */

/* ── Лист протокола ──────────────────────────────────────────────────────── */

/*
 * Миллиметровка. Тот же --steel, разбавленный до 8%: седьмого цвета нет,
 * есть седьмая прозрачность. Сетка держит ощущение бумаги для форм и не
 * читается как «фактура ради фактуры» — на ней реально выстроены поля.
 */
.lp {
  --cell: 40px;
  background-color: var(--form);
  background-image:
    repeating-linear-gradient(to right,  transparent 0 calc(var(--cell) - 1px), rgba(124, 135, 131, 0.08) calc(var(--cell) - 1px) var(--cell)),
    repeating-linear-gradient(to bottom, transparent 0 calc(var(--cell) - 1px), rgba(124, 135, 131, 0.08) calc(var(--cell) - 1px) var(--cell));
  border: var(--line);
  margin-bottom: var(--gap);
}

.lp__section {
  padding: 34px 30px;
  border-bottom: var(--line);
}
.lp__section:last-child { border-bottom: none; }

/*
 * Перфорация: лист, оторванный от блокнота форм. Приём разовый — стоит
 * ровно на одном стыке, где страница переходит от вывода к доказательствам.
 */
.lp__perf {
  height: 11px;
  border-bottom: var(--line);
  background-image: radial-gradient(circle, var(--tile) 1.6px, transparent 1.7px);
  background-size: 9px 11px;
  background-position: center;
}

/* Номер листа на полях — как в настоящем деле. */
.lp__folio {
  float: right;
  margin: -10px -8px 0 12px;
  color: var(--steel);
  font-size: 12px;
  letter-spacing: 0.04em;
}

/* ── Шапка заключения ────────────────────────────────────────────────────── */

.lp-head {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 10px;
  margin-bottom: 22px;
}
.lp-head__title {
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.lp-head__tag {
  margin-left: auto;
  color: var(--steel);
  font-size: 14px;
}

/* ── Поле с отточием ─────────────────────────────────────────────────────── */

/*
 * Отточие настоящее: точки рисует фон, а не строка из символов. Их можно
 * протянуть от подписи к значению за фиксированное время независимо от
 * длины поля, и они не попадают в выделение и в чтение с экрана.
 */
.lp-field {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 0;
  border-bottom: var(--line-thin);
}
.lp-field:last-child { border-bottom: none; }

.lp-field__label {
  color: var(--steel);
  font-size: 14px;
  white-space: nowrap;
}
.lp-field__leader {
  flex: 1 1 24px;
  min-width: 24px;
  align-self: center;
  height: 1em;
  background-image: radial-gradient(circle, var(--steel) 1px, transparent 1.1px);
  background-size: 6px 6px;
  background-repeat: repeat-x;
  background-position: left bottom 3px;
  opacity: 0.55;
}
.lp-field__value { white-space: nowrap; }

/* ── Вывод ───────────────────────────────────────────────────────────────── */

/*
 * Первое, что видит клиент, — не график, а строка вывода (§18.3).
 * Кегль здесь крупнее всего на странице: это и есть продукт.
 */
.lp-cause {
  font-size: clamp(22px, 3.4vw, 31px);
  line-height: 1.3;
  letter-spacing: -0.01em;
  max-width: 30ch;
  margin: 22px 0 16px;
  text-wrap: balance;
}
.lp-cause b { font-weight: 500; }

.lp-meta {
  color: var(--steel);
  border-top: var(--line-thin);
  padding-top: 12px;
  margin-bottom: 22px;
}
.lp-meta .mono { color: var(--ink); }

.lp-cta {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}
/* На экране ровно одно основное действие, и оно единственное залито (§18.4). */
.lp-cta__aside { color: var(--steel); font-size: 15px; }

/* ── Штамп ───────────────────────────────────────────────────────────────── */

/*
 * Штамп стоит на свободном поле бланка справа от вывода. Раскладку задаёт
 * сетка, а не координаты: при любой длине причины и любом кегле штамп
 * не наезжает на заполненные поля.
 */
.lp-verdict {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 28px;
  align-items: start;
}

.lp-stamp {
  justify-self: end;
  margin-top: 26px;
  border: 2px solid var(--green);
  color: var(--green);
  padding: 5px 12px;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: rotate(-7deg);
  pointer-events: none;
  line-height: 1.35;
  text-align: center;
  white-space: nowrap;
  /* Наклон делает штамп шире его же коробки: у повёрнутого прямоугольника
     к ширине добавляется высота, умноженная на синус угла. На широком экране
     это те самые четыре пикселя, из-за которых по всей странице появлялась
     горизонтальная полоса прокрутки. Запас по бокам их и съедает. */
  margin-inline: 8px;
  max-width: calc(100% - 16px);
}

/* На узком экране наклонённый штамп во всю ширину — это уже не приём,
   а текст, уехавший за край. Ставим его по левому краю, разрешаем перенос
   и уменьшаем угол: смысл «оттиска на бланке» сохраняется, край — тоже. */
@media (max-width: 560px) {
  .lp-stamp {
    justify-self: start;
    white-space: normal;
    transform: rotate(-3deg);
    font-size: 12px;
    margin-inline: 4px 8px;
    max-width: calc(100% - 12px);
    /* Прилетает штамп с перелётом, увеличенным в полтора раза. Растёт он
       от центра, и на узком экране левый угол на секунду уходит за край
       экрана. Точка отсчёта у левого края решает это независимо от того,
       какое из правил появления победит в каскаде: увеличение идёт вправо,
       где место есть. */
    transform-origin: left center;
  }
}
.lp-stamp__date {
  display: block;
  font-size: 11px;
  letter-spacing: 0.04em;
  opacity: 0.75;
}
/* ── Заголовки разделов ──────────────────────────────────────────────────── */

.lp-h {
  font-size: clamp(19px, 2.2vw, 23px);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
  max-width: 26ch;
}
.lp-sub {
  color: var(--steel);
  max-width: var(--measure);
  margin: 0 0 22px;
}

/* ── Диф по блочным хешам ────────────────────────────────────────────────── */

/*
 * Главный технический довод продукта (§7.3): диф показывает не «текст
 * изменился», а какой именно блок из скольких. Показываем ровно это —
 * две колонки хешей и результат сравнения построчно.
 */
.lp-diff {
  border: var(--line);
  background: var(--form);
  max-width: 620px;
}
.lp-diff__head {
  display: grid;
  grid-template-columns: 1fr 88px 88px 62px;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: var(--line);
  color: var(--steel);
  font-size: 13px;
}
.lp-diff__row {
  display: grid;
  grid-template-columns: 1fr 88px 88px 62px;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: var(--line-thin);
  align-items: baseline;
}
.lp-diff__row:last-child { border-bottom: none; }
.lp-diff__name { color: var(--ink); }
.lp-diff__hash { color: var(--steel); font-size: 14px; }
.lp-diff__mark { font-size: 14px; color: var(--steel); }

/* Изменившийся блок — единственная строка, набранная йодом. */
.lp-diff__row.is-changed .lp-diff__name { font-weight: 500; }
.lp-diff__row.is-changed .lp-diff__hash--new,
.lp-diff__row.is-changed .lp-diff__mark { color: var(--iodine); }
.lp-diff__row.is-changed { background: rgba(140, 58, 22, 0.05); }

.lp-diff__foot {
  border-top: var(--line);
  padding: 10px 14px;
  color: var(--steel);
  font-size: 14px;
}
.lp-diff__foot b { color: var(--ink); font-weight: 500; }

/* ── Кривая позиций ──────────────────────────────────────────────────────── */

.lp-plot {
  display: block;
  width: 100%;
  height: 190px;
  border: var(--line);
  background: var(--form);
}
.lp-plot__grid   { stroke: rgba(124, 135, 131, 0.30); stroke-width: 1; }
.lp-plot__line   { fill: none; stroke: var(--green); stroke-width: 1.75; stroke-linejoin: round; }
.lp-plot__line--dead { stroke: var(--iodine); }
.lp-plot__death  { stroke: var(--iodine); stroke-width: 1; stroke-dasharray: 3 3; }
.lp-plot__dot    { fill: var(--iodine); }
.lp-plot__label  { fill: var(--steel); font-size: 11px; }
.lp-plot__label--death { fill: var(--iodine); }

/* Подпись под графиком: то, чего конкуренты не говорят. */
.lp-plot-note {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border: var(--line);
  border-top: none;
}
.lp-plot-note > div { padding: 14px 16px; }
.lp-plot-note > div + div { border-left: var(--line); }
.lp-plot-note__label { color: var(--steel); font-size: 13px; display: block; margin-bottom: 4px; }
.lp-plot-note__them { color: var(--steel); }

/* ── Слои ────────────────────────────────────────────────────────────────── */

/*
 * Пять слоёв (§3) — списком с волосяными линиями, а не пятью карточками.
 * Ряды разной высоты и выравнивание по базовой линии дают ритм, которого
 * не даёт сетка из одинаковых плиток.
 */
.lp-layers { border-top: var(--line); }
.lp-layer {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 18px;
  padding: 15px 0;
  border-bottom: var(--line-thin);
  align-items: start;
}
.lp-layer__no { color: var(--steel); font-size: 14px; padding-top: 1px; }
.lp-layer__name { font-weight: 500; margin: 0 0 3px; font-size: 16px; }
.lp-layer__what { color: var(--steel); margin: 0; max-width: 62ch; }

/* Пятый слой — единственный, у которого есть ограничение, и оно важнее всего. */
.lp-layer--sealed { border-left: 3px solid var(--green); padding-left: 14px; margin-left: -17px; }
.lp-layer--sealed .lp-layer__no { color: var(--green); }

/* ── Индекс шторма ───────────────────────────────────────────────────────── */

.lp-flux {
  display: flex;
  align-items: flex-end;
  gap: 24px;
  flex-wrap: wrap;
}
.lp-flux__value {
  font-size: clamp(56px, 9vw, 84px);
  line-height: 0.85;
  font-variant-numeric: tabular-nums;
}
.lp-flux__value--rough { color: var(--iodine); }
.lp-flux__side { padding-bottom: 5px; max-width: 42ch; }
.lp-flux__verdict { font-size: 17px; margin: 0 0 3px; }

/* Линейка порогов: 0 — 35 — 60 — 100, с засечкой на текущем значении. */
.lp-scale { margin-top: 18px; max-width: 520px; }
.lp-scale__track {
  position: relative;
  height: 9px;
  border: var(--line-thin);
  border-top: none;
  border-bottom: 1px solid var(--steel);
}
.lp-scale__tick {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 9px;
  background: var(--steel);
}
.lp-scale__now {
  position: absolute;
  bottom: 0;
  width: 2px;
  height: 17px;
  background: var(--green);
}
.lp-scale__now--rough { background: var(--iodine); }
/*
 * Подписи стоят ровно под своими засечками, а не раскладываются поровну:
 * 35 и 60 — пороги из §5.8, и подпись, съехавшая с порога, врёт.
 * Проценты проставляет скрипт (он же ставит засечки). Без скрипта работает
 * запасная раскладка flex: числа встают неточно, но читаются и не наезжают.
 */
.lp-scale__marks {
  display: flex;
  justify-content: space-between;
  color: var(--steel);
  font-size: 12px;
  padding-top: 5px;
}
.lp-scale--placed .lp-scale__marks {
  display: block;
  position: relative;
  height: 1.35em;
}
.lp-scale--placed .lp-scale__mark {
  position: absolute;
  top: 5px;
  transform: translateX(-50%);
}
.lp-scale--placed .lp-scale__mark:first-child { transform: none; }
.lp-scale--placed .lp-scale__mark:last-child  { transform: translateX(-100%); }

.lp-scale__legend { font-size: 13px; margin: 6px 0 0; }

/* ── Модули ──────────────────────────────────────────────────────────────── */

/*
 * Нумерация здесь законна: ТЗ §1 фиксирует очерёдность запуска модулей,
 * то есть содержимое действительно является последовательностью.
 */
.lp-mods { border-top: var(--line); }
.lp-mod {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  gap: 18px;
  padding: 17px 0;
  border-bottom: var(--line-thin);
  align-items: baseline;
}
.lp-mod:last-child { border-bottom: none; }
.lp-mod__no { color: var(--steel); }
.lp-mod__name { font-weight: 500; font-size: 17px; margin: 0 0 3px; }
.lp-mod__what { color: var(--steel); margin: 0; max-width: 58ch; }
.lp-mod__link { white-space: nowrap; }
.lp-mod__state { color: var(--steel); font-size: 13px; white-space: nowrap; }

/* ── Оговорка ────────────────────────────────────────────────────────────── */

.lp-honest {
  border-left: 3px solid var(--green);
  padding: 4px 0 4px 16px;
  max-width: var(--measure);
}
.lp-honest p:last-child { margin-bottom: 0; }

.lp-quote {
  font-size: 18px;
  line-height: 1.45;
  max-width: 46ch;
  margin: 0 0 10px;
}

/* ── Движение ────────────────────────────────────────────────────────────── */

/*
 * Класс lp--anim ставит JS. Без него страница полностью видна и читаема:
 * ни один блок не спрятан разметкой, скрывать нечего, если скрипт не
 * выполнился. Это же снимает мигание при загрузке.
 */
.lp--anim .reveal {
  opacity: 0;
  transform: translateY(7px);
}
.lp--anim .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 460ms ease, transform 460ms cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: var(--delay, 0ms);
}

/* Отточие протягивается от подписи к значению. */
.lp--anim .lp-field__leader { transform: scaleX(0); transform-origin: left center; }
.lp--anim .is-in .lp-field__leader,
.lp--anim .lp-field.is-in .lp-field__leader {
  transform: scaleX(1);
  transition: transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: var(--delay, 0ms);
}
.lp--anim .lp-field__value { opacity: 0; }
.lp--anim .lp-field.is-in .lp-field__value {
  opacity: 1;
  transition: opacity 260ms ease;
  transition-delay: calc(var(--delay, 0ms) + 300ms);
}

/* Штамп ставят на готовый документ: он прилетает последним и с перелётом. */
.lp--anim .lp-stamp { opacity: 0; transform: rotate(-7deg) scale(1.5); }
.lp--anim .lp-stamp.is-in {
  opacity: 1;
  transform: rotate(-7deg) scale(1);
  transition: opacity 200ms ease, transform 380ms cubic-bezier(0.2, 1.5, 0.4, 1);
  transition-delay: 900ms;
}

/* Строки дифа сравниваются сверху вниз, как их читает человек. */
.lp--anim .lp-diff__row .lp-diff__hash--new,
.lp--anim .lp-diff__row .lp-diff__mark { opacity: 0; }
.lp--anim .lp-diff__row.is-in .lp-diff__hash--new,
.lp--anim .lp-diff__row.is-in .lp-diff__mark {
  opacity: 1;
  transition: opacity 200ms ease;
  transition-delay: var(--delay, 0ms);
}
.lp--anim .lp-diff__row { background-color: transparent; }
.lp--anim .lp-diff__row.is-changed.is-in {
  background-color: rgba(140, 58, 22, 0.05);
  transition: background-color 320ms ease;
  transition-delay: calc(var(--delay, 0ms) + 120ms);
}

/* Кривая позиций вычерчивается, а не появляется. */
.lp--anim .lp-plot__line {
  stroke-dasharray: var(--len, 1000);
  stroke-dashoffset: var(--len, 1000);
}
.lp--anim .lp-plot.is-in .lp-plot__line {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.lp--anim .lp-plot__death,
.lp--anim .lp-plot__dot,
.lp--anim .lp-plot__label--death { opacity: 0; }
.lp--anim .lp-plot.is-in .lp-plot__death,
.lp--anim .lp-plot.is-in .lp-plot__dot,
.lp--anim .lp-plot.is-in .lp-plot__label--death {
  opacity: 1;
  transition: opacity 300ms ease;
  transition-delay: 900ms;
}

/* Засечка на линейке штормов доезжает до своего значения. */
.lp--anim .lp-scale__now { transform: scaleY(0); transform-origin: bottom; }
.lp--anim .lp-scale.is-in .lp-scale__now {
  transform: scaleY(1);
  transition: transform 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: 260ms;
}

/*
 * Наведение на слой подсвечивает его номер: ответ на действие, а не
 * самостоятельное движение.
 */
.lp-layer__no, .lp-mod__no { transition: color 160ms ease; }
.lp-layer:hover .lp-layer__no, .lp-mod:hover .lp-mod__no { color: var(--ink); }

/*
 * Узкий экран: угол наклона меньше, и прилетает штамп без перелёта
 * в полтора раза. Правило стоит здесь, а не рядом с остальным адаптивом:
 * при равной специфичности выигрывает то, что ниже по файлу, — а выше
 * стоят как раз правила появления.
 */
@media (max-width: 560px) {
  .lp--anim .lp-stamp { transform: rotate(-3deg) scale(1.1); }
  .lp--anim .lp-stamp.is-in { transform: rotate(-3deg) scale(1); }
}

/*
 * §18.4 и §16.2: при отключённом движении никаких переходов, всё сразу
 * в конечном состоянии. Правило дублирует общее из morg.css намеренно —
 * здесь оно должно снять и стартовые сдвиги, а не только длительности.
 */
@media (prefers-reduced-motion: reduce) {
  .lp--anim .reveal,
  .lp--anim .lp-field__value,
  .lp--anim .lp-stamp,
  .lp--anim .lp-diff__row .lp-diff__hash--new,
  .lp--anim .lp-diff__row .lp-diff__mark,
  .lp--anim .lp-plot__death,
  .lp--anim .lp-plot__dot,
  .lp--anim .lp-plot__label--death {
    opacity: 1;
  }
  .lp--anim .reveal,
  .lp--anim .lp-stamp { transform: none; }
  .lp--anim .lp-stamp { transform: rotate(-7deg); }
  .lp--anim .lp-field__leader,
  .lp--anim .lp-scale__now { transform: none; }
  .lp--anim .lp-plot__line { stroke-dasharray: none; stroke-dashoffset: 0; }
  .lp--anim .lp-diff__row.is-changed { background-color: rgba(140, 58, 22, 0.05); }
}

/* ── Адаптив до 380px ────────────────────────────────────────────────────── */

@media (max-width: 760px) {
  .lp__section { padding: 26px 18px; }
  .lp { --cell: 32px; }
  /* На узком экране вывод и штамп встают в колонку. */
  .lp-verdict { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .lp-stamp { justify-self: start; margin: 2px 0 16px; transform: rotate(-3deg); }
  .lp--anim .lp-stamp { transform: rotate(-3deg) scale(1.4); }
  .lp--anim .lp-stamp.is-in { transform: rotate(-3deg) scale(1); }
  .lp-plot-note { grid-template-columns: 1fr; }
  .lp-plot-note > div + div { border-left: none; border-top: var(--line); }
  .lp__folio { display: none; }
}

@media (max-width: 520px) {
  .lp__section { padding: 22px 14px; }
  .lp-cause { max-width: none; }
  /* Отточие на узком экране съедает значение — подпись уходит на свою строку. */
  .lp-field { display: block; padding: 9px 0; }
  .lp-field__leader { display: none; }
  .lp-field__label { display: block; margin-bottom: 2px; font-size: 13px; }
  .lp-field__value { white-space: normal; }
  .lp-diff__head { display: none; }
  .lp-diff__row { grid-template-columns: 1fr 74px 44px; row-gap: 2px; }
  /* Вчерашний хеш на узком экране не нужен: важен факт расхождения. */
  .lp-diff__hash--old { display: none; }
  .lp-layer { grid-template-columns: 22px 1fr; gap: 12px; }
  .lp-layer--sealed { margin-left: 0; padding-left: 11px; }
  .lp-mod { grid-template-columns: 22px 1fr; gap: 12px; }
  .lp-mod__link, .lp-mod__state { grid-column: 2; }
}
