/* world.css: только то, чего нет нигде, кроме главной.
   3D-сцена и её HUD, маскот, панель ассистента, карточки роликов, тарифы с
   выезжающим ящиком «что входит». Всё остальное главная берёт из site.css.

   Подключается ПОСЛЕ site.css. Несколько правил здесь намеренно переопределяют
   общие, потому что на главной у них другая работа: scroll-behavior:auto (плавная
   прокрутка спорит с полётом камеры), своя подложка под WebGL, другая плотность
   зерна поверх сцены, сетка тарифов с областями под выезжающий ящик.
   Список таких правил живёт в KEEP в scratchpad/css-merge.js. */

/* ══════ из styles.css ══════ */
:root{
  /* ── Тема одним переключателем.
     Весь интерфейс собран из полупрозрачных подложек «на белом» и линий «в чёрное».
     Поэтому вместо сотни отдельных цветов здесь ровно два канала: --w1/--w2 — то, что
     было белым (панели, стекло, заливки), --k1 — то, что было чёрным (линии, тени,
     обводки). В тёмной теме они меняются местами по светлоте, и все прозрачности,
     подобранные в светлой, продолжают работать как задумано. */
  --w1:255,255,255;
  --w2:232,235,240;
  --k1:20,23,28;
  /* фон обычной страницы — тоже частью темы, иначе в тёмной она остаётся светлой */
  --page-bg:linear-gradient(180deg,#FAFBFC 0%,#EEF0F4 42%,#F7F5F0 100%);
  /* подложка под текстом станции: приподнимает буквы над живой сценой */
  --plate:248,249,251;
  --plate-a:.95;

  --ink:#14171C;
  --ink-soft:#5A626E;
  --silver:#C9CFD8;
  --line:rgba(var(--k1),.14);
  --gold:#C79A3C;
  --gold-soft:#E4C27A;
  /* Золото для ТЕКСТА. #C79A3C на почти белом фоне даёт контраст 2.6:1 — на подписях
     в 9-11 px это читается как выцветшая надпись, особенно капслоком в разрядку.
     Тот же тон, уведённый в тень, даёт 4.2:1 и остаётся тем же золотом.
     Правило простое: линии, точки, заливки и наведение — --gold; буквы — --gold-ink. */
  --gold-ink:#9C7620;
  --paper:#F4F5F7;
  --shadow:0 24px 60px -30px rgba(var(--k1),.35);
  --font-d:"Unbounded","Onest",system-ui,sans-serif;
  --font-t:"Onest","Segoe UI",system-ui,sans-serif;
  /* --k — общий масштаб интерфейса, его считает main.js от размера окна:
     панели и текст растут вместе со сценой, поэтому вид одинаков на 4K и на ноутбуке */
  --k:1;
}
/* ── тёмная тема. Те же два канала, вывернутые по светлоте, плюс своя типографика:
   на тёмном фоне тонкое золото читается хуже, поэтому буквенное золото уходит вверх
   по яркости, а не вниз, как на светлом. Сцену переключает world.js. */
html.dark{
  --w1:26,30,37;
  --w2:16,19,24;
  --k1:226,233,243;
  --ink:#EDF1F7;
  --ink-soft:#98A2B2;
  --silver:#6D7686;
  --gold-ink:#E2B463;
  --paper:#141820;
  --shadow:0 26px 64px -32px rgba(0,0,0,.75);
  --page-bg:linear-gradient(180deg,#0D1016 0%,#141922 42%,#191410 100%);
  --plate:8,10,14;
  --plate-a:.72;
}
/* Точечные правки тёмной темы: места, где цвет был прибит к светлому и переменными
   не выражается — превью роликов, «пузырь» своего сообщения, точки карты сети. */
html.dark .v-frame,html.dark .clip-frame{background-color:#11151C}
html.dark .r-dot{background:#2A303A}
html.dark .msg-me p{background:linear-gradient(140deg,#C79A3C,#8F6C24);color:#14171C}
html.dark .bot-chips button:hover{background:rgba(var(--w1),.9)}
html.dark .btn-gold{color:#14171C}
html.dark .cta-top:hover{color:#14171C}
html.dark .v-hint,html.dark .v-live,html.dark .v-time{color:#E7ECF4}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:auto;-webkit-text-size-adjust:100%;background:#FAFBFC}
html.dark{background:#0D1016}
body{
  background:linear-gradient(180deg,#FAFBFC 0%,#EEF0F4 45%,#F7F5F0 100%);
  color:var(--ink);font-family:var(--font-t);overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
html.dark body{background:linear-gradient(180deg,#0D1016 0%,#141922 48%,#191410 100%)}
canvas#scene{position:fixed;inset:0;width:100vw;height:100vh;z-index:0;display:block}
#flip{position:fixed;inset:0;width:100vw;height:100vh;object-fit:cover;z-index:0;display:none}
/* на телефоне адресная строка съедает 100vh — берём «динамическую» высоту экрана */
@supports (height:100dvh){canvas#scene,#flip{height:100dvh}}
body.flipbook canvas#scene{display:none}
body.flipbook #flip{display:block}
body.bake .hud-top,body.bake .rail,body.bake .hud-bottom,body.bake .stations,body.bake .bot,
body.bake #grain,body.bake #vignette,body.bake #loader{display:none!important}
/* Виньетка держит читаемость шапки над живой сценой. Верхняя плёнка была плотной (.55)
   и тянулась до 22% высоты — над сценой стоял белый налёт, и сеть за ним выцветала.
   Оставляем ровно столько, сколько нужно строке статуса: вдвое слабее и вдвое короче. */
#vignette{
  position:fixed;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(120% 85% at 50% 45%, rgba(var(--w1),0) 46%, rgba(140,150,168,.11) 84%, rgba(94,105,124,.19) 100%),
    linear-gradient(180deg, rgba(var(--w2),.26) 0%, rgba(var(--w1),0) 13%);
}
/* на тёмном виньетка должна затемнять края, а не осветлять их */
html.dark #vignette{
  background:
    radial-gradient(120% 85% at 50% 45%, rgba(0,0,0,0) 40%, rgba(0,0,0,.28) 80%, rgba(0,0,0,.5) 100%),
    linear-gradient(180deg, rgba(0,0,0,.45) 0%, rgba(0,0,0,0) 24%);
}
html.dark #grain{opacity:.16;mix-blend-mode:screen}
/* Текст лежит поверх живой сцены, а в ней есть яркие места — хромовые ядра и блики.
   На светлой теме текст тёмный и всегда читается, на тёмной он светлый и над бликом
   пропадает. Мягкая тень под буквами дешевле любой плашки и не меняет вид. */
html.dark:not(.page) .station h1,html.dark:not(.page) .station h2,
html.dark:not(.page) .station .lead,html.dark:not(.page) .station p,
html.dark:not(.page) .hb-name{text-shadow:0 2px 22px rgba(0,0,0,.6),0 0 2px rgba(0,0,0,.35)}
/* У золотых слов заливка прозрачная (градиент режется по тексту) — тень от буквы
   просвечивает НАСКВОЗЬ и делает золото грязным. Им тень не нужна: они и так яркие. */
html.dark .hero-title em,html.dark .station h2 em{text-shadow:none}
/* МЯГКИЙ СВЕТ — чистая картинка: поверх сцены не лежит ничего.
   Виньетка и зерно — плёнки на весь экран; вместе со свечением они и дают тот самый
   «белый налёт». В обычном режиме они держат читаемость шапки и живость картинки,
   а мягкий режим ровно за тем и включают, чтобы смотреть на саму сцену.
   На тёмной теме виньетку оставляем: она края ЗАТЕМНЯЕТ, налётом это не читается. */
html.calm:not(.dark) #vignette{background:none}
html.calm #grain{opacity:0}
#grain{
  position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.22;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.28'/></svg>");
}
/* Длина прокрутки на все восемь узлов. Было 880vh — это ~110vh на переход, то есть
   десяток щелчков колеса на каждый узел и под восемьдесят на весь сайт: перемещаться
   тяжело. 520vh дают ~60vh на переход — один спокойный мах колеса до следующего узла,
   а доводчик ниже сам подтягивает к ближайшему. Пропорции сцены не трогаем: всё
   в кадре считается от нормированного progress, а не от пикселей. */
.scroll-space{height:520vh;pointer-events:none}

/* ── загрузка ──
   Раньше здесь была непрозрачная заставка на весь экран. Она перекрывала заголовок, и браузер
   считал «главным содержимым» не текст, а её — LCP уезжал на секунду с лишним, пока грузился
   three.js. Теперь это тонкая линия сверху: текст первого экрана виден с первой отрисовки. */
#loader{position:fixed;left:0;right:0;top:0;z-index:60;height:2px;pointer-events:none;
  transition:opacity .6s ease,visibility .6s}
#loader::before{content:"";position:absolute;left:0;top:0;height:2px;width:34%;border-radius:2px;
  background:linear-gradient(90deg,rgba(199,154,60,0),var(--gold),rgba(199,154,60,0));
  animation:loadline 1.5s cubic-bezier(.6,0,.35,1) infinite}
@keyframes loadline{0%{left:-34%}100%{left:100%}}
#loader.hide{opacity:0;visibility:hidden}
.l-ring{display:none}
@keyframes spin{to{transform:rotate(360deg)}}
.l-txt{position:absolute;top:12px;left:50%;transform:translateX(-50%);white-space:nowrap;
  font-size:9px;letter-spacing:.32em;text-transform:uppercase;color:var(--ink-soft);opacity:.8}

/* Обычная страница (без JS и по кнопке «обычная страница») описана отдельно —
   assets/home-page.css: тот же язык, что у посадочных. Здесь только живой мир. */

/* элементы, которые существуют ТОЛЬКО в обычном режиме */
html.js:not(.page) .hud-nav,html.js:not(.page) .site-foot,html.js:not(.page) .hero-stage{display:none}

/* ── спутник в живом мире ──
   Пока он летит рядом в самой сцене, капсула-кнопка ассистента не нужна: вход один,
   и это он сам. Курсор над ним меняется, чтобы было понятно, что по нему кликают. */
body.mascot-live .bot-launcher{display:none}
body.mascot-hover canvas#scene{cursor:pointer}

/* Его реплика. Живёт над сценой, но под интерфейсом и не ловит мышь: это подпись
   к живому объекту, а не кнопка — кликают по самому маскоту. */
.mas-say{position:fixed;left:0;top:0;z-index:15;max-width:min(280px,52vw);padding:10px 15px;
  border-radius:16px 16px 16px 5px;background:rgba(var(--w1),.93);border:1px solid rgba(199,154,60,.34);
  box-shadow:0 20px 44px -24px rgba(var(--k1),.55);
  font-size:13.5px;line-height:1.32;color:var(--ink);white-space:nowrap;pointer-events:none;
  opacity:0;transform:translate(-50%,-100%) translateY(10px) scale(.94);
  transition:opacity .26s ease,transform .32s cubic-bezier(.2,.9,.25,1)}
.mas-say.on{opacity:1;transform:translate(-50%,-100%) translateY(0) scale(1)}

/* «Думает». Пока модель готовит ответ, над спутником всплывают вопросы — три штуки
   вразнобой, с разной задержкой и размером: одинаковые читались бы как индикатор
   загрузки, а не как «он соображает». Позицию ставит world.js, он ходит за маскотом. */
.mas-think{position:fixed;left:0;top:0;z-index:14;pointer-events:none;opacity:0;transition:opacity .3s ease}
.mas-think.on{opacity:1}
.mas-think i{position:absolute;left:0;top:0;font-family:var(--font-d);font-style:normal;font-weight:700;
  color:var(--gold);text-shadow:0 8px 20px rgba(199,154,60,.4);opacity:0;
  animation:think 2.2s cubic-bezier(.35,0,.4,1) infinite}
.mas-think i:nth-child(1){font-size:15px;--tx:-24px;animation-delay:0s}
.mas-think i:nth-child(2){font-size:22px;--tx:2px;animation-delay:.6s}
.mas-think i:nth-child(3){font-size:13px;--tx:26px;animation-delay:1.2s}
@keyframes think{
  0%{opacity:0;transform:translate(var(--tx),8px) scale(.55) rotate(-10deg)}
  22%{opacity:1;transform:translate(var(--tx),-10px) scale(1) rotate(5deg)}
  70%{opacity:.85;transform:translate(calc(var(--tx) * 1.3),-32px) scale(1.04) rotate(-4deg)}
  100%{opacity:0;transform:translate(calc(var(--tx) * 1.6),-52px) scale(.85) rotate(8deg)}
}
@media (prefers-reduced-motion:reduce){.mas-think i{animation-duration:0s;opacity:.9;transform:translate(var(--tx),-14px)}}
@media (max-width:760px){.mas-say{font-size:12.5px;padding:8px 12px;white-space:normal}}

/* ── верхняя панель ── */
.hud-top{position:fixed;top:0;left:0;right:0;z-index:20;display:flex;align-items:center;justify-content:space-between;
  padding:26px 40px;pointer-events:none;
  transition:transform .32s cubic-bezier(.2,.8,.3,1)}
.hud-top>*{pointer-events:auto}
/* то же поведение, что у шапки обычных страниц: вниз уезжает, вверх возвращается.
   В мире прокрутка ведёт камеру, и на пролёте вперёд панель не нужна тем более. */
html.head-off .hud-top{transform:translateY(-100%)}
html.head-off .hud-top:focus-within{transform:none}
@media (prefers-reduced-motion:reduce){.hud-top{transition:none}}
.brand-name{font-family:var(--font-d);font-weight:700;font-size:17px;letter-spacing:-.02em}
.hud-mid{font-size:10px;letter-spacing:.28em;text-transform:uppercase;color:var(--ink-soft)}
.hud-status{display:flex;align-items:center;gap:8px}
.hud-status .dot{width:6px;height:6px;border-radius:50%;background:var(--gold);box-shadow:0 0 0 0 rgba(199,154,60,.5);
  animation:pulse 2.4s infinite}
@keyframes pulse{70%{box-shadow:0 0 0 9px rgba(199,154,60,0)}100%{box-shadow:0 0 0 0 rgba(199,154,60,0)}}
.cta-top{font-family:var(--font-t);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);
  background:rgba(var(--w1),.55);border:1px solid rgba(199,154,60,.55);border-radius:100px;padding:11px 20px;cursor:pointer;
  display:flex;align-items:center;gap:9px;transition:.35s}
.cta-top:hover{background:var(--gold);border-color:var(--gold);color:#fff}
.arr{transition:transform .35s}
.cta-top:hover .arr,.btn:hover .arr{transform:translateX(4px)}

/* ── карта сети (правое меню) ── */
.rail{position:fixed;right:34px;top:50%;transform:translateY(-50%) scale(var(--k));transform-origin:right center;z-index:20;width:264px;
  padding:18px 16px 16px;border-radius:18px;
  background:linear-gradient(160deg,rgba(var(--w1),.72),rgba(var(--w1),.5));
  border:1px solid rgba(var(--k1),.09);box-shadow:0 28px 60px -40px rgba(var(--k1),.5)}
.rail-head{font-size:9px;letter-spacing:.32em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:14px;
  padding-left:26px}
.rail-body{position:relative;display:flex}
.rail-track{position:absolute;left:8px;top:6px;bottom:6px;width:1px;background:rgba(var(--k1),.13)}
.rail-fill{position:absolute;left:0;top:0;width:1px;height:0;
  background:linear-gradient(180deg,var(--gold),var(--gold-soft))}
.rail ul{list-style:none;display:flex;flex-direction:column;gap:4px;width:100%}
.rail li{position:relative;display:grid;grid-template-columns:20px auto 1fr;grid-template-rows:auto auto;
  column-gap:9px;align-items:center;padding:7px 8px 7px 0;cursor:pointer;border-radius:10px;
  transition:background .3s ease,opacity .3s ease;opacity:.5}
.rail li:hover{opacity:.92;background:rgba(var(--w1),.6)}
.rail li.on{opacity:1;background:rgba(var(--w1),.85)}
.rail li.done{opacity:.72}
.r-dot{grid-row:1/3;justify-self:center;width:7px;height:7px;border-radius:50%;background:#fff;
  border:1px solid rgba(var(--k1),.28);transition:.35s;z-index:1}
.rail li.done .r-dot{background:var(--gold-soft);border-color:var(--gold-soft)}
.rail li.on .r-dot{background:var(--gold);border-color:var(--gold);box-shadow:0 0 0 4px rgba(199,154,60,.18);
  transform:scale(1.25)}
.rail li b{grid-column:2;grid-row:1;font-family:var(--font-d);font-size:9px;font-weight:400;letter-spacing:.08em;
  color:var(--ink-soft)}
.rail li.on b{color:var(--gold-ink);font-weight:700}
.r-name{grid-column:3;grid-row:1;font-size:12.5px;letter-spacing:-.005em;color:var(--ink-soft);white-space:nowrap;
  transition:.3s}
.rail li.on .r-name{color:var(--ink);font-weight:500}
.r-sub{grid-column:3;grid-row:2;font-size:9.5px;letter-spacing:.06em;color:var(--ink-soft);opacity:.72;
  font-style:normal;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail li.on .r-sub{color:var(--gold-ink);opacity:1}
.rail li::after{content:"→";position:absolute;right:8px;top:50%;transform:translate(6px,-50%);opacity:0;
  font-size:12px;color:var(--gold);transition:.3s}
.rail li:hover::after{opacity:1;transform:translate(0,-50%)}
.hud-back{color:var(--gold-ink);text-decoration:none;border-bottom:1px solid rgba(199,154,60,.5)}
.hud-back:hover{border-bottom-color:var(--gold)}

/* ── нижняя панель ── */
.hud-bottom{position:fixed;left:40px;right:40px;bottom:26px;z-index:20;display:flex;align-items:flex-end;
  justify-content:flex-start;pointer-events:none}
.hb-left{display:flex;flex-direction:column;gap:5px}
.hb-label{font-size:9px;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-soft);opacity:.75}
.hb-name{font-family:var(--font-d);font-size:15px;letter-spacing:-.01em}
/* подсказка про скролл — по центру низа: справа её накрывала капсула ассистента.
   Как только человек тронулся с места, она больше не нужна и гаснет. */
.hb-scroll{position:absolute;left:50%;bottom:2px;transform:translateX(-50%);
  display:flex;align-items:center;gap:12px;font-size:10px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink-soft);transition:opacity .6s ease}
body.moved .hb-scroll{opacity:0}
/* второй способ передвижения — тише первого: подсказка одна, но клавиши в ней
   не должны спорить с основной строкой */
.hb-keys{font-weight:400;color:var(--silver)}

/* ── автопролёт: полоска сегмента, дошла до конца — летим к следующему узлу ── */
.tour{position:absolute;left:50%;bottom:0;transform:translateX(-50%) translateY(8px);
  display:none;align-items:center;gap:12px;padding:9px 16px;border-radius:100px;pointer-events:auto;
  background:linear-gradient(150deg,rgba(var(--w1),.86),rgba(var(--w1),.7));
  border:1px solid rgba(199,154,60,.4);box-shadow:0 22px 46px -34px rgba(var(--k1),.7);
  opacity:0;transition:opacity .45s ease,transform .45s ease}
body.tour-on .hb-scroll{opacity:0}
body.tour-on .tour{display:flex;opacity:1;transform:translateX(-50%) translateY(0)}
.tour-label{font-size:9px;letter-spacing:.3em;text-transform:uppercase;color:var(--gold-ink)}
.tour-bar{position:relative;display:block;width:150px;height:2px;border-radius:2px;
  background:rgba(var(--k1),.14);overflow:hidden}
.tour-bar b{position:absolute;left:0;top:0;bottom:0;width:0;border-radius:2px;
  background:linear-gradient(90deg,var(--gold),var(--gold-soft))}
.tour-step{font-family:var(--font-d);font-size:10px;letter-spacing:.06em;color:var(--ink)}
.tour-hint{font-size:8.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft);opacity:.75}
.scroll-bar{position:relative;display:block;width:74px;height:1px;background:var(--line)}
.scroll-bar b{position:absolute;left:0;top:-1px;width:20px;height:3px;background:var(--gold);border-radius:2px;
  animation:slide 2.6s cubic-bezier(.6,0,.3,1) infinite}
@keyframes slide{0%{left:0;opacity:0}20%{opacity:1}80%{opacity:1}100%{left:54px;opacity:0}}

/* ── станции ── */
.stations{position:fixed;inset:0;z-index:10;pointer-events:none;perspective:1500px;transform-style:preserve-3d}
.station{position:absolute;width:min(560px,42vw);will-change:transform,opacity;pointer-events:none;isolation:isolate}
/* Прятать станции имеет право только сценарий. Первый экран виден СРАЗУ, из HTML и CSS,
   не дожидаясь three.js — это и есть LCP страницы. */
.js .station{opacity:0}
.js .station[data-i="0"]{opacity:1;visibility:visible}
/* Подложка под текстом узла. Это она давала в тёмной теме «светлое пятно во весь
   первый экран»: цвет был прибит гвоздями к почти белому. Теперь это переменная темы —
   в тёмной она тёмная и работает ровно так же: приподнимает буквы над сценой. */
.station::before{
  content:"";position:absolute;inset:-56px -76px;z-index:-1;pointer-events:none;
  background:radial-gradient(58% 56% at 50% 50%,
    rgba(var(--plate),var(--plate-a)) 0%,
    rgba(var(--plate),calc(var(--plate-a) * .9)) 38%,
    rgba(var(--plate),calc(var(--plate-a) * .58)) 62%,
    rgba(var(--plate),calc(var(--plate-a) * .19)) 80%,
    rgba(var(--plate),0) 100%)}
.station.live{pointer-events:auto}
/* ОДНА ПОСАДКА ДЛЯ ВСЕХ УЗЛОВ.
   Блок стоит по центру кадра со смещением влево — справа остаётся воздух,
   в котором висит сам узел сети. Раньше станции прыгали от левого края к правому,
   и каждая выглядела своей страницей; теперь композиция одна, меняется только содержимое. */
.st-center{left:calc(50% - 130px);top:50%;transform:translate(-50%,-50%);text-align:center;width:min(720px,58vw)}
/* Финал опущен: сверху остаётся воздух под само ядро сети — в него на глазах
   собирают детали. Раньше блок стоял по центру и закрывал узел собой. */
.st-final{top:60%}
@media (max-width:1100px){.st-final{top:54%}}
.st-center .btn-row,.st-center .marks{justify-content:center}
.st-node{left:calc(50% - 150px);top:50%;transform:translate(-50%,-50%);width:min(1020px,74vw);text-align:left}
.st-node .lead{margin-left:0;text-align:left}
.hero-title{font-family:var(--font-d);font-weight:300;font-size:clamp(34px,4.4vw,62px);line-height:1.08;letter-spacing:-.035em}
.hero-title em{font-style:normal;font-weight:700;
  background:linear-gradient(96deg,#8E7333 0%,#D8B45F 28%,#F2E0AE 46%,#C79A3C 68%,#7C6534 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
/* На тёмном тёмные концы градиента уходят в фон, и слово буквально обрывается.
   Тот же перелив, но вся шкала поднята по яркости. */
html.dark .hero-title em{
  background:linear-gradient(96deg,#C9A253 0%,#EBCE86 28%,#FFF3D2 46%,#E4BC66 68%,#B4924A 100%);
  -webkit-background-clip:text;background-clip:text}
/* Список возможностей на узле 06. Раньше здесь был хронометраж ролика — он держался
   на конкретном видео и врал при любой замене файла. Возможности живут дольше. */
.cap-list{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:12px 26px;margin:22px 0 4px}
.cap-list li{display:flex;flex-direction:column;gap:3px;padding-left:14px;position:relative}
.cap-list li::before{content:"";position:absolute;left:0;top:7px;width:5px;height:5px;border-radius:50%;
  background:var(--gold);box-shadow:0 0 0 3px rgba(199,154,60,.14)}
.cap-list b{font-weight:600;font-size:13.5px;line-height:1.25}
.cap-list span{font-size:12px;line-height:1.35;color:var(--ink-soft)}
@media (max-width:1100px){.cap-list{grid-template-columns:1fr;gap:10px}}
/* В карточках узлов текстовая колонка вдвое уже, чем на узле 06, — там список идёт
   в одну колонку и компактнее. Класс отдельный: у 06 список длинный и ему нужны две. */
.cap-list--slim{grid-template-columns:1fr;gap:9px;margin:16px 0 2px}
.cap-list--slim b{font-size:12.5px}
.cap-list--slim span{font-size:11.5px;line-height:1.32}
.st-num{font-size:10px;letter-spacing:.36em;text-transform:uppercase;color:var(--gold-ink);margin-bottom:14px}
.station h2{font-family:var(--font-d);font-weight:400;font-size:clamp(30px,3.4vw,50px);line-height:1.06;letter-spacing:-.035em}
.st-right .lead{margin-left:auto}
.st-center .lead{margin:20px auto 0;text-align:center}

.tags{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin-top:24px}
.tags li{font-size:12px;letter-spacing:.02em;padding:8px 14px;border-radius:100px;color:var(--ink);
  background:rgba(var(--w1),.5);border:1px solid rgba(var(--k1),.1);
  transition:.35s}
.tags li:hover{border-color:var(--gold);color:var(--gold);transform:translateY(-2px)}
/* ── КАПСУЛА РАСКРЫВАЕТСЯ.
   Раньше капсула была просто подписью (а одна — ссылкой). Теперь это переключатель:
   клик разворачивает под рядом строку о самой услуге, а наведение подсвечивает
   «свой» объект в сцене. Ссылка на посадочную переехала внутрь раскрытия — иначе
   один клик значил бы два разных действия, и попасть в нужное было бы лотереей. */
.tags li{cursor:pointer;user-select:none}
.tags li::after{content:"+";margin-left:8px;color:var(--gold);font-size:12px;line-height:1;
  display:inline-block;transition:transform .35s cubic-bezier(.3,.7,.3,1),opacity .3s;opacity:.75}
.tags li.on::after{transform:rotate(45deg);opacity:1}
.tags li.on{border-color:var(--gold);color:var(--gold);background:rgba(var(--w1),.8)}
/* у услуги есть своя страница — метка на капсуле, чтобы это было видно до раскрытия */
.tags li.has-page{border-color:rgba(199,154,60,.45);background:rgba(var(--w1),.72)}
.tags li:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

.tag-more{display:grid;grid-template-rows:0fr;opacity:0;
  transition:grid-template-rows .4s cubic-bezier(.2,.75,.2,1),opacity .3s}
.tag-more.on{grid-template-rows:1fr;opacity:1}
.tag-more>.tm-in{overflow:hidden;min-height:0}
.tag-more p{margin-top:12px;font-size:12.5px;line-height:1.5;color:var(--ink-soft);max-width:52ch;
  padding-left:12px;border-left:2px solid rgba(199,154,60,.5)}
.st-center .tag-more p{margin-left:auto;margin-right:auto;text-align:left}
.tm-go{display:inline-block;margin:9px 0 0 14px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold-ink);text-decoration:none;border-bottom:1px solid rgba(199,154,60,.45);padding-bottom:2px}
.tm-go span{display:inline-block;transition:transform .3s}
.tm-go:hover span{transform:translateX(4px)}

.st-foot{display:flex;align-items:center;gap:20px;margin-top:30px;flex-wrap:wrap}
.price{font-family:var(--font-d);font-weight:500;font-size:22px;letter-spacing:-.02em}
.term{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft)}
.btn-mini{padding:11px 18px;font-size:11px;background:rgba(var(--w1),.55);border-color:rgba(var(--k1),.14);
  color:var(--ink)}
.btn-mini:hover{border-color:var(--gold);color:var(--gold)}
.btn-row{display:flex;gap:12px;margin-top:34px;flex-wrap:wrap}

.marks{display:flex;gap:44px;margin-top:46px;flex-wrap:wrap}
.marks div{display:flex;flex-direction:column;gap:6px}
.marks b{font-family:var(--font-d);font-weight:500;font-size:26px;letter-spacing:-.03em}
.marks span{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}

/* ── раскрытый экран ролика: он есть у каждого узла ── */
.v-wrap{display:grid;grid-template-columns:1.05fr .95fr;gap:34px;align-items:center}
.v-card{display:flex;flex-direction:column;gap:12px}
.v-card[data-clip]{cursor:pointer}
.v-card[data-clip]:hover .v-frame{border-color:rgba(199,154,60,.55);transform:translateY(-3px)}
.v-card[data-clip]:hover .v-play{transform:scale(1.06);border-color:var(--gold)}
.v-frame{position:relative;aspect-ratio:16/9;border-radius:16px;overflow:hidden;
  background-color:#EDEFF3;background-size:cover;background-position:center;
  transition:transform .4s cubic-bezier(.2,.8,.3,1),border-color .4s;
  border:1px solid rgba(var(--k1),.14);box-shadow:0 40px 80px -46px rgba(var(--k1),.72)}
.v-frame::after{content:"";position:absolute;inset:0;pointer-events:none;border-radius:16px;
  background:linear-gradient(115deg,rgba(var(--w1),.55) 0%,rgba(var(--w1),0) 34%,rgba(var(--w1),0) 66%,rgba(199,154,60,.16) 100%)}
.v-frame video{width:100%;height:100%;object-fit:cover;display:block}
.v-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px}
.v-play{position:relative;width:82px;height:82px;border-radius:50%;cursor:pointer;border:1px solid rgba(199,154,60,.7);
  background:radial-gradient(120% 120% at 30% 25%,rgba(var(--w1),.95),rgba(240,236,226,.72));
  display:flex;align-items:center;justify-content:center;transition:.4s;box-shadow:0 18px 40px -22px rgba(var(--k1),.7)}
.v-play:hover{transform:scale(1.06);border-color:var(--gold)}
.v-tri{width:0;height:0;margin-left:5px;border-left:19px solid var(--gold);border-top:12px solid transparent;
  border-bottom:12px solid transparent}
.v-ring{position:absolute;inset:-12px;border-radius:50%;border:1px solid rgba(199,154,60,.35);
  animation:vpulse 2.8s ease-out infinite}
@keyframes vpulse{0%{transform:scale(.9);opacity:.9}100%{transform:scale(1.35);opacity:0}}
.v-hint{font-size:9.5px;letter-spacing:.26em;text-transform:uppercase;color:var(--ink-soft);
  background:rgba(var(--w1),.75);padding:6px 12px;border-radius:100px;border:1px solid rgba(var(--k1),.1)}
.v-bar{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:space-between;
  padding:11px 14px;background:linear-gradient(180deg,rgba(var(--w1),0),rgba(250,251,252,.9));
  font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft)}
.v-live{display:flex;align-items:center;gap:7px}
.v-live i{width:6px;height:6px;border-radius:50%;background:var(--gold);animation:pulse 2.4s infinite}
.v-tags{display:flex;gap:8px;flex-wrap:wrap}
.v-tags span{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);
  padding:7px 12px;border-radius:100px;background:rgba(var(--w1),.6);border:1px solid rgba(var(--k1),.1)}
.v-text h2{margin-bottom:0}
/* Заголовок узла ведёт на страницу узла. До этого с главной в раздел было не
   попасть вовсе: наружу вели только капсулы тех веток, у которых есть посадочная,
   а сам узел оставался тупиком. Стрелка нужна, чтобы ссылка читалась как ссылка:
   один цвет с заголовком, без подчёркивания, она иначе неотличима от текста. */
.h2-go{color:inherit;text-decoration:none;transition:color .3s}
.h2-go .go{display:inline-block;margin-left:.22em;color:var(--gold);opacity:.65;
  transform:translateX(-5px);transition:transform .3s,opacity .3s}
.h2-go:hover{color:var(--gold-ink)}
.h2-go:hover .go{transform:none;opacity:1}
.h2-go:focus-visible{outline:2px solid var(--gold);outline-offset:5px;border-radius:6px}
.v-list{list-style:none;margin-top:22px;display:flex;flex-direction:column}
.v-list li{display:flex;align-items:baseline;gap:14px;padding:9px 0;border-top:1px solid rgba(var(--k1),.1)}
.v-list b{font-family:var(--font-d);font-weight:400;font-size:11px;color:var(--gold-ink);letter-spacing:.04em;min-width:34px}
.v-list span{font-size:13.5px;color:var(--ink-soft)}
.st-video .btn-row{margin-top:26px}

/* модалка ролика */
.clip-modal{position:fixed;inset:0;z-index:70;display:none;align-items:center;justify-content:center;padding:5vh 5vw}
.clip-modal.on{display:flex}
/* Подложка без backdrop-filter: под ней живая сцена, и браузер пересчитывал бы размытие
   каждый кадр. Тот же эффект даёт плотная заливка — ролику фон не нужен вовсе. */
.clip-back{position:absolute;inset:0;background:rgba(var(--w2),.95)}
.clip-box{position:relative;width:min(980px,92vw);border-radius:20px;overflow:hidden;
  background:linear-gradient(160deg,rgba(var(--w1),.96),rgba(243,245,248,.92));
  border:1px solid rgba(var(--k1),.12);box-shadow:0 60px 120px -60px rgba(var(--k1),.9);
  animation:clipIn .4s cubic-bezier(.2,.8,.3,1)}
@keyframes clipIn{from{opacity:0;transform:translateY(16px) scale(.98)}to{opacity:1;transform:none}}
.clip-head{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 16px;
  border-bottom:1px solid rgba(var(--k1),.09)}
.clip-title{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
.clip-x{width:30px;height:30px;border-radius:9px;cursor:pointer;background:rgba(var(--w1),.7);
  border:1px solid rgba(var(--k1),.12);color:var(--ink-soft);font-size:12px}
.clip-x:hover{border-color:var(--gold);color:var(--gold)}
.clip-frame{position:relative;aspect-ratio:16/9;background:#E9ECF1 center/cover no-repeat}
.clip-frame video{width:100%;height:100%;object-fit:cover;display:none}
.clip-frame.has-video video{display:block}
/* в мире предлагаем уйти на обычную страницу, там — вернуться в мир */
html.js:not(.page) .m-to-world,html.page .m-to-page,html:not(.js) .m-to-page{display:none}

/* ── переключатель звука ── */
/* Переключатель темы. Значок — та же геометрия, что у бренда: круг, который наполовину
   залит. Светлая тема — залита нижняя половина (солнце над горизонтом), тёмная —
   верхняя. Никаких эмодзи-луны: она бы выпала из языка всего интерфейса. */
/* ── плашка переключателей вида ──
   Тема, мягкий свет и звук это один вопрос: как показывать сцену. Поодиночке
   они расползались по всей ширине шапки (шапка это flex со space-between),
   и человек искал их глазами по трём углам. Собраны в одну группу с общей
   подложкой и одним разделителем между кнопками. */
.hud-tools{display:flex;align-items:center;gap:2px;padding:3px;border-radius:100px;
  background:rgba(var(--w1),.72);border:1px solid rgba(var(--k1),.09)}
.hud-tools>button{width:36px;height:36px;border:0;background:none}
.hud-tools>button:hover{background:rgba(var(--k1),.05)}
.hud-tools>button+button{box-shadow:inset 1px 0 0 rgba(var(--k1),.08)}

.thm{position:relative;width:42px;height:42px;border-radius:50%;cursor:pointer;display:flex;align-items:center;
  justify-content:center;background:rgba(var(--w1),.55);border:1px solid rgba(var(--k1),.12);transition:.35s}
.thm:hover{border-color:var(--gold)}
.thm i{position:relative;width:16px;height:16px;border-radius:50%;border:1.5px solid var(--ink);display:block;overflow:hidden}
.thm i::after{content:"";position:absolute;left:-1px;right:-1px;bottom:-1px;height:8px;background:var(--ink);transition:.35s}
html.dark .thm i::after{bottom:auto;top:-1px}
/* ── мягкий свет: второй переключатель рядом с ночным.
   Значок объясняет режим без подписи: резкая звёздочка с лучами (обычный свет, блик
   бьёт точкой) превращается в мягкое пятно без краёв. Кнопка «нажата» — золотая. */
.calm-btn{position:relative;width:42px;height:42px;border-radius:50%;cursor:pointer;display:flex;align-items:center;
  justify-content:center;background:rgba(var(--w1),.55);border:1px solid rgba(var(--k1),.12);transition:.35s}
.calm-btn:hover{border-color:var(--gold)}
.cl-core{width:9px;height:9px;border-radius:50%;background:var(--ink);transition:.45s cubic-bezier(.3,.7,.3,1)}
.cl-ray{position:absolute;width:2px;height:5px;border-radius:2px;background:var(--ink);
  transition:.45s cubic-bezier(.3,.7,.3,1)}
.cl-ray:nth-of-type(2){transform:translateY(-11px)}
.cl-ray:nth-of-type(3){transform:translateY(11px)}
.cl-ray:nth-of-type(4){transform:translateX(-11px) rotate(90deg)}
.cl-ray:nth-of-type(5){transform:translateX(11px) rotate(90deg)}
html.calm .calm-btn{border-color:rgba(199,154,60,.5);background:rgba(var(--w1),.75)}
html.calm .cl-core{width:12px;height:12px;background:var(--gold);box-shadow:0 0 10px 3px rgba(199,154,60,.45)}
html.calm .cl-ray{opacity:0;transform:scale(.35)}
.snd{position:relative;width:42px;height:42px;border-radius:50%;cursor:pointer;display:flex;align-items:center;
  justify-content:center;gap:2.5px;background:rgba(var(--w1),.55);border:1px solid rgba(var(--k1),.12);transition:.35s}
.snd:hover{border-color:var(--gold)}
.snd-w{width:2px;border-radius:2px;background:var(--ink-soft);height:6px;transition:.3s}
.snd.on .snd-w{background:var(--gold);animation:eq 1.1s ease-in-out infinite}
.snd.on .snd-w:nth-child(1){animation-delay:0s}
.snd.on .snd-w:nth-child(2){animation-delay:.18s}
.snd.on .snd-w:nth-child(3){animation-delay:.36s}
.snd.on .snd-w:nth-child(4){animation-delay:.54s}
@keyframes eq{0%,100%{height:5px}50%{height:15px}}
.snd-off{position:absolute;width:24px;height:1px;background:var(--ink-soft);transform:rotate(-38deg);transition:.3s}
.snd.on .snd-off{opacity:0}

/* ── ассистент ── */
.bot{position:fixed;right:34px;bottom:26px;z-index:40;transform:scale(var(--k));transform-origin:right bottom}
.bot-launcher{display:flex;align-items:center;gap:12px;padding:10px 18px 10px 10px;border-radius:100px;cursor:pointer;
  background:linear-gradient(150deg,rgba(var(--w1),.9),rgba(243,244,247,.7));
  border:1px solid rgba(var(--k1),.1);box-shadow:0 26px 50px -34px rgba(var(--k1),.7);transition:.35s;position:relative}
.bot-launcher:hover{transform:translateY(-2px);border-color:rgba(199,154,60,.6)}
.bot-launch-txt{display:flex;flex-direction:column;text-align:left;gap:2px}
.bot-launch-txt b{font-size:12.5px;font-weight:500;color:var(--ink)}
.bot-launch-txt em{font-style:normal;font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft)}
.bot-badge{position:absolute;top:4px;left:36px;min-width:16px;height:16px;border-radius:100px;background:var(--gold);
  color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;font-weight:600}

/* аватар-узел */
.bot-node{position:relative;width:42px;height:42px;flex:0 0 42px;display:block}
.bn-core{position:absolute;left:50%;top:50%;width:17px;height:17px;margin:-8.5px 0 0 -8.5px;border-radius:50%;
  background:radial-gradient(120% 120% at 32% 26%,#fff 0%,#DCE1E9 42%,#9BA5B4 100%);
  box-shadow:0 2px 6px rgba(var(--k1),.28)}
.bn-ring{position:absolute;left:50%;top:50%;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;
  border:1px solid var(--gold);opacity:.75;transform:rotate(28deg) scaleY(.42);animation:botspin 7s linear infinite}
@keyframes botspin{to{transform:rotate(388deg) scaleY(.42)}}
.bn-sat{position:absolute;width:6px;height:6px;border-radius:50%;background:#B9C1CD}
.bn-sat:nth-of-type(3){left:2px;top:9px}
.bn-sat:nth-of-type(4){right:1px;bottom:11px;background:var(--gold-soft)}
.bn-sat:nth-of-type(5){left:14px;bottom:2px;width:5px;height:5px}
.bot-node--sm{width:34px;height:34px;flex:0 0 34px}
.bot-node--sm .bn-core{width:14px;height:14px;margin:-7px 0 0 -7px}
.bot-node--sm .bn-ring{width:28px;height:28px;margin:-14px 0 0 -14px}

/* панель */
.bot-panel{position:absolute;right:0;bottom:0;width:376px;max-height:min(560px,78vh);display:none;flex-direction:column;
  border-radius:20px;overflow:hidden;background:linear-gradient(165deg,rgba(var(--w1),.94),rgba(244,246,249,.88));
  border:1px solid rgba(var(--k1),.1);box-shadow:0 44px 90px -48px rgba(var(--k1),.85)}
body.bot-open .bot-panel{display:flex;animation:botIn .42s cubic-bezier(.2,.8,.3,1)}
body.bot-open .bot-launcher{display:none}
body.bot-open .rail{opacity:.16;pointer-events:none;transition:opacity .4s}
@keyframes botIn{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}
.bot-head{display:flex;align-items:center;gap:11px;padding:14px 14px 13px;border-bottom:1px solid rgba(var(--k1),.09)}
.bot-who{display:flex;flex-direction:column;gap:2px;flex:1}
.bot-who b{font-size:13px;font-weight:500}
.bot-who em{font-style:normal;font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);
  display:flex;align-items:center;gap:6px}
.bot-live{width:6px;height:6px;border-radius:50%;background:#68B37A}
.bot-min{width:26px;height:26px;border-radius:8px;border:1px solid rgba(var(--k1),.12);background:rgba(var(--w1),.6);
  cursor:pointer;color:var(--ink-soft);font-size:12px;line-height:1}
.bot-min:hover{border-color:var(--gold);color:var(--gold)}

/* лента сообщений — нанизана на золотую нить */
.bot-thread{position:relative;flex:1;overflow-y:auto;padding:18px 16px 12px 26px;display:flex;flex-direction:column;gap:12px}
.bot-thread::before{content:"";position:absolute;left:14px;top:14px;bottom:10px;width:1px;
  background:linear-gradient(180deg,rgba(199,154,60,.55),rgba(199,154,60,.08))}
.msg{position:relative;max-width:88%}
.msg p{font-size:13.5px;line-height:1.5;padding:11px 14px;border-radius:14px;color:var(--ink)}
.msg-dot{position:absolute;left:-16px;top:15px;width:7px;height:7px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 0 3px rgba(199,154,60,.16)}
.msg-bot p{background:rgba(var(--w1),.92);border:1px solid rgba(var(--k1),.09);border-top-left-radius:4px}
.msg-me{align-self:flex-end;max-width:80%}
.msg-me p{background:linear-gradient(140deg,#1B1F26,#2C333D);color:#F3F4F6;border-top-right-radius:4px}
.msg-me .msg-dot{display:none}
.msg-typing p{display:flex;gap:5px;align-items:center}
.msg-typing i{width:5px;height:5px;border-radius:50%;background:var(--ink-soft);opacity:.5;animation:blink 1.1s infinite}
.msg-typing i:nth-child(2){animation-delay:.18s}.msg-typing i:nth-child(3){animation-delay:.36s}
@keyframes blink{0%,100%{opacity:.25;transform:translateY(0)}50%{opacity:.9;transform:translateY(-2px)}}

.bot-chips{display:flex;flex-wrap:wrap;gap:6px;padding:0 14px 12px 26px}
.bot-chips button{font-family:var(--font-t);font-size:11px;padding:7px 12px;border-radius:100px;cursor:pointer;
  background:rgba(var(--w1),.75);border:1px solid rgba(var(--k1),.11);color:var(--ink-soft);transition:.3s}
.bot-chips button:hover{border-color:var(--gold);color:var(--gold);background:#fff}
.bot-input{display:flex;gap:8px;padding:12px 14px;border-top:1px solid rgba(var(--k1),.09)}
.bot-input input{flex:1;padding:11px 15px;border-radius:100px;border:1px solid rgba(var(--k1),.13);
  background:rgba(var(--w1),.8);font-family:var(--font-t);font-size:13px;color:var(--ink)}
.bot-input input:focus{outline:none;border-color:var(--gold)}
.bot-input button{width:40px;height:40px;border-radius:50%;border:none;cursor:pointer;color:#fff;font-size:15px;
  background:linear-gradient(140deg,#B98F35,#E0BC6C);transition:.3s}
.bot-input button:hover{filter:brightness(1.08);transform:translateY(-1px)}
.bot-foot{padding:0 14px 12px;font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);
  opacity:.7;text-align:center}

/* ── финал ── */
.st-final{width:min(1040px,84vw);top:60%}
.final-title{margin-bottom:34px}
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;text-align:left}
.plan{position:relative;display:flex;flex-direction:column;gap:8px;padding:24px 22px;border-radius:18px;
  background:rgba(var(--w1),.55);border:1px solid rgba(var(--k1),.1);transition:.4s}
/* ── раскрывающийся узел ──
   Свёрнутый вид держит главное — цену и срок, чтобы три варианта читались одним взглядом.
   Состав работ выезжает ящиком ПОД рядом карточек, во всю ширину и в две колонки:
   внутри карточки колонка вдвое уже, тот же текст растит её втрое, и ряд разъезжается.
   Прячем не в display:none, а в нулевую строку грида — текст остаётся в DOM, его видит
   поиск, а высоту можно анимировать (max-height пришлось бы задавать «на глаз»). */
.plans{align-items:start}
.plan{cursor:pointer}
.plan.open{border-color:rgba(199,154,60,.65);background:rgba(var(--w1),.78);transform:translateY(-4px)}
.plan-gold.open{background:linear-gradient(150deg,rgba(255,250,238,.96),rgba(243,228,193,.85))}
/* Карточка «выбирают чаще» и в тёмной теме остаётся светло-золотой — значит и буквы
   на ней должны остаться тёмными. Раньше она забирала общие светлые чернила темы
   и надписи на ней выцветали до нечитаемых. Переопределяем токены на самой карточке. */
html.dark .plan-gold{--ink:#171614;--ink-soft:#5C5546;--gold-ink:#8A6A1E;color:var(--ink)}
.pl-open{margin-top:6px;display:flex;align-items:center;gap:9px;
  font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold-ink);transition:.3s}
.plan:hover .pl-open,.plan.open .pl-open{color:var(--gold)}
.pl-open i{width:6px;height:6px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:translateY(-2px) rotate(45deg);transition:transform .38s cubic-bezier(.2,.75,.2,1)}
.plan.open .pl-open i{transform:translateY(1px) rotate(-135deg)}
.plan:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

.pl-more{display:grid;grid-template-rows:0fr;opacity:0;
  transition:grid-template-rows .45s cubic-bezier(.2,.75,.2,1),opacity .32s}
.pl-more.open{grid-template-rows:1fr;opacity:1}
.pl-more-in{overflow:hidden;min-height:0}
.pl-drawer{position:relative;margin-top:14px;padding:22px 24px 24px;border-radius:18px;text-align:left;
  background:rgba(var(--w1),.62);border:1px solid rgba(199,154,60,.34)}
/* Уголок в сторону раскрытой карточки: ящик один на три узла, и без него непонятно,
   чей состав работ сейчас показан. Едет к нужной колонке вместе с переключением. */
.pl-drawer::before{content:"";position:absolute;top:-7px;left:50%;width:12px;height:12px;
  transform:translateX(-50%) rotate(45deg);background:rgba(var(--w1),.62);
  border-left:1px solid rgba(199,154,60,.34);border-top:1px solid rgba(199,154,60,.34);
  transition:left .38s cubic-bezier(.2,.75,.2,1)}
@media (min-width:1101px){
  .plans:has(>.plan:nth-child(1).open) .pl-drawer::before{left:16.6%}
  .plans:has(>.plan:nth-child(5).open) .pl-drawer::before{left:83.4%}
  /* четыре тарифа: центры колонок другие. Тарифы это дети 1,3,5,7, между ними ящики. */
  .plans[data-n="4"]:has(>.plan:nth-child(1).open) .pl-drawer::before{left:12.5%}
  .plans[data-n="4"]:has(>.plan:nth-child(3).open) .pl-drawer::before{left:37.5%}
  .plans[data-n="4"]:has(>.plan:nth-child(5).open) .pl-drawer::before{left:62.5%}
  .plans[data-n="4"]:has(>.plan:nth-child(7).open) .pl-drawer::before{left:87.5%}
}

/* Вид карточки тарифа (первая ступень, окупаемость, плата за модель) описан один
   раз в site.css: тарифы одинаковы на главной, узлах, посадочных и листе цен.
   Здесь остаётся только то, чего нет нигде, кроме главной: раскрывающийся ящик. */
.pl-hd{font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--gold-ink);margin-bottom:14px}
.pl-list{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:11px 30px;margin:0;padding:0}
.pl-list li{position:relative;padding-left:14px;display:flex;flex-direction:column;gap:2px}
.pl-list li::before{content:"";position:absolute;left:0;top:6px;width:5px;height:5px;border-radius:50%;
  background:var(--gold);box-shadow:0 0 0 3px rgba(199,154,60,.14)}
.pl-list b{font-weight:600;font-size:12.5px;line-height:1.25}
.pl-list span{font-size:11.5px;line-height:1.34;color:var(--ink-soft)}
.pl-notes{display:grid;grid-template-columns:1fr 1fr;gap:6px 30px;margin-top:16px;padding-top:14px;
  border-top:1px solid rgba(var(--k1),.1)}
.pl-note{font-size:11.5px;line-height:1.42;color:var(--ink-soft)}
.pl-note b{font-weight:600;color:var(--ink)}
/* Ящик — общий для всех трёх карточек: он лежит второй строкой во всю ширину, а сами
   карточки держатся в первой. Закрытые ящики стоят в той же клетке нулевой высоты. */
@media (min-width:1101px){
  .plans{grid-template-rows:auto auto}
  /* карточки тянутся на всю строку — ряд остаётся ровным; ящики, наоборот, прижаты
     к верху: растянутый закрытый ящик лёг бы прозрачной плитой поверх открытого */
  .plan{grid-row:1;align-self:stretch}
  .pl-more{grid-row:2;grid-column:1/-1}
}
/* Узкий экран: карточки идут в столбик и втроём занимают его целиком. Ящик в две
   колонки там не помещается, а поверх трёх карточек — тем более. Поэтому на время
   чтения состава соседние узлы уходят: остаётся выбранный и его состав работ. */
@media (max-width:1100px){
  .pl-list,.pl-notes{grid-template-columns:1fr}
  .plans:has(.plan.open) .plan:not(.open){display:none}
  .pl-drawer{padding:18px 18px 20px}
}
/* Короткий экран телефона (667 px и ниже): даже один узел с составом не влезает целиком —
   верхний край уходит под шапку. Ящик получает свою прокрутку, а не режет содержимое.
   overscroll-behavior обязателен: докрутив список до конца, палец иначе продолжит
   прокручивать страницу — то есть уведёт камеру с узла. */
@media (max-width:900px) and (max-height:760px){
  .pl-drawer{max-height:44vh;overflow-y:auto;overscroll-behavior:contain;
    /* растворяем нижний край: обрубленная на середине строка читается как поломка,
       а не как «дальше есть ещё» — полосы прокрутки на телефоне не видно */
    -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 30px),transparent);
    mask-image:linear-gradient(180deg,#000 calc(100% - 30px),transparent)}
}
/* Раскрытый узел выше свёрнутого — блок уезжает вверх, иначе нижний край уходит
   под панель полёта. transform занят сценарием покадрово, поэтому двигаем top. */
.st-final{transition:top .45s cubic-bezier(.2,.75,.2,1)}
@media (min-width:901px){.st-final.has-open{top:52%}}
/* На телефоне блок стоит по центру и растёт в обе стороны — верхний край подбирается
   к шапке. Там, наоборот, опускаем: снизу запас есть, сверху его нет. */
@media (max-width:900px){.st-final.has-open{top:46%}}
.form{display:flex;gap:10px;margin-top:26px;justify-content:center}
.form input{width:min(420px,46vw);padding:15px 22px;border-radius:100px;border:1px solid rgba(var(--k1),.16);
  background:rgba(var(--w1),.6);font-family:var(--font-t);font-size:14px;color:var(--ink)}
.final-note{margin-top:20px;font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft)}

@media (max-width:1280px){
  .st-node,.st-video{width:min(920px,86vw)}
  .v-wrap{grid-template-columns:1fr 1fr;gap:24px}
  .v-list{display:none}
}
@media (max-width:1100px){
  .station{width:min(520px,62vw)}
  .st-node,.st-video{width:min(820px,88vw)}
  .bot{right:18px;bottom:18px}
  .bot-panel{width:min(360px,88vw)}
  .rail{right:18px}
  .plans{grid-template-columns:1fr;gap:10px}
  .st-final{width:min(560px,86vw)}
}
/* узко — экран ролика встаёт над текстом; высоту кадра ограничиваем, иначе пара
   «видео + текст» перестаёт помещаться в экран целиком */
@media (max-width:900px){
  .v-wrap{grid-template-columns:1fr;gap:16px}
  .v-frame{max-height:30vh}
  .v-card{gap:8px}
}

/* ═══ планшет и телефон ═══════════════════════════════════════════
   Карта сети переезжает вниз и становится лентой: вертикальная панель
   на узком экране съедала половину ширины и накрывала текст. */
@media (max-width:900px){
  .rail{
    left:0;right:0;bottom:0;top:auto;width:auto;z-index:35;
    transform:none;border:0;border-top:1px solid rgba(var(--k1),.09);border-radius:0;
    padding:9px 10px calc(9px + env(safe-area-inset-bottom,0px));
    background:linear-gradient(180deg,rgba(var(--w1),.55),rgba(var(--w1),.95));
    box-shadow:0 -20px 44px -32px rgba(var(--k1),.7)
  }
  .rail-head,.rail-track{display:none}
  .rail ul{flex-direction:row;gap:6px;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
  .rail ul::-webkit-scrollbar{display:none}
  .rail li{display:flex;align-items:center;gap:8px;flex:0 0 auto;padding:8px 13px;border-radius:100px;
    background:rgba(var(--w1),.62);border:1px solid rgba(var(--k1),.08)}
  .rail li::after{display:none}
  .rail li .r-sub{display:none}
  .rail li .r-name{display:none;font-size:12px}
  .rail li.on .r-name{display:block}
  .rail li b{font-size:10px}
  body.bot-open .rail{opacity:0}

  .bot{right:12px;bottom:86px;transform:none}
  .bot-launcher{padding:9px;border-radius:50%;gap:0}
  .bot-launch-txt{display:none}
  .bot-badge{top:0;right:0;left:auto}
  .bot-panel{position:fixed;left:8px;right:8px;bottom:78px;width:auto;max-height:min(72vh,540px)}

  .hud-bottom{left:16px;right:16px;bottom:82px}
  .hb-scroll{display:none}
}
@media (max-width:760px){
  .hud-top{padding:16px 14px}
  .hud-mid,.cta-top{display:none}
  /* на телефоне подпись не влезает рядом с логотипом — оставляем значок, смысл в title */
  .mode-btn{width:42px;height:42px;padding:0;border-radius:50%;justify-content:center;gap:0;
    margin-left:auto;margin-right:10px}
  .mode-btn span{display:none}
  .m-ico{width:16px;height:16px;flex:0 0 16px}
  .station,.st-center,.st-final,.st-node,.st-video{width:88vw;left:6vw;right:auto;top:44%;
    text-align:left;transform:translateY(-50%)}
  .st-center .lead,.st-node .lead{margin:16px 0 0;text-align:left}
  .st-center .btn-row,.st-center .marks{justify-content:flex-start}
  .station::before{inset:-30px -34px}
  .eyebrow{margin-bottom:14px;letter-spacing:.28em}
  .lead{margin-top:14px;font-size:14px;line-height:1.55;max-width:none}
  .tags{margin-top:16px;gap:6px}
  .tags li{font-size:11.5px;padding:7px 12px}
  .tags li:nth-child(n+7){display:none}          /* длинные списки не выпихивают кнопку за экран */
  .st-foot{margin-top:20px;gap:14px}
  .btn-row{margin-top:22px}
  .btn{padding:13px 20px;font-size:12px}
  .marks{margin-top:26px;gap:20px}
  .marks b{font-size:21px}
  .marks span{font-size:9.5px;letter-spacing:.1em}
  .v-tags,.v-bar{display:none}
  .v-play{width:62px;height:62px}
  .plans{grid-template-columns:1fr}
  .plan{padding:16px 18px;gap:5px}
  .pl-desc{font-size:12px}
  .form{flex-direction:column;margin-top:18px}
  .form input{width:100%}
  .final-note{font-size:9px;letter-spacing:.14em}
  .tour{gap:9px;padding:8px 13px}
  .tour-hint{display:none}
  .tour-bar{width:84px}
  .scroll-space{height:420vh}                    /* на тач-скролле дистанция короче */
  .clip-modal{padding:0}
  .clip-box{width:100vw;border-radius:0}
}
@media (max-width:760px) and (max-height:720px){
  .marks,.final-note{display:none}
  .station{top:42%}
}
/* пользователь просил меньше движения — оставляем только смысловое */
@media (prefers-reduced-motion:reduce){
  .scroll-bar b,.v-ring,.bn-ring,.snd.on .snd-w{animation:none}
}
/* ══════ из assets/home-page.css ══════ */
/* home-page.css — ГЛАВНАЯ КАК ОБЫЧНАЯ СТРАНИЦА.
   У сайта два лица, и только два: живой мир и обычная страница. Обычная — не «урезанный
   вариант мира», а та же посадочная вёрстка, что у страниц категорий (assets/page.css):
   золотая нить вдоль разделов, металлические пластины, раскрытые экраны роликов.
   Разметка при этом ОДНА — index.html. Меняются только правила.

   Действует в двух случаях:
     html.page      — человек сам выбрал обычный режим кнопкой в шапке;
     html:not(.js)  — сценарий выключен или это робот, который не рендерит JS.
   Поэтому каждое правило адресовано обоим: :is(html:not(.js),html.page).
   `:is()` берёт вес самого «тяжёлого» аргумента (.page) — этого хватает, чтобы перебить
   правила мира из styles.css, которые идут выше по файлу. */

/* ── что нужно ТОЛЬКО обычной странице ──
   data-flat-only стоял в разметке с самого начала, а правила под него не было ни
   в одном файле: атрибут ничего не значил. Поэтому в живом мире поверх сцены
   висела полоса контактов, которую перекрывала шапка, и туда же попадала сводка
   отзывов. В мире у обоих есть свои формы: контакты живут в самой сцене, отзывы
   приходят на своей станции. */
html.js:not(.page) [data-flat-only]{display:none}

/* ── что в обычном режиме не нужно ── */
:is(html:not(.js),html.page) canvas#scene,
:is(html:not(.js),html.page) #flip,
:is(html:not(.js),html.page) #loader,
:is(html:not(.js),html.page) .rail,
:is(html:not(.js),html.page) .hud-bottom,
:is(html:not(.js),html.page) .scroll-space,
:is(html:not(.js),html.page) .hud-mid,
:is(html:not(.js),html.page) .snd{display:none}
html:not(.js) .bot{display:none}          /* без сценария ассистент всё равно не ответит */
/* на обычной странице ассистент сворачивается в кружок: развёрнутая капсула
   ложилась поверх кнопки «запросить расчёт» в правом нижнем углу раздела */
html.page .bot-launcher{padding:9px;border-radius:50%;gap:0}
html.page .bot-launch-txt{display:none}
html.page .bot-badge{top:0;right:0;left:auto}

/* ── маскот в углу ──
   Живёт только на обычной странице: в мире он летит рядом с камерой прямо в сцене.
   Когда чат раскрывается, он переезжает влево и встаёт рядом с окном, а не за ним. */
.mascot-dock{display:none}
html.page .mascot-dock{display:block;position:fixed;right:16px;bottom:10px;
  width:146px;height:166px;z-index:41;cursor:pointer;
  transition:right .55s cubic-bezier(.2,.8,.3,1),transform .35s ease}
html.page .mascot-dock canvas{width:100%;height:100%;display:block}
html.page .mascot-dock:hover{transform:translateY(-4px)}
html.page .mascot-dock:focus-visible{outline:2px solid var(--gold);outline-offset:6px;border-radius:18px}
html.page body.bot-open .mascot-dock{right:calc(376px + 40px)}
.md-tip{position:absolute;left:50%;bottom:-2px;transform:translateX(-50%) translateY(6px);
  white-space:nowrap;pointer-events:none;opacity:0;transition:.35s;
  font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft);
  background:rgba(var(--w1),.9);border:1px solid rgba(var(--k1),.1);padding:6px 12px;border-radius:100px}
html.page .mascot-dock:hover .md-tip{opacity:1;transform:translateX(-50%) translateY(0)}
html.page body.bot-open .md-tip{display:none}
.md-badge{position:absolute;top:16px;right:12px;min-width:17px;height:17px;border-radius:100px;
  background:var(--gold);color:#fff;font-size:9px;display:flex;align-items:center;justify-content:center;
  font-weight:600;pointer-events:none}
html.page body.bot-open .md-badge{display:none}
/* пока маскот на месте, капсула-кнопка ассистента не нужна — вход один */
html.mascot-dock-on .bot-launcher{display:none}
@media (max-width:900px){
  html.page .mascot-dock{width:110px;height:126px;right:8px;bottom:4px}
  html.page body.bot-open .mascot-dock{display:none}   /* панель занимает всю ширину */
  .md-tip{display:none}
}

/* Мир не смог запуститься, и мы говорим об этом прямо, а не подсовываем молча
   другую страницу. Текст правился 11.08.2026: раньше он винил устройство,
   «не запустился на этом устройстве». Единственная причина этого состояния,
   которая вообще бывает, это неудачная загрузка файла сцены (см. main.js), и
   на боевом сервере так и вышло: файл не доехал. Человек с нормальной машиной
   читал, что дело в его машине, и это была неправда. */
html.world-failed .stations::before{content:"живая сцена не загрузилась, показываем обычную страницу";
  display:block;margin:0 auto 22px;width:fit-content;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold);border:1px solid rgba(199,154,60,.5);border-radius:100px;padding:8px 16px}

:is(html:not(.js),html.page) body{
  overflow-x:hidden;
  background:
    radial-gradient(120% 60% at 78% -8%, rgba(199,154,60,.10) 0%, rgba(199,154,60,0) 60%),
    var(--page-bg);
  background-attachment:fixed;
}
:is(html:not(.js),html.page) #grain{opacity:.16}

/* ── шапка: не накладка поверх сцены, а обычная липкая полоса ── */
:is(html:not(.js),html.page) .hud-top{
  position:sticky;top:0;left:auto;right:auto;z-index:30;pointer-events:auto;gap:22px;
  padding:11px max(18px, calc(50vw - min(1180px,92vw)/2));
  background:rgba(var(--w1),.97);border-bottom:1px solid rgba(var(--k1),.07);
}
.hud-nav{display:flex;gap:20px;margin-left:auto;font-size:13px}
.hud-nav a{color:var(--ink-soft);text-decoration:none;transition:.3s}
.hud-nav a:hover{color:var(--gold)}
:is(html:not(.js),html.page) .mode-btn{border-color:rgba(199,154,60,.55);color:var(--gold);
  background:rgba(var(--w1),.85)}
@media (max-width:900px){.hud-nav{display:none}}

/* ── лента разделов ──
   Разделы идут один под другим и отбиты верхней границей. Золотую нить вдоль
   левого поля убрали вместе с такой же на посадочных: у края экрана она читалась
   как случайная вертикальная полоса, а не как связь узлов. */
:is(html:not(.js),html.page) .stations{
  position:relative;inset:auto;z-index:2;pointer-events:auto;perspective:none;transform-style:flat;
  width:min(1180px,92vw);margin:0 auto;padding:8px 0 30px;
}
:is(html:not(.js),html.page) .station{
  position:relative;left:auto;right:auto;top:auto;width:auto;
  opacity:1;visibility:visible;transform:none;pointer-events:auto;
  text-align:left;padding:58px 0;border-top:1px solid rgba(var(--k1),.09);
}
:is(html:not(.js),html.page) .station::before{display:none}
:is(html:not(.js),html.page) #s0{border-top:0;padding-top:26px}

/* ── первый экран: текст и живой узел рядом ── */
:is(html:not(.js),html.page) #s0{
  display:grid;grid-template-columns:1.04fr .96fr;gap:50px;align-items:center;text-align:left;
}
:is(html:not(.js),html.page) #s0 .lead{margin:20px 0 0;text-align:left;max-width:46ch}
:is(html:not(.js),html.page) #s0 .btn-row,
:is(html:not(.js),html.page) #s0 .marks{justify-content:flex-start}
:is(html:not(.js),html.page) .hero-title{font-size:clamp(32px,4vw,56px)}

/* УЗЕЛ ГЕРОЯ: 2D-узел на 5 КБ рисуется сразу, настоящий 3D проявляется поверх,
   когда догрузится движок. Композиция у обоих одна, поэтому подмены не видно.
   Кадра-заглушки здесь нет намеренно: LCP страницы — заголовок, и добавлять
   на критический путь ещё одну картинку незачем. */
.hero-stage{position:relative;aspect-ratio:1/1;isolation:isolate}
.hero-stage::before{content:"";position:absolute;inset:-10%;z-index:0;pointer-events:none;
  background:radial-gradient(46% 46% at 50% 50%, rgba(226,188,110,.22) 0%, rgba(226,188,110,.07) 46%,
    rgba(226,188,110,0) 72%)}
.stage-still,.stage-3d{position:absolute;inset:0;width:100%;height:100%;z-index:1}
html.poster .stage-still,html.poster .stage-cap{display:none}

/* ── узлы: текст слева, экран ролика справа ──
   В мире ролик стоит слева: он там ближе к сцене, из которой камера прилетела.
   На обычной странице читают сверху вниз и слева направо, поэтому первым идёт
   заголовок с описанием, а ролик уходит вправо. Порядок в разметке при этом не
   меняется: ролик остаётся первым ребёнком, и мир, и чтение с экрана берут его
   оттуда же, где он был. Перестановка живёт только в раскладке. */
:is(html:not(.js),html.page) .v-wrap{grid-template-columns:1.02fr .98fr;gap:38px}
:is(html:not(.js),html.page) .v-text{grid-area:1/1}
:is(html:not(.js),html.page) .v-card{grid-area:1/2}
:is(html:not(.js),html.page) .v-list{display:flex}
:is(html:not(.js),html.page) .v-frame{max-height:none}
:is(html:not(.js),html.page) .station h2{font-size:clamp(26px,2.9vw,42px)}
:is(html:not(.js),html.page) .lead{max-width:52ch}

/* ── цены и заявка ── */
:is(html:not(.js),html.page) #s7{text-align:center;padding-bottom:70px}
:is(html:not(.js),html.page) #s7 .plans{grid-template-columns:repeat(3,1fr)}
:is(html:not(.js),html.page) #s7 .form{justify-content:center}

/* ── подвал ── */
.site-foot{position:relative;z-index:2;width:min(1180px,92vw);margin:0 auto;
  padding:44px 0 60px;border-top:1px solid rgba(var(--k1),.1)}
/* Подвал главной это тот же подвал, что на остальных страницах: контакты одной
   строкой, ссылки разделов ниже. Раскладка описана в site.css, здесь только то,
   что своё у главной: своя ширина и отступы. */
.site-foot .foot{display:flex;flex-direction:column;gap:26px;
  font-size:12.5px;color:var(--ink-soft)}
.site-foot a{text-decoration:none;color:inherit}
.site-foot a:hover{color:var(--gold)}
.site-foot .foot-cols{display:flex;gap:54px;flex-wrap:wrap}
.site-foot .foot-col{display:flex;flex-direction:column;gap:7px}
.site-foot>.foot>.foot-col{flex-direction:row;flex-wrap:wrap;align-items:center;gap:10px 22px}
.site-foot .foot-col b{font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink);
  opacity:.6;margin-bottom:3px}
.site-foot .brand{color:var(--ink);margin-bottom:4px}
.site-foot .brand b{font-family:var(--font-d);font-weight:700;font-size:16px;letter-spacing:-.02em;opacity:1;
  text-transform:none}

@media (max-width:900px){
  :is(html:not(.js),html.page) #s0{grid-template-columns:1fr;gap:26px}
  /* width:100% + justify-self обязательны: `margin:0 auto` у grid-элемента отключает
     растягивание, и коробка с одними абсолютными детьми схлопывается в ноль */
  :is(html:not(.js),html.page) .hero-stage{width:100%;max-width:400px;justify-self:center;order:-1}
  :is(html:not(.js),html.page) .station{padding:40px 0}
  /* в одну колонку перестановка не нужна, и жёсткие координаты сетки её бы сломали:
     grid-area:1/2 создал бы вторую колонку из ничего */
  :is(html:not(.js),html.page) .v-wrap{grid-template-columns:1fr;gap:18px}
  :is(html:not(.js),html.page) .v-text,
  :is(html:not(.js),html.page) .v-card{grid-area:auto}
  :is(html:not(.js),html.page) #s7 .plans{grid-template-columns:1fr}
}