/* ═══════════════════════════════════════════════════════════
   VTS ENGINEERING — дизайн-система

   Палитра — единственный источник цвета в проекте.
   Графит (холст) → белый (текст) → золото (акцент).

   Правило акцента: золото отмечает то, что живёт или что
   измеряется — шов, ток, поток, траекторию, размер, разрез.
   Вся остальная геометрия чертежей — белый с прозрачностью.
   ═══════════════════════════════════════════════════════════ */

:root{
  /* ─── поверхности ─── */
  --canvas:    #0E1013;   /* фон */
  --surface:   #16191E;   /* карточки */
  --surface-2: #1E222A;   /* приподнятая поверхность */

  /* ─── текст ─── */
  --text:      #ECEFF2;   /* основной */
  --text-2:    #A3ABB4;   /* вторичный */
  --text-3:    #6E767F;   /* приглушённый (только крупный или декоративный) */

  /* ─── акцент ─── */
  --gold:      #C6A16A;
  --gold-hi:   #D9BA8B;   /* hover */
  --gold-line: rgba(198,161,106,.32);
  --gold-soft: rgba(198,161,106,.10);
  --gold-haze: rgba(198,161,106,.07);
  --gold-glow: rgba(198,161,106,.17);

  /* Свечение под курсором.
     Ступеней много намеренно: затухание идёт по кривой, близкой к настоящему
     источнику света — маленькое яркое ядро и длинный еле заметный хвост.
     Нигде не используется ключевое слово transparent: оно означает
     ПРОЗРАЧНЫЙ ЧЁРНЫЙ, и градиент к нему идёт через темнеющие оттенки,
     рисуя по краю сероватое кольцо. Уходим в тот же цвет с нулевой альфой. */
  --glow: radial-gradient(closest-side,
    rgba(217,186,139,.20)  0%,
    rgba(207,173,120,.135) 7%,
    rgba(198,161,106,.085) 14%,
    rgba(198,161,106,.052) 22%,
    rgba(198,161,106,.030) 32%,
    rgba(198,161,106,.017) 44%,
    rgba(198,161,106,.009) 57%,
    rgba(198,161,106,.004) 72%,
    rgba(198,161,106,.001) 86%,
    rgba(198,161,106,0)    100%);

  /* золотой блик — ровно одно слово на всей странице */
  --gold-sheen: linear-gradient(102deg,
    #8A6E42 0%, #E4CB9E 32%, #C6A16A 50%, #7E6339 70%, #EFDCB8 100%);

  /* ─── линии: белый с прозрачностью, без отдельного цвета ─── */
  --line:      rgba(255,255,255,.09);   /* hairline: рамки, разделители */
  --line-soft: rgba(255,255,255,.05);
  --grid:      rgba(255,255,255,.045);  /* фоновые инженерные сетки */
  --draw:      rgba(255,255,255,.15);   /* линии чертежей */
  --draw-dim:  rgba(255,255,255,.09);   /* второстепенные линии чертежей */

  /* ─── статусные ───
     Зарезервированы системой. На сайте задействован только danger —
     в состояниях ошибки формы. Остальные ждут применения. */
  --success: #6FA88A;
  --warning: #D9A54B;
  --danger:  #C2584B;
  --info:    #6E8CA8;

  /* ─── геометрия ─── */
  --gutter: clamp(20px, 4vw, 56px);
  --maxw: 1320px;
  /* Единый вертикальный ритм между ВСЕМИ крупными блоками сайта —
     направления, «О компании», «Проекты», «Как работаем», «Преимущества»,
     заявка, контакты. Раньше --sec-pad (150+px на 1280px) и отступ между
     направлениями (.dir) жили разными числами — блоки не читались
     одинаково. Теперь один источник: .dir тоже ссылается на эту
     переменную. Сжато по просьбе заказчика — меньше чёрного экрана
     между блоками при скролле, везде поровну. */
  --sec-pad: clamp(28px, 3.4vw, 50px);
  --hdr-h: 72px;   /* было 76px→96px→116px→108px, теперь под 40px логотип, см. .logo--hdr */

  /* ─── движение ─── */
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-draw: cubic-bezier(.62,.03,.31,1);

  /* ─── шрифты ─── */
  --sans: "Manrope","Segoe UI",system-ui,-apple-system,sans-serif;
  --mono: "JetBrains Mono",Consolas,"SF Mono",ui-monospace,monospace;
}

/* ─── база ─────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; }

html{
  scroll-behavior:smooth;
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--canvas);
  color:var(--text);
  font-family:var(--sans);
  font-size:clamp(15px,1.05vw,16.5px);
  line-height:1.65;
  font-weight:400;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

body.is-locked{ overflow:hidden; }

img,svg{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; }

::selection{ background:var(--gold); color:var(--canvas); }

:focus-visible{
  outline:1px solid var(--gold);
  outline-offset:3px;
  border-radius:2px;
}

.skip-link{
  position:absolute; left:-9999px; top:0; z-index:200;
  padding:12px 20px; background:var(--gold); color:var(--canvas);
  font-family:var(--mono); font-size:12px;
}
.skip-link:focus{ left:12px; top:12px; }

.container{
  width:100%;
  max-width:var(--maxw);
  margin-inline:auto;
  padding-inline:var(--gutter);
  /* Поднимаем содержимое над слоем свечения (.cursor-glow, z-index:0),
     чтобы свет оставался на фоне и уходил за текст, кнопки и карточки. */
  position:relative;
  z-index:1;
}

/* ─── свечение под курсором ───
   Фоны секций рисуются как фоны неспозиционированных блоков, то есть
   раньше любого позиционированного элемента. Поэтому слой с z-index:0
   ложится поверх фонов, но ниже поднятого содержимого. */
.cursor-glow{
  position:fixed; top:0; left:0;
  /* Габарит больше видимого пятна: хвосту нужно место, чтобы дойти
     до нуля. Яркое ядро — примерно внутренние 15 %, то есть на глаз
     свечение читается как ~60 px, а не как 300.
     Стороны намеренно не равны: идеальный круг выглядит синтетическим. */
  width:300px; height:272px;
  margin:-136px 0 0 -150px;          /* половина габарита — центр на курсоре */
  z-index:0;
  pointer-events:none;
  background:var(--glow);            /* без border-radius: свет гаснет сам */
  opacity:0;
  transform:translate3d(-9999px,-9999px,0);
  transition:opacity .45s var(--ease);
  will-change:transform;
}
body.is-hot .cursor-glow{ opacity:1; }

/* ─── типографика ──────────────────────────────────────── */
.mono{
  font-family:var(--mono);
  font-size:11px;
  font-weight:500;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--text-2);
}

.h2{
  font-size:clamp(30px,4.4vw,60px);
  line-height:1.06;
  font-weight:800;
  letter-spacing:-.035em;
  margin:14px 0 0;
}

/* надзаголовок секции: золотая риска + нейтральный текст */
.label{
  display:inline-flex; align-items:center; gap:12px;
  margin:0;
}
.label::before{
  content:""; width:36px; height:1px; background:var(--gold);
}

.sheen{
  background:var(--gold-sheen);
  background-size:220% 100%;
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
  animation:sheen 7s var(--ease) infinite;
}
@keyframes sheen{
  0%,100%{ background-position:0% 50%; }
  50%    { background-position:100% 50%; }
}

/* ─── появление по скроллу ─────────────────────────────── */
.reveal{
  opacity:0;
  transform:translateY(26px);
  transition:opacity .85s var(--ease) var(--d,0s),
             transform .85s var(--ease) var(--d,0s);
}
.is-visible .reveal{ opacity:1; transform:none; }

/* ─── кнопки ───────────────────────────────────────────── */
.btn{
  --btn-pad: 15px 30px;
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:var(--btn-pad);
  font-family:var(--mono);
  font-size:11.5px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase;
  border:1px solid var(--line);
  border-radius:2px;
  background:transparent;
  color:var(--text);
  cursor:pointer;
  position:relative;
  overflow:hidden;
  transition:border-color .4s var(--ease), color .4s var(--ease), background-color .4s var(--ease);
}
.btn::after{
  content:"";
  position:absolute; inset:0;
  background:linear-gradient(105deg,transparent 20%,rgba(255,255,255,.14) 50%,transparent 80%);
  transform:translateX(-120%);
  transition:transform .7s var(--ease);
}
.btn:hover::after{ transform:translateX(120%); }

.btn--solid{
  background:var(--gold);
  border-color:var(--gold);
  color:var(--canvas);
  font-weight:600;
}
.btn--solid:hover{ background:var(--gold-hi); border-color:var(--gold-hi); }

.btn--ghost:hover{ border-color:var(--gold-line); color:var(--gold); }

.btn--wide{ width:100%; padding:18px 30px; }

/* ─── сплит-кнопка «Смотреть направления» с выпадающим списком ───
   Слева — обычная ссылка (клик = переход к #directions, как было),
   справа — отдельная кнопка-шеврон, раскрывающая список всех 8 направлений,
   чтобы можно было прыгнуть сразу к нужному, не пролистывая остальные. */
.dir-menu{
  position:relative;
  display:inline-flex; align-items:stretch;
  border:1px solid var(--line);
  border-radius:2px;
  transition:border-color .35s var(--ease);
}
.dir-menu:hover,
.dir-menu.is-open{ border-color:var(--gold-line); }
.dir-menu__label{
  display:inline-flex; align-items:center;
  padding:15px 20px;
  font-family:var(--mono);
  font-size:11.5px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase;
  color:var(--text);
  transition:color .35s var(--ease);
}
.dir-menu:hover .dir-menu__label,
.dir-menu.is-open .dir-menu__label{ color:var(--gold); }
.dir-menu__toggle{
  display:inline-flex; align-items:center; justify-content:center;
  width:40px;
  border:0; border-left:1px solid var(--line);
  background:transparent;
  color:var(--text-3);
  cursor:pointer;
  transition:color .35s var(--ease), border-color .35s var(--ease);
}
.dir-menu:hover .dir-menu__toggle,
.dir-menu.is-open .dir-menu__toggle{ border-color:var(--gold-line); color:var(--gold); }
.dir-menu__chev{ width:10px; height:7px; transition:transform .35s var(--ease); }
.dir-menu.is-open .dir-menu__chev{ transform:rotate(180deg); }

.dir-menu__panel{
  position:absolute; top:calc(100% + 10px); left:0;
  z-index:40;
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:2px;
  width:min(360px, calc(100vw - 2 * var(--gutter)));
  max-height:min(420px, 70vh);
  overflow-y:auto;
  padding:10px;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:2px;
  box-shadow:0 28px 56px -16px rgba(0,0,0,.65);
  opacity:0; visibility:hidden; pointer-events:none;
  transform:translateY(-8px);
  transition:opacity .3s var(--ease), transform .3s var(--ease), visibility 0s linear .3s;
}
.dir-menu.is-open .dir-menu__panel{
  opacity:1; visibility:visible; pointer-events:auto;
  transform:translateY(0);
  transition:opacity .3s var(--ease), transform .3s var(--ease), visibility 0s linear 0s;
}
.dir-menu__item{
  display:flex; align-items:baseline; gap:10px;
  padding:11px 12px;
  border-radius:2px;
  color:var(--text-2);
  font-size:13.5px;
  line-height:1.3;
  opacity:0;
  transform:translateY(6px);
  transition:opacity .3s var(--ease) var(--i,0s), transform .3s var(--ease) var(--i,0s),
             background-color .25s var(--ease), color .25s var(--ease);
}
.dir-menu.is-open .dir-menu__item{ opacity:1; transform:none; }
.dir-menu__item .mono{ font-size:10px; color:var(--text-3); transition:color .25s var(--ease); }
.dir-menu.is-open .dir-menu__item:hover,
.dir-menu.is-open .dir-menu__item:focus-visible{
  background:var(--surface-2);
  color:var(--text);
  transform:translateX(2px);
  outline:none;
}
.dir-menu__item:hover .mono,
.dir-menu__item:focus-visible .mono{ color:var(--gold); }
.dir-menu__backdrop{ display:none; }   /* включается только в мобильной раскладке ниже */

/* ─── тот же dir-menu, но упакован под пункт «Направления» в шапке —
   без рамки/фона кнопки, метка выглядит как обычная .nav__link (каскад:
   .nav__link объявлен ниже по файлу и перекрывает padding/шрифт
   у .dir-menu__label той же специфичностью). Раскрывающийся список —
   только на ширинах, где .nav — обычная горизонтальная строка; там,
   где .nav становится полноэкранным меню (≤1024px), у пункта уже есть
   тот же список в hero — не дублируем сложную bottom-sheet-механику
   ещё и здесь, пункт просто ведёт себя как обычная ссылка. */
.dir-menu--nav{ border:0; }
.dir-menu--nav .dir-menu__toggle{
  width:16px;
  border:0;
  padding-left:2px;
  color:var(--text-2);
}
.dir-menu--nav:hover .dir-menu__toggle,
.dir-menu--nav.is-open .dir-menu__toggle{ border-color:transparent; color:var(--gold); }
@media (max-width:1024px){
  .dir-menu--nav .dir-menu__toggle,
  .dir-menu--nav .dir-menu__panel{ display:none !important; }
}

.link-arrow{
  display:inline-flex; align-items:center; gap:10px;
  font-family:var(--mono); font-size:11.5px;
  letter-spacing:.16em; text-transform:uppercase;
  color:var(--text-2);
  padding-bottom:6px;
  border-bottom:1px solid var(--line);
  transition:color .35s var(--ease), border-color .35s var(--ease);
}
.link-arrow::after{
  content:"↗"; font-size:13px;
  transition:transform .35s var(--ease);
}
.link-arrow:hover{ color:var(--gold); border-color:var(--gold-line); }
.link-arrow:hover::after{ transform:translate(3px,-3px); }

/* ═══════════════════ ШАПКА ═══════════════════ */
.hdr{
  position:fixed; inset:0 0 auto; z-index:100;
  height:var(--hdr-h);
  display:flex; align-items:center;
  transition:background-color .45s var(--ease), border-color .45s var(--ease), backdrop-filter .45s;
  border-bottom:1px solid transparent;
}
.hdr.is-stuck{
  background:rgba(14,16,19,.74);
  backdrop-filter:blur(16px) saturate(140%);
  -webkit-backdrop-filter:blur(16px) saturate(140%);
  border-bottom-color:var(--line);
}
.hdr__inner{
  display:flex; align-items:center; gap:clamp(16px,3vw,44px);
}
/* ─── логотип ───
   Векторный знак, пропорция 1597 : 346,25 ≈ 4,61 : 1.
   Задаём высоту — ширина следует за ней, поэтому знак одинаково
   «весит» в любой строке независимо от ширины экрана. */
.logo{
  display:block;
  width:auto;
  color:var(--text);
  fill:currentColor;
}
/* Подстрочник «ENGINEERING» — 46 из 346,25 единиц viewBox, то есть 13,3 %
   высоты знака. История размера в шапке: 44 → 48 → 55 → 69 → 88 → 80 →
   40px (см. README, «Про подстрочник» — там вся цепочка с числами
   и с найденным по пути багом про flex-shrink).
   ШЕСТОЙ ЗАХОД — логотип уменьшен вдвое (80px→40px) по прямой просьбе
   заказчика: на 80px знак стал ШИРЕ (369px при пропорции 4,61:1), чем
   помещалось в шапку вместе с полным меню (6 пунктов) + кнопкой +
   переключателем языка — flex-строка не резиновая, а .hdr__logo с
   flex-shrink:0 (см. ниже) больше не ужимался сам, поэтому вместо
   этого не помещались ДРУГИЕ элементы (кнопка/переключатель обрезались
   за край экрана). 40px укладывается в бюджет строки с запасом. */
.logo--hdr{ height:40px; }
.logo--ftr{ height:60px; }

.hdr__logo{
  position:relative; z-index:101;                /* выше оверлея меню */
  display:flex; align-items:center;
  /* НАЙДЕННЫЙ БАГ: .hdr__inner — flex-строка (логотип + nav + кнопка +
     переключатель языка), а у SVG-логотипа (replaced-элемент) по
     умолчанию min-width:auto ведёт себя иначе, чем у текста — браузер
     охотно сжимает именно его, если все пункты меню (белые, nowrap,
     не сжимаются) + кнопка + RU/EST/EN не помещаются в доступную
     ширину. Именно это происходило: CSS height оставался «80px», но
     реальная ширина SVG (и с ней — видимый размер знака) схлопывалась
     до кадров вроде 89px вместо ожидаемых ~370px, и логотип выглядел
     маленьким, хотя формально «увеличенным». flex-shrink:0 — тот же
     приём, что и в .promo__slide > * (см. выше) для той же природы
     бага, просто на этот раз с логотипом, а не с содержимым карточки. */
  flex-shrink:0;
}
.hdr__logo .logo{
  opacity:.94;
  transition:opacity .35s var(--ease), color .35s var(--ease);
}
.hdr__logo:hover .logo{ opacity:1; }

.nav{
  display:flex; align-items:center; gap:clamp(14px,2.2vw,30px);
  margin-left:auto;
}
.nav__link{
  font-family:var(--mono); font-size:11px;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--text-2);
  padding:6px 0;
  position:relative;
  transition:color .35s var(--ease);
  white-space:nowrap;
}
.nav__link::after{
  content:""; position:absolute; left:0; bottom:0;
  width:100%; height:1px; background:var(--gold);
  transform:scaleX(0); transform-origin:left;
  transition:transform .4s var(--ease);
}
.nav__link:hover{ color:var(--text); }
.nav__link.is-active{ color:var(--gold); }
.nav__link.is-active::after,.nav__link:hover::after{ transform:scaleX(1); }

.hdr__cta{ --btn-pad:11px 20px; flex:0 0 auto; }

/* дубль CTA — только внутри мобильного меню */
.nav__link--cta{ display:none; }

/* ─── переключатель языка (RU/EST/EN) ───
   Пока декоративный — переводов ещё нет, готовит интерфейс на будущее.
   Два экземпляра (шапка и подвал) держатся синхронными через
   initLangSwitch() в main.js. */
.lang-switch{
  display:inline-flex; align-items:center;
  flex:0 0 auto;
  border:1px solid var(--line);
  border-radius:2px;
  transition:border-color .35s var(--ease);
}
.lang-switch:hover{ border-color:var(--gold-line); }
.lang-switch__btn{
  padding:8px 10px;
  font-family:var(--mono); font-size:10px; font-weight:500;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-3);
  background:transparent;
  border:0;
  border-left:1px solid var(--line);
  cursor:pointer;
  transition:color .3s var(--ease), background-color .3s var(--ease), border-color .3s var(--ease);
}
.lang-switch__btn:first-child{ border-left:0; }
.lang-switch__btn:hover{ color:var(--text); background:var(--surface-2); }
.lang-switch__btn:focus-visible{ outline:1px solid var(--gold); outline-offset:-2px; }
.lang-switch__btn.is-active{ color:var(--gold); background:var(--surface-2); cursor:default; }

.burger{
  display:none;
  width:44px; height:44px;
  margin-left:auto;
  background:none; border:1px solid var(--line); border-radius:2px;
  cursor:pointer;
  position:relative;
  z-index:101;                                  /* выше оверлея меню */
}
.burger span{
  position:absolute; left:13px; width:18px; height:1px;
  background:var(--text);
  transition:transform .4s var(--ease), opacity .3s var(--ease);
}
.burger span:nth-child(1){ top:19px; }
.burger span:nth-child(2){ top:25px; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(3px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ transform:translateY(-3px) rotate(-45deg); }

/* ═══════════════════ ГЛАВНЫЙ ЭКРАН ═══════════════════ */
.hero{
  position:relative;
  min-height:100svh;
  display:flex; flex-direction:column; justify-content:center;
  padding-top:calc(var(--hdr-h) + 40px);
  padding-bottom:120px;
  overflow:hidden;
  border-bottom:1px solid var(--line);
}

.hero__bg{ position:absolute; inset:-6%; pointer-events:none; }

.hero__grid{
  position:absolute; inset:0;
  background-image:
    linear-gradient(to right, var(--grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px);
  background-size:76px 76px;
  mask-image:radial-gradient(ellipse 78% 62% at 50% 42%, #000 12%, transparent 76%);
  -webkit-mask-image:radial-gradient(ellipse 78% 62% at 50% 42%, #000 12%, transparent 76%);
  transform:translate3d(calc(var(--px,0) * 14px), calc(var(--py,0) * 14px), 0);
  transition:transform .9s cubic-bezier(.16,1,.3,1);
}
/* тёплая дымка: чёрный читается дорого, а не дёшево */
.hero__glow{
  position:absolute; inset:0;
  background:
    radial-gradient(ellipse 44% 38% at 64% 32%, var(--gold-haze), transparent 68%),
    radial-gradient(ellipse 62% 52% at 16% 80%, rgba(255,255,255,.045), transparent 70%);
  transform:translate3d(calc(var(--px,0) * -26px), calc(var(--py,0) * -20px), 0);
  transition:transform 1.1s cubic-bezier(.16,1,.3,1);
}
/* ─── слои главного экрана, снизу вверх ───
   hero__bg (сетка, дымка) → hero__net (сеть узлов) → ticker → hero__inner.
   Свечение под курсором — глобальный слой .cursor-glow, см. выше. */

.hero__net{
  position:absolute; inset:0;
  width:100%; height:100%;
  z-index:2;
  pointer-events:none;
  opacity:0;
  transition:opacity 1.4s var(--ease) .3s;
}
.hero.is-visible .hero__net{ opacity:1; }

.hero__inner{ position:relative; z-index:4; }

.hero__eyebrow{ margin:0 0 26px; }

.hero__title{
  margin:0;
  font-size:clamp(44px,8.4vw,124px);
  line-height:.96;
  font-weight:800;
  letter-spacing:-.045em;
  max-width:16ch;
}
.hero__title .dot{ color:var(--gold); }
/* «Одна команда.» — по просьбе заказчика гарантированно в одну строку,
   даже когда это шире общего max-width:16ch у заголовка (тут можно —
   overflow у h1 не обрезается, просто вторая строка не переносится сама) */
.hero__title .nowrap{ white-space:nowrap; }

.hero__lead{
  margin:30px 0 0;
  max-width:56ch;
  color:var(--text-2);
  font-size:clamp(15px,1.35vw,18px);
  line-height:1.72;
}

.hero__actions{
  display:flex; flex-wrap:wrap; gap:14px;
  margin-top:40px;
}

.hero__stats{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1px;
  margin:72px 0 0;
  background:var(--line);
  border:1px solid var(--line);
  max-width:820px;
}
.hero__stats > div{
  background:var(--surface);
  padding:22px 24px;
}
/* Подпись всегда в одну строку — иначе у плиток с более длинной подписью
   число «плывёт» ниже, чем у соседей с короткой (было с «Совокупный опыт,
   лет»). white-space:nowrap + ellipsis — подстраховка на случай, если
   текст всё же не поместится на очень узком экране; в норме не срабатывает,
   т.к. подписи сокращены так, чтобы помещаться сами. */
.hero__stats dt{
  margin:0 0 8px;
  color:var(--text-3);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.hero__stats dd{
  margin:0;
  font-size:clamp(26px,3vw,38px);
  font-weight:800;
  letter-spacing:-.04em;
  line-height:1;
}

/* ═══════════════════ ПРОМО-ПЛАШКА В HERO ═══════════════════
   Три плашки, видна одна. Контент — PROMO_SLIDES в js/main.js,
   разметка каждого слайда собирается в initPromo(). Ниже — только
   визуальный компонент: карточка, переходы между слайдами, точки. */
.hero__main{ min-width:0; }

.promo{
  width:100%;
  max-width:360px;
  margin:clamp(40px,5vw,64px) 0 0;
}
.promo__frame{
  position:relative;
  overflow:hidden;
  background:rgba(22,25,30,.1);   /* по умолчанию почти стеклянная — сквозь неё виден фон hero */
  border:1px solid var(--line-soft);
  border-radius:2px;
  min-height:366px;
  transition:background-color .4s var(--ease), border-color .4s var(--ease);
}
.promo__frame::before{
  content:"";
  position:absolute; top:0; left:0; right:0; height:2px;
  background:var(--gold);
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .6s var(--ease);
}
.promo:hover .promo__frame::before,
.promo:focus-within .promo__frame::before{ transform:scaleX(1); }
.promo:hover .promo__frame,
.promo:focus-within .promo__frame{
  /* Прозрачным при наведении/фокусе становится ТОЛЬКО фон карточки —
     альфа-канал у самого background-color (var(--surface-2) в rgba,
     50%), а не opacity на .promo__frame целиком: opacity действует на
     элемент И его детей как на одну группу, из-за чего текст/иконка
     тускнели вместе с фоном и читались хуже — заказчик явно попросил
     оставить текст полностью чётким, прозрачным должен быть только
     фон позади него. */
  background:rgba(30,34,42,.5);
  border-color:var(--line);
}

.promo__stage{ position:static; }
.promo__slide{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:flex-start;
  padding:clamp(24px,2.6vw,30px) clamp(22px,2.4vw,26px);
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transition:opacity .4s var(--ease), transform .5s var(--ease);
}
/* flex-column сжимает детей, если контент не помещается по высоте —
   без этого длинный слайд (со строкой скидки) ужимал саму иллюстрацию
   вместо того, чтобы просто не помещаться; высота у .promo__frame
   выше и так, но фиксируем размеры на будущее, при любом тексте. */
.promo__slide > *{ flex-shrink:0; }
.promo__slide.is-active{
  /* по умолчанию текст и графика приглушены — ярче фона, но не на полную;
     полная контрастность только при наведении/фокусе, см. ниже */
  opacity:.72;
  visibility:visible;
  pointer-events:auto;
  transform:translateX(0);
}
.promo:hover .promo__slide.is-active,
.promo:focus-within .promo__slide.is-active{ opacity:1; }

.promo__art{
  display:block;
  /* ширина — доля карточки (не 100%), высота считается из aspect-ratio
     самого viewBox (300×84 ≈ 3.57:1): так символ гарантированно широкий
     и низкий без леттербоксинга — при width:100%+фиксированной высоте
     PRESERVEASPECTRATIO вписывал бы контент по высоте и оставлял пустые
     поля по бокам, а не растягивал его на бо́льшую часть ширины. */
  width:100%;
  aspect-ratio:300/84;
  height:auto;
  align-self:center;
  margin-bottom:18px;
  color:var(--text-2);
  transition:color .4s var(--ease);
}
.promo:hover .promo__art,
.promo:focus-within .promo__art{ color:var(--text); }
/* ─── фирменный знак: 8 узлов → ядро, горизонтальная симметрия, без круга ───
   .mark__links  — тонкие ломаные связи, в покое приглушены, видны всегда;
   .mark__pulses — их дубликаты с draw-on обводкой (pathLength=1 +
                   stroke-dashoffset:1→0, тот же приём, что и .draw по
                   всему сайту) — золотая линия прочерчивается ОТ палочки
                   К ЯДРУ;
   .mark__bars   — 8 толстых диагональных «блейдов», каждый вспыхивает
                   в свой черёд;
   .mark__core   — ромб-ядро (не круг), коротко вспыхивает золотым
                   при каждом прибытии линии.
   Все восемь пар (блейд + линия) зациклены в одну общую «бегущую»
   последовательность на 4s: у каждой пары свой animation-delay (0, .5s,
   1s, … 3.5s), при этом «активное» окно внутри 4s-цикла — те же ~0.5s
   у всех, поэтому в моменте светится только одна пара, следующая
   подхватывает эстафету, и так по кругу — ПОСТОЯННО, без hover/focus
   (заказчик прямо попросил, чтобы «эстафета» шла непрерывно, а не
   только при наведении курсора; было иначе в предыдущей редакции —
   см. README). Задержка задаётся через inline `style="--pd:…"` на
   каждом path в index.html и `animation-delay:var(--pd)` здесь —
   НЕ через `:nth-child`: проверено изолированным тестом, что
   структурные псевдоклассы по позиции среди соседей не матчатся
   внутри клона `<use>` в этом движке (класс/атрибут через `<use>`
   работают как обычно, `:nth-child` — нет), поэтому селектор с ним
   просто ничего не находит внутри инстанса — именно поэтому символ
   рендерится через клонирование настоящих узлов в initPromo()
   (js/main.js), а не через `<use>`, см. README. Под
   prefers-reduced-motion отдельная ветка не нужна: сайтовое глобальное
   правило форсирует animation-iteration-count:1 — даже infinite
   проигрывается ровно один раз и почти мгновенно (.001ms), без
   бесконечного мигания. */
.promo__art .mark__links{ opacity:.4; }

.promo__art .mark__bars path,
.promo__art .mark__pulses path{
  animation-duration:4s;
  animation-timing-function:linear;
  animation-iteration-count:infinite;
  animation-delay:var(--pd,0s);
}
.promo__art .mark__bars path{ animation-name:markChaseBar; opacity:.82; }
.promo__art .mark__pulses path{
  animation-name:markChaseLine;
  stroke:var(--gold);
  stroke-width:1.3;
  stroke-dasharray:1;
  stroke-dashoffset:1;
  opacity:0;
}

@keyframes markChaseBar{
  0%,88%,100%{ opacity:.82; }
  2%{ opacity:1; }
  14%{ opacity:.82; }
}
@keyframes markChaseLine{
  0%,88%,100%{ stroke-dashoffset:1; opacity:0; }
  2%{ opacity:1; }
  10%{ stroke-dashoffset:0; opacity:1; }
  14%{ opacity:0; }
}

/* ядро вспыхивает 8 раз за 4s-цикл — ровно в момент, когда очередная
   линия дорисовывается до конца (10% каждого 0.5s-окна: .5, 1, 1.5s… —
   те же точки, что стрелка dashoffset:0 в markChaseLine выше, плюс
   первая в 0-м окне на 10%). Список точек «none» и список точек
   «glow» — сгруппированы через запятую вместо восьми копий правила. */
.promo__art .mark__core{
  animation:markCoreArrive 4s linear infinite;
}
/* мягкое свечение ЗА ядром при прибытии линии — без увеличения самого
   ромба (было transform:scale, резало глаз) и без резкого ближнего
   контура (был двойной drop-shadow с --gold сплошным вблизи). Один
   широкий мягкий слой на приглушённом --gold-glow — заметно, но спокойно. */
@keyframes markCoreArrive{
  0%, 7%, 13%, 19.5%, 25.5%, 32%, 38%, 44.5%, 50.5%,
  57%, 63%, 69.5%, 75.5%, 82%, 88%, 94.5%, 100%{ filter:none; }
  9%, 11%, 21.5%, 23.5%, 34%, 36%, 46.5%, 48.5%,
  59%, 61%, 71.5%, 73.5%, 84%, 86%, 96.5%, 98.5%{
    filter:drop-shadow(0 0 7px var(--gold-glow));
  }
}

.promo__eyebrow{ margin:0 0 14px; color:var(--text-3); }
.promo__discount{
  margin:0 0 4px;
  font-size:clamp(30px,3vw,38px);
  font-weight:800;
  letter-spacing:-.03em;
  line-height:1;
  color:var(--gold);
}
/* Модификатор для фразы вместо цифры (см. slide.discountSm в
   PROMO_SLIDES/initPromo(), main.js) — тот же вес и цвет, что у
   .promo__discount, кегль чуть меньше и без переноса, чтобы короткая
   фраза встала в одну строку на ширине карточки и не толкала контент
   за границы плашки (frame — overflow:hidden). */
.promo__discount--sm{
  font-size:clamp(19px,2.3vw,23px);
  white-space:nowrap;
}
.promo__title{
  margin:0 0 10px;
  font-size:16.5px;
  font-weight:700;
  letter-spacing:-.02em;
  line-height:1.35;
}
.promo__text{
  margin:0 0 22px;
  color:var(--text-2);
  font-size:13.5px;
  line-height:1.62;
}
.promo__cta{ margin-top:auto; padding-bottom:14px; }

/* ─── таймлайн обратного отсчёта ───
   Тонкая линия внизу карточки — одновременно и индикатор, и сам таймер:
   по достижении 100% JS ловит `animationend` и переключает плашку
   (initPromo() в js/main.js). Ручное переключение просто перезапускает
   анимацию с нуля (снять .is-running → reflow → вернуть класс).
   Наведение курсора ставит анимацию на паузу через animation-play-state —
   отдельного JS-таймера для «паузы при наведении» не нужно вообще. */
.promo__progress{
  position:absolute; left:0; right:0; bottom:0;
  height:2px;
  background:var(--line-soft);
  z-index:1;
}
.promo__progress-bar{
  position:relative;
  height:100%;
  width:0%;
  background:var(--gold);
  transition:background-color .4s var(--ease);
}
.promo__progress-bar.is-running{
  animation:promoProgress var(--promo-dur,6s) linear;
}
@keyframes promoProgress{ from{ width:0%; } to{ width:100%; } }
.promo__progress-bar::after{
  content:"";
  position:absolute; top:50%; right:-3px;
  width:6px; height:6px;
  border-radius:50%;
  background:var(--gold);
  transform:translateY(-50%);
  box-shadow:0 0 5px 1px var(--gold-glow);
}
/* пауза: наведение/фокус на плашке, скрытая вкладка (класс из JS) */
.promo:hover .promo__progress-bar,
.promo:focus-within .promo__progress-bar,
.promo__progress-bar.is-paused{ animation-play-state:paused; }
.promo:hover .promo__progress-bar,
.promo:focus-within .promo__progress-bar{ background:var(--gold-hi); }

.promo__dots{
  display:flex; gap:10px;
  margin-top:16px;
}
.promo__dot{
  width:8px; height:8px;
  padding:0; margin:0;
  border:1px solid var(--line);
  border-radius:50%;
  background:transparent;
  cursor:pointer;
  transition:background-color .35s var(--ease), border-color .35s var(--ease),
             transform .35s var(--ease), box-shadow .35s var(--ease);
}
.promo__dot:hover{
  border-color:var(--gold-line);
  transform:scale(1.2);
}
.promo__dot:focus-visible{ outline:2px solid var(--gold); outline-offset:3px; }
.promo__dot.is-active{
  background:var(--gold);
  border-color:var(--gold);
  transform:scale(1.15);
  box-shadow:0 0 6px 1px var(--gold-glow);
}
.promo__dot.is-active:hover{ transform:scale(1.3); }

@media (min-width:1400px){
  .hero__inner{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(260px,320px);
    align-items:start;
    gap:56px;
  }
  /* по просьбе заказчика — верх плашки примерно на уровне верха буквы «В»
     в «Восемь» (т.е. верха hero__title), не по центру всего hero__main.
     Подобрано численно под текущий отступ eyebrow (см. .hero__eyebrow). */
  .promo{ margin:46px 0 0; max-width:320px; justify-self:end; }
}

.ticker{
  position:absolute; left:0; right:0; bottom:52px;
  overflow:hidden;
  border-block:1px solid var(--line-soft);
  padding:11px 0;
  z-index:3;
  mask-image:linear-gradient(to right,transparent,#000 12%,#000 88%,transparent);
  -webkit-mask-image:linear-gradient(to right,transparent,#000 12%,#000 88%,transparent);
}
.ticker__track{
  display:flex; width:max-content;
  animation:ticker 46s linear infinite;
}
.ticker__track span{
  font-family:var(--mono); font-size:11px;
  letter-spacing:.24em; text-transform:uppercase;
  color:var(--text-3);
  white-space:nowrap;
}
@keyframes ticker{ to{ transform:translateX(-50%); } }

.hero__scroll{
  position:absolute; left:var(--gutter); bottom:16px;
  display:inline-flex; align-items:center; gap:12px;
  z-index:4;
  color:var(--text-3);
  transition:color .35s var(--ease);
}
.hero__scroll span{
  width:1px; height:20px; background:var(--line);
  position:relative; overflow:hidden;
}
.hero__scroll span::after{
  content:""; position:absolute; inset:0;
  background:var(--gold);
  animation:scrollcue 2.2s var(--ease) infinite;
}
@keyframes scrollcue{
  0%{ transform:translateY(-100%); }
  60%,100%{ transform:translateY(100%); }
}
.hero__scroll:hover{ color:var(--text); }

/* ═══════════════════ ЗАГОЛОВОК СЕКЦИИ НАПРАВЛЕНИЙ ═══════════════════ */
.sec-head{
  padding-block:var(--sec-pad) clamp(40px,6vw,72px);
}
.sec-head__lead{
  margin:28px 0 0;
  max-width:64ch;
  color:var(--text-2);
  font-size:clamp(15px,1.2vw,17px);
}

/* ═══════════════════ НАПРАВЛЕНИЯ ═══════════════════ */
.dir{
  position:relative;
  /* Было своим числом (clamp(70px,9vw,120px), затем clamp(46px,5.4vw,80px)),
     отдельным от остальных секций сайта. Заказчик попросил сократить ещё
     и сделать расстояние ОДИНАКОВЫМ между всеми блоками — теперь просто
     var(--sec-pad), тот же ритм, что у «О компании», «Проектов» и т.д. */
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line-soft);
}
.dir__inner{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.08fr);
  gap:clamp(32px,6vw,88px);
  align-items:center;
}
.dir--flip .dir__text{ order:2; }
.dir--flip .dir__figure{ order:1; }

/* «01 / 08» — позиция в наборе, а не порядок: помогает ориентироваться
   на длинной странице. Золото только на текущем номере. */
.dir__num{
  display:flex; align-items:baseline; gap:8px;
  margin:0 0 20px;
  color:var(--gold);
  font-size:13px;
  letter-spacing:.14em;
}
.dir__num i{ color:var(--text-3); font-style:normal; font-size:11px; }

.dir__title{
  margin:0;
  font-size:clamp(27px,3.6vw,47px);
  line-height:1.08;
  font-weight:800;
  letter-spacing:-.035em;
}

.dir__lead{
  margin:20px 0 0;
  max-width:48ch;
  color:var(--text-2);
  line-height:1.75;
}

.dir__list{
  list-style:none;
  margin:30px 0 0;
  padding:0;
  border-top:1px solid var(--line);
}
.dir__list li{
  padding:13px 0 13px 26px;
  border-bottom:1px solid var(--line);
  position:relative;
  font-size:14.5px;
  color:var(--text-2);
  transition:color .35s var(--ease), padding-left .35s var(--ease);
}
.dir__list li::before{
  content:"";
  position:absolute; left:2px; top:23px;
  width:9px; height:1px;
  background:var(--text-3);
  transition:width .35s var(--ease), background-color .35s var(--ease);
}
.dir__list li:hover{ color:var(--text); padding-left:32px; }
.dir__list li:hover::before{ width:16px; background:var(--gold); }

.dir__text .link-arrow{ margin-top:30px; }

/* Вторая, соседняя кнопка у блока «3D-печать» (пока только там — см.
   dir-01 в index.html) — обёртка держит обе .link-arrow в одном ряду
   с общим отступом сверху вместо margin-top на каждой ссылке по
   отдельности: иначе при переносе на мобильных вторая кнопка получила бы
   ещё один лишний отступ поверх row-gap. Сама .link-arrow не меняется —
   TikTok-ссылка держит тот же inline-flex, шрифт, подчёркивание и
   стрелку ::after, что и «Обсудить задачу», только с маленькой
   монохромной иконкой перед текстом (в той же линейной манере, что
   .contact-card__icon, — не логотип TikTok, а обобщённый значок ноты). */
.dir__actions{
  display:flex; align-items:center; flex-wrap:wrap;
  gap:14px 28px;
  margin-top:30px;
}
.dir__actions .link-arrow{ margin-top:0; }
.link-arrow__icon{ width:14px; height:14px; flex:0 0 auto; }

.dir__figure{ position:relative; }

/* Чертёж: белая геометрия с низкой непрозрачностью.
   currentColor с альфой — так золотые элементы внутри сохраняют
   собственную плотность и читаются как акцент. */
.dir__figure .gfx{
  width:100%; height:auto;
  color:var(--draw);
  opacity:0;
  transition:opacity 1.2s var(--ease);
}
.is-visible .dir__figure .gfx{ opacity:1; }

/* ─── общие анимационные примитивы графики ───
   (не привязаны к .gfx — тем же механизмом живут линии главного экрана) */
.draw{
  stroke-dasharray:1;
  stroke-dashoffset:1;
  transition:stroke-dashoffset var(--dur,1.5s) var(--ease-draw) var(--d,0s);
}
.is-visible .draw{ stroke-dashoffset:0; }

.fade{
  opacity:0;
  transition:opacity .9s var(--ease) var(--d,0s);
}
.is-visible .fade{ opacity:1; }

.gfx text.mono-svg{
  font-family:var(--mono);
  font-size:10.5px;
  letter-spacing:.14em;
  fill:currentColor;
  stroke:none;
}

.gfx-thin{ color:var(--draw-dim); }
.gfx-tag{ color:var(--draw-dim); }
.gfx-axis{ color:var(--draw-dim); }

/* ─── ЗОЛОТО: живое и измеряемое ───────────────────────
   01 траектория сопла · 02 шов, искры · 03 размеры
   04 шина и ток       · 05 поток, манометр
   06 траектория курсора · 07 размеры · 08 разрез и КИП   */
.gfx-accent,
.gfx-seam,
.gfx-head,
.gfx-dim,
.gfx-cut,
.gfx-kip,
.gfx .flow{ color:var(--gold); }

/* ═══════════════════ 01 · 3D-ПЕЧАТЬ ═══════════════════
   Технический рендер вместо схемы. Объём даётся тремя вещами:
   иерархией толщин линий, слабыми заливками граней и затуханием
   дальних элементов. Золото — только на горячей зоне и траектории. */

.gfx--print{ stroke-linecap:round; stroke-linejoin:round; }
.gfx--print g[transform] *{ vector-effect:non-scaling-stroke; }

/* Опорная плотность сцены. Все классы ниже берут от неё свою долю,
   поэтому яркость всего чертежа регулируется одним значением —
   и на мобильных он уходит фоном простой сменой этого цвета. */
.dir__figure .gfx--print{ color:rgba(255,255,255,.40); }

/* ─── иерархия линий: от силуэта к волосяной ─── */
.gfx--print .ln-sil { stroke:currentColor; stroke-width:2.2; opacity:1; }
.gfx--print .ln-med { stroke:currentColor; stroke-width:1.4; opacity:.62; }
.gfx--print .ln-thin{ stroke:currentColor; stroke-width:.9;  opacity:.34; }
.gfx--print .ln-hair{ stroke:currentColor; stroke-width:.5;  opacity:.19; }

/* ─── заливки граней: свет сверху, тени по бокам ─── */
.gfx--print .fill-top  { fill:rgba(255,255,255,.055); stroke:none; }
.gfx--print .fill-right{ fill:rgba(255,255,255,.032); stroke:none; }
.gfx--print .fill-left { fill:rgba(255,255,255,.014); stroke:none; }
.gfx--print .fill-nozzle{ fill:rgba(198,161,106,.16); stroke:none; }

/* ─── стол ─── */
.gfx--print .p-plate{ opacity:1; }
.gfx--print .grid path{ stroke:currentColor; stroke-width:.5; opacity:.13; }
.gfx--print .heater path{ stroke:var(--gold); opacity:.5; }
.gfx--print .lead-dot{ fill:var(--gold); stroke:none; opacity:.8; }

/* ─── слои детали и заполнение ─── */
.gfx--print .layers path{ stroke:currentColor; stroke-width:.6; opacity:.3; }
.gfx--print .infill path{ stroke:currentColor; stroke-width:.7; opacity:.42; }
.gfx--print .front{ stroke:var(--gold); stroke-width:1.6; opacity:.8; }

/* ─── траектория сопла ─── */
.gfx--print .toolpath{
  stroke:var(--gold); stroke-width:1.8;
  stroke-dasharray:1; stroke-dashoffset:1;
  transition:stroke-dashoffset 2.6s var(--ease-draw) 1.1s;
}
.is-visible .gfx--print .toolpath{ stroke-dashoffset:0; }

/* ─── экструдер ─── */
.gfx--print .p-head{
  color:var(--text);
  opacity:0;
  transform:translateY(-26px);
  transition:opacity .8s var(--ease) .2s, transform 1s var(--ease) .2s;
}
.is-visible .gfx--print .p-head{ opacity:.9; transform:none; }
.gfx--print .fins{ opacity:.85; }
.gfx--print .nz{ color:var(--gold); opacity:.9; }

/* ─── горячая зона ─── */
.gfx--print .p-hot{ color:var(--gold); opacity:0; transition:opacity .7s var(--ease) 1s; }
.is-visible .gfx--print .p-hot{ opacity:1; }
.gfx--print .bead{ fill:var(--gold); stroke:none; }
.gfx--print .bead-glow{
  fill:var(--gold); stroke:none;
  filter:blur(7px); opacity:.55;
}
.is-visible .gfx--print .bead-glow{ animation:beadPulse 2.8s var(--ease) infinite; }
@keyframes beadPulse{ 0%,100%{ opacity:.4; } 50%{ opacity:.75; } }
.gfx--print .strand{ stroke:var(--gold); stroke-width:2.2; }

/* ─── пруток, выноски ─── */
.gfx--print .p-tube{ opacity:.5; }
.gfx--print .p-tag{ color:var(--draw-dim); }
.gfx--print .lead{ stroke:var(--gold); stroke-width:.7; opacity:.55; }
.gfx--print .p-tag text{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.16em;
  fill:var(--text-3); stroke:none;
}

/* появление всей сцены */
.gfx--print .p-plate,
.gfx--print .p-part,
.gfx--print .p-tube,
.gfx--print .p-tag{
  opacity:0;
  transition:opacity 1s var(--ease) var(--d,0s);
}
.is-visible .gfx--print .p-plate{ opacity:.75; }
.is-visible .gfx--print .p-part { opacity:1; }
.is-visible .gfx--print .p-tube { opacity:.5; }
.is-visible .gfx--print .p-tag  { opacity:1; }

/* ═══════════════════ 02 · СВАРКА ═══════════════════
   Тавровое соединение, угловой шов, горелка MIG как герой.
   Иерархия линий и опорная плотность — те же, что в блоке 01. */

.gfx--weld{ stroke-linecap:round; stroke-linejoin:round; }
.gfx--weld g[transform] *{ vector-effect:non-scaling-stroke; }
.dir__figure .gfx--weld{ color:rgba(255,255,255,.40); }

.gfx--weld .ln-sil { stroke:currentColor; stroke-width:2.2; opacity:1; }
.gfx--weld .ln-med { stroke:currentColor; stroke-width:1.4; opacity:.62; }
.gfx--weld .ln-thin{ stroke:currentColor; stroke-width:.9;  opacity:.34; }
.gfx--weld .ln-hair{ stroke:currentColor; stroke-width:.5;  opacity:.19; }

.gfx--weld .fill-top  { fill:rgba(255,255,255,.055); stroke:none; }
.gfx--weld .fill-right{ fill:rgba(255,255,255,.032); stroke:none; }
.gfx--weld .fill-left { fill:rgba(255,255,255,.014); stroke:none; }

/* прокатная текстура плиты — почти на пороге видимости */
.gfx--weld .brushed path{ stroke:currentColor; stroke-width:.5; opacity:.1; }

/* незаваренный участок стыка: тонкая тёмная щель */
.gfx--weld .joint{ stroke:currentColor; stroke-width:1.6; opacity:.5; }

/* ─── шов: остывший металл, поэтому приглушённое золото ─── */
.gfx--weld .fill-bead{ fill:rgba(198,161,106,.13); stroke:none; }
.gfx--weld .w-bead .ln-sil{ stroke:var(--gold); opacity:.62; }
.gfx--weld .w-bead .ln-med{ stroke:var(--gold); opacity:.42; }
.gfx--weld .ripples path{ stroke:var(--gold); stroke-width:1.1; opacity:.5; fill:none; }

/* ─── горелка ─── */
.gfx--weld .w-torch{
  opacity:0; transform:translate(16px,-14px);
  transition:opacity .9s var(--ease) .25s, transform 1.1s var(--ease) .25s;
}
.is-visible .gfx--weld .w-torch{ opacity:1; transform:none; }
.gfx--weld .tp{ stroke:var(--gold); }
.gfx--weld .fill-hot{ fill:rgba(198,161,106,.22); stroke:none; }

/* ─── дуга и ванна ─── */
.gfx--weld .w-hot{ opacity:0; transition:opacity .6s var(--ease) 1.1s; }
.is-visible .gfx--weld .w-hot{ opacity:1; }
.gfx--weld .arc{ stroke:var(--gold-hi); stroke-width:2.6; }
.gfx--weld .pool{ fill:var(--gold-hi); stroke:none; opacity:.9; }
.gfx--weld .glow{ fill:var(--gold); stroke:none; filter:blur(6px); opacity:.75; }
.gfx--weld .glow-wide{ fill:var(--gold); stroke:none; filter:blur(15px); opacity:.4; }
.is-visible .gfx--weld .glow{ animation:arcPulse 1.9s var(--ease) infinite; }
@keyframes arcPulse{ 0%,100%{ opacity:.55; } 45%{ opacity:.95; } }

/* ─── искры ─── */
.gfx--weld .spark{
  fill:var(--gold-hi); stroke:none; opacity:0;
}
.is-visible .gfx--weld .spark{
  animation:weldSpark 2.4s linear var(--d,0s) infinite;
}
@keyframes weldSpark{
  0%   { opacity:0; transform:translate(0,0) scale(1); }
  6%   { opacity:1; }
  70%  { opacity:.5; }
  100% { opacity:0; transform:translate(var(--sx,0),var(--sy,40px)) scale(.35); }
}
.gfx--weld .spatter{ fill:var(--gold); stroke:none; opacity:0; transition:opacity .8s var(--ease) 1.5s; }
.is-visible .gfx--weld .spatter{ opacity:.4; }

/* ─── подписи ─── */
.gfx--weld .w-tag{ color:var(--draw-dim); }
.gfx--weld .lead{ stroke:var(--gold); stroke-width:.7; opacity:.55; }
.gfx--weld .lead-dot{ fill:var(--gold); stroke:none; opacity:.8; }
.gfx--weld .w-tag text{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.16em;
  fill:var(--text-3); stroke:none;
}

/* появление сцены */
.gfx--weld .w-plate,
.gfx--weld .w-bead,
.gfx--weld .w-tag{ opacity:0; transition:opacity 1s var(--ease); }
.is-visible .gfx--weld .w-plate{ opacity:1; }
.is-visible .gfx--weld .w-bead { opacity:1; }
.is-visible .gfx--weld .w-tag  { opacity:1; }

/* ═══════════════════ 03 · МЕЛКИЙ РЕМОНТ ═══════════════════
   Шуруповёрт закручивает винт кронштейна настенной полки.
   Стена развёрнута: при фронтальной инструмент сжимался бы в обрубок. */

.gfx--fix{ stroke-linecap:round; stroke-linejoin:round; }
.gfx--fix g[transform] *{ vector-effect:non-scaling-stroke; }
.dir__figure .gfx--fix{ color:rgba(255,255,255,.40); }

.gfx--fix .ln-sil { stroke:currentColor; stroke-width:2.2; opacity:1; }
.gfx--fix .ln-med { stroke:currentColor; stroke-width:1.4; opacity:.62; }
.gfx--fix .ln-thin{ stroke:currentColor; stroke-width:.9;  opacity:.34; }
.gfx--fix .ln-hair{ stroke:currentColor; stroke-width:.5;  opacity:.19; }

.gfx--fix .fill-top  { fill:rgba(255,255,255,.055); stroke:none; }
.gfx--fix .fill-right{ fill:rgba(255,255,255,.032); stroke:none; }
.gfx--fix .fill-left { fill:rgba(255,255,255,.014); stroke:none; }
.gfx--fix .fill-wall { fill:rgba(255,255,255,.012); stroke:none; }
.gfx--fix .fill-hot  { fill:rgba(198,161,106,.2);   stroke:none; }

/* ─── местный разрез стены ─── */
.gfx--fix .cut-fill{ fill:rgba(255,255,255,.03); stroke:none; }
.gfx--fix .cut-edge{ fill:none; stroke:currentColor; stroke-width:1.2; opacity:.5; }
.gfx--fix .hatch path{ stroke:currentColor; stroke-width:.5; opacity:.17; }
.gfx--fix .r-cut .hatch{ clip-path:none; }
.gfx--fix .thread{ opacity:.5; }

/* ─── шуруповёрт ───
   Заливки заметно плотнее общих: инструмент собран из десятков мелких
   сегментов, и на слабых заливках он читается как проволочный каркас,
   а не как цельный предмет. */
.gfx--fix .drill-fill .fill-top  { fill:rgba(255,255,255,.115); }
.gfx--fix .drill-fill .fill-right{ fill:rgba(255,255,255,.075); }
.gfx--fix .drill-fill .fill-left { fill:rgba(255,255,255,.042); }

.gfx--fix .r-drill{
  opacity:0; transform:translate(22px,10px);
  transition:opacity .9s var(--ease) .3s, transform 1.1s var(--ease) .3s;
}
.is-visible .gfx--fix .r-drill{ opacity:1; transform:none; }
.gfx--fix .bt{ stroke:var(--gold); }
.gfx--fix .clutch-ticks{ opacity:.55; }

/* объём рукояти: поперечные контуры, накладка хвата, сопряжение */
.gfx--fix .saddle{ opacity:.75; }
.gfx--fix .hcuts path{ stroke:currentColor; stroke-width:.75; opacity:.24; fill:none; }
.gfx--fix .fingers path{ stroke:currentColor; stroke-width:1.3; opacity:.4; fill:none; }
.gfx--fix .grip{ opacity:.42; }
.gfx--fix .grip-tex path{ stroke:currentColor; stroke-width:.9; opacity:.3; fill:none; }

/* ─── золото: живое и измеряемое ─── */
.gfx--fix .r-gold{ opacity:0; transition:opacity .7s var(--ease) 1.1s; }
.is-visible .gfx--fix .r-gold{ opacity:1; }
.gfx--fix .index{ stroke:var(--gold); stroke-width:2.6; }
.gfx--fix .led{ fill:var(--gold-hi); stroke:none; }
.gfx--fix .led-glow{ fill:var(--gold); stroke:none; filter:blur(5px); opacity:.5; }
.gfx--fix .spin{ stroke:var(--gold); stroke-width:1.3; fill:none; opacity:.7; }
.gfx--fix .contact{ fill:var(--gold-hi); stroke:none; opacity:.9; }
.gfx--fix .contact-glow{ fill:var(--gold); stroke:none; filter:blur(7px); opacity:.45; }
.is-visible .gfx--fix .contact-glow{ animation:fixPulse 2.2s var(--ease) infinite; }
@keyframes fixPulse{ 0%,100%{ opacity:.3; } 50%{ opacity:.6; } }

/* ─── подписи ─── */
.gfx--fix .r-tag{ color:var(--draw-dim); }
.gfx--fix .lead{ stroke:var(--gold); stroke-width:.7; opacity:.55; }
.gfx--fix .lead-dot{ fill:var(--gold); stroke:none; opacity:.8; }
.gfx--fix .r-tag text{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.16em;
  fill:var(--text-3); stroke:none;
}

/* появление сцены */
.gfx--fix .r-wall,
.gfx--fix .r-cut,
.gfx--fix .r-anchor,
.gfx--fix .r-bracket,
.gfx--fix .r-shelf,
.gfx--fix .r-screw,
.gfx--fix .r-tag{ opacity:0; transition:opacity 1s var(--ease); }
.is-visible .gfx--fix .r-wall,
.is-visible .gfx--fix .r-cut,
.is-visible .gfx--fix .r-anchor,
.is-visible .gfx--fix .r-bracket,
.is-visible .gfx--fix .r-shelf,
.is-visible .gfx--fix .r-screw,
.is-visible .gfx--fix .r-tag{ opacity:1; }

/* ═══════════════════ 05 · САНТЕХНИКА ═══════════════════
   Аксонометрическая схема водоснабжения. Трубы — толстые штрихи:
   для схемы это верный уровень условности. Золото — поток. */

.gfx--plumb{ stroke-linecap:round; stroke-linejoin:round; }
.gfx--plumb g[transform] *{ vector-effect:non-scaling-stroke; }
.dir__figure .gfx--plumb{ color:rgba(255,255,255,.40); }

.gfx--plumb .ln-sil { stroke:currentColor; stroke-width:2; opacity:1; }
.gfx--plumb .ln-med { stroke:currentColor; stroke-width:1.3; opacity:.62; }
.gfx--plumb .ln-thin{ stroke:currentColor; stroke-width:.9;  opacity:.34; }
.gfx--plumb .ln-hair{ stroke:currentColor; stroke-width:.5;  opacity:.19; }

.gfx--plumb .fill-top  { fill:rgba(255,255,255,.055); stroke:none; }
.gfx--plumb .fill-right{ fill:rgba(255,255,255,.032); stroke:none; }
.gfx--plumb .fill-left { fill:rgba(255,255,255,.014); stroke:none; }
.gfx--plumb .fill-slab { fill:rgba(255,255,255,.012); stroke:none; }

.gfx--plumb .hcut{ opacity:.22; }
.gfx--plumb .grid path{ stroke:currentColor; stroke-width:.5; opacity:.1; }
.gfx--plumb .lvl{ opacity:.4; }
.gfx--plumb .gauge{ stroke:var(--gold); opacity:.85; }
.gfx--plumb .jet{ opacity:.3; }

/* ─── трубы ─── */
.gfx--plumb .pipe{ stroke:currentColor; stroke-width:7.5; opacity:.3; fill:none; }
.gfx--plumb .bore{ stroke:currentColor; stroke-width:3.6; opacity:.72; fill:none; }
.gfx--plumb .fitting{ stroke:currentColor; stroke-width:1; opacity:.5; fill:none; }

/* ─── арматура ─── */
.gfx--plumb .s-valves path{ stroke:currentColor; stroke-width:1.3; opacity:.62; fill:none; }

/* ─── поток: единственное золото ───
   Класс намеренно НЕ .flow: тот уже занят общим правилом блоков 01 и 04,
   которое задаёт currentColor и свою анимацию и побеждает по порядку. */
.gfx--plumb .wflow{
  stroke:var(--gold); stroke-width:2.6; fill:none;
  stroke-dasharray:20 130; stroke-dashoffset:0; opacity:0;
}
.is-visible .gfx--plumb .wflow{
  opacity:.95;
  animation:plumbFlow 3.6s linear var(--d,0s) infinite;
}
@keyframes plumbFlow{ to{ stroke-dashoffset:-150; } }

/* ─── позиции и экспликация ───
   На чертеже только номера в кружках; расшифровка вынесена вправо,
   за габарит, чтобы текст нигде не ложился на линии. */
.gfx--plumb .lead{ stroke:var(--gold); stroke-width:.7; opacity:.5; }
.gfx--plumb .pos-dot{ fill:var(--gold); stroke:none; opacity:.85; }
.gfx--plumb .pos-ring,
.gfx--plumb .leg-ring{ fill:none; stroke:var(--gold); stroke-width:.9; opacity:.6; }
.gfx--plumb .pos-num{
  font-family:var(--mono); font-size:9px; letter-spacing:0;
  fill:var(--gold); stroke:none; text-anchor:middle;
}
.gfx--plumb .leg-rule{ stroke:currentColor; stroke-width:.8; opacity:.3; }
.gfx--plumb .leg-title{
  font-family:var(--mono); font-size:9px; letter-spacing:.2em;
  fill:var(--gold); stroke:none;
}
.gfx--plumb .leg-text{
  font-family:var(--sans); font-size:11px;
  fill:var(--text-2); stroke:none;
}
.gfx--plumb .leg-note,
.gfx--plumb .s-lvl text{
  font-family:var(--mono); font-size:9px; letter-spacing:.14em;
  fill:var(--text-3); stroke:none;
}

/* появление сцены */
.gfx--plumb .s-slab,
.gfx--plumb .s-plant,
.gfx--plumb .s-manifold,
.gfx--plumb .s-pipes,
.gfx--plumb .s-valves,
.gfx--plumb .s-fix,
.gfx--plumb .s-pos,
.gfx--plumb .s-legend,
.gfx--plumb .s-lvl{ opacity:0; transition:opacity 1s var(--ease) var(--d,0s); }
.is-visible .gfx--plumb .s-slab{ opacity:1; }
.is-visible .gfx--plumb .s-plant{ opacity:1; transition-delay:.15s; }
.is-visible .gfx--plumb .s-manifold{ opacity:1; transition-delay:.3s; }
.is-visible .gfx--plumb .s-pipes{ opacity:1; transition-delay:.45s; }
.is-visible .gfx--plumb .s-valves{ opacity:1; transition-delay:.6s; }
.is-visible .gfx--plumb .s-fix{ opacity:1; transition-delay:.7s; }
.is-visible .gfx--plumb .s-lvl{ opacity:1; transition-delay:.8s; }
.is-visible .gfx--plumb .s-pos{ opacity:1; transition-delay:.9s; }
.is-visible .gfx--plumb .s-legend{ opacity:1; transition-delay:1s; }

/* ═══════════════════ 07 · ПРОЕКТИРОВАНИЕ (CAD) ═══════════════════
   Рабочий чертёж: три проекции + изометрия, размерные цепи,
   осевые линии, невидимый контур штрихами. */

.gfx--cad{ stroke-linecap:round; stroke-linejoin:round; }
.dir__figure .gfx--cad{ color:rgba(255,255,255,.40); }

.gfx--cad .ln-sil { stroke:currentColor; stroke-width:1.9; opacity:1;   fill:none; }
.gfx--cad .ln-med { stroke:currentColor; stroke-width:1.2; opacity:.62; fill:none; }
.gfx--cad .ln-thin{ stroke:currentColor; stroke-width:.85; opacity:.34; fill:none; }
.gfx--cad .ln-hair{ stroke:currentColor; stroke-width:.5;  opacity:.19; fill:none; }

.gfx--cad .fill-part { fill:rgba(255,255,255,.035); stroke:none; }
.gfx--cad .fill-top  { fill:rgba(255,255,255,.06);  stroke:none; }
.gfx--cad .fill-right{ fill:rgba(255,255,255,.035); stroke:none; }
.gfx--cad .fill-left { fill:rgba(255,255,255,.016); stroke:none; }

/* невидимый контур и осевые — по ГОСТ */
.gfx--cad .hidden{
  stroke:currentColor; stroke-width:.9; opacity:.4; fill:none;
  stroke-dasharray:5 3.5;
}
.gfx--cad .axis{
  stroke:var(--gold); stroke-width:.7; opacity:.55; fill:none;
  stroke-dasharray:9 2.5 1.5 2.5;
}

/* ─── размеры: золото, потому что это измерение ─── */
.gfx--cad .v-dim path{ stroke:var(--gold); stroke-width:.8; opacity:.68; fill:var(--gold); }
.gfx--cad .lead{ stroke:var(--gold); stroke-width:.8; opacity:.6; fill:none; }
.gfx--cad .v-dimtxt text,
.gfx--cad .dim-txt{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.06em;
  fill:var(--gold); stroke:none;
}

/* ─── подписи видов и основная надпись: вне поля проекций ─── */
.gfx--cad .v-label text{
  font-family:var(--mono); font-size:9px; letter-spacing:.2em;
  fill:var(--text-3); stroke:none;
}
.gfx--cad .ttl-rule{ stroke:currentColor; stroke-width:.8; opacity:.3; fill:none; }
.gfx--cad .ttl-name{
  font-family:var(--mono); font-size:10px; letter-spacing:.18em;
  fill:var(--gold); stroke:none;
}
.gfx--cad .ttl-line{
  font-family:var(--sans); font-size:11px;
  fill:var(--text-2); stroke:none;
}

/* ═══ АНИМАЦИЯ: как работают в CAD ═══
   Сначала строится геометрия, потом наносятся размеры, потом по ним
   проходит измерение. Порядок фаз повторяет реальную работу в SolidWorks. */

/* 1. Контуры прочерчиваются — класс .draw + pathLength="1" в разметке,
      задержки заданы там же через --d. Заливки и второстепенные линии
      подтягиваются следом. */
.gfx--cad .fill-part,
.gfx--cad .fill-top,
.gfx--cad .fill-right,
.gfx--cad .fill-left,
.gfx--cad .ln-med,
.gfx--cad .ln-thin,
.gfx--cad .ln-hair,
.gfx--cad .hidden{ opacity:0; transition:opacity .7s var(--ease) 1s; }
.is-visible .gfx--cad .fill-part { opacity:1; }
.is-visible .gfx--cad .fill-top  { opacity:1; }
.is-visible .gfx--cad .fill-right{ opacity:1; }
.is-visible .gfx--cad .fill-left { opacity:1; }
.is-visible .gfx--cad .ln-med    { opacity:.62; }
.is-visible .gfx--cad .ln-thin   { opacity:.34; }
.is-visible .gfx--cad .ln-hair   { opacity:.19; }
.is-visible .gfx--cad .hidden    { opacity:.4; }

/* 2. Осевые линии — сразу за геометрией */
.gfx--cad .axis{ opacity:0; transition:opacity .6s var(--ease) 1.35s; }
.is-visible .gfx--cad .axis{ opacity:.55; }

/* 3. Размерные цепи прочерчиваются, цифры проявляются следом */
.gfx--cad .v-dim path{
  stroke-dasharray:1; stroke-dashoffset:1;
  transition:stroke-dashoffset 1s var(--ease-draw) 1.6s;
}
.is-visible .gfx--cad .v-dim path{ stroke-dashoffset:0; }

.gfx--cad .v-dimtxt,
.gfx--cad .v-lead,
.gfx--cad .v-label,
.gfx--cad .v-title{ opacity:0; transition:opacity .8s var(--ease); }
.is-visible .gfx--cad .v-dimtxt{ opacity:1; transition-delay:2.3s; }
.is-visible .gfx--cad .v-lead  { opacity:1; transition-delay:2.4s; }
.is-visible .gfx--cad .v-label { opacity:1; transition-delay:2.5s; }
.is-visible .gfx--cad .v-title { opacity:1; transition-delay:2.65s; }

/* 4. Проход измерения: импульс бежит по размерным линиям по очереди */
.gfx--cad .v-scan path{
  stroke:var(--gold-hi); stroke-width:2.4; fill:none;
  stroke-linecap:round;
  stroke-dasharray:12 320; stroke-dashoffset:0;
  opacity:0;
}
.is-visible .gfx--cad .v-scan path{
  opacity:1;
  animation:cadScan 4.4s linear var(--d,0s) infinite;
  animation-delay:calc(2.8s + var(--d,0s));
}
@keyframes cadScan{
  0%   { stroke-dashoffset:12;  opacity:0; }
  6%   { opacity:.95; }
  46%  { opacity:.95; }
  55%  { stroke-dashoffset:-332; opacity:0; }
  100% { stroke-dashoffset:-332; opacity:0; }
}

/* ═══════════════════ 08 · АРХИТЕКТУРА И ПЛАНИРОВКА ═══════════════════
   Дом строится поэтапно: участок → фундамент → стены → крыша → дымоход.
   Иерархия линий и опорная плотность — те же, что и во всех чертежах. */

.gfx--build{ stroke-linecap:round; stroke-linejoin:round; }
.gfx--build g[transform] *{ vector-effect:non-scaling-stroke; }
.dir__figure .gfx--build{ color:rgba(255,255,255,.40); }

.gfx--build .ln-sil { stroke:currentColor; stroke-width:1.9; opacity:1;   fill:none; }
.gfx--build .ln-med { stroke:currentColor; stroke-width:1.2; opacity:.62; fill:none; }
.gfx--build .ln-thin{ stroke:currentColor; stroke-width:.85; opacity:.34; fill:none; }
.gfx--build .ln-hair{ stroke:currentColor; stroke-width:.5;  opacity:.19; fill:none; }

.gfx--build .fill-top  { fill:rgba(255,255,255,.06);  stroke:none; }
.gfx--build .fill-left { fill:rgba(255,255,255,.035); stroke:none; }
.gfx--build .fill-right{ fill:rgba(255,255,255,.02);  stroke:none; }
.gfx--build .fill-ground{ fill:rgba(255,255,255,.014); stroke:none; }
.gfx--build .fill-drive{ fill:rgba(255,255,255,.03);  stroke:none; }
.gfx--build .fill-gable{ fill:rgba(255,255,255,.05);  stroke:none; }
.gfx--build .fill-slope{ fill:rgba(255,255,255,.032); stroke:none; }

.gfx--build .grid path{ stroke:currentColor; stroke-width:.5; opacity:.1; fill:none; }
.gfx--build .boundary{
  stroke:currentColor; stroke-width:.9; opacity:.4; fill:none;
  stroke-dasharray:7 4;
}
.gfx--build .tile{ opacity:.22; }
.gfx--build .b-window path,
.gfx--build .b-door path,
.gfx--build .b-gdoor path{ stroke:currentColor; stroke-width:1; opacity:.55; fill:none; }

/* ─── геодезия: золото, потому что это привязка к участку ─── */
.gfx--build .survey{ stroke:var(--gold); stroke-width:.9; opacity:0; fill:none; }
.is-visible .gfx--build .survey{ opacity:.6; transition:opacity .5s var(--ease) var(--d,0s); }

/* ─── позиции и экспликация: тот же язык, что в 05/07 ─── */
.gfx--build .lead{ stroke:var(--gold); stroke-width:.7; opacity:.5; }
.gfx--build .pos-dot{ fill:var(--gold); stroke:none; opacity:.85; }
.gfx--build .pos-ring,
.gfx--build .leg-ring{ fill:none; stroke:var(--gold); stroke-width:.9; opacity:.6; }
.gfx--build .pos-num{
  font-family:var(--mono); font-size:9px; letter-spacing:0;
  fill:var(--gold); stroke:none; text-anchor:middle;
}
.gfx--build .leg-rule{ stroke:currentColor; stroke-width:.8; opacity:.3; fill:none; }
.gfx--build .leg-title{
  font-family:var(--mono); font-size:9px; letter-spacing:.2em;
  fill:var(--gold); stroke:none;
}
.gfx--build .leg-text{ font-family:var(--sans); font-size:10px; fill:var(--text-2); stroke:none; }
.gfx--build .leg-note{
  font-family:var(--mono); font-size:9px; letter-spacing:.14em;
  fill:var(--text-3); stroke:none;
}

/* ─── тёплое свечение: дом обитаем ─── */
.gfx--build .win-glow{ fill:var(--gold-hi); stroke:none; opacity:0; }
.gfx--build .door-glow{ fill:var(--gold); stroke:none; opacity:0; }
.gfx--build .flue{ stroke:var(--gold); stroke-width:.8; opacity:0; fill:none; }
.gfx--build .flue-glow{ fill:var(--gold-hi); stroke:none; opacity:0; filter:blur(3px); }

/* ═══ АНИМАЦИЯ: этапы поднимаются вверх, внахлёст, без пауз ═══
   Задержка следующего этапа начинается ДО того, как закончится подъём
   предыдущего — стройка идёт непрерывно, а не «этап / стоп / этап». */
.gfx--build .b-site,
.gfx--build .b-found,
.gfx--build .b-walls,
.gfx--build .b-roof,
.gfx--build .b-garage,
.gfx--build .b-chimney{
  opacity:0;
  transform:translateY(46px);
  transition:opacity .8s var(--ease) var(--d,0s),
             transform .85s var(--ease) var(--d,0s);
}
.is-visible .gfx--build .b-site   { opacity:1; transform:none; transition-delay:0s,0s; }
.is-visible .gfx--build .b-found  { opacity:1; transform:none; transition-delay:.22s,.22s; }
.is-visible .gfx--build .b-walls  { opacity:1; transform:none; transition-delay:.62s,.62s; }
.is-visible .gfx--build .b-roof   { opacity:1; transform:none; transition-delay:1.15s,1.15s; }
.is-visible .gfx--build .b-garage { opacity:1; transform:none; transition-delay:1.45s,1.45s; }
.is-visible .gfx--build .b-chimney{ opacity:1; transform:none; transition-delay:1.8s,1.8s; }

/* «живой» дом: свечение проступает после стройки, дальше — тихий пульс.
   Задержки сдвинуты на +.1s из-за добавленной стадии b-garage. */
.gfx--build .b-glow{ opacity:0; transition:opacity .8s var(--ease) 2.15s; }
.is-visible .gfx--build .b-glow{ opacity:1; }
.is-visible .gfx--build .win-glow  { opacity:.5;  transition:opacity 1s ease 2.25s; }
.is-visible .gfx--build .door-glow { opacity:.28; transition:opacity 1s ease 2.25s; }
.is-visible .gfx--build .flue      { opacity:.5;  transition:opacity 1s ease 2.3s; }
.is-visible .gfx--build .flue-glow { opacity:.6;  transition:opacity 1s ease 2.3s; }
.is-visible .gfx--build .win-glow,
.is-visible .gfx--build .flue-glow{ animation:buildPulse 4.6s var(--ease) 3.1s infinite; }
@keyframes buildPulse{ 0%,100%{ opacity:.4; } 50%{ opacity:.7; } }

/* позиции и экспликация — последний штрих */
.gfx--build .b-pos,
.gfx--build .b-legend{ opacity:0; transition:opacity .8s var(--ease); }
.is-visible .gfx--build .b-pos   { opacity:1; transition-delay:2.45s; }
.is-visible .gfx--build .b-legend{ opacity:1; transition-delay:2.6s; }

/* слои 3D-печати */
.gfx-layers .lyr{
  opacity:0;
  transform:translateY(16px);
  transition:opacity .6s var(--ease) var(--d,0s),
             transform .7s var(--ease) var(--d,0s);
}
.is-visible .gfx-layers .lyr{ opacity:1; transform:none; }

/* печатающая головка / горелка / курсор — активный инструмент */
.gfx-head{
  opacity:0;
  transform:translateY(-14px);
  transition:opacity .7s var(--ease) var(--d,.9s),
             transform .8s var(--ease) var(--d,.9s);
}
.is-visible .gfx-head{ opacity:1; transform:none; }

/* сварной шов */
.gfx-seam{
  stroke-linecap:round;
  filter:drop-shadow(0 0 7px rgba(198,161,106,.45));
}
.gfx-beads .bead{
  fill:none; stroke:var(--gold);
  opacity:0;
  transform:scale(.3);
  transform-box:fill-box; transform-origin:center;
  transition:opacity .5s var(--ease) var(--d,0s),
             transform .6s var(--ease) var(--d,0s);
}
.is-visible .gfx-beads .bead{ opacity:.8; transform:none; }

.gfx-sparks .spark{ fill:var(--gold); stroke:none; opacity:0; }
.is-visible .gfx-sparks .spark{
  animation:spark 2.6s var(--ease) var(--d,0s) infinite;
}
@keyframes spark{
  0%   { opacity:0; transform:translate(0,0) scale(1); }
  12%  { opacity:.95; }
  100% { opacity:0; transform:translate(var(--sx,0),var(--sy,40px)) scale(.4); }
}

/* разнесённая сборка */
.gfx .xpl{
  opacity:0;
  transform:translateY(0);
  transition:opacity .7s var(--ease) var(--d,0s),
             transform .9s var(--ease) var(--d,0s);
}
.is-visible .gfx .xpl{ opacity:1; transform:translateY(var(--ty,0)); }

/* блоки и узлы */
.gfx-boxes .box,
.gfx-nodes .node,
.gfx-kip .kip{
  opacity:0;
  transform:translateY(10px);
  transition:opacity .7s var(--ease) var(--d,0s),
             transform .8s var(--ease) var(--d,0s);
}
.is-visible .gfx-boxes .box,
.is-visible .gfx-nodes .node,
.is-visible .gfx-kip .kip{ opacity:1; transform:none; }

/* заливки (скелетон-блоки, остекление) — плотность задаётся цветом,
   поэтому opacity здесь работает только на появление */
.gfx-blocks{ color:rgba(255,255,255,.22); }
.gfx-blocks .blk{
  fill:currentColor;
  stroke:none;
  opacity:0;
  transform:translateY(12px);
  transition:opacity .6s var(--ease) var(--d,0s),
             transform .7s var(--ease) var(--d,0s);
}
.is-visible .gfx-blocks .blk{ opacity:1; transform:none; }

/* бегущие импульсы / поток */
.gfx .flow{
  stroke:currentColor;
  stroke-dasharray:14 210;
  stroke-dashoffset:0;
  opacity:0;
}
.is-visible .gfx .flow{
  opacity:1;
  animation:flow 3.4s linear var(--d,0s) infinite;
}
@keyframes flow{ to{ stroke-dashoffset:-224; } }

/* трубы */
.gfx-pipe{ color:var(--draw-dim); }
.gfx-bore{ color:var(--draw); }
.gfx-stream{ stroke-dasharray:18 190; }

/* манометр: стрелка — измерение, значит золото */
.gfx-gauge .needle{
  color:var(--gold);
  transform-box:view-box;
  transform-origin:120px 366px;
  transform:rotate(-96deg);
  opacity:0;
  transition:transform 1.6s cubic-bezier(.34,1.3,.5,1) 1.5s, opacity .5s ease 1.45s;
}
.is-visible .gfx-gauge .needle{ transform:rotate(58deg); opacity:1; }

.gfx-wall{ stroke-width:1.6; }
.gfx-door,.gfx-window{ stroke-width:1.2; color:var(--draw-dim); }
.gfx-grid{ color:var(--grid); }
.gfx-axis-grid{ color:var(--draw-dim); }

/* ═══════════════════ О КОМПАНИИ ═══════════════════ */
.about{
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
  background:
    radial-gradient(ellipse 70% 60% at 82% 0%, var(--gold-haze), transparent 70%),
    var(--canvas);
}
.about__inner{
  display:grid;
  grid-template-columns:minmax(0,.95fr) minmax(0,1fr);
  column-gap:clamp(32px,6vw,96px);
  row-gap:56px;
}
.about__body p{
  margin:0 0 22px;
  color:var(--text-2);
  font-size:clamp(15px,1.2vw,17px);
  line-height:1.78;
}
/* Счётчики намеренно без золотого блика: два металлических момента
   рядом гасят друг друга. Блик работает один раз — в заголовке. */
.counters{
  grid-column:1 / -1;
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1px;
  margin:20px 0 0;
  background:var(--line);
  border:1px solid var(--line);
}
.counter{
  position:relative;
  background:var(--surface);
  padding:clamp(24px,3vw,38px);
  transition:background-color .5s var(--ease);
}
.counter::before{
  content:"";
  position:absolute; left:0; top:0;
  width:0; height:1px;
  background:var(--gold);
  transition:width .8s var(--ease) var(--d,0s);
}
.is-visible .counter::before{ width:100%; }
.counter:hover{ background:var(--surface-2); }
.counter dd{
  margin:0 0 10px;
  font-size:clamp(38px,5.6vw,68px);
  font-weight:800;
  letter-spacing:-.05em;
  line-height:1;
  color:var(--text);
}
.counter dd i{ font-style:normal; color:var(--gold); }
.counter dt{ margin:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* ═══════════════════ ПАРТНЁРАМ (баннер) ═══════════════════
   Полный питч и форма заявки партнёра — на отдельной странице
   partners.html; здесь только приглашение, чтобы не путать с
   основным предложением «закажите у нас» (см. README). */
.partner-teaser{
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
}
/* Широкая вертикальная композиция — как у sec-head/adv/process — а не
   «текст слева, кнопка справа»: заказчик отметил, что справа оставалось
   пустое поле и это читалось как недоделанная вёрстка. Кнопка теперь
   идёт под текстом, вровень с левым краем заголовка. */
.partner-teaser__lead{
  margin:24px 0 0;
  max-width:70ch;
  color:var(--text-2);
  font-size:clamp(15px,1.2vw,17px);
  line-height:1.75;
}
.partner-teaser__cta{ margin-top:clamp(28px,3vw,40px); }

/* ═══════════════════ ВТОРИЧНЫЕ СТРАНИЦЫ (partners.html, faq.html, privacy.html) ═══════════════════
   .page-hero — общий вводный экран для любой страницы, которая не index.html:
   надзаголовок + h1 + широкий лид-абзац, без параллакса и без тикера hero
   на главной (они завязаны на .hero и здесь не нужны). Сеть узлов —
   исключение: по умолчанию её тоже нет, но она подключается точечно,
   там, где в разметке есть canvas .page-hero__net (сейчас только
   partners.html, по прямой просьбе «эффект такой же, как на главной») —
   .is-visible на .page-hero подключается тем же generic-реиклом
   (initReveal(), data-observe уже стоит на .page-hero), отдельная
   логика показа не нужна. */
.page-hero{
  position:relative;
  overflow:hidden;
  padding:calc(var(--hdr-h) + clamp(56px,8vw,120px)) 0 var(--sec-pad);
  border-bottom:1px solid var(--line);
}
/* тот же канвас-эффект, что в hero (#hero-net) и в .adv (#adv-net) —
   тот же initNet() из main.js, просто на своём canvas и в своей секции. */
.page-hero__net{
  position:absolute; inset:0;
  width:100%; height:100%;
  pointer-events:none;
  opacity:0;
  transition:opacity 1.4s var(--ease) .3s;
}
.page-hero.is-visible .page-hero__net{ opacity:1; }
.page-hero__lead{
  margin:22px 0 34px;
  max-width:68ch;
  color:var(--text-2);
  font-size:clamp(15px,1.3vw,18px);
  line-height:1.75;
}
.how{
  padding-block:var(--sec-pad);
}

/* ═══════════════════ КАК РАБОТАЕМ ═══════════════════ */
.process{
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
  background:
    radial-gradient(ellipse 58% 48% at 10% 18%, rgba(255,255,255,.04), transparent 70%),
    var(--canvas);
}
/* Здесь нумерация оправдана: это настоящая последовательность,
   порядок несёт смысл. Полоса прогресса прочерчивается по скроллу. */
.steps{
  list-style:none; margin:clamp(44px,5vw,76px) 0 0; padding:0;
  display:grid;
  grid-template-columns:repeat(5,minmax(0,1fr));
  gap:1px;
  background:var(--line);
  border:1px solid var(--line);
}
.step{
  background:var(--surface);
  padding:clamp(24px,2.4vw,34px) clamp(20px,2vw,28px) clamp(32px,3.4vw,48px);
  position:relative;
  transition:background-color .5s var(--ease);
}
.step:hover{ background:var(--surface-2); }
.step::after{
  content:"";
  position:absolute; left:0; top:-1px;
  width:0; height:2px;
  background:var(--gold);
  transition:width 1.1s var(--ease) var(--d,0s);
}
.is-visible .step::after{ width:100%; }
.step__num{
  display:block;
  font-size:12px;
  color:var(--gold);
  margin-bottom:22px;
}
.step h3{
  margin:0 0 12px;
  font-size:17px; font-weight:700;
  letter-spacing:-.02em; line-height:1.3;
}
.step p{
  margin:0;
  color:var(--text-2);
  font-size:13.5px; line-height:1.65;
}

/* ═══════════════════ ПРЕИМУЩЕСТВА ═══════════════════ */
.adv{
  position:relative;
  overflow:hidden;
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
}
/* тот же канвас-эффект, что в hero (#hero-net) — тот же initNet(),
   другой id/секция. Прозрачный фон, поэтому лежит просто позади
   .container (у которого глобальный z-index:1) без доп. z-index здесь. */
.adv-net{
  position:absolute; inset:0;
  width:100%; height:100%;
  pointer-events:none;
  opacity:0;
  transition:opacity 1.4s var(--ease) .3s;
}
.adv.is-visible .adv-net{ opacity:1; }
.adv-grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1px;
  margin-top:clamp(44px,5vw,72px);
  background:var(--line);
  border:1px solid var(--line);
}
.adv-card{
  background:var(--surface);
  padding:clamp(28px,3vw,44px);
  position:relative;
  overflow:hidden;
  transition:background-color .5s var(--ease);
}
.adv-card::before{
  content:"";
  position:absolute; inset:0;
  background:radial-gradient(ellipse 80% 70% at 50% 0%, var(--gold-soft), transparent 70%);
  opacity:0;
  transition:opacity .55s var(--ease);
}
.adv-card:hover{ background:var(--surface-2); }
.adv-card:hover::before{ opacity:1; }
.adv-card__idx{
  display:block;
  color:var(--text-3);
  margin-bottom:26px;
  font-size:12px;
  position:relative;
  transition:color .4s var(--ease);
}
.adv-card:hover .adv-card__idx{ color:var(--gold); }
.adv-card h3{
  margin:0 0 14px;
  font-size:19px; font-weight:700;
  letter-spacing:-.025em; line-height:1.28;
  position:relative;
}
.adv-card p{
  margin:0;
  color:var(--text-2);
  font-size:14px; line-height:1.7;
  position:relative;
}

/* ═══════════════════ ЗАЯВКА ═══════════════════ */
.request{
  position:relative;
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
  overflow:hidden;
}
.request__bg{
  position:absolute; inset:0;
  background:
    linear-gradient(to right, var(--grid) 1px, transparent 1px) 0 0/64px 64px,
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px) 0 0/64px 64px;
  mask-image:radial-gradient(ellipse 70% 70% at 24% 40%, #000, transparent 72%);
  -webkit-mask-image:radial-gradient(ellipse 70% 70% at 24% 40%, #000, transparent 72%);
  pointer-events:none;
}
.request__inner{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,.86fr) minmax(0,1fr);
  gap:clamp(36px,6vw,88px);
  align-items:start;
}
/* Заголовок узкий колонки (.86fr от .request__inner) — общий .h2 (clamp
   до 60px) в ней разваливается на 3-4 строки с сиротским тире на своей
   строке. Здесь свой, чуть меньший потолок + .nowrap на каждой половине
   фразы гарантирует ровно 2 строки в любом окне: тире и последнее слово
   никогда не переносятся сами по себе (разрыв — только там, где <br>). */
.request__h2{ font-size:clamp(22px,3.2vw,40px); }
.request__h2 .nowrap{ white-space:nowrap; }

.request__note{
  margin:28px 0 0;
  color:var(--text-2);
  max-width:44ch;
  line-height:1.75;
}
.request__points{
  list-style:none; margin:32px 0 0; padding:0;
  border-top:1px solid var(--line);
}
.request__points li{
  padding:13px 0 13px 26px;
  border-bottom:1px solid var(--line);
  font-size:14px;
  color:var(--text-2);
  position:relative;
}
.request__points li::before{
  content:"";
  position:absolute; left:2px; top:22px;
  width:9px; height:1px; background:var(--gold);
}

/* ─── форма ─── */
.form{
  position:relative;
  border:1px solid var(--line);
  background:var(--surface);
  padding:clamp(26px,3.2vw,44px);
}
/* Honeypot-ловушка от спам-ботов (см. initAntiSpam() в main.js): поле,
   которое не видит и не может заполнить живой человек — ни глазами, ни
   табуляцией, ни скринридером, — а простые боты, слепо заполняющие
   каждый input формы, попадаются на него. position:absolute с уводом за
   пределы экрана вместо display:none — часть ботов пропускает именно
   display:none/visibility:hidden поля как явную защиту, а на «просто вне
   экрана» это работает надёжнее. */
.hp-field{
  position:absolute !important;
  left:-9999px !important; top:auto !important;
  width:1px !important; height:1px !important;
  overflow:hidden !important;
  opacity:0 !important;
  pointer-events:none !important;
}
.form__row{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:18px;
}
.field{ margin-bottom:20px; }
.field label.mono{
  display:block;
  margin-bottom:10px;
  font-size:10.5px;
}
.field label.mono i{ color:var(--gold); font-style:normal; }
.field label.mono i.field__opt{ color:var(--text-3); text-transform:none; letter-spacing:normal; }

.field input[type="text"],
.field input[type="tel"],
.field input[type="email"],
.field select,
.field textarea{
  width:100%;
  padding:14px 16px;
  background:var(--canvas);
  border:1px solid var(--line);
  border-radius:2px;
  color:var(--text);
  font-family:var(--sans);
  font-size:14.5px;
  line-height:1.5;
  transition:border-color .35s var(--ease), background-color .35s var(--ease);
}
.field textarea{ resize:vertical; min-height:120px; }
.field select{
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--gold) 50%),
                   linear-gradient(135deg,var(--gold) 50%,transparent 50%);
  background-position:calc(100% - 20px) center, calc(100% - 14px) center;
  background-size:6px 6px, 6px 6px;
  background-repeat:no-repeat;
  padding-right:44px;
  cursor:pointer;
}
.field select option{ background:var(--surface); color:var(--text); }

.field ::placeholder{ color:var(--text-3); }
.field input:focus,
.field select:focus,
.field textarea:focus{
  border-color:var(--gold-line);
  background:var(--surface-2);
  outline:none;
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible{ outline:1px solid var(--gold); outline-offset:1px; }

/* единственное применение статусного цвета на сайте */
.field.has-error input,
.field.has-error select,
.field.has-error textarea{ border-color:var(--danger); }
.field.has-error .check__box{ border-color:var(--danger); }

.field__err{
  display:none;
  margin-top:8px;
  font-family:var(--mono);
  font-size:10.5px;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--danger);
}
.field.has-error .field__err{ display:block; }

/* ─── счётчик символов + линия прогресса (сейчас только у «Задачи») ───
   Линия — чистый индикатор, не таймер: ширину и цвет пересчитывает
   updateMsgCounter() в initForm() при каждом input (js/main.js). */
.field__limit{
  display:flex; align-items:center; gap:14px;
  margin-top:10px;
}
.field__limit-bar{
  flex:1 1 auto;
  height:2px;
  background:var(--line);
  border-radius:1px;
  overflow:hidden;
}
.field__limit-bar i{
  display:block;
  height:100%;
  width:0%;
  background:var(--gold);
  border-radius:1px;
  transition:width .2s var(--ease), background-color .3s var(--ease);
}
.field__limit-count{
  flex:0 0 auto;
  font-size:10.5px;
  letter-spacing:.08em;
  color:var(--text-3);
  white-space:nowrap;
  font-variant-numeric:tabular-nums;
  transition:color .3s var(--ease);
}
/* деликатное предупреждение при приближении к лимиту */
.field__limit.is-near .field__limit-count{ color:var(--gold); }
.field__limit.is-near .field__limit-bar i{ background:var(--gold-hi); }
.field__limit.is-full .field__limit-count{ color:var(--gold-hi); font-weight:700; }
.field__limit.is-full .field__limit-bar i{ background:var(--gold-hi); }

.field--check{ margin-top:6px; }
.check{
  display:flex; align-items:flex-start; gap:13px;
  cursor:pointer;
  font-size:13.5px;
  color:var(--text-2);
  line-height:1.6;
}
.check input{
  position:absolute;
  opacity:0; width:1px; height:1px;
}
.check__box{
  flex:0 0 auto;
  width:18px; height:18px;
  margin-top:2px;
  border:1px solid var(--line);
  border-radius:2px;
  background:var(--canvas);
  position:relative;
  transition:border-color .3s var(--ease), background-color .3s var(--ease);
}
.check__box::after{
  content:"";
  position:absolute; left:5px; top:1px;
  width:5px; height:10px;
  border:solid var(--canvas);
  border-width:0 1.6px 1.6px 0;
  transform:rotate(45deg) scale(0);
  transition:transform .25s var(--ease);
}
.check input:checked + .check__box{ background:var(--gold); border-color:var(--gold); }
.check input:checked + .check__box::after{ transform:rotate(45deg) scale(1); }
.check input:focus-visible + .check__box{ outline:1px solid var(--gold); outline-offset:2px; }
.check__text a{ color:var(--gold); text-decoration:underline; text-underline-offset:3px; }

/* ─── «Вы наш подписчик?» — необязательный чекбокс перед согласием на
   обработку данных (id="f-subscribe-field" в index.html). Про скидку за
   подписку тут ничего не пишем — это уже объяснено в начале страницы
   (промо-плашка в hero), здесь только сам факт. Пока чекбокс не отмечен —
   рядом видны две маленькие ссылки «TikTok»/«Instagram», чтобы можно было
   сразу подписаться; отметил — ссылки прячутся, они больше не нужны.
   Прячет/показывает JS
   (syncSubscribeLinks() в initForm(), main.js) через .is-subscribed на
   .field--subscribe, не голый :checked-селектор — .subscribe-links лежит
   рядом с .check, а не внутри него, а input у чекбокса визуально скрыт
   (position:absolute), так что :checked ~ работал бы, но менее явно, чем
   поведенческий класс, который сразу видно в разметке при отладке. */
.subscribe-links{
  display:flex; align-items:center; flex-wrap:wrap;
  gap:8px 18px;
  margin:12px 0 0 31px;   /* 18px чекбокс + 13px gap — вровень с текстом .check */
}
.field--subscribe.is-subscribed .subscribe-links{ display:none; }
.subscribe-links__hint{ color:var(--text-3); font-size:10px; }
.link-arrow--sm{
  font-size:10.5px;
  gap:7px;
  padding-bottom:3px;
}
.link-arrow--sm .link-arrow__icon{ width:12px; height:12px; }

/* ─── Вложения к заявке ─── */
.dropzone{
  position:relative;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:8px;
  padding:22px 16px;
  border:1px dashed var(--line);
  border-radius:2px;
  background:var(--canvas);
  text-align:center;
  cursor:pointer;
  transition:border-color .3s var(--ease), background-color .3s var(--ease);
}
.dropzone input[type="file"]{
  position:absolute; width:1px; height:1px;
  margin:-1px; padding:0; border:0;
  clip:rect(0 0 0 0); overflow:hidden;
}
.dropzone:hover,
.dropzone:focus-within,
.dropzone.is-drag{ border-color:var(--gold-line); background:var(--surface-2); }
.dropzone__icon{ width:26px; height:26px; color:var(--text-3); transition:color .3s var(--ease); }
.dropzone:hover .dropzone__icon,
.dropzone.is-drag .dropzone__icon{ color:var(--gold); }
.dropzone__text{ font-size:13.5px; color:var(--text-2); }
.dropzone__text em{ color:var(--gold); font-style:normal; text-decoration:underline; text-underline-offset:3px; }
.dropzone__formats{ font-size:9.5px; color:var(--text-3); letter-spacing:.14em; }

.file-list{ list-style:none; margin:12px 0 0; padding:0; display:flex; flex-direction:column; gap:6px; }
.file-list[hidden]{ display:none; }
.file-item{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  padding:8px 10px;
  border:1px solid var(--line);
  border-radius:2px;
  background:var(--canvas);
  font-size:12.5px;
  color:var(--text-2);
}
.file-item__name{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text); }
.file-item__size{ flex:0 0 auto; color:var(--text-3); font-family:var(--mono); font-size:10.5px; }
.file-item__remove{
  flex:0 0 auto;
  width:20px; height:20px;
  display:flex; align-items:center; justify-content:center;
  border:0; background:none; padding:0;
  color:var(--text-3); cursor:pointer;
  font-size:16px; line-height:1;
  transition:color .25s var(--ease);
}
.file-item__remove:hover,
.file-item__remove:focus-visible{ color:var(--danger); outline:none; }
.file-item.is-error{ border-color:var(--danger); }
.file-item.is-error .file-item__name{ color:var(--danger); }
.file-item__reason{
  flex:0 0 100%;
  font-family:var(--mono); font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--danger);
}

.form__hint{
  margin:14px 0 0;
  text-align:center;
  font-size:10px;
  color:var(--text-3);
}
/* «*» перед текстом — та же золотая звёздочка, что помечает обязательные
   поля в самих лейблах (.field label.mono i), чтобы было видно, на какой
   именно символ ссылается подсказка. Ссылка на FAQ — доп. напоминание
   прямо у кнопки отправки, не заменяет .request__faq-note над формой,
   а дублирует его в месте, которое точно увидят перед сабмитом. */
.form__hint i{ color:var(--gold); font-style:normal; }
.form__hint-sep{ margin:0 2px; }
.form__hint a{
  color:var(--text-2);
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color .3s var(--ease);
}
.form__hint a:hover{ color:var(--gold); }

.form__done{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:8px;
  padding:40px;
  text-align:center;
  background:var(--surface);
  animation:doneIn .6s var(--ease);
}
.form__done[hidden]{ display:none; }
@keyframes doneIn{ from{ opacity:0; transform:scale(.98); } }
.form__done svg{ width:52px; height:52px; color:var(--gold); margin-bottom:10px; }
.form__done h3{ margin:0; font-size:22px; font-weight:700; letter-spacing:-.025em; }
.form__done p{ margin:0 0 16px; color:var(--text-2); font-size:14px; max-width:36ch; }

/* ═══════════════════ КОНТАКТЫ ═══════════════════ */
.contacts{
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
}
.contacts__grid{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1px;
  margin-top:clamp(44px,5vw,72px);
  background:var(--line);
  border:1px solid var(--line);
}
.contact-card{
  position:relative;
  overflow:hidden;
  background:var(--surface);
  padding:clamp(26px,3vw,40px);
  display:flex; flex-direction:column; gap:14px;
  transition:background-color .5s var(--ease);
}
.contact-card::before{
  content:"";
  position:absolute; top:0; left:0; right:0; height:2px;
  background:var(--gold);
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .6s var(--ease);
}
.contact-card:hover::before{ transform:scaleX(1); }
.contact-card:hover{ background:var(--surface-2); }

.contact-card__icon{
  width:30px; height:30px;
  color:var(--text-2);
  transition:color .4s var(--ease), transform .4s var(--ease);
}
.contact-card:hover .contact-card__icon{
  color:var(--text);
  transform:translateY(-3px);
}

.contact-card__num{
  display:flex; align-items:baseline; gap:6px;
  margin:0;
  color:var(--gold);
}
.contact-card__num i{ color:var(--text-3); font-style:normal; }

.contact-card strong{
  font-size:clamp(15px,1.25vw,18px);
  font-weight:700;
  letter-spacing:-.02em;
  line-height:1.35;
  overflow-wrap:anywhere;
  transition:color .35s var(--ease);
}
.contact-card:hover strong{ color:var(--gold); }
.contact-card__desc{
  display:block;
  font-style:normal;
  color:var(--text-2);
  font-size:13px;
  line-height:1.55;
}

.contacts__legal{
  margin-top:clamp(28px,3vw,40px);
  padding-top:22px;
  border-top:1px solid var(--line);
  display:flex; flex-wrap:wrap; align-items:baseline; gap:8px 14px;
}
.contacts__legal p{ margin:0; }
.contacts__legal p:first-child{ color:var(--text-3); flex:0 0 auto; }
.contacts__legal p:last-child{
  color:var(--text-2);
  font-size:12.5px;
  line-height:1.6;
}

/* ═══════════════════ ПОДВАЛ ═══════════════════ */
.ftr{
  border-top:1px solid var(--line);
  background:var(--surface);
  padding-top:clamp(56px,6vw,84px);
}
.ftr__inner{
  display:grid;
  grid-template-columns:1.6fr repeat(3,1fr);
  gap:clamp(28px,4vw,56px);
  padding-bottom:clamp(44px,5vw,68px);
}
.ftr__brand .logo{
  color:var(--text-2);
  margin-bottom:24px;
}
.ftr__brand p{
  margin:0;
  color:var(--text-2);
  font-size:13.5px;
  line-height:1.7;
  max-width:38ch;
}
.ftr__nav{ display:flex; flex-direction:column; gap:11px; }
.ftr__nav .mono{ margin:0 0 8px; color:var(--gold); }
.ftr__nav a{
  font-size:13.5px;
  color:var(--text-2);
  transition:color .3s var(--ease), transform .3s var(--ease);
  width:fit-content;
}
.ftr__nav a:hover{ color:var(--text); transform:translateX(3px); }

.ftr__bottom{
  display:flex; align-items:center; justify-content:space-between;
  gap:20px; flex-wrap:wrap;
  padding-block:24px;
  border-top:1px solid var(--line);
}
.ftr__bottom p{ margin:0; font-size:10.5px; color:var(--text-2); }
.ftr__bottom a{ transition:color .3s var(--ease); }
.ftr__bottom a:hover{ color:var(--gold); }

/* ═══════════════════ КНОПКА НАВЕРХ ═══════════════════ */
.to-top{
  position:fixed; right:clamp(16px,3vw,32px); bottom:clamp(16px,3vw,32px);
  z-index:90;
  width:48px; height:48px;
  display:grid; place-items:center;
  background:rgba(22,25,30,.88);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line);
  border-radius:2px;
  cursor:pointer;
  color:var(--text-2);
  opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity .4s var(--ease), transform .4s var(--ease), visibility .4s,
             border-color .4s var(--ease), color .4s var(--ease);
}
.to-top.is-shown{ opacity:1; visibility:visible; transform:none; }
.to-top:hover{ border-color:var(--gold-line); color:var(--gold); }
.to-top svg{ width:18px; height:18px; }

/* ═══════════════════ АДАПТИВ ═══════════════════ */
@media (max-width:1400px){
  /* Порог поднят с 1180 до 1400px: логотип с flex-shrink:0
     (см. .hdr__logo) больше не сжимается сам, если строка шапки не
     влезает — вместо него обрезался бы переключатель языка справа.
     На 1180px граница была недостаточной — сама строка (логотип +
     полное меню + кнопка + переключатель) не помещается вплоть
     примерно до 1320px (потолок .container), проверено численно на
     1025/1181/1320/1450px. Сжимаем зазоры и паддинги между
     логотипом/меню/кнопкой/переключателем, а не сам логотип. */
  .hdr__inner{ gap:6px; }
  .nav{ gap:8px; }
  .nav__link{ font-size:10px; letter-spacing:.1em; }
  .hdr__cta{ --btn-pad:9px 14px; }
  .lang-switch__btn{ padding:6px 7px; }
  .steps{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .contacts__grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

@media (max-width:1024px){
  :root{ --hdr-h:64px; }   /* было 68px→84px→92px→88px — под 30px логотип ниже */
  .logo--hdr{ height:30px; }   /* было 60px — уменьшен вдвое вместе с десктопным, см. комментарий выше */

  /* мобильное меню */
  .nav{
    position:fixed; inset:0;
    flex-direction:column; align-items:flex-start; justify-content:center;
    gap:6px;
    margin:0;
    padding:calc(var(--hdr-h) + 24px) var(--gutter) 40px;
    overflow-y:auto;
    background:
      radial-gradient(ellipse 90% 50% at 0% 40%, var(--gold-haze), transparent 70%),
      var(--canvas);
    opacity:0; visibility:hidden;
    transition:opacity .45s var(--ease), visibility .45s;
    z-index:99;
  }
  .nav.is-open{ opacity:1; visibility:visible; }

  /* Пока меню открыто, шапка не должна применять backdrop-filter:
     он создаёт containing block и схлопывает position:fixed оверлей
     до высоты самой шапки. */
  body.is-locked .hdr{
    background:transparent;
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
    border-bottom-color:transparent;
  }

  .nav__link{
    font-size:22px;
    font-family:var(--sans);
    font-weight:700;
    letter-spacing:-.03em;
    text-transform:none;
    color:var(--text);
    padding:13px 0;
    opacity:0; transform:translateY(14px);
    transition:opacity .5s var(--ease) var(--i,0s), transform .5s var(--ease) var(--i,0s), color .3s var(--ease);
  }
  .nav.is-open .nav__link{ opacity:1; transform:none; }
  .nav__link::after{ display:none; }
  .nav__link.is-active{ color:var(--gold); }

  .nav__link--cta{
    display:block;
    margin-top:26px;
    padding:15px 28px;
    font-family:var(--mono);
    font-size:11.5px;
    font-weight:600;
    letter-spacing:.16em;
    text-transform:uppercase;
    background:var(--gold);
    color:var(--canvas);
    border-radius:2px;
  }

  .hdr__cta{ display:none; }
  .burger{ display:block; }

  .about__inner{ grid-template-columns:1fr; }
  .adv-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .request__inner{ grid-template-columns:1fr; }
  .ftr__inner{ grid-template-columns:1fr 1fr; }
  .ftr__brand{ grid-column:1 / -1; }
}

@media (max-width:860px){
  .hero__stats{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .counters{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .steps{ grid-template-columns:repeat(2,minmax(0,1fr)); }

  /* направления: чертёж уходит фоном за текст */
  .dir__inner{ grid-template-columns:1fr; gap:0; }
  .dir--flip .dir__text,
  .dir--flip .dir__figure{ order:initial; }
  .dir__figure{
    position:absolute;
    inset:0;
    display:grid; place-items:center;
    pointer-events:none;
    overflow:hidden;
  }
  .dir__figure .gfx{
    width:132%;
    max-width:none;
    color:rgba(255,255,255,.07);
  }
  /* золото на фоне приглушается, но остаётся ориентиром */
  .dir__figure .gfx-accent,
  .dir__figure .gfx-seam,
  .dir__figure .gfx-head,
  .dir__figure .gfx-dim,
  .dir__figure .gfx-cut,
  .dir__figure .gfx-kip,
  .dir__figure .gfx .flow,
  .dir__figure .gfx-gauge .needle{ color:rgba(198,161,106,.30); }
  .dir__figure .gfx-seam{ filter:none; }
  .dir__figure .gfx-beads .bead{ stroke:rgba(198,161,106,.30); }
  .dir__figure .gfx-sparks .spark{ fill:rgba(198,161,106,.30); }

  /* блок 01: горячая зона и траектория */
  .dir__figure .gfx--print .toolpath,
  .dir__figure .gfx--print .front,
  .dir__figure .gfx--print .strand{ stroke:rgba(198,161,106,.30); }
  .dir__figure .gfx--print .bead{ fill:rgba(198,161,106,.30); }
  .dir__figure .gfx--print .bead-glow{ opacity:.14; }

  /* блок 02: дуга, шов, искры */
  .dir__figure .gfx--weld .arc{ stroke:rgba(217,186,139,.34); }
  .dir__figure .gfx--weld .pool{ fill:rgba(217,186,139,.34); }
  .dir__figure .gfx--weld .glow{ opacity:.16; }
  .dir__figure .gfx--weld .glow-wide{ opacity:.1; }
  .dir__figure .gfx--weld .spark{ fill:rgba(217,186,139,.34); }
  .dir__figure .gfx--weld .spatter{ fill:rgba(198,161,106,.3); }
  .dir__figure .gfx--weld .ripples path,
  .dir__figure .gfx--weld .w-bead .ln-sil,
  .dir__figure .gfx--weld .w-bead .ln-med{ stroke:rgba(198,161,106,.3); }
  .dir__figure .gfx--weld .fill-bead{ fill:rgba(198,161,106,.05); }

  /* блок 03: подсветка, риска момента, контакт */
  .dir__figure .gfx--fix .index,
  .dir__figure .gfx--fix .spin,
  .dir__figure .gfx--fix .bt{ stroke:rgba(198,161,106,.32); }
  .dir__figure .gfx--fix .led,
  .dir__figure .gfx--fix .contact{ fill:rgba(217,186,139,.34); }
  .dir__figure .gfx--fix .led-glow{ opacity:.14; }
  .dir__figure .gfx--fix .contact-glow{ opacity:.14; }
  .dir__figure .gfx--fix .fill-hot{ fill:rgba(198,161,106,.05); }

  /* блок 05: поток, манометр, позиции и экспликация.
     Текст экспликации задан токеном и не наследует ослабление фигуры —
     на мобильных он спорил бы с текстом самого блока. */
  .dir__figure .gfx--plumb .wflow{ stroke:rgba(198,161,106,.32); }
  .dir__figure .gfx--plumb .gauge{ stroke:rgba(198,161,106,.32); }
  .dir__figure .gfx--plumb .lead{ stroke:rgba(198,161,106,.22); }
  .dir__figure .gfx--plumb .pos-dot{ fill:rgba(198,161,106,.28); }
  .dir__figure .gfx--plumb .pos-ring,
  .dir__figure .gfx--plumb .leg-ring{ stroke:rgba(198,161,106,.24); }
  .dir__figure .gfx--plumb .pos-num,
  .dir__figure .gfx--plumb .leg-title{ fill:rgba(198,161,106,.3); }
  .dir__figure .gfx--plumb .leg-text{ fill:rgba(255,255,255,.13); }
  .dir__figure .gfx--plumb .leg-note,
  .dir__figure .gfx--plumb .s-lvl text{ fill:rgba(255,255,255,.1); }

  /* блок 07: размеры, осевые, основная надпись */
  .dir__figure .gfx--cad .v-dim path{ stroke:rgba(198,161,106,.3); fill:rgba(198,161,106,.3); }
  .dir__figure .gfx--cad .axis,
  .dir__figure .gfx--cad .lead{ stroke:rgba(198,161,106,.24); }
  .dir__figure .gfx--cad .v-scan path{ stroke:rgba(198,161,106,.3); }
  .dir__figure .gfx--cad .v-dimtxt text,
  .dir__figure .gfx--cad .dim-txt,
  .dir__figure .gfx--cad .ttl-name{ fill:rgba(198,161,106,.3); }
  .dir__figure .gfx--cad .ttl-line{ fill:rgba(255,255,255,.13); }
  .dir__figure .gfx--cad .v-label text{ fill:rgba(255,255,255,.1); }

  /* блок 08: геодезия, свечение, позиции и экспликация */
  .dir__figure .gfx--build .survey{ stroke:rgba(198,161,106,.28); }
  .dir__figure .gfx--build .lead{ stroke:rgba(198,161,106,.22); }
  .dir__figure .gfx--build .pos-dot{ fill:rgba(198,161,106,.26); }
  .dir__figure .gfx--build .pos-ring,
  .dir__figure .gfx--build .leg-ring{ stroke:rgba(198,161,106,.22); }
  .dir__figure .gfx--build .pos-num,
  .dir__figure .gfx--build .leg-title{ fill:rgba(198,161,106,.28); }
  .dir__figure .gfx--build .leg-text{ fill:rgba(255,255,255,.13); }
  .dir__figure .gfx--build .leg-note{ fill:rgba(255,255,255,.1); }
  .dir__figure .gfx--build .win-glow,
  .dir__figure .gfx--build .flue-glow{ fill:rgba(217,186,139,.3); }
  .dir__figure .gfx--build .door-glow{ fill:rgba(198,161,106,.26); }
  .dir__figure .gfx--build .flue{ stroke:rgba(198,161,106,.28); }

  .dir__text{ position:relative; z-index:1; }
}

@media (max-width:640px){
  /* Тот же общий ритм, но со своей vw-долей под узкие экраны —
     иначе на 375px базовый clamp() выше даёт менее естественную
     пропорцию к тексту. */
  :root{ --sec-pad:clamp(24px,6vw,32px); }

  .hero{ padding-bottom:150px; }
  .hero__title{ letter-spacing:-.035em; }
  .hero__actions .btn,
  .hero__actions .dir-menu{ flex:1 1 100%; }
  .dir-menu__label{ flex:1 1 auto; justify-content:center; }

  /* На узких экранах позиция кнопки в hero «плавающая» (зависит от того,
     сколько строк занял заголовок) — выпадающий список от кнопки может
     не влезть до низа экрана. Поэтому на мобильных это не флаут, а лист,
     выезжающий снизу экрана целиком, плюс затемнение фона. */
  .dir-menu__backdrop{
    display:block;
    position:fixed; inset:0;
    background:rgba(4,5,7,.7);
    opacity:0; visibility:hidden; pointer-events:none;
    transition:opacity .35s var(--ease), visibility 0s linear .35s;
    z-index:39;
  }
  .dir-menu.is-open ~ .dir-menu__backdrop{
    opacity:1; visibility:visible; pointer-events:auto;
    transition:opacity .35s var(--ease), visibility 0s linear 0s;
  }
  .dir-menu__panel{
    position:fixed; top:auto; right:0; bottom:0; left:0;
    width:auto;
    max-height:75vh;
    grid-template-columns:1fr;
    border-radius:16px 16px 0 0;
    border-bottom:0;
    padding:14px 14px calc(14px + env(safe-area-inset-bottom, 0px));
    box-shadow:0 -24px 48px -12px rgba(0,0,0,.6);
    transform:translateY(100%);
  }
  .dir-menu.is-open .dir-menu__panel{ transform:translateY(0); }
  .ticker{ bottom:64px; }

  .form__row{ grid-template-columns:1fr; gap:0; }
  .partner-teaser__cta{ width:100%; text-align:center; }
  .adv-grid{ grid-template-columns:1fr; }
  .steps{ grid-template-columns:1fr; }
  .contacts__grid{ grid-template-columns:1fr; }
  .ftr__inner{ grid-template-columns:1fr; gap:36px; }
  .ftr__nav[aria-label="Направления, продолжение"] .mono{ display:none; }
  .ftr__bottom{ justify-content:flex-start; }
}

@media (max-width:400px){
  :root{ --gutter:18px; }
  .hero__stats > div{ padding:16px 16px; }
  .counter{ padding:22px 18px; }
  .contact-card strong{ font-size:15px; }
}

/* ═══════════════════ ДОСТУПНОСТЬ: МЕНЬШЕ ДВИЖЕНИЯ ═══════════════════ */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }

  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    transition-delay:0s !important;
  }

  /* графика показывается сразу в конечном состоянии */
  .reveal{ opacity:1; transform:none; }
  .draw{ stroke-dashoffset:0; }
  .fade,
  .gfx-layers .lyr,
  .gfx-head,
  .gfx-beads .bead,
  .gfx .xpl,
  .gfx-boxes .box,
  .gfx-nodes .node,
  .gfx-kip .kip{ opacity:1; transform:none; }
  .dir__figure .gfx{ opacity:1; }
  .gfx .xpl{ transform:translateY(var(--ty,0)); }
  .gfx-blocks .blk{ opacity:1; transform:none; }
  .gfx .flow{ opacity:.7; }
  .gfx-sparks .spark{ opacity:0; }
  .gfx-gauge .needle{ transform:rotate(58deg); opacity:1; }
  .step::after,.is-visible .step::after{ width:100%; }
  .counter::before,.is-visible .counter::before{ width:100%; }
  .ticker__track{ animation:none; }
  .hero__scroll span::after{ display:none; }
}

/* ═══════════════════ FAQ (faq.html) ═══════════════════
   Аккордеон на чистом CSS-переходе grid-template-rows (0fr → 1fr) —
   не нужно измерять scrollHeight в JS и переигрывать при ресайзе,
   работает для ответа любой длины. JS только переключает класс is-open
   и aria-expanded, см. initFaq() в js/main.js. */
.faq{
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
}
.faq-list{
  margin-top:clamp(32px,4vw,56px);
  border-top:1px solid var(--line);
}
.faq-item{ border-bottom:1px solid var(--line); }
.faq-item h3{ margin:0; }
.faq-item__q{
  display:flex; align-items:center; justify-content:space-between;
  gap:24px;
  width:100%;
  padding:22px 2px;
  background:none; border:0;
  color:var(--text);
  font-family:var(--sans);
  font-size:clamp(15px,1.5vw,17px);
  font-weight:600;
  letter-spacing:-.01em;
  text-align:left;
  cursor:pointer;
  transition:color .3s var(--ease);
}
.faq-item__q:hover{ color:var(--gold); }
.faq-item__q:focus-visible{ outline:1px solid var(--gold); outline-offset:2px; }
.faq-item.is-open .faq-item__q{ color:var(--gold); }

.faq-item__chev{
  flex:0 0 auto;
  width:11px; height:8px;
  color:var(--text-3);
  transition:transform .35s var(--ease), color .35s var(--ease);
}
.faq-item.is-open .faq-item__chev{ transform:rotate(180deg); color:var(--gold); }

.faq-item__panel{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .4s var(--ease);
}
.faq-item.is-open .faq-item__panel{ grid-template-rows:1fr; }
.faq-item__answer{ overflow:hidden; }
.faq-item__answer p{
  margin:0;
  padding:0 2px 22px;
  max-width:72ch;
  color:var(--text-2);
  font-size:14.5px; line-height:1.7;
}

.faq-cta{ margin-top:clamp(32px,4vw,48px); }

/* ─── подсказка к форме заявки: «загляните в FAQ перед отправкой» ─── */
.request__faq-note{
  display:flex; align-items:flex-start; gap:12px;
  margin-top:22px;
  padding:14px 16px;
  border:1px solid var(--gold-line);
  background:var(--gold-haze);
  border-radius:2px;
  color:var(--gold);
  font-size:13.5px; line-height:1.6;
  transition:background-color .3s var(--ease), border-color .3s var(--ease);
}
.request__faq-note:hover{ background:rgba(198,161,106,.12); border-color:var(--gold); }
.request__faq-note svg{ flex:0 0 auto; width:18px; height:18px; margin-top:1px; }

/* ═══════════════════ ПРЕИМУЩЕСТВА: радиальная схема ═══════════════════
   .adv-grid/.adv-card (карточки) больше не выводятся в index.html, но
   стили НЕ трогаем — та же разметка ещё используется в partners.html
   («Как это работает»). Новая схема живёт под собственными именами:
   .adv-diagram (десктоп) и .adv-timeline (мобильные, см. медиа-запрос).

   Единая система координат 0–100 — те же числа задают точки в SVG
   (viewBox="0 0 100 100", preserveAspectRatio="none", поэтому X и Y
   растягиваются независимо ровно как проценты) и в HTML через --x/--y
   (left/top в %). Одна точка = одно число в обоих местах, поэтому линия
   и узел никогда не расходятся при изменении ширины. */
.adv-diagram{
  position:relative;
  width:100%;
  max-width:1320px;
  margin:clamp(48px,6vw,88px) auto 0;
  /* заказчик попросил компактнее по высоте (иначе весь блок не влезал
     на экран без долгой прокрутки) — max-width расширен до предела
     контейнера сайта (--maxw), а пропорция снова заметно шире/ниже,
     чем в предыдущей версии (1.55:1 → 2/1). Держится без наложения
     узлов только за счёт того, что текстовые колонки теперь шире
     (меньше строк на карточку) и номер идёт в строку с текстом,
     а не отдельной строкой сверху — см. .adv-node__text ниже. */
  aspect-ratio:2 / 1;
  transform:translateY(calc(var(--scroll,0) * 8px));
  transition:transform .2s linear;
}

.adv-diagram__lines{
  position:absolute; inset:0;
  width:100%; height:100%;
  overflow:visible;
}
.adv-line{
  fill:none;
  stroke:rgba(255,255,255,.14);
  stroke-width:1;
  vector-effect:non-scaling-stroke;
  stroke-dasharray:1;
  stroke-dashoffset:1;
  opacity:.55;
  animation:advLineGlow 6s ease-in-out infinite;
  transition:stroke .5s var(--ease), stroke-width .3s var(--ease), opacity .5s var(--ease);
}
.is-visible .adv-line{
  stroke-dashoffset:0;
  transition:stroke-dashoffset 1.5s var(--ease-draw) var(--ld,.2s), stroke .5s var(--ease), stroke-width .3s var(--ease), opacity .5s var(--ease);
}
.adv-line[data-node="1"]{ --ld:.1s; animation-delay:.1s; }
.adv-line[data-node="2"]{ --ld:.3s; animation-delay:.9s; }
.adv-line[data-node="3"]{ --ld:.5s; animation-delay:1.7s; }
.adv-line[data-node="4"]{ --ld:.7s; animation-delay:2.4s; }
.adv-line[data-node="5"]{ --ld:.2s; animation-delay:.5s; }
.adv-line[data-node="6"]{ --ld:.4s; animation-delay:1.3s; }
.adv-line[data-node="7"]{ --ld:.6s; animation-delay:2.1s; }
.adv-line[data-node="8"]{ --ld:.8s; animation-delay:2.8s; }
@keyframes advLineGlow{
  0%,100%{ opacity:.5; }
  50%{ opacity:.85; }
}
.adv-line.is-hot{
  stroke:var(--gold);
  stroke-width:1.4;
  opacity:1 !important;
  animation-play-state:paused;
}

/* mesh: чисто декоративная «паутина» вокруг основных линий — никуда не
   ведёт, ни на что не реагирует, только плотность/атмосфера. Слабее
   и медленнее основных линий, чтобы не спорить с ними за внимание. */
.adv-mesh path{
  fill:none;
  stroke:rgba(255,255,255,.07);
  stroke-width:.6;
  vector-effect:non-scaling-stroke;
}
.adv-mesh__dot{
  fill:rgba(255,255,255,.22);
  animation:advMeshPulse 4.5s ease-in-out infinite;
}
.adv-mesh__dot:nth-of-type(odd){ animation-duration:5.6s; animation-delay:.6s; }
@keyframes advMeshPulse{
  0%,100%{ opacity:.4; }
  50%{ opacity:.9; }
}

/* ─── центр: голый логотип (без диска-подложки) + 3D-наклон ───
   По просьбе заказчика круг-подложка убран целиком — остаётся только
   сам знак и линии, идущие прямо от него. Два вложенных слоя всё равно
   нужны: внешний (.adv-diagram__core) отвечает только за позицию
   (центр + scroll-параллакс), внутренний (-inner) — только за наклон
   (rotateX/rotateY от курсора, initAdvDiagram() в main.js). Если бы оба
   transform'а стояли на одном элементе, один бы затирал другой при
   каждом кадре. Раньше core был квадратом под круг; теперь его форма —
   пропорция самого логотипа (1597:346.25), под голый знак это точнее. */
.adv-diagram__core{
  position:absolute; left:50%; top:50%;
  transform:translate(-50%, calc(-50% + var(--scroll,0) * -16px));
  width:clamp(290px,32vw,480px);
  aspect-ratio:1597 / 346.25;
  transition:transform .2s linear;
  perspective:900px;
}
.adv-diagram__core-inner{
  width:100%; height:100%;
  display:flex; align-items:center; justify-content:center;
  transform:rotateX(var(--tilt-y,0deg)) rotateY(var(--tilt-x,0deg));
  transition:transform .5s var(--ease);
}
.adv-diagram__logo{
  width:100%; height:auto;
  color:var(--text);
  animation:advCoreBreathe 5s ease-in-out infinite;
  filter:drop-shadow(0 8px 32px rgba(0,0,0,.55)) drop-shadow(0 0 22px rgba(255,255,255,.12));
}
.adv-diagram.is-hot .adv-diagram__logo{
  filter:drop-shadow(0 8px 32px rgba(0,0,0,.55)) drop-shadow(0 0 28px var(--gold-haze));
}
@keyframes advCoreBreathe{
  0%,100%{ opacity:.92; }
  50%{ opacity:1; }
}

.adv-node{
  position:absolute; top:var(--y);
  display:flex; align-items:center; gap:9px;
  background:none; border:0; padding:0; margin:0;
  cursor:pointer;
  color:var(--text-2);
  animation:advFloat var(--fd,8s) ease-in-out var(--ff,0s) infinite;
}
/* невидимая зона побольше для тача/клика — псевдоэлемент не входит в
   собственный размер кнопки, поэтому не сдвигает transform:translate(-100%)
   / translate(0) ниже, которым точка узла выравнивается точно на конец
   линии (без псевдоэлемента любой padding здесь сдвигал бы точку на себя). */
.adv-node::before{
  content:"";
  position:absolute; inset:-10px;
}
.adv-node--l{ left:var(--x); transform:translate(-100%,-50%); justify-content:flex-end; text-align:right; }
.adv-node--r{ left:var(--x); transform:translate(0,-50%); text-align:left; }
@keyframes advFloat{
  0%,100%{ margin-top:0; }
  50%{ margin-top:-5px; }
}
.adv-node__text{
  /* На границе переключения (1081px) диаграмма занимает всю ширину
     контейнера без запаса — здесь колонка уже, чем на широких экранах,
     иначе текст вылезает за край страницы (было — проверено числами,
     не на глаз). На ≥1400px, где вокруг диаграммы уже есть реальный
     запас (см. .adv-diagram { max-width:1320px }), колонка расширяется
     override'ом ниже — это и есть «пошире», о чём просил заказчик. */
  max-width:clamp(150px,15vw,200px);
  font-size:clamp(15px,1.8vw,23px); line-height:1.4;
  transition:color .35s var(--ease);
}
@media (min-width:1400px){
  .adv-node__text{ max-width:clamp(210px,17vw,260px); }
}
.adv-node__text i{
  display:inline;
  margin-right:7px;
  color:var(--text-3);
  font-size:14px;
  font-style:normal;
  transition:color .35s var(--ease);
}
.adv-node__dot{
  flex:0 0 auto;
  width:7px; height:7px;
  border-radius:50%;
  background:var(--text-3);
  box-shadow:0 0 0 3px var(--canvas);
  transition:background-color .35s var(--ease), box-shadow .35s var(--ease), transform .35s var(--ease);
}
.adv-node:hover,
.adv-node:focus-visible,
.adv-node.is-hot{ color:var(--text); }
.adv-node:hover .adv-node__text i,
.adv-node:focus-visible .adv-node__text i,
.adv-node.is-hot .adv-node__text i{ color:var(--gold); }
.adv-node:hover .adv-node__dot,
.adv-node:focus-visible .adv-node__dot,
.adv-node.is-hot .adv-node__dot{
  background:var(--gold);
  box-shadow:0 0 0 3px var(--canvas), 0 0 10px 1px var(--gold-haze);
  transform:scale(1.3);
}
.adv-node:focus-visible{ outline:1px solid var(--gold); outline-offset:3px; border-radius:2px; }

/* ─── мобильные/узкие десктопы: вертикальная версия ───
   Порог подняли с 860px до 1080px: после увеличения логотипа (~3×)
   и текста узлов (~2×) радиальная схема физически перестала помещаться
   на узких десктопных ширинах (861–1000px) без наложения соседних
   узлов друг на друга — проверено численно (getBoundingClientRect),
   не на глаз. Таймлайн сам по себе не растягивается шире 420px, поэтому
   на «пограничных» 1000-1080px выглядит так же собранно, как на телефоне. */
.adv-timeline{ display:none; }

@media (max-width:1080px){
  .adv-diagram{ display:none; }

  .adv-timeline{
    display:block;
    max-width:420px;
    margin:clamp(40px,8vw,64px) auto 0;
  }
  .adv-timeline__core{
    display:flex; justify-content:center;
    margin-bottom:32px;
  }
  .adv-timeline__core .logo{ height:42px; width:auto; color:var(--text); }

  .adv-timeline__list{
    position:relative;
    list-style:none; margin:0; padding:0;
  }
  .adv-timeline__list::before{
    content:"";
    position:absolute; left:3px; top:6px; bottom:6px;
    width:1px; background:var(--line);
  }
  .adv-timeline__list li{
    position:relative;
    margin-left:24px;
    padding:0 0 26px 20px;
    font-size:13.5px; line-height:1.55;
    color:var(--text-2);
  }
  .adv-timeline__list li:last-child{ padding-bottom:0; }
  .adv-timeline__list li::before{
    content:"";
    position:absolute; left:-24px; top:5px;
    width:7px; height:7px; border-radius:50%;
    background:var(--text-3);
    box-shadow:0 0 0 3px var(--canvas);
  }
  .adv-timeline__list li .mono{
    display:block; margin-bottom:4px;
    color:var(--gold); font-size:10px;
  }
}

/* ═══════════════════ ПОЛИТИКА КОНФИДЕНЦИАЛЬНОСТИ (privacy.html) ═══════════════════
   Длинный юридический текст поделён на пронумерованные блоки .policy__block —
   тот же приём «мелкий mono-номер + заголовок», что в шапках .faq-item__q,
   только без аккордеона: тут весь текст должен быть виден и доступен для
   поиска по Ctrl+F, сворачивать его незачем. */
.policy{
  padding-block:var(--sec-pad);
  border-top:1px solid var(--line);
}
.policy__meta{
  margin:0 0 clamp(28px,3.4vw,44px);
  padding-bottom:24px;
  border-bottom:1px solid var(--line);
  color:var(--text-3);
  font-size:13px;
}
.policy__block{
  max-width:74ch;
  padding-block:clamp(26px,3.2vw,40px);
  border-bottom:1px solid var(--line);
}
.policy__block:last-child{ border-bottom:0; padding-bottom:0; }
.policy__block > .mono{
  display:block;
  margin:0 0 10px;
  color:var(--gold);
}
.policy__block h2{
  margin:0 0 14px;
  font-size:clamp(18px,1.8vw,22px);
  font-weight:700;
  letter-spacing:-.01em;
  color:var(--text);
}
.policy__block p{
  margin:0 0 14px;
  max-width:72ch;
  color:var(--text-2);
  font-size:14.5px; line-height:1.75;
}
.policy__block ul{
  margin:0 0 14px; padding-left:20px;
  max-width:72ch;
  color:var(--text-2);
  font-size:14.5px; line-height:1.75;
}
.policy__block li{ margin-bottom:6px; }
.policy__block p:last-child,
.policy__block ul:last-child,
.policy__block li:last-child{ margin-bottom:0; }
.policy__block a{ color:var(--gold); text-decoration-color:var(--gold-line); text-underline-offset:2px; }
.policy__block a:hover{ color:var(--gold-hi); }
.policy__block strong{ color:var(--text); font-weight:600; }
