/* ============================================================================
   site/field.css — места, где живёт «поле» (site/field.js).

   Холст всегда лежит ПОД содержимым и никогда не перехватывает указатель:
   волну бьёт сам раздел, а ссылки и кнопки поверх должны работать как
   обычно. Поэтому pointer-events на холсте нет, а обработчик касания висит
   на разделе.

   Холст растворяется маской по ВСЕМ ЧЕТЫРЁМ краям. Причина простая: контекст
   WebGL заведён с alpha:false, то есть холст непрозрачен и красит туман до
   последнего пикселя. Где маска не доходит — там ровная кромка, и раздел
   читается как «сюда вставили картинку», а не «раздел так выглядит».

   Раньше маска гасила только верх («transparent 0, #000 26%, #000 100%»):
   низ оставался непрозрачным и упирался в светлую секцию полосой, а боков
   маска не касалась вовсе — волна обрубалась по левому и правому краю окна.
   ========================================================================== */

/* Полоса растворения плиты. Живёт на :root, а не на .field-slab: её же
   читает секция, которую плита закрывает, — бумага обязана кончиться ровно
   там, где плита ещё непрозрачна. */
:root{ --slab-fade:clamp(38px,4.6vw,86px) }
@media (max-width:760px){ :root{ --slab-fade:clamp(26px,6vw,52px) } }

/* ─────────────── общий слой ─────────────── */

.has-field{ position:relative; isolation:isolate }

.field-canvas{
  position:absolute; inset:0; width:100%; height:100%;
  display:block; z-index:0; pointer-events:none;
  /* Появление без рывка: первый кадр приезжает через кадр-два после
     разметки, и без этого раздел моргает зелёным. */
  opacity:0; transition:opacity .9s cubic-bezier(.22,1,.36,1);

  /* Две маски, пересечение. Механика описана один раз здесь, а каждое место
     ниже меняет только --mask-v и --mask-h — иначе набор из четырёх префиксов
     пришлось бы копировать в каждое правило и он бы разъехался.
     mask-composite:intersect — стандарт; -webkit-mask-composite:source-in —
     то же самое старым словарём WebKit, без него Safari складывает маски и
     гасит всё. */
  --mask-v:linear-gradient(to bottom,
    transparent 0, #000 22%, #000 74%, transparent 100%);
  --mask-h:linear-gradient(to right,
    transparent 0, #000 9%, #000 91%, transparent 100%);
  -webkit-mask-image:var(--mask-v), var(--mask-h);
          mask-image:var(--mask-v), var(--mask-h);
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%;   mask-size:100% 100%;
  -webkit-mask-composite:source-in;
          mask-composite:intersect;
}
.field-on .field-canvas{ opacity:1 }

/* Содержимое раздела — над холстом. Без этого текст оказывается под
   полем: холст вставлен первым ребёнком. */
/* Из правила исключена коробка фигуры: иначе поле поднимало бы `.fig` над
   содержимым — та же война слоёв, только в обратную сторону. */
.has-field > *:not(.field-canvas):not(.fig){ position:relative; z-index:1 }

/* ─────────────── шапки внутренних страниц ───────────────
   Поле гаснет ВНУТРИ шапки — и сверху, и снизу. Первым заходом холст
   свешивался в следующий блок, чтобы не было границы, но `overflow:hidden`
   срезал его ровной линией и получалось ровно то, чего избегали. Проще:
   ничего не свешиваем, а маску доводим до нуля к нижнему краю секции. */
.ptop.has-field{ overflow:hidden }
.ptop.has-field .field-canvas{
  /* Верхние сорок процентов шапки поле не занимает вовсе: там стоят заголовок
     страницы и лид, и гребень проходил ровно по их строкам. Рельеф начинается
     ПОД текстом и к низу секции сходит на нет. */
  --mask-v:linear-gradient(to bottom,
    transparent 0, #000 42%, #000 70%, transparent 99%);
}

/* ─────────────── тёмная плита в светлом разделе ───────────────
   «Пять программ» остаётся светлым разделом — светлые секции держат ритм
   страницы. Но карточки переезжают на тёмную плиту во всю ширину: и поле
   получает свой тёмный дом, и порядок «светло → темно → светло» читается
   резче, чем ровная светлая плоскость. */
.field-slab{
  position:relative; isolation:isolate; overflow:hidden;
  margin-top:clamp(34px,4vw,58px);
  /* Воздуха больше, чем полоса растворения: иначе подпись и карточки
     попадают в градиент и теряют фон под собой. */
  padding-block:clamp(64px,7vw,116px);
  /* Цвет плиты — из палитры, а не цифрами: сайт красится отдельным файлом
     (site/palette.css), и зашитый зелёный стал бы единственным зелёным
     пятном на странице после смены направления. */
  /* Края плиты растворяются в цвете секции, в которой она лежит. Пока под
     холстом стоит непрозрачный прямоугольник, любая маска на самом холсте
     бесполезна: волна гаснет, а плита — нет, и глаз читает не «поле
     кончилось», а «в светлую страницу вставили тёмный прямоугольник». */
  --slab-edge:var(--paper);
  /* Верх и низ красятся раздельно: плита в конце светлой секции уходит не
     обратно в бумагу, а в фон страницы — см. правило ниже. */
  --slab-edge-t:var(--slab-edge);
  --slab-edge-b:var(--slab-edge);
  background:linear-gradient(to bottom,
    var(--slab-edge-t) 0,
    var(--bg) var(--slab-fade),
    var(--bg) calc(100% - var(--slab-fade)),
    var(--slab-edge-b) 100%);
  /* Линии на кромках нет. Она спорила с тем, ради чего маска гасит поле:
     рельеф растворяется, а нарисованная линия остаётся и держит
     прямоугольник — глаз читает её первой и видит «вставку».
     Маску на саму плиту не вешаем: внутри лежат карточки с backdrop-filter,
     а маска на родителе меняет им фон-источник и стекло перестаёт работать.
     Плита остаётся плоской заливкой — растворяется только поле над ней. */
  border-block:0;
}
/* Плита — не окно в другую сцену, а часть раздела, поэтому поле гаснет со
   всех сторон. Раньше нижний конец останавливался на 35 % непрозрачности:
   волна не гасла, а исчезала вместе с элементом — ровно та кромка, которой
   избегали сверху. Доводим до нуля. */
.field-slab .field-canvas{
  --mask-v:linear-gradient(to bottom,
    transparent 0, #000 14%, #000 76%, transparent 100%);
}
.field-slab > *:not(.field-canvas){ position:relative; z-index:1 }

/* ── плита, закрывающая светлую секцию ──────────────────────────────────
   Раньше под плитой оставалась полоса бумаги высотой в отступ секции: пусто,
   ни строки, — а сразу за ней светлое обрывалось в тёмное по линейке. Два
   изъяна из одного места.

   Теперь плита и есть переход. Отступ секции снизу убран, а бумага под
   плитой кончается на полосу растворения раньше её низа — дальше плита
   гаснет уже над фоном страницы. Гаснет прозрачностью, а не подобранным
   цветом: аврора прибита к экрану (position:fixed), её оттенок под одной и
   той же точкой страницы меняется при прокрутке, попасть в неё числом
   нельзя. Бумага обрывается там, где плита ещё полностью непрозрачна, —
   поэтому светлого ореола на стыке не остаётся. */
.paper:has(> .field-slab:last-child){
  padding-bottom:0;
  /* Бумага обрывается там, где плита ещё полностью непрозрачна: ниже
     красит уже сама плита, растворяясь в фоне страницы. Отрицательным
     полем это не сделать — при нулевом нижнем отступе поле последнего
     ребёнка схлопывается наружу и высоту секции не меняет. */
  background:linear-gradient(to bottom,
    var(--paper) calc(100% - var(--slab-fade)),
    transparent calc(100% - var(--slab-fade)));
}
.paper > .field-slab:last-child{ --slab-edge-b:transparent }

/* Подпись над плитой: одна строка, объясняющая, что тут можно трогать.
   Без неё интерактив остаётся незамеченным — никто не догадается ткнуть. */
.field-say{
  margin:0 0 clamp(22px,2.6vw,38px); font-size:14px; letter-spacing:.01em;
  color:var(--muted);
}
.field-say b{ color:var(--cta); font-weight:700 }

/* ─────────────── карточки на плите ───────────────
   На тёмном белые карточки из светлой секции выглядели бы дырами, поэтому
   здесь они стеклянные. Наклон остаётся статичным — как и был. */
/* Настоящее стекло, а не намёк: поле под карточкой размывается, и она
   читается как предмет НАД полем. С одной полупрозрачной заливкой без
   размытия карточки выглядели дырами в рельефе. */
.field-slab .five-i{
  background:var(--glass-base, rgba(0,0,0,.55));
  -webkit-backdrop-filter:blur(14px) saturate(1.15);
          backdrop-filter:blur(14px) saturate(1.15);
  border:1px solid rgba(255,255,255,.14);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10), 0 18px 40px -26px rgba(0,0,0,.9);
  border-radius:18px; padding:18px 20px;
  color:var(--ink);
  transition:rotate .24s var(--e-micro), border-color .24s var(--e-micro),
             transform .24s var(--e-micro), box-shadow .24s var(--e-micro);
}
.field-slab .five-i .five-t{ color:var(--ink) }
.field-slab .five-i .card-s{ color:var(--muted) }
.field-slab .five-i:hover{ rotate:0deg; transform:translateY(-3px);
  border-color:var(--cta-edge, rgba(255,255,255,.4));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 22px 46px -24px rgba(0,0,0,.95) }

/* ─────────────── цепочка над полем ───────────────
   Шаг, до которого волна уже дошла, светится. Это и есть довод раздела:
   одно событие докатилось до всех четырёх мест. */
.chain-i{ transition:border-color .3s var(--e-micro), background .3s var(--e-micro) }
.chain-i.is-lit{ border-color:var(--cta-edge, rgba(255,255,255,.4)) }
.chain-i.is-lit .chain-n{ background:var(--cta-soft, rgba(255,255,255,.12));
  border-color:var(--cta-edge, rgba(255,255,255,.4)); color:var(--cta) }

/* ─────────────── бережно ───────────────
   При «уменьшить движение» поле рисует один статичный кадр (это делает
   field.js), маска и слои остаются — раздел не разваливается. */
@media (prefers-reduced-motion: reduce){
  .field-canvas{ transition:none }
}

/* На узком экране поле занимает меньше места по высоте: на телефоне важнее
   текст, а рельеф во весь экран съедает первый разворот. */
@media (max-width:760px){
  .field-slab{ padding-block:clamp(50px,9vw,74px) }
}

/* ─────────────── поле в липкой сцене «Показа» ───────────────
   Рельеф лежит ПОД телефоном и занимает нижнюю половину сцены: сверху там
   заголовок главы и сам телефон, и гребень на их строках убил бы контраст.
   Полоса намеренно высокая — маленький рельеф у нижней кромки читался
   полоской, а не далью.

   Сцена приколота (position:sticky) и обрезана по себе, поэтому холст
   гасим и сверху, и снизу: иначе на въезде и выезде раздела по всей ширине
   встаёт горизонтальная линия — та же беда, от которой .show-light спасает
   своя маска. */
.show-stage.has-field .field-canvas{
  --mask-v:linear-gradient(to bottom,
    transparent 0, #000 38%, #000 88%, transparent 100%);
  --mask-h:linear-gradient(to right, #000 0, #000 100%);
}
