/* ═══════════════════════════════════════════════════════════════════════
   ПАТТЕРН — слой оформления и движения
   ───────────────────────────────────────────────────────────────────────
   Одна идея на весь сайт: разрозненное собирается в закономерность.
   Любой элемент приходит смещённым, размытым и чуть развёрнутым —
   и встаёт на своё место. Так же ведёт себя фоновое поле точек,
   которое перетекает из шума в сетку и в поверхность.

   Файл подключается после site.css и только дополняет его.
   Разметку почти не трогаем: недостающие обёртки, соединители и
   служебные атрибуты расставляет site-motion.js уже в браузере.
   Пока скрипт не отработал, класса .m-on на <html> нет — и страница
   выглядит обычной статичной вёрсткой. Значит, при отключённом или
   упавшем JS ничего не пропадает.
   ═══════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────
   1. ТОКЕНЫ
   ─────────────────────────────────────────────────────────────────────── */
:root{
  /* Кривые. Основная — экспоненциальное торможение: быстрый старт,
     длинное мягкое приземление. Уверенное прибытие без пружины. */
  --e-out:cubic-bezier(.16,1,.3,1);
  --e-in:cubic-bezier(.7,0,.84,0);
  --e-soft:cubic-bezier(.4,0,.2,1);

  /* Длительности. Уход всегда быстрее прихода. */
  --t-tap:.12s;      /* мгновенный отклик на нажатие      */
  --t-state:.24s;    /* обычная смена состояния           */
  --t-move:.42s;     /* перекладка, слой, оверлей         */
  --t-enter:.68s;    /* появление блока                   */

  /* Глубина: у каждой тени есть смещение и мягкое размытие,
     иначе это не тень, а декоративный ореол. */
  --sh-1:0 1px 2px rgba(11,26,58,.06), 0 4px 10px -4px rgba(11,26,58,.08);
  --sh-2:0 2px 4px rgba(11,26,58,.06), 0 14px 30px -14px rgba(11,26,58,.16);
  --sh-3:0 4px 8px rgba(11,26,58,.07), 0 30px 60px -28px rgba(11,26,58,.28);
  --sh-lift:0 6px 12px rgba(11,26,58,.08), 0 40px 80px -34px rgba(11,26,58,.34);

  /* Свет под курсором на карточках */
  --spot:520px;
  --spot-a:.10;

  --rule:linear-gradient(90deg,transparent,rgba(var(--fgc),.16) 22%,
         rgba(var(--accent-rgb),.5) 50%,rgba(var(--fgc),.16) 78%,transparent);
}

/* ───────────────────────────────────────────────────────────────────────
   2. ПОВЕРХНОСТИ, КОТОРЫЕ ДАЁТ БРАУЗЕР
   Выделение, каретка, кольцо фокуса и подчёркивания по умолчанию
   не принадлежат ни одной дизайн-системе. Красим их от палитры.
   ─────────────────────────────────────────────────────────────────────── */
::selection{background:rgba(var(--accent-rgb),.26);color:rgb(var(--fgc))}
::-moz-selection{background:rgba(var(--accent-rgb),.26);color:rgb(var(--fgc))}
input,textarea{caret-color:var(--cyan)}
:focus-visible{
  outline:2px solid var(--cyan);outline-offset:3px;
  border-radius:6px;
  transition:outline-offset var(--t-tap) var(--e-out);
}
a:not([class]){text-underline-offset:3px;text-decoration-thickness:1px}
/* Цифры в одном ритме: суммы в тарифах и годы в таймлайне не «пляшут». */
.c3-tier-large,.timeline-date,.metric-card b,.stage__n,.info-card .num,
.row__s,.side__nav i{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* ───────────────────────────────────────────────────────────────────────
   3. СИСТЕМА ПОЯВЛЕНИЯ
   Базовый .rv из site.css остаётся, но приезжает богаче: к сдвигу
   добавляются лёгкое размытие и микроповорот, которые снимаются
   на финише. Размытие живёт только во время перехода.
   ─────────────────────────────────────────────────────────────────────── */
/* will-change здесь намеренно не ставится. Появляющихся блоков на
   странице сотни; постоянный will-change держал бы для каждого
   отдельный слой композитора — это и память, и задержка старта
   самих переходов. Браузер поднимает слой сам на время анимации. */
html.m-on .rv{
  opacity:0;
  transform:translate3d(var(--rx,0),var(--ry,26px),0) scale(var(--rs,1)) rotate(var(--rr,0deg));
  filter:blur(var(--rb,7px));
  transition:opacity var(--t-enter) var(--e-out),
             transform var(--t-enter) var(--e-out),
             filter calc(var(--t-enter) * .7) var(--e-out);
  transition-delay:var(--d,0s);
}
html.m-on .rv.in{opacity:1;transform:none;filter:none}

/* «Прилипающий» блок сам управляет своим transform: скрипт держит его
   у верхней кромки, пока рядом прокручивается длинная колонка. Поэтому
   появляется он без сдвига — иначе два механизма спорят за одно
   свойство и перебивают друг друга. */
html.m-on .rv[data-pin]{
  transform:none;
  transition:opacity var(--t-enter) var(--e-out),filter calc(var(--t-enter) * .7) var(--e-out);
  transition-delay:var(--d,0s);
}
html.m-on .rv[data-pin].in{transform:none}

/* Направление прихода зависит от роли элемента, а не от того,
   что он просто следующий на странице. */
html.m-on [data-rv="left"]  {--rx:-34px;--ry:0;--rr:-.6deg}
html.m-on [data-rv="right"] {--rx:34px;--ry:0;--rr:.6deg}
html.m-on [data-rv="rise"]  {--ry:34px;--rr:.4deg}
html.m-on [data-rv="settle"]{--ry:14px;--rs:.965;--rb:9px}
html.m-on [data-rv="calm"]  {--ry:12px;--rb:4px}

/* Дети появляются очередью — но только там, где список и правда список.
   Задержка ограничена, чтобы низ группы не ждал слишком долго. */
html.m-on [data-stagger]>*{
  opacity:0;
  transform:translate3d(0,22px,0) scale(.985);
  filter:blur(6px);
  transition:opacity .66s var(--e-out),transform .66s var(--e-out),filter .46s var(--e-out);
  transition-delay:calc(var(--i,0) * var(--step,62ms));
}
html.m-on [data-stagger].in>*{opacity:1;transform:none;filter:none}
html.m-on [data-stagger="side"]>*{transform:translate3d(-26px,0,0)}
html.m-on [data-stagger="scale"]>*{transform:translate3d(0,30px,0) scale(.94)}

/* ───────────────────────────────────────────────────────────────────────
   4. НАБОР ТЕКСТА
   Заголовки не выцветают целиком — они набираются словами из-под
   маски строки. Градиентная часть остаётся цельной, иначе заливка
   разорвётся на куски.
   ─────────────────────────────────────────────────────────────────────── */
.tx{display:inline}
.tx-w{
  display:inline-block;
  overflow:hidden;
  vertical-align:top;
  /* компенсация обрезки выносных элементов буквы */
  padding:.2em .02em .26em;
  margin:-.2em -.02em -.26em;
}
.tx-w>i{
  display:inline-block;
  font-style:inherit;
  transform:translate3d(0,110%,0) rotate(2.4deg);
  opacity:0;
  /* Заголовок обязан закончить раньше текста под ним, иначе порядок
     чтения переворачивается. Отсюда короткий шаг и короткий ход. */
  transition:transform .62s var(--e-out),opacity .38s var(--e-out);
  transition-delay:calc(var(--wi,0) * 36ms + var(--wd,0s));
}
html:not(.m-on) .tx-w>i{transform:none;opacity:1}
.tx.in .tx-w>i{transform:none;opacity:1}

/* ───────────────────────────────────────────────────────────────────────
   5. ШАПКА
   При прокрутке уплотняется и наливается фоном: страница «под» ней
   продолжается, а не начинается заново.
   ─────────────────────────────────────────────────────────────────────── */
.nav{
  transition:backdrop-filter var(--t-move) var(--e-out),
             -webkit-backdrop-filter var(--t-move) var(--e-out);
}
.nav::before{
  opacity:0;
  box-shadow:none;
  transition:opacity var(--t-move) var(--e-out),box-shadow var(--t-move) var(--e-out);
}
.nav.is-stuck::before{opacity:.88;box-shadow:var(--sh-2)}
/* Шапка выведена из потока, поэтому смена её внутренних отступов
   ничего на странице не перекладывает — переливается только сама
   полоса. Порог переключения в скрипте с запасом, чтобы шапка
   не дёргалась, когда прокрутка стоит ровно на границе. */
.nav__in{transition:padding var(--t-move) var(--e-out)}
.nav.is-stuck .nav__in{padding-top:11px;padding-bottom:11px}
/* Логотип уменьшается через transform, а не через height:
   размер — свойство раскладки, масштаб считает композитор. */
.nav.is-stuck .mark{transform:scale(.875)}

/* Тонкая линия прогресса живёт в самой шапке. */
.nav::after{
  content:"";position:absolute;left:0;bottom:0;height:1.5px;width:100%;
  transform:scaleX(var(--nav-p,0));transform-origin:0 50%;
  background:linear-gradient(90deg,var(--deep),var(--cyan) 60%,var(--ice));
  opacity:.9;pointer-events:none;
}

/* Логотип: четыре шеврона слегка расходятся по наведению —
   тот же жест «сборки», только в обратную сторону. */
.mark{transform-origin:0 50%;transition:transform var(--t-move) var(--e-out),color var(--t-state) var(--e-out)}
.mark path{transition:transform .5s var(--e-out);transform-origin:50% 50%}
.brand:hover .mark path:nth-child(1){transform:translateX(-16px)}
.brand:hover .mark path:nth-child(2){transform:translateX(-6px)}
.brand:hover .mark path:nth-child(3){transform:translateX(6px)}
.brand:hover .mark path:nth-child(4){transform:translateX(16px)}
.brand b{transition:letter-spacing var(--t-move) var(--e-out)}
.brand:hover b{letter-spacing:.2em}

/* Пока открыто выдвижное меню, шапка должна оставаться сверху:
   иначе лист меню накрывает её, и крестик закрытия не виден —
   пользователю нечем закрыть меню, кроме промаха мимо листа.
   Собственный фон шапки при этом убираем, чтобы она читалась
   как часть листа, а не как вторая полоса поверх него. */
html.menu-open .nav{z-index:260}
html.menu-open .nav::before{opacity:0;box-shadow:none}
html.menu-open .nav::after{opacity:0}

/* Подчёркивание пунктов меню растёт от центра. */
.nav__links a{position:relative;padding-bottom:3px}
.nav__links a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1.5px;border-radius:2px;
  background:var(--cyan);transform:scaleX(0);transform-origin:50% 50%;
  transition:transform var(--t-state) var(--e-out);
}
.nav__links a:hover::after,
.nav__links a[aria-current="page"]::after{transform:scaleX(1)}
.nav__links a[aria-current="page"]::after{opacity:.55}

/* ───────────────────────────────────────────────────────────────────────
   6. КНОПКИ
   Отклик на нажатие — 120 мс, иначе он читается как задержка.
   Магнитное притяжение к курсору задаёт site-motion.js через --mgx/--mgy.
   ─────────────────────────────────────────────────────────────────────── */
.pill,.c3-btn,.side__btn,.att,.mobile-map-back{
  position:relative;overflow:hidden;isolation:isolate;
  transform:translate3d(var(--mgx,0),var(--mgy,0),0);
  transition:background var(--t-state) var(--e-out),
             color var(--t-state) var(--e-out),
             box-shadow var(--t-move) var(--e-out),
             transform var(--t-move) var(--e-out);
}
.pill:active,.c3-btn:active,.side__btn:active,.att:active{
  transform:translate3d(var(--mgx,0),var(--mgy,0),0) scale(.972);
  transition-duration:var(--t-tap);
}
/* Блик проходит по кнопке один раз при наведении. */
.pill::before,.c3-btn::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  background:linear-gradient(105deg,transparent 34%,rgba(255,255,255,.22) 48%,transparent 62%);
  background-size:260% 100%;background-position:180% 0;
  transition:background-position .72s var(--e-out);
}
.pill:hover::before,.c3-btn:hover::before{background-position:-60% 0}
.pill:hover{box-shadow:var(--sh-2)}
.pill--ghost:hover{box-shadow:none;border-color:rgba(var(--accent-rgb),.42)}
.pill svg.chev{transition:transform var(--t-move) var(--e-out)}
.pill:hover svg.chev{transform:translateX(4px)}

/* ───────────────────────────────────────────────────────────────────────
   7. КАРТОЧКИ
   Свет идёт за курсором, кромка со стороны курсора подсвечивается.
   Обе величины считает скрипт, CSS только рисует.
   ─────────────────────────────────────────────────────────────────────── */
.deliv,.info-card,.c3-card,.case-card,.timeline-item,.scope-pill,
.service-track__item,.metric-card,.executive-card,.founder-card,
.leadership-note,.origin-moment,.principle,.page-cta,.contact-extra{
  position:relative;isolation:isolate;
  --px:50%;--py:50%;
}
.deliv::before,.info-card::before,.case-card::before,.timeline-item::before,
.scope-pill::before,.service-track__item::before,.metric-card::before,
.founder-card::before,.leadership-note::before,.contact-extra::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  background:radial-gradient(var(--spot) circle at var(--px) var(--py),
             rgba(var(--accent-rgb),var(--spot-a)),transparent 62%);
  opacity:0;transition:opacity var(--t-move) var(--e-out);
}
.deliv:hover::before,.info-card:hover::before,.case-card:hover::before,
.timeline-item:hover::before,.scope-pill:hover::before,
.service-track__item:hover::before,.metric-card:hover::before,
.founder-card:hover::before,.leadership-note:hover::before,
.contact-extra:hover::before{opacity:1}

.deliv,.info-card,.metric-card,.case-card,.service-track__item,.scope-pill{
  transition:transform var(--t-move) var(--e-out),
             box-shadow var(--t-move) var(--e-out),
             border-color var(--t-move) var(--e-out);
}
.info-card:hover,.metric-card:hover,.case-card:hover,
.service-track__item:hover,.scope-pill:hover{
  transform:translateY(-5px);box-shadow:var(--sh-lift);
}
.c3-card{box-shadow:var(--sh-1)}
.c3-card:hover{box-shadow:var(--sh-lift)}

/* Кромка карточки светится там, где курсор. */
.deliv::after,.info-card::after,.c3-card .c3-edge,.case-card::after{
  pointer-events:none;
}
.info-card,.deliv,.case-card{
  border:1px solid transparent;
  background-clip:padding-box;
}

/* ───────────────────────────────────────────────────────────────────────
   8. ЭТАПЫ И СОЕДИНИТЕЛИ
   Пять этапов — это последовательность, и она рисуется как
   последовательность: линия прочерчивается сверху вниз, номера
   наливаются по мере того, как линия до них доходит.
   ─────────────────────────────────────────────────────────────────────── */
.chain{position:relative}
.chain .stage{overflow:hidden}
.stage__n{
  position:relative;z-index:2;
  transform:scale(.55);opacity:0;
  transition:transform .6s var(--e-out),opacity .4s var(--e-out);
  transition-delay:calc(var(--si,0) * 130ms + .1s);
}
html:not(.m-on) .stage__n{transform:none;opacity:1}
.chain.in .stage__n{transform:none;opacity:1}
/* Импульс, пробегающий по номеру ровно один раз при появлении. */
.chain.in .stage__n::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1px solid var(--cyan);
  animation:pulse-once 1.1s var(--e-out) both;
  animation-delay:calc(var(--si,0) * 130ms + .3s);
}
@keyframes pulse-once{
  from{transform:scale(.7);opacity:.9}
  to{transform:scale(1.9);opacity:0}
}
/* Вертикальная линия, связывающая этапы: проходит ровно по центрам
   номеров. Смещение считается от отступов .chain и .stage, поэтому
   на телефоне значение своё. */
.chain::before{
  content:"";position:absolute;left:51px;top:44px;bottom:44px;width:1px;
  background:linear-gradient(180deg,transparent,rgba(var(--accent-rgb),.5) 12%,
             rgba(var(--accent-rgb),.5) 88%,transparent);
  transform:scaleY(0);transform-origin:50% 0;
  transition:transform 1.35s var(--e-out) .16s;
  pointer-events:none;
}
.chain.in::before{transform:scaleY(1)}
@media(max-width:760px){.chain::before{left:34px;top:34px;bottom:34px}}

/* Строка этапов в герое: линия прочерчивается, звенья встают по очереди. */
.hero__chain{position:relative}
.hero__chain span{
  opacity:0;transform:translate3d(0,10px,0) scale(.9);
  transition:opacity .5s var(--e-out),transform .62s var(--e-out),
             background var(--t-state),border-color var(--t-state);
  transition-delay:calc(var(--ci,0) * 86ms + .1s);
}
.hero__chain i{
  opacity:0;transform:translateX(-6px);
  transition:opacity .4s var(--e-out),transform .5s var(--e-out);
  transition-delay:calc(var(--ci,0) * 86ms + .16s);
}
html:not(.m-on) .hero__chain span,
html:not(.m-on) .hero__chain i{opacity:1;transform:none}
.hero__chain.in span,.hero__chain.in i{opacity:1;transform:none}
.hero__chain span:hover{
  border-color:rgba(var(--accent-rgb),.45);
  background:rgba(var(--accent-rgb),.09);
  transform:translateY(-2px);
  transition-delay:0s;
}

/* ───────────────────────────────────────────────────────────────────────
   9. ИКОНКИ
   Штрих прочерчивается при появлении — это видно на крупных
   иконках блока «Результат» и на галочках в тарифах.
   ─────────────────────────────────────────────────────────────────────── */
html.m-on .draw path,html.m-on .draw circle,html.m-on .draw polyline{
  stroke-dasharray:var(--len,120);
  stroke-dashoffset:var(--len,120);
  transition:stroke-dashoffset 1.05s var(--e-out);
  transition-delay:calc(var(--di,0) * 90ms + .2s);
}
html.m-on .draw.in path,html.m-on .draw.in circle,html.m-on .draw.in polyline{
  stroke-dashoffset:0;
}
.deliv svg{transition:transform .5s var(--e-out),color var(--t-state)}
.deliv:hover svg{transform:translateY(-3px) scale(1.06);color:var(--cyan)}

/* Галочки тарифов наливаются очередью. */
.c3-check{
  transform:scale(.6);opacity:0;
  transition:transform .5s var(--e-out),opacity .35s var(--e-out),
             background var(--t-state),color var(--t-state);
  transition-delay:calc(var(--li,0) * 58ms + .18s);
}
html:not(.m-on) .c3-check{transform:none;opacity:1}
.c3-card.in .c3-check{transform:none;opacity:1}
.c3-card:hover .c3-check{background:rgba(var(--accent-rgb),.18);color:var(--ice)}

/* ───────────────────────────────────────────────────────────────────────
   10. ГЕРОЙ — авторский момент
   Заголовок набирается, под ним прочерчивается волосяная линия,
   кнопка один раз мягко вспыхивает. Дальше страница успокаивается.
   ─────────────────────────────────────────────────────────────────────── */
.hero{position:relative}
.hero h1{position:relative;text-wrap:balance}
/* Первый экран — единственное место, где вход намеренно длиннее:
   это авторский момент страницы, а не рядовое появление блока. */
.hero h1 .tx-w>i,.inner-hero h1 .tx-w>i{
  transition:transform .84s var(--e-out),opacity .5s var(--e-out);
  transition-delay:calc(var(--wi,0) * 64ms + var(--wd,0s));
}
.hero h1::after{
  content:"";position:absolute;left:50%;bottom:-.34em;height:1px;width:min(320px,52%);
  transform:translateX(-50%) scaleX(0);
  background:var(--rule);
  transition:transform 1.15s var(--e-out) .5s;
}
.hero h1.in::after{transform:translateX(-50%) scaleX(1)}
.hero__lead{text-wrap:pretty}
.hero__cta .pill{position:relative}
.hero__cta.in .pill::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:0 0 0 0 rgba(var(--accent-rgb),.55);
  animation:cta-bloom 1.5s var(--e-out) .75s 1 both;
}
@keyframes cta-bloom{
  from{box-shadow:0 0 0 0 rgba(var(--accent-rgb),.5)}
  to{box-shadow:0 0 0 22px rgba(var(--accent-rgb),0)}
}
/* Мягкое свечение под героем, чуть смещающееся при прокрутке. */
.hero::before{
  content:"";position:absolute;z-index:-1;left:50%;top:-6%;
  width:min(1100px,124%);aspect-ratio:2/1;
  transform:translate(-50%,var(--hero-par,0px));
  background:radial-gradient(50% 50% at 50% 50%,rgba(var(--accent-rgb),.13),transparent 70%);
  pointer-events:none;opacity:.9;
}

/* ───────────────────────────────────────────────────────────────────────
   11. СЕКЦИИ
   Разделители прочерчиваются, заголовки набираются, подзаголовок
   догоняет. Ни одна секция не повторяет вход предыдущей буквально.
   ─────────────────────────────────────────────────────────────────────── */
.page-rule{transform:scaleX(0);transform-origin:0 50%;background:var(--rule)}
html:not(.m-on) .page-rule{transform:none}
.page-rule.in{transform:scaleX(1);transition:transform 1.25s var(--e-out)}

.eyebrow{position:relative}
.eyebrow em{transition:border-color var(--t-state),color var(--t-state)}

/* Водяной знак тарифов: строки открываются снизу вверх, а затем
   медленно расходятся в стороны, пока секция идёт через экран.
   Раскрытие ведём по clip-path, чтобы не спорить с этим сдвигом. */
.c3-watermark-line-1{transform:translateX(var(--wm-a,0px))}
.c3-watermark-line-2{transform:translateX(var(--wm-b,0px))}
.c3-watermark-line-1,.c3-watermark-line-2{transition:transform .3s linear}
html.m-on .wm>span{
  clip-path:inset(0 0 106% 0);
  opacity:0;
  transition:clip-path 1.05s var(--e-out),opacity .55s var(--e-out),transform .3s linear;
  transition-delay:calc(var(--wmi,0) * 140ms);
}
html.m-on .wm.in>span{clip-path:inset(-20% -6% -20% -6%);opacity:1}

/* ───────────────────────────────────────────────────────────────────────
   11-бис. МЕЛКИЕ ОТКЛИКИ
   По отдельности незаметны, вместе дают ощущение, что страница
   отвечает на каждое движение.
   ─────────────────────────────────────────────────────────────────────── */

/* Этап: у левого края прочерчивается акцентная риска. */
.stage::after{
  content:"";position:absolute;left:0;top:14px;bottom:14px;width:2px;border-radius:2px;
  background:var(--cyan);transform:scaleY(0);transform-origin:50% 50%;
  transition:transform var(--t-move) var(--e-out);
}
.stage:hover::after{transform:scaleY(1)}

/* Ссылки в контактах: подчёркивание вырастает от левого края. */
.dl a{position:relative;border-bottom-color:transparent!important}
.dl a::after{
  content:"";position:absolute;left:0;right:0;bottom:-2px;height:1px;
  background:rgba(var(--fgc),.28);
  transition:background var(--t-state) var(--e-out),transform var(--t-state) var(--e-out);
}
.dl a:hover::after{background:var(--cyan);transform:scaleY(2)}

/* Способы оплаты и чипы связи. */
.payment-item,.contact-chip{
  transition:transform var(--t-state) var(--e-out),border-color var(--t-state) var(--e-out),
             background var(--t-state) var(--e-out);
}
.payment-item:hover{transform:translateY(-2px);border-color:rgba(var(--accent-rgb),.3)}
.contact-chip::before{transition:transform var(--t-state) var(--e-out),box-shadow var(--t-state)}
.contact-chip:hover::before{transform:scale(1.5);box-shadow:0 0 16px rgba(var(--accent-rgb),.65)}

/* Номера в карточках: наливаются вместе с карточкой. */
.info-card .num,.service-track__num{
  transition:transform var(--t-move) var(--e-out),background var(--t-state),color var(--t-state);
}
.info-card:hover .num,.service-track__item:hover .service-track__num{transform:scale(1.12)}

/* Продуктовый макет приезжает чуть крупнее прочих блоков:
   это главный экспонат страницы. */
html.m-on #mock{--ry:44px;--rs:.972;--rb:10px}

/* Подвал. */
.foot a{transition:color var(--t-state) var(--e-out)}
.foot a:hover{color:var(--ice)}

/* Лента тарифов на узких экранах прижималась вплотную к краю экрана:
   отрицательный внешний отступ не был скомпенсирован полем секции.
   Возвращаем ленте нормальные поля и правильную точку прилипания. */
@media(max-width:1024px){
  .c3-grid{
    width:100%;max-width:none;margin-left:0;margin-right:0;
    padding-left:var(--pad);padding-right:var(--pad);
    scroll-padding-left:var(--pad);scroll-padding-right:var(--pad);
  }
  .c3-card{scroll-snap-align:start}
}
@media(max-width:760px){
  .c3-grid{margin:30px 0 0;padding:4px var(--pad) 12px}
}

/* Полоса зон бизнеса и другие горизонтальные ленты
   получают затухание по краям, чтобы обрез читался как прокрутка. */
.side__nav,.c3-grid,.scope-strip{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 18px,#000 calc(100% - 18px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 18px,#000 calc(100% - 18px),transparent);
}
@media(min-width:1025px){.c3-grid{-webkit-mask-image:none;mask-image:none}}
@media(min-width:900px){.scope-strip{-webkit-mask-image:none;mask-image:none}}

/* ───────────────────────────────────────────────────────────────────────
   12. КАРТА БИЗНЕСА
   Живой блок: не украшаем, а объясняем состояния.
   ─────────────────────────────────────────────────────────────────────── */
.mock{box-shadow:var(--sh-3);transition:box-shadow var(--t-move) var(--e-out)}
.mock:hover{box-shadow:var(--sh-lift)}
.row{transition:background var(--t-state),transform var(--t-state) var(--e-out),
     box-shadow var(--t-state) var(--e-out)}
.row.on{box-shadow:inset 2px 0 0 var(--cyan)}
.stepper div::after{transition:transform .7s var(--e-out) var(--sd,0s)}
.stepper__l span{transition:color var(--t-state) var(--e-out)}
/* Смена карточки: короткое перекрытие, чтобы переход читался как замена. */
.read__body{transition:opacity .2s var(--e-soft),transform .2s var(--e-out),filter .2s var(--e-soft)}
.read__body.is-switching{opacity:.14;transform:translateY(6px);filter:blur(3px)}
.map-toast{box-shadow:var(--sh-3)}

/* ───────────────────────────────────────────────────────────────────────
   13. ФОРМА
   Обратная связь важнее украшений: поле в фокусе поднимает подпись,
   кольцо расцветает, состояние отправки читается на кнопке.
   ─────────────────────────────────────────────────────────────────────── */
.field{position:relative}
.field label{transition:color var(--t-state) var(--e-out),transform var(--t-state) var(--e-out)}
.field:focus-within label{transform:translateX(2px)}
.field input,.field textarea{
  transition:border-color var(--t-state) var(--e-out),
             box-shadow var(--t-state) var(--e-out),
             background var(--t-state) var(--e-out);
}
.field input:focus,.field textarea:focus{
  box-shadow:0 0 0 3px rgba(var(--accent-rgb),.16);
  background:rgba(var(--fgc),.045);
}
.field input:hover:not(:focus),.field textarea:hover:not(:focus){border-color:rgba(var(--fgc),.26)}
button[aria-busy="true"]{cursor:progress}
button[aria-busy="true"] span{opacity:.75}
.consent input{transition:transform var(--t-tap) var(--e-out)}
.consent:hover input{transform:scale(1.08)}
.status{transition:color var(--t-state),opacity var(--t-state)}
.status[data-state="err"]{animation:nudge .32s var(--e-soft)}
@keyframes nudge{25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
/* Галочка в окне подтверждения прочерчивается. */
.success-modal__icon svg path{
  stroke-dasharray:30;stroke-dashoffset:30;
  animation:draw-check .6s var(--e-out) .2s both;
}
@keyframes draw-check{to{stroke-dashoffset:0}}
.success-modal__backdrop{animation:fade-in .3s var(--e-soft) both}
@keyframes fade-in{from{opacity:0}to{opacity:1}}

/* ───────────────────────────────────────────────────────────────────────
   14. ВНУТРЕННИЕ СТРАНИЦЫ
   ─────────────────────────────────────────────────────────────────────── */
/* Таймлайн «О компании». Сплошная линия сквозь карточки читалась бы
   как ошибка вёрстки — карточки здесь отдельные, с собственной рамкой.
   Поэтому каждая получает акцентную риску у левого края: она
   прочерчивается по очереди и складывается в общую последовательность. */
.timeline{position:relative}
.timeline-date{position:relative;display:inline-block}
.timeline-item{
  position:relative;overflow:hidden;
  transition:transform var(--t-move) var(--e-out),border-color var(--t-move);
}
.timeline-item::after{
  content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:linear-gradient(180deg,transparent,var(--cyan) 22%,var(--cyan) 78%,transparent);
  transform:scaleY(0);transform-origin:50% 0;
  transition:transform .8s var(--e-out);
  transition-delay:calc(var(--i,0) * 110ms + .25s);
}
.timeline.in .timeline-item::after{transform:scaleY(1)}
.timeline-item:hover{transform:translateX(5px)}

/* Портреты руководителей: лёгкий параллакс внутри рамки
   и раскрытие маской снизу вверх. */
.executive-photo img{
  transform:scale(1.06) translate3d(0,var(--ph-par,0px),0);
  transition:transform 1.1s var(--e-out);
}
.executive-card.in .executive-photo img{transform:scale(1.02) translate3d(0,var(--ph-par,0px),0)}
/* Штора над портретом уезжает вверх. Класс .m-mask ставит скрипт и
   только после того, как портрет встал под наблюдение: если скрипт
   не отработает, шторы просто не будет и фотография видна сразу.

   Портрет — это содержимое, а не украшение: он не имеет права остаться
   закрытым из-за подвисшего наблюдателя или восстановленной позиции
   прокрутки. Поэтому там, где браузер умеет анимации по прокрутке,
   штора открывается вообще без скрипта — чистым CSS, привязанным к
   положению карточки на экране. Скриптовый путь остаётся запасным
   для браузеров постарше. */
.executive-photo.m-mask::before{
  content:"";position:absolute;inset:0;z-index:2;background:var(--bg);
  transform-origin:50% 100%;transform:scaleY(1);
  transition:transform 1.05s var(--e-out) .1s;
}
.executive-card.in .executive-photo.m-mask::before{transform:scaleY(0)}

@supports (animation-timeline:view()){
  .executive-photo.m-mask::before{
    transition:none;
    animation:curtain-open 1s linear both;
    animation-timeline:view();
    animation-range:entry 12% entry 78%;
  }
}
@keyframes curtain-open{to{transform:scaleY(0)}}

/* На телефоне шторы нет совсем.
   Карточка руководителя тут вдвое выше экрана — целиком раскрытие
   портрета всё равно не увидеть, эффект не читается. Зато любая
   осечка в его логике стоит посетителю самой фотографии. Ради
   незаметного эффекта такой риск не берём: на узких экранах портрет
   просто есть, сразу и без условий. */
@media(max-width:819px){
  .executive-photo.m-mask::before{display:none!important}
}
.executive-role{transition:transform var(--t-state) var(--e-out),background var(--t-state)}
.executive-role:hover{transform:translateY(-2px)}
.executive-focus div{transition:transform var(--t-move) var(--e-out),border-color var(--t-move)}
.executive-focus div:hover{transform:translateY(-3px);border-color:rgba(var(--accent-rgb),.3)}

/* Крупная цитата на «О компании» набирается по словам. */
.origin-quote{text-wrap:balance}

/* Нумерация направлений — часть последовательности, поэтому считается. */
.service-track__num{font-variant-numeric:tabular-nums}

/* ───────────────────────────────────────────────────────────────────────
   15. КУРСОР (только точный указатель)
   Небольшое поле, которое следует за курсором и расширяется
   над интерактивным. Не заменяет системный курсор, а дополняет.
   ─────────────────────────────────────────────────────────────────────── */
/* Два слоя с разными задачами. Внешний двигается каждый кадр вслед за
   курсором и ничего не анимирует переходом. Внутренний только меняет
   масштаб, когда курсор заходит на интерактивный элемент. Размер
   через transform, а не width/height: это единственный элемент
   страницы, который перерисовывается постоянно. */
.m-cursor{
  position:fixed;top:0;left:0;z-index:400;pointer-events:none;
  width:0;height:0;
  transform:translate3d(var(--cx,-100px),var(--cy,-100px),0);
  opacity:0;
  transition:opacity .3s var(--e-out);
  will-change:transform;
}
.m-cursor i{
  position:absolute;top:-17px;left:-17px;
  width:34px;height:34px;border-radius:50%;display:block;
  border:1px solid rgba(var(--accent-rgb),.55);
  background:radial-gradient(circle,rgba(var(--accent-rgb),.12),transparent 68%);
  transform:scale(var(--cs,1));
  transition:transform .3s var(--e-out),background .3s var(--e-out),border-color .3s var(--e-out);
}
html.m-cursor-on .m-cursor{opacity:.9}
html.m-cursor-on.m-cursor-hot .m-cursor i{
  --cs:1.55;
  border-color:rgba(var(--accent-rgb),.75);
  background:radial-gradient(circle,rgba(var(--accent-rgb),.2),transparent 66%);
}
@media(hover:none),(pointer:coarse){.m-cursor{display:none}}

/* ───────────────────────────────────────────────────────────────────────
   16. ПЕРЕХОД МЕЖДУ СТРАНИЦАМИ
   Уход быстрее прихода, направление совпадает с направлением
   шевронов логотипа.

   Важно: движение и размытие живут на .page, а не на <body>.
   Любой transform или filter на теле документа делает его содержащим
   блоком для position:fixed — и закреплённая шапка, фоновое поле и
   полоса прогресса перестают быть закреплёнными. На .page это
   безопасно: фон и шапка лежат вне неё, поэтому при переходе
   поле точек остаётся на месте, а уезжает только содержимое.
   ─────────────────────────────────────────────────────────────────────── */
body{animation:pattern-page-fade .5s var(--e-out) both}
@keyframes pattern-page-fade{0%{opacity:0}100%{opacity:1}}

.page{animation:pattern-page-enter .66s var(--e-out) both}
@keyframes pattern-page-enter{
  0%{transform:translate3d(16px,0,0);filter:blur(6px)}
  100%{transform:none;filter:none}
}
html.page-leaving body{
  opacity:0;
  transition:opacity .3s var(--e-in);
}
html.page-leaving .page{
  transform:translate3d(-16px,0,0);
  filter:blur(6px);
  transition:transform .32s var(--e-in),filter .32s var(--e-in);
}

/* ───────────────────────────────────────────────────────────────────────
   17. АДАПТАЦИЯ
   Планшет и телефон, книжная и альбомная ориентация.
   Правило простое: чем ниже экран, тем короче вертикальный ритм.
   ─────────────────────────────────────────────────────────────────────── */

/* Учитываем вырез и скруглённые углы. */
.wrap,.nav__in{
  padding-left:max(var(--pad),env(safe-area-inset-left));
  padding-right:max(var(--pad),env(safe-area-inset-right));
}
.foot{padding-bottom:max(44px,calc(34px + env(safe-area-inset-bottom)))}
.mnav__sheet{padding-top:max(86px,calc(76px + env(safe-area-inset-top)))}

/* Колонки карты бизнеса не должны раздуваться содержимым.
   По умолчанию у элемента сетки min-width:auto, поэтому одна длинная
   строка находки растягивает колонку за пределы макета. */
.mock__body>*{min-width:0}
.row__n,.read__h,.sum p,.read__body>p{overflow-wrap:anywhere}
.list__search input{min-width:0}

/* — Планшет, книжная ориентация — */
@media(min-width:761px) and (max-width:1024px){
  .hero{padding:76px 0 64px}
  .sec{padding:88px 0}
  .trio{grid-template-columns:repeat(2,1fr)}
  .info-grid.cols-3,.info-grid.cols-4,.leadership-pair{grid-template-columns:repeat(2,1fr)}
  .executive-card,.executive-card--reverse{grid-template-columns:minmax(220px,38%) 1fr}
  .executive-copy{padding:30px 30px 28px}
  /* Карта бизнеса на планшете: список и подробности рядом.
     В исходной вёрстке ниже 900 px сетка схлопывалась в одну колонку,
     но пролёты span 5 / span 7 оставались — браузер достраивал
     неявные колонки, и блоки получали разную, случайную ширину.
     Задаём две явные колонки и явные позиции. */
  .mock__body{grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);min-height:0}
  .side{grid-column:1/-1}
  .list{grid-column:1;border-right:1px solid rgba(var(--fgc),.08);border-bottom:0}
  .read{grid-column:2}
  .finding-list{max-height:340px;overflow-y:auto;overscroll-behavior:contain}
  .read__body{max-height:420px;overflow-y:auto;overscroll-behavior:contain}
  .story-grid{grid-template-columns:1fr;gap:26px}
}

/* — Планшет, альбомная ориентация — */
@media(min-width:1025px) and (max-width:1366px) and (orientation:landscape){
  :root{--wrap:1100px}
  .sec{padding:96px 0}
  .c3-card{min-height:0}
}

/* — Любой короткий экран: телефон и планшет «на боку» —
   Высоты меньше 560 px: убираем всё, что съедает вертикаль. */
@media(max-height:560px) and (orientation:landscape){
  .hero{padding:38px 0 34px;min-height:0}
  .hero h1{font-size:clamp(28px,5.4vw,44px)}
  .hero__lead{margin-top:16px;font-size:14px}
  .hero__chain{margin-top:14px}
  .hero__cta{margin-top:18px}
  .sec,.wrap.sec{padding-top:44px;padding-bottom:44px}
  .inner-hero{padding:44px 0 34px}
  .inner-hero h1{font-size:clamp(28px,5.6vw,46px)}
  .mock__body{height:auto;min-height:0}
  .nav.is-stuck .nav__in{padding-top:8px;padding-bottom:8px}
  .mnav__sheet{padding-top:70px;padding-bottom:18px;max-height:100dvh;overflow-y:auto}
  .mnav__sheet a{padding:11px 2px;font-size:15px}
  .cta{padding:34px 20px}
  .page-cta{padding:26px 22px;margin-bottom:48px}
}

/* — Телефон в альбомной ориентации: карта бизнеса снова
     раскладывается в две колонки, места по горизонтали хватает. — */
@media(max-width:900px) and (max-height:520px) and (orientation:landscape){
  .mock{width:100%;max-width:none;margin:6px auto 40px}
  .mock__body{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1.2fr);
    height:auto;min-height:0;
  }
  /* Сбрасываем колоночные пролёты широкой раскладки: иначе браузер
     достраивает недостающие колонки и сетка расползается. */
  .side{grid-column:1/-1;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;padding:10px}
  .side__btn{grid-column:1/-1;width:100%}
  .side__nav{grid-column:1/-1;display:flex;margin:0;overflow-x:auto}
  .side__tag{width:auto;min-height:34px;padding:6px 9px;font-size:11px}
  .list{grid-column:1;border-right:1px solid rgba(var(--fgc),.08);border-bottom:0;min-width:0}
  .finding-list{max-height:200px;overflow-y:auto}
  /* Подробности снова рядом со списком, а не поверх него:
     по горизонтали места хватает на обе колонки. */
  .read{grid-column:2;position:static;transform:none;opacity:1;pointer-events:auto;min-width:0}
  .mobile-map-back{display:none}
  .read__body{max-height:236px;overflow-y:auto}
  .trio,.info-grid.cols-3,.info-grid.cols-4,.leadership-pair{grid-template-columns:repeat(2,1fr)}
  .contacts{grid-template-columns:1fr 1fr;gap:26px}
  .two-col{grid-template-columns:1fr 1fr}
  .executive-card,.executive-card--reverse{grid-template-columns:minmax(200px,32%) 1fr}
  .executive-card{min-height:0}
  .story-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px}
}

/* — Очень узкие экраны — */
@media(max-width:360px){
  :root{--pad:14px}
  .hero h1{font-size:34px}
  .h2{font-size:27px}
  .hero__chain span{padding:5px 9px;font-size:11px}
  .c3-card{flex-basis:min(268px,86vw)}
  .executive-focus{grid-template-columns:1fr}
}

/* Ничто не должно выпирать по горизонтали ни на одной ширине. */
html,body{max-width:100%;overflow-x:clip}
img,svg,video,canvas{max-width:100%}
.h2,.hero h1,.inner-hero h1,.cta h2,.page-cta h2,.executive-name,
.founder-card h2,.principle h2,.origin-quote{overflow-wrap:break-word}

/* Сенсорный ввод: наведения не существует, поэтому подсветку
   карточек и магнит кнопок отключаем, а цели нажатия увеличиваем. */
@media(hover:none){
  .deliv::before,.info-card::before,.case-card::before,.timeline-item::before,
  .scope-pill::before,.service-track__item::before,.metric-card::before,
  .founder-card::before,.leadership-note::before,.contact-extra::before{display:none}
  .pill::before,.c3-btn::before{display:none}
  .info-card:hover,.metric-card:hover,.case-card:hover,
  .service-track__item:hover,.scope-pill:hover,.timeline-item:hover{transform:none}
  .brand:hover .mark path{transform:none}
  .brand:hover b{letter-spacing:.16em}
  /* Взамен — честный отклик на касание. */
  .pill:active,.c3-btn:active,.row:active,.info-card:active,
  .c3-card:active,.side__nav button:active{transform:scale(.985);transition-duration:var(--t-tap)}
}
@media(pointer:coarse){
  .nav__links a,.dl a,.consent-link{min-height:44px;display:inline-flex;align-items:center}
  .contact-chip{min-height:38px}
}

/* ───────────────────────────────────────────────────────────────────────
   18. УМЕНЬШЕННОЕ ДВИЖЕНИЕ
   Не «выключить всё», а убрать перемещение и размытие, сохранив
   смену состояний: пользователь по-прежнему видит отклик.
   ─────────────────────────────────────────────────────────────────────── */
@media(prefers-reduced-motion:reduce){
  html.m-on .rv,
  html.m-on [data-stagger]>*,
  .tx-w>i,.stage__n,.c3-check,.hero__chain span,.hero__chain i{
    transform:none!important;filter:none!important;
    transition:opacity .2s linear!important;transition-delay:0s!important;
  }
  .chain::before,.timeline-item::after,.page-rule,.hero h1::after,.stage::after{
    transform:none!important;transition:none!important;
  }
  html.m-on .wm>span{clip-path:none!important;transition:opacity .2s linear!important}
  .executive-photo.m-mask::before{display:none}
  .executive-photo img{transform:none!important}
  html.m-on .draw path,html.m-on .draw circle,html.m-on .draw polyline{
    stroke-dashoffset:0!important;transition:none!important;
  }
  .hero__cta.in .pill::after,.chain.in .stage__n::after{animation:none!important}
  .m-cursor{display:none}
  .page{animation:none!important}
  html.page-leaving .page{transform:none!important;filter:none!important}
  html.page-leaving body{transition-duration:.15s!important}
  /* Отклик на действие остаётся: он несёт смысл, а не украшает. */
  .pill:active,.c3-btn:active{transform:scale(.98)!important;transition-duration:.1s!important}
  .status[data-state="err"]{animation:none!important}
}
