/* Анимации русской версии. Всё под .motion: класс ставит motion-boot.js, и не ставит при
   prefers-reduced-motion, поэтому без него страница выглядит как обычно. */

/* Плавный переход между страницами там, где браузер это умеет. */
@media(prefers-reduced-motion:no-preference){
 @view-transition{navigation:auto}
 ::view-transition-old(root){animation:vt-out .32s cubic-bezier(.4,0,1,1) both}
 ::view-transition-new(root){animation:vt-in .55s cubic-bezier(.16,1,.3,1) both}
}
@keyframes vt-out{to{opacity:0;transform:scale(.985)}}
@keyframes vt-in{from{opacity:0;transform:translateY(18px)}}

/* Сцена с частицами лежит за всем содержимым страницы. */
.stage{position:fixed;left:0;top:0;width:100%;height:100lvh;z-index:0;pointer-events:none;opacity:0;transition:opacity .9s ease}
.stage.is-on{opacity:1}
/* Содержимое поднято над холстом обычным порядком слоёв: отрицательный z-index у холста
   давал в WebKit пустой экран. */
.motion-gl .site-header{position:relative;z-index:2}
.motion-gl main,.motion-gl .site-footer,.motion-gl .analytics-notice{position:relative;z-index:1}

/* Полоса прогресса чтения. */
.scroll-bar{position:fixed;left:0;top:0;right:0;height:2px;z-index:70;background:var(--color-link);transform:scaleX(var(--p,0));transform-origin:0 50%;pointer-events:none}

/* Первый экран: сверху живёт логотип из частиц, снизу текст. */
.motion-gl .cover{min-height:calc(100svh - var(--space-80));box-sizing:border-box;display:flex;flex-direction:column;justify-content:flex-end;padding-top:clamp(210px,40svh,460px);padding-bottom:var(--space-48)}
.motion-gl .cover .cover-intro{margin-top:var(--space-20)}
.motion-gl .cover .actions{margin-top:var(--space-24)}

/* Заголовки появляются по словам из-под маски. */
.motion .w{display:inline-block;max-width:100%;overflow:hidden;vertical-align:top;padding-bottom:.14em;margin-bottom:-.14em;padding-inline:.04em;margin-inline:-.04em}
.motion .wi{display:inline-block;max-width:100%;overflow-wrap:anywhere;transform:translateY(112%) rotate(4deg);transform-origin:0 100%;transition:transform 1.15s cubic-bezier(.16,1,.3,1);transition-delay:calc(var(--i,0)*55ms + var(--wd,0ms));will-change:transform}
.motion .split.in .wi{transform:none}
/* Страховка: если скрипт не загрузился, заголовок первого экрана всё равно появится. */
.motion .cover h1:not(.split),.motion .inner-hero h1:not(.split){animation:motion-failsafe .4s 1.4s both}
@keyframes motion-failsafe{from{opacity:0}to{opacity:1}}

/* Первый экран: остальные элементы проявляются после заголовка без участия скрипта. */
.motion .cover-intro,.motion .cover .actions,.motion .cover-location,.motion .inner-hero .hero-lead,.motion .inner-hero .eyebrow,.motion .inner-hero .actions{animation:rise-in 1.1s cubic-bezier(.16,1,.3,1) both;animation-delay:var(--rd,.55s)}
.motion .cover .actions{--rd:.72s}.motion .cover-location{--rd:.9s}.motion .inner-hero .eyebrow{--rd:.1s}.motion .inner-hero .actions{--rd:.7s}
@keyframes rise-in{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}

/* Блоки появляются при прокрутке. */
.motion .r{opacity:0;translate:0 38px;transition:opacity .95s cubic-bezier(.2,.7,.2,1),translate 1.25s cubic-bezier(.16,1,.3,1);transition-delay:var(--d,0ms)}
.motion .r.in{opacity:1;translate:none}

/* Строки услуг: линия прорисовывается, при наведении строка оживает. */
.motion .service-rows{border-top-color:transparent;position:relative}
.motion .service-rows::before{content:"";position:absolute;left:0;right:0;top:-1px;height:1px;background:var(--line);transform:scaleX(0);transform-origin:0 50%;transition:transform 1.4s cubic-bezier(.16,1,.3,1)}
.motion .service-rows.in::before{transform:none}
.motion .service-row{position:relative;border-bottom-color:transparent}
.motion .service-row::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--line);transform:scaleX(0);transform-origin:0 50%;transition:transform 1.4s cubic-bezier(.16,1,.3,1) calc(var(--d,0ms) + .1s)}
.motion .service-row.in::after{transform:none}
.motion .service-row h3,.motion .service-row .row-no,.motion .service-row .row-arrow,.motion .service-row p{transition:transform .7s cubic-bezier(.16,1,.3,1),color .35s ease,opacity .35s ease}
@media(hover:hover){
 .motion .service-rows:hover .service-row:not(:hover) h3,.motion .service-rows:hover .service-row:not(:hover) p{opacity:.35}
 .motion .service-row:hover h3{transform:translateX(14px)}
 .motion .service-row:hover .row-no{color:var(--color-link)}
 .motion .service-row:hover .row-arrow{transform:translate(6px,-6px) scale(1.25);color:var(--color-link)}
}

/* Подсветка плиток, которая следует за курсором. */
.spot{position:relative;isolation:isolate}
.spot::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:radial-gradient(420px circle at var(--mx,50%) var(--my,50%),color-mix(in srgb,var(--color-link) 16%,transparent),transparent 70%);opacity:0;transition:opacity .45s ease;pointer-events:none}
@media(hover:hover){.spot:hover::before{opacity:1}}

/* Кейс: снимок выпрямляется при прокрутке и наклоняется за курсором. */
.motion .case-tile{position:relative}
.motion .case-shot,.motion .case-shot:hover,.motion .case-shot:focus-visible{position:relative;transform:perspective(1400px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) scale(var(--sc,1));transition:box-shadow .5s ease;transform-style:preserve-3d;will-change:transform}
.motion .case-shot::after{content:"";position:absolute;inset:0;background:radial-gradient(600px circle at var(--gx,50%) var(--gy,0%),rgb(255 255 255 / .22),transparent 60%);opacity:var(--ga,0);transition:opacity .4s ease;pointer-events:none}
.motion .case-stats dd{transition:color .3s ease}

/* Инструменты: снимок выезжает снизу плитки. */
.motion .tool-tile img{translate:0 var(--tx,0px);will-change:translate}
.motion .project-image img,.motion .example-preview img{transition:transform 1.2s cubic-bezier(.16,1,.3,1)}
@media(hover:hover){.motion .project-image:hover img,.motion .example-preview a:hover img{transform:scale(1.025)}}

/* Магнитные кнопки: используем translate, чтобы не спорить с transform из interaction-kit. */
.motion .button{translate:var(--bx,0px) var(--by,0px);transition:translate .55s cubic-bezier(.16,1,.3,1),transform var(--ui-release,.2s) var(--ui-spring-pop,ease),background-color .2s ease,color .2s ease,filter .2s ease;position:relative;overflow:hidden}
.motion .button::after{content:"";position:absolute;top:0;bottom:0;left:-60%;width:40%;transform:skewX(-20deg);background:linear-gradient(90deg,transparent,rgb(127 127 127 / .35),transparent);transition:left .9s cubic-bezier(.16,1,.3,1);pointer-events:none}
@media(hover:hover){.motion .button:hover::after{left:120%}}

/* Финальный экран: заголовок подрастает к призыву. */
.motion .closing h2{transform:scale(var(--cs,1));transform-origin:0 50%;will-change:transform}

/* Карточки цен и контакты слегка приподнимаются. */
@media(hover:hover){
 .motion .services .price-card,.motion .contact-grid>a,.motion .demo-card{transition:translate .6s cubic-bezier(.16,1,.3,1),background-color .25s ease}
 .motion .services .price-card:hover,.motion .contact-grid>a:hover,.motion .demo-card:hover{translate:0 -6px}
}

@media(max-width:734px){
 .motion-gl .cover{padding-top:clamp(170px,27svh,260px);min-height:0;padding-bottom:var(--space-40)}
}
@media print{.stage,.scroll-bar{display:none}.motion .r,.motion .wi{opacity:1!important;translate:none!important;transform:none!important}}
