/* ==========================================================================
   ТРИУМФ — obekt.css (вариант А4 «Объект», аниматик 27.09.2026)
   Поверх ruki.css + reaktor.css. Три правила режиссуры:
   1) утверждённая картинка — первый кадр каждого слоя: руки по kompozitsiya.json
      в vw без пиксельного потолка;
   2) видео/картинка — актёр, код — осветитель: цвет состояния кладётся
      слоями screen через маску руки, объект между пальцами (obekt.js) сам
      светит на пальцы;
   3) ничего быстрее 0,8 с, кроме отклика на нажатие.
   Цвета света: холод #95B5DA, тепло #DAB88B — только как свет; красный
   #a32f36 — только знак и объект.
   ========================================================================== */
.stage--obekt{
  /* единица масштаба сцены: 1vw на экранах не шире 16:10 (1440×900 — утверждённая композиция),
     а на широких/невысоких окнах (1920×800–945 в Chrome с панелями) — от высоты (1,6vh), иначе
     руки и слово растут от ширины и наезжают друг на друга (владелец 27.09, снимки в Chrome) */
  --k:min(1vw, 1.6vh);
  /* руки — всегда от ШИРИНЫ (62vw): предплечья должны уходить за края экрана (уменьшение по высоте
     27.09 обрезало руки посередине экрана — владелец). От наезда на слово спасает ось: obekt.js
     ставит --axis не выше низа слова + высота раскрытой ладони (fitAxis). Слово — по --k. */
  /* 70vw (было 62): при 62 срез предплечья стоял в 34–70 px от края, а наведённая рука ещё шла к центру —
     «руки к экрану не притянуты» (владелец 28.09). Кончики пальцев остаются на 50 % ∓ gap, растёт только
     кисть (+13 %); внешний край коробки — за экраном: робот −2,9 %, человек −1,5 % ширины окна. */
  --w:max(420px, 70vw); --gap:7vw;                 /* доли экрана, без потолка в px */
  --holod:149,181,218; --teplo:218,184,139;
  --vx:50%;                                         /* центр виньетки */
  --easeo:cubic-bezier(.19,1,.22,1);                /* expo-out */
  --easeio:cubic-bezier(.65,0,.35,1);               /* cubic-in-out */
}
/* прежние тона сторон (синий/красный) выключаем: свет теперь свой */
.stage--obekt .ruki-tint{ display:none; }

/* ---------- воздух: две дымки с разными периодами, виньетка, зерно 12 к/с ---------- */
.stage--obekt .dymka{
  position:absolute; inset:-20%; z-index:1; pointer-events:none; opacity:.9;
  background:
    radial-gradient(38% 46% at 42% 62%, rgba(255,255,255,.075), transparent 70%),
    radial-gradient(30% 40% at 62% 50%, rgba(255,255,255,.05), transparent 70%);
  /* 28.09: дымка неподвижна — дрейф 60/95 с был незаметен, а стоил слой компоновщика и ЦП */
  transition:filter 2s var(--easeo);
}
.stage--obekt .dymka.b{
  background:
    radial-gradient(44% 30% at 55% 66%, rgba(255,255,255,.055), transparent 70%),
    radial-gradient(26% 34% at 36% 56%, rgba(255,255,255,.04), transparent 70%);
}
@keyframes dymka-a{ from{ transform:translate3d(-2%, 1%, 0) } to{ transform:translate3d(2.5%, -1.5%, 0) } }
@keyframes dymka-b{ from{ transform:translate3d(2%, -1%, 0) } to{ transform:translate3d(-2.5%, 1.5%, 0) } }
/* тон дымки: сторона окрашивает воздух у оси */
.stage--obekt .dymka-ton{
  position:absolute; inset:0; z-index:1; pointer-events:none; opacity:0;   /* без screen (28.09): смешивание = отдельная поверхность в памяти видеокарты */
  transition:opacity 2s var(--easeo);                    /* только opacity: переход background перерисовывал экран 2 с */
}
/* окно «Связаться с юристом»: кнопка «Написать через форму» лишняя (владелец 28.09) — в макете скрыта,
   на сервере убрать из lawyer.js при правке */
body.home dialog .btn.btn--solid[href="contacts.html"]{ display:none; }
.stage--obekt[data-hover="ai"] .dymka-ton{ opacity:1;
  background:radial-gradient(45vw 60vh at 30vw 55vh, rgba(var(--holod),.10), transparent 70%); }
.stage--obekt[data-hover="human"] .dymka-ton{ opacity:1;
  background:radial-gradient(45vw 60vh at 70vw 55vh, rgba(var(--teplo),.08), transparent 70%); }
/* затемнение чужой стороны */
/* затемнение чужой стороны отключено: владелец 28.09 читает любое затемнение у рук как «тень» */
.stage--obekt .ten{ display:none; }
/* дымка и виньетка рисуются шейдером поля (field.js, has-dymka-gl) — DOM-слои не нужны; остаются как запас без WebGL */
.stage--obekt.has-dymka-gl .dymka, .stage--obekt.has-dymka-gl .dymka.b, .stage--obekt.has-dymka-gl .vinetka{ display:none; }
.stage--obekt .vinetka{
  position:absolute; inset:0; z-index:1; pointer-events:none;   /* под руками (было 5, поверх): виньетка затемняла края рук — «тень» */
  background:radial-gradient(75% 70% at var(--vx) 52%, transparent 55%, rgba(0,0,0,.22) 100%);
}
/* виньетка неподвижна: сдвиг центра перерисовывал полноэкранный градиент 2 с при каждой смене стороны */
/* зерно двигается transform-ом (композитор), а не background-position (перерисовка всего экрана):
   слой шире экрана на тайл 220 px слева и сверху и сдвигается на тайл за секунду шагами */
.stage--obekt .ruki-grain{ display:none; opacity:.035; inset:auto; left:-220px; top:-220px; width:calc(100% + 220px); height:calc(100% + 220px); animation:zerno-t 1s steps(6) infinite; will-change:transform; }
.stage--obekt.t-polnyy .ruki-grain{ display:block; }   /* зерно — только сильным машинам (режим polnyy) */
@keyframes zerno-t{ from{ transform:translate(0, 0) } to{ transform:translate(220px, 220px) } }
/* телефон (28.09 вечер, память/ЦП): карточки, подсказка и кнопки — без размытия подложки (backdrop-filter
   пересчитывает размытие живой сцены каждый кадр), сплошная полупрозрачная подложка выглядит так же */
@media (max-width: 860px){
  .stage--obekt .ruki-label, .stage--obekt .ruki-hint, .stage--obekt .ruki-cta{ backdrop-filter:none; -webkit-backdrop-filter:none; }
  .stage--obekt .ruki-label{ background:rgba(10,11,12,.78); }
  .stage--obekt .ruki-hint{ background:rgba(10,11,12,.72); }
}
/* режим statika (obekt.js): клипов нет — стоп-кадры и кроссфейд ладони; свет, блики и тон выключены */
.stage--obekt.t-statika .ruki-hand .svet, .stage--obekt.t-statika .ruki-hand .blik, .stage--obekt.t-statika .svet-tips, .stage--obekt.t-statika .dymka-ton, .stage--obekt.t-statika .ruki-grain{ display:none !important; }
.stage--obekt.t-statika .ruki-hand{ animation:none; }
/* облегчённый режим (obekt.js liteOn): без зерна, блика, дыхания рук и движения дымки — клипы и ядро остаются */
.stage--obekt.is-lite .ruki-grain, .stage--obekt.is-lite .ruki-hand .blik, .stage--obekt.is-lite .dymka-ton{ display:none; }
.stage--obekt.is-lite .dymka, .stage--obekt.is-lite .dymka.b, .stage--obekt.is-lite .ruki-hand, .stage--obekt.is-lite .ruki-hand--human{ animation:none; }
@keyframes zerno{ from{ background-position:0 0 } to{ background-position:220px 220px } }

/* ---------- руки: положение, наведение (2.3 режиссуры) ---------- */
.stage--obekt .ruki-hand{ transition:transform 1.8s var(--easeo), opacity 2.2s var(--easeio), filter 2.2s var(--easeio); }
.stage--obekt .ruki-hand img{ filter:none; }   /* владелец 27.09: никаких теней у рук — край идеально чёткий */
/* наведённая рука к центру почти не идёт (0,4vw вместо 2,4): иначе её предплечье отрывалось от края экрана;
   движение даёт сама раскрывающаяся ладонь. Чужая рука отступает на 0,8vw наружу. */
/* без filter на руках: фильтр яркости на слое с живым холстом пересчитывается каждый кадр (тормозил iGPU),
   а затемнение чужой руки владелец читает как «тень» (28.09) */
.stage--obekt[data-hover="ai"] .ruki-hand--ai{ --sx:calc(0.4vw + var(--px) * 18px); opacity:1; filter:none; }
.stage--obekt[data-hover="ai"] .ruki-hand--human{ --sx:calc(0.8vw + var(--px) * 18px); opacity:1; filter:none; }
.stage--obekt[data-hover="human"] .ruki-hand--human{ --sx:calc(-0.4vw + var(--px) * 18px); opacity:1; filter:none; }
.stage--obekt[data-hover="human"] .ruki-hand--ai{ --sx:calc(-0.8vw + var(--px) * 18px); opacity:1; filter:none; }
/* лёгкий кивок к подписи (идея владельца), не 11°, а 5° */
.stage--obekt[data-hover="ai"] .ruki-hand--ai .bob{ transform:rotate(-5deg) translateX(.6%); }
.stage--obekt[data-hover="human"] .ruki-hand--human .bob{ transform:rotate(5deg) translateX(-.6%); }
/* дыхание рук: некратные периоды, амплитуда 0,45 vh */
.stage--obekt .ruki-hand{ animation:ruka-dyh 11s cubic-bezier(.37,0,.63,1) infinite; }
.stage--obekt .ruki-hand--human{ animation:ruka-dyh 13s cubic-bezier(.37,0,.63,1) infinite; animation-delay:-5.5s; }
/* дыхание руки — свойством translate (композитор), не margin-top: margin перекладывал раскладку каждый кадр */
@keyframes ruka-dyh{ 0%,100%{ translate:0 0 } 50%{ translate:0 -.45vh } }

/* ---------- свет на руках: цвет состояния через маску руки, screen ---------- */
.stage--obekt .ruki-hand .svet, .stage--obekt .ruki-hand .blik{
  position:absolute; inset:0; pointer-events:none;
  -webkit-mask:var(--m) center / contain no-repeat; mask:var(--m) center / contain no-repeat;
  /* без mix-blend-mode:screen (28.09): каждое смешивание — своя поверхность компоновщика (замер: −81 МБ, −66 % ЦП) */
  display:none;                                          /* вне наведения слоя нет вовсе (замер: −50 МБ); появление — анимацией */
}
@keyframes svet-in{ from{ opacity:0 } }
.stage--obekt .ruki-hand .svet{
  opacity:0;
  background:radial-gradient(55% 70% at var(--tx) var(--ty), rgba(var(--c), .95) 0%, rgba(var(--c), .35) 38%, transparent 70%);
}
.stage--obekt .ruki-hand--ai .svet{ --c:var(--holod); --tx:65.5%; --ty:43.6%; }
.stage--obekt .ruki-hand--human .svet{ --c:var(--teplo); --tx:36.4%; --ty:42.7%; }
.stage--obekt[data-hover="ai"] .ruki-hand--ai .svet{ opacity:.22; }
.stage--obekt[data-hover="human"] .ruki-hand--human .svet{ opacity:.18; }
.stage--obekt[data-hover="ai"] .svet, .stage--obekt[data-hover="human"] .svet{ display:block; animation:svet-in 2s var(--easeo) both; }
/* чужая рука ловит слабый отсвет выбранной стороны */
.stage--obekt[data-hover="ai"] .ruki-hand--human .svet{ opacity:.05; --c:var(--holod); }
.stage--obekt[data-hover="human"] .ruki-hand--ai .svet{ opacity:.08; --c:var(--teplo); }
/* световая полоса: блик идёт по руке по своему расписанию (16 с робот, 23 с человек) */
.stage--obekt .ruki-hand .blik{
  background:linear-gradient(100deg, transparent 35%, rgba(255,255,255,.22) 50%, transparent 65%);
  background-size:60% 100%; background-repeat:no-repeat;
  animation:blik-hod 16s linear infinite;
}
.stage--obekt .ruki-hand--human .blik{ animation-duration:23s; animation-delay:-9s; opacity:.4; }
/* с клипами силуэт руки дышит, а маска блика — стоп-кадр: в покое полоса блика рисовала «второй» контур
   пальца (владелец 28.09: «палец человека притормаживает и двоится при первом появлении»). У рук с клипами
   блик в покое выключен и остаётся только на раскрытой ладони, где маска снята с кадра клипа. */
.stage--obekt .ruki-hand:not(.has-klipy) .blik{ display:block; }   /* без клипов (стоп-кадры) блик виден всегда, как раньше */
.stage--obekt[data-hover="ai"] .ruki-hand--ai.has-klipy .blik{ display:block; opacity:1; }
.stage--obekt[data-hover="human"] .ruki-hand--human.has-klipy .blik{ display:block; opacity:.4; }
@keyframes blik-hod{ 0%{ background-position:-70% 0 } 15%{ background-position:170% 0 } 100%{ background-position:170% 0 } }
.stage--obekt[data-hover="ai"] .ruki-hand--ai .blik{ animation-duration:2.4s; }
.stage--obekt[data-hover="human"] .ruki-hand--human .blik{ animation-duration:2.4s; }

/* свечение на кончиках пальцев — от объекта (obekt.js двигает точки) */
.stage--obekt .svet-tips{ position:absolute; inset:0 auto auto 0; width:0; height:0; overflow:visible; z-index:4; pointer-events:none; opacity:0; }   /* контейнер нулевой: полноэкранный был отдельным слоем */   /* без screen (28.09) */
/* два пятна света — маленькие слои, obekt.js двигает их transform-ом и меняет opacity (композитор,
   без перерисовки полноэкранного градиента каждый кадр) */
.stage--obekt .svet-tips .tip-glow{
  position:absolute; left:-30px; top:-30px; width:60px; height:60px; border-radius:50%;
  --c:255,250,240; background:radial-gradient(circle closest-side, rgba(var(--c),1) 0, transparent 100%);
  will-change:transform, opacity; opacity:.25;
}
.is-in .svet-tips{ opacity:1; transition:opacity 1.4s var(--easeo) 1.4s; }

/* ---------- объект между пальцами ---------- */
.stage--obekt .ruki-obekt{ position:absolute; inset:0; z-index:4; pointer-events:none; opacity:0; transition:opacity 1s var(--easeo) 1.4s; }
.stage--obekt.js-obekt .ruki-obekt{ inset:0 auto auto 0; width:0; height:0; overflow:visible; }   /* холст ядра позиционируется transform-ом от начала сцены; полноэкранный контейнер был слоем */
.stage--obekt.js-obekt .ruki-obekt canvas{ max-width:none; }   /* общий сброс canvas{max-width:100%} схлопывал холст в 0 при нулевом контейнере */
.is-in .ruki-obekt{ opacity:1; }
.stage--obekt .ruki-obekt canvas{ position:absolute; left:0; top:0; display:block; will-change:transform; }
/* без WebGL — тихая капля CSS-ом на оси */
.stage--obekt .ruki-obekt::before{
  content:""; position:absolute; left:50%; top:var(--axis); width:calc(8 * var(--k)); height:calc(8 * var(--k)); border-radius:50%;
  transform:translate(-50%, -50%);
  background:radial-gradient(circle at 38% 32%, #fff 0%, #cfd3d8 18%, #5a5e64 45%, #15171a 72%, #000 100%);
  box-shadow:0 0 40px 6px rgba(255,255,255,.06);
}
.stage--obekt.js-obekt .ruki-obekt::before{ display:none; }

/* ---------- подсказка: перетекает в действие стороны ---------- */
.stage--obekt .ruki-hint{ letter-spacing:.18em; transition:border-color 1.2s var(--easeo), box-shadow 1.2s var(--easeo), opacity .8s var(--ease) 1.6s; }
.stage--obekt .ruki-hint .hint-t{ transition:opacity .25s var(--easeio); }   /* быстрая смена: пустая пилюля не должна висеть */
.stage--obekt .ruki-hint.is-swap .hint-t{ opacity:0; }
.stage--obekt[data-hover="ai"] .ruki-hint{ border-color:rgba(var(--holod),.45); box-shadow:none; }
.stage--obekt[data-hover="human"] .ruki-hint{ border-color:rgba(var(--teplo),.45); box-shadow:none; }
.stage--obekt .ruki-hint .arrow:first-child{ animation:strelka 2.4s var(--easeio) infinite; }
.stage--obekt .ruki-hint .arrow:last-child{ animation:strelka 2.4s var(--easeio) infinite; animation-delay:-1.2s; }
@keyframes strelka{ 0%,100%{ opacity:.6; transform:none } 50%{ opacity:1; transform:none } }

/* фокус после закрытия окна возвращается на половину-ссылку: рамку и подсветку показываем только с клавиатуры */
.stage--obekt .ruki-side:focus:not(:focus-visible){ outline:none; background:transparent; }
.stage--obekt .ruki-side:focus-visible{ outline:2px solid rgba(242,243,244,.5); outline-offset:-6px; background:transparent; }

/* лид перенесён из первого экрана в блок bridge (SEO-текст остаётся видимым) */
.bridge-seo{ margin:14px auto 0; max-width:58ch; color:var(--fg-muted); font-size:var(--t-sm); line-height:1.55; text-wrap:balance; }
.bridge-seo b{ color:var(--fg); }

/* ---------- кикер у слова (замечание владельца 27.09 ~14:10) ----------
   Десктоп: эпиграф над словом — по центру, крупнее, с разрядкой и двумя короткими чертами.
   Верхняя строка — только факты справа. */
.stage--obekt .ruki-top{ justify-content:flex-end; }
.stage--obekt .ruki-mid{ padding-top:clamp(4px, 2.4vh, 26px); }
.stage--obekt .ruki-kicker{
  position:relative; z-index:2;                      /* как слово: выше фоновых слоёв (на телефоне поле их накрывает) */
  order:0; margin:0 0 clamp(8px, 1.6vh, 18px); max-width:none;
  display:inline-flex; align-items:center; gap:18px;
  font-family:var(--font); font-weight:500; font-size:clamp(15px, 1.25vw, 20px);
  letter-spacing:.16em; text-transform:uppercase; color:rgba(242,243,244,.8); text-align:center;
  opacity:0; transform:translateY(10px); transition:opacity 1s var(--easeo) .25s, transform 1s var(--easeo) .25s;
}
.is-in .ruki-kicker{ opacity:1; transform:none; }
.stage--obekt .ruki-kicker::before, .stage--obekt .ruki-kicker::after{ content:""; width:28px; height:1px; background:rgba(242,243,244,.35); }
.stage--obekt .ruki-mark{ order:1; }
@media (min-width: 861px){
  .stage--obekt .ruki-mark{ font-size:clamp(3.2rem, calc(12.4 * var(--k)), 12.6rem); }   /* слово — той же единицей, что руки */
}

/* ---------- подписи и кнопки: описания в одну строку, кнопки нейтральные ---------- */
.stage--obekt .ruki-text{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:44ch; }   /* 34ch резало «…круглосуточно» (рецензент 28.09) */
/* подписи читаются на любом фоне (белая манжета, хром запястья): лёгкая тёмная подложка текста, не тень руки */
.stage--obekt .ruki-tag, .stage--obekt .ruki-title, .stage--obekt .ruki-text{ text-shadow:0 0 14px rgba(10,11,12,.95), 0 1px 2px rgba(0,0,0,.7); }
/* фокус с клавиатуры показываем на подписи, а не рамкой на полэкрана (линия посередине) */
.stage--obekt .ruki-side:focus-visible{ outline:none; }
.stage--obekt .ruki-side:focus-visible .ruki-label{ outline:2px solid rgba(242,243,244,.6); outline-offset:6px; border-radius:6px; }
/* узкие и невысокие десктопные окна: нижний ряд (подписи · подсказка · ссылка) не помещается в три колонки —
   описания и ссылку «Посмотреть пример» убираем, подсказка компактнее с переносом (рецензент 28.09, № 2–3) */
@media (min-width: 861px) and (max-width: 1120px), (min-width: 861px) and (max-height: 780px){
  .stage--obekt .ruki-text, .stage--obekt .ruki-under{ display:none; }
  .stage--obekt .ruki-hint{ font-size:.62rem; letter-spacing:.12em; max-width:34vw; white-space:normal; text-align:center; line-height:1.35; padding:10px 18px; }
  .stage--obekt .ruki-bottom{ padding-top:0; }
}
/* персонаж портала на нешироких десктопах — ближе к краю, чтобы не уходить под окно */
@media (min-width: 861px) and (max-width: 1500px){
  .portal[data-side="ai"] .portal-fig, .portal-klip[data-side="ai"]{ left:1.5vw; }
  .portal[data-side="human"] .portal-fig, .portal-klip[data-side="human"]{ right:1.5vw; }
  .portal-fig, .portal-klip{ height:min(82vh, 900px); }
}
/* подсветка кнопки стороны — по зоне курсора (data-hover, obekt.js), а не по :hover половины экрана:
   иначе у середины кнопки мигают, пока руки и ядро держат состояние (владелец 27.09) */
.stage--obekt .ruki-side:hover .ruki-cta, .stage--obekt .ruki-side--human:hover .ruki-cta{ background:rgba(10,11,12,.4); color:var(--fg); border-color:var(--line-strong); }
.stage--obekt .ruki-side:hover .ruki-cta .arw{ transform:none; }
.stage--obekt[data-hover="ai"] .ruki-side--ai .ruki-cta, .stage--obekt[data-hover="human"] .ruki-side--human .ruki-cta{ background:var(--fg); color:#0a0b0c; border-color:var(--fg); }
.stage--obekt[data-hover="ai"] .ruki-side--ai .ruki-cta .arw, .stage--obekt[data-hover="human"] .ruki-side--human .ruki-cta .arw{ transform:translateX(4px); }
.stage--obekt .ruki-lead{ font-size:15px; max-width:520px; color:rgba(242,243,244,.58); }

/* ---------- телефон: те же слои, руки по диагонали (reaktor.css), объект между ---------- */
@media (max-width: 860px){
  .stage--obekt{ --w:min(94vw, 480px); --gap:44px; }
  /* решение владельца 27.09: руки ближе к слову ТРИУМФ; лид убран — карточки и подсказка входят в экран.
     Доли режиссёра для 390×844: кисть робота 31 vh, кисть человека 45 vh, ось ядра 38 vh, карточки 57–69, подсказка 73–79 */
  /* 28.09 (владелец): руки ниже — раскрытая ладонь робота не должна доставать до кикера и слова; нижняя часть
     (карточки, подсказка, факты) плотнее. Центры рук 38/52 % высоты, распорка 36 vh, карточки по содержимому. */
  .stage--obekt{ --axis:45%; }
  .stage--obekt .ruki-hand--ai{ top:38%; }
  .stage--obekt .ruki-hand--human{ top:52%; }
  .stage--obekt .ruki-mid::after{ height:36vh; }
  .stage--obekt .ruki-bottom{ padding-top:2px; gap:0; }
  .stage--obekt .ruki-bottom > span{ display:none; }   /* пустые ячейки сетки давали лишний ряд и зазор над подсказкой */
  .stage--obekt .ruki-label{ min-height:0; justify-content:center; padding:12px 14px; gap:6px; }
  .stage--obekt .ruki-hint{ margin-top:0; padding:7px 12px; }
  .stage--obekt .ruki-cta{ padding:9px 12px; }
  /* короткие телефоны (375×667): распорка и карточки ниже, чтобы факты 24/7 · ПРАВО-300 входили в первый экран */
  @media (max-height: 700px){
    .stage--obekt{ --w:min(84vw, 480px); }         /* короткий экран: руки чуть меньше, иначе ладонь робота упирается в кикер */
    .stage--obekt .ruki-mid::after{ height:31vh; }
    .stage--obekt .ruki-label{ min-height:0; padding:9px 12px; gap:4px; }
    .stage--obekt .ruki-title{ font-size:.92rem; }
    .stage--obekt .ruki-cta{ padding:8px 11px; font-size:.7rem; }
    .stage--obekt .ruki-hint{ padding:8px 14px; font-size:.6rem; }
    .stage--obekt .ruki-meta{ padding-top:8px; font-size:.62rem; gap:4px 16px; }
    .stage--obekt .ruki-hand--ai{ top:38%; }
    .stage--obekt .ruki-hand--human{ top:53%; }
    .stage--obekt{ --axis:45.5%; }
  }
  /* телефон: верхняя строка без кикера — слово с отступом шапки; кикер ПОД словом; факты — внизу экрана */
  .stage--obekt .ruki-top{ display:contents; }
  .stage--obekt .ruki-mid{ padding-top:calc(68px + var(--s2)); }
  .stage--obekt .ruki-kicker{ order:1; margin:6px 0 0; gap:12px; font-size:.86rem; letter-spacing:.1em; color:rgba(242,243,244,.78); white-space:normal; line-height:1.3; }
  .stage--obekt .ruki-kicker::before, .stage--obekt .ruki-kicker::after{ width:16px; flex:none; }
  .stage--obekt .ruki-mid::after{ order:2; }        /* распорка сцены — после кикера, иначе кикер уезжает под руки */
  .stage--obekt .ruki-mark{ order:0; }
  .stage--obekt .ruki-meta{
    position:relative; z-index:5;
    display:flex; order:6; width:100%; flex-direction:row; justify-content:center; align-items:center; flex-wrap:wrap;
    gap:6px 22px; margin:0; padding:6px var(--gutter) 0; text-align:center; font-size:.72rem; letter-spacing:.08em; color:var(--fg-muted);
  }
  .stage--obekt .ruki-meta b{ color:var(--fg); font-size:.86rem; }
  .stage--obekt .ruki-hand--ai .bob, .stage--obekt .ruki-hand--human .bob,
  .stage--obekt[data-hover] .ruki-hand .bob{ transform:rotate(22deg); }
  .stage--obekt .ruki-text{ display:none; }
  .stage--obekt .ruki-grain{ opacity:.025; }
  .stage--obekt .dymka, .stage--obekt .dymka.b{ animation-duration:80s; }
  .stage--obekt .ruki-side--ai .ruki-label{ border-color:rgba(var(--holod),.35); }
  .stage--obekt .ruki-side--human .ruki-label{ border-color:rgba(var(--teplo),.35); }
  .stage--obekt .ruki-side--human .ruki-cta{ background:rgba(255,255,255,.08); border-color:var(--line-strong); }
  .stage--obekt[data-hover="ai"] .ruki-side--ai .ruki-label{ border-color:rgba(var(--holod),.6); }
  .stage--obekt[data-hover="human"] .ruki-side--human .ruki-label{ border-color:rgba(var(--teplo),.6); }
}
/* ==========================================================================
   ЛАДОНЬ (решение владельца 27.09 ~11:40): при наведении рука раскрывает
   ладонь, ядро окрашивается в цвет стороны и перелетает в ладонь; при нажатии
   впитывается. В аниматике переход «указывает → ладонь» — кроссфейд двух
   стоп-кадров (в производстве это видеоклип из этих же кадров). Маски света
   переключаются на ладонь вместе с картинкой.
   ========================================================================== */
/* раскрытие — задержка 0,2 с, 1,1 с expo-out; закрытие — задержка 0,5 с после ухода ядра, 1,4 с cubic-in-out
   (рука держит раскрытую ладонь мгновение после того, как ядро улетело) */
.stage--obekt .ruki-hand .bob img{ position:absolute; inset:0; width:100%; height:100%; object-fit:contain; transition:opacity 1.4s var(--easeio) .5s; }
.stage--obekt .ruki-hand .bob{ aspect-ratio:16 / 9; }
.stage--obekt .ruki-hand .ladon{ opacity:0; }
.stage--obekt[data-hover="ai"] .ruki-hand--ai .ukaz, .stage--obekt[data-hover="human"] .ruki-hand--human .ukaz{ opacity:0; transition:opacity 1.1s var(--easeo) .2s; }
.stage--obekt[data-hover="ai"] .ruki-hand--ai .ladon, .stage--obekt[data-hover="human"] .ruki-hand--human .ladon{ opacity:1; transition:opacity 1.1s var(--easeo) .2s; }
/* ---------- клипы рук (производство 27.09): <video> — невидимый источник кадров, показывает
   WebGL-холст .klip-canvas с ключом по яркости (чёрный фон прозрачен покадрово, край резкий;
   obekt.js Keyer). Статичные маски (maska-*.png) больше не используются — давали тёмный ореол. ---------- */
.stage--obekt .klipy{ position:absolute; inset:0; pointer-events:none; }
body.v-skryt .stage--obekt .klipy video, body.v-skryt .portal-klip-src{ display:none !important; }   /* Chromium-десктоп: видео — источники кадров для холста, слои им не нужны (−43 % ЦП) */
.stage--obekt .klipy video{ position:absolute; inset:0; width:100%; height:100%; object-fit:contain; display:block; opacity:0; }
.stage--obekt .klipy .klip-canvas{ position:absolute; inset:0; width:100%; height:100%; display:block; }
/* когда клипы готовы (нарисован первый кадр), стоп-кадры уходят (они дублируют кадр) */
/* стоп-кадр уходит за 0,35 с, а не мгновенно: первый кадр клипа отличается от стоп-кадра на 1–3 px, и резкая
   подмена читалась как рывок пальца; холст клипа лежит выше — двойного изображения не возникает */
.stage--obekt .ruki-hand.has-klipy .ukaz, .stage--obekt .ruki-hand.has-klipy .ladon{ opacity:0 !important; transition:opacity .35s ease-out !important; }
.stage--obekt .ruki-hand.has-klipy-2 .ukaz, .stage--obekt .ruki-hand.has-klipy-2 .ladon{ display:none; }   /* после растворения стоп-кадры не держим в памяти (28.09) */

/* маски света: указательная рука / ладонь */
.stage--obekt .ruki-hand--ai .svet, .stage--obekt .ruki-hand--ai .blik{ --m:url(../images/ruka-robot-pokoy.webp); }   /* маска = стоп-кадр из клипа (28.09) */
.stage--obekt .ruki-hand--human .svet, .stage--obekt .ruki-hand--human .blik{ --m:url(../images/ruka-chelovek-pokoy.webp); }
.stage--obekt[data-hover="ai"] .ruki-hand--ai .svet, .stage--obekt[data-hover="ai"] .ruki-hand--ai .blik{ --m:url(../images/ruka-robot-ladon.webp); --tx:var(--palm-x); --ty:var(--palm-y); }
.stage--obekt[data-hover="human"] .ruki-hand--human .svet, .stage--obekt[data-hover="human"] .ruki-hand--human .blik{ --m:url(../images/ruka-chelovek-ladon.webp); --tx:var(--palm-x); --ty:var(--palm-y); }
/* с клипами силуэт ладони берётся из кадра клипа (стоп-кадры v2a стоят ниже плейтов на 14–22 %) */
.stage--obekt[data-hover="ai"] .ruki-hand--ai.has-klipy .svet, .stage--obekt[data-hover="ai"] .ruki-hand--ai.has-klipy .blik{ --m:url(../images/maska-robot-ladon.png); }
.stage--obekt[data-hover="human"] .ruki-hand--human.has-klipy .svet, .stage--obekt[data-hover="human"] .ruki-hand--human.has-klipy .blik{ --m:url(../images/maska-chelovek-ladon.png); }
/* метка центра ладони (доли картинки ладони; уточняются по кадру) */
.stage--obekt .ruki-hand [data-palm]{ position:absolute; width:2px; height:2px; pointer-events:none; left:var(--palm-x); top:var(--palm-y); }
/* КЛИПЫ ладоней (плейты 27.09 выровнены по предплечью указывающей руки, кадр 16:9 = коробка руки):
   чаша ладони робота ≈ (53 %, 40 %), человека ≈ (50 %, 36 %) по сетке кадра (video/ruki/*-palm.jpg);
   ядро (радиус ≈ 9 % высоты) лежит в чаше — центр на 4–5 % выше чаши. Прежние 48 %/52 % были
   от стоп-кадров v2a, у которых ладонь стояла на 14–22 % ниже, — ядро не попадало в ладонь. */
.stage--obekt .ruki-hand--ai{ --palm-x:54%; --palm-y:35%; }
.stage--obekt .ruki-hand--human{ --palm-x:49%; --palm-y:33%; }
/* при раскрытой ладони кивок к подписи не нужен — рука и так «говорит» */
.stage--obekt[data-hover="ai"] .ruki-hand--ai .bob, .stage--obekt[data-hover="human"] .ruki-hand--human .bob{ transform:none; }
/* свет ядра на ладони заметнее, чем на кончике пальца */
.stage--obekt[data-hover="ai"] .ruki-hand--ai .svet{ opacity:.34; }
.stage--obekt[data-hover="human"] .ruki-hand--human .svet{ opacity:.28; }

/* ==========================================================================
   ПОРТАЛ (решение владельца 27.09 ~11:50): после впитывания ядра — волна
   энергии из ладони, вспышка, сцена гаснет, из света проявляется персонаж
   (робот-женщина для ИИ, юрист для человека), и открывается прежнее окно.
   Слой живёт в body (obekt.js), ниже <dialog> (тот в top layer).
   ========================================================================== */
.portal{ position:fixed; inset:0; z-index:90; pointer-events:none; --c:149,181,218; --px:50vw; --py:58vh; --easeo:cubic-bezier(.19,1,.22,1); --easeio:cubic-bezier(.65,0,.35,1); }
.portal[data-side="human"]{ --c:218,184,139; }
/* вспышка ≤ 15 %: подъём 0,2 с, спад 0,9 с */
.portal-vspyshka{ position:absolute; inset:0; background:rgba(var(--c),.14); opacity:0; mix-blend-mode:screen; }
.portal.is-on .portal-vspyshka{ animation:portal-flash 1.1s var(--easeo) forwards; }
@keyframes portal-flash{ 0%{ opacity:0 } 18%{ opacity:1 } 100%{ opacity:0 } }
/* волна — не кольцо-контур, а мягкий световой фронт без кромки (режиссура Г1) */
.portal-volna{
  position:absolute; left:var(--px); top:var(--py); width:600px; height:600px; margin:-300px 0 0 -300px; border-radius:50%;
  background:radial-gradient(circle, transparent 38%, rgba(var(--c),.34) 50%, rgba(var(--c),.10) 60%, transparent 68%);
  opacity:0; mix-blend-mode:screen; will-change:transform, opacity;
}
.portal.is-on .portal-volna{ animation:portal-volna 1.5s var(--easeo) forwards; }
@keyframes portal-volna{ 0%{ transform:scale(.05); opacity:1 } 100%{ transform:scale(7); opacity:0 } }
/* фигура: картинка + цветной свет стороны (screen 15 %) + тёмный низ; проявление —
   радиус маски от точки ладони (--mx/--my/--r ставит obekt.js) */
.portal-fig{
  position:absolute; bottom:0; height:min(88vh, 900px); aspect-ratio:9 / 16; opacity:0;
  --mx:50%; --my:60%; --r:0%;
  transform:translateY(3vh) scale(1.05);
  filter:brightness(1.9);   /* без анимированной drop-shadow: пересчёт размытия каждый кадр на слое 608×1080 (28.09 вечер) */
  -webkit-mask-image:radial-gradient(circle at var(--mx) var(--my), #000 var(--r), transparent calc(var(--r) + 22%));
  mask-image:radial-gradient(circle at var(--mx) var(--my), #000 var(--r), transparent calc(var(--r) + 22%));
  transition:opacity .25s, transform 1.6s var(--easeo), filter 1.4s var(--easeo);
}
.portal-fig > *{ position:absolute; inset:0; width:100%; height:100%; }
.portal-figura{ object-fit:contain; object-position:center bottom; }
/* клип появления персонажа: WebGL-холст .portal-klip в body (ключ по яркости — чёрный фон прозрачен
   покадрово, резкий край; без screen-смешивания). Источник кадров — невидимый <video class="portal-klip-src">.
   Геометрия — как у .portal-fig. Слои фигуры (стоп-кадр, цветной свет, тёмный низ) скрыты, пока идёт клип,
   и проявляются кроссфейдом 0,5 с на video-done; без клипа (no-video) — сразу под радиальной маской. */
.portal-klip{ position:fixed; bottom:0; height:min(88vh, 900px); aspect-ratio:9 / 16; z-index:91; pointer-events:none; display:block; opacity:0; }
.portal-klip-src{ position:fixed; bottom:0; left:0; height:min(88vh, 900px); aspect-ratio:9 / 16; opacity:0; pointer-events:none; }
.portal-klip[data-side="ai"]{ left:4vw; }
.portal-klip[data-side="human"]{ right:4vw; }
.portal-klip.is-on{ opacity:1; }
.portal-klip.is-done{ opacity:0; transition:opacity .5s cubic-bezier(.65,0,.35,1); }
.portal-figura, .portal-ton, .portal-niz{ opacity:0; transition:opacity .5s var(--easeio); }
.portal-fig.video-done .portal-figura, .portal-fig.video-done .portal-ton, .portal-fig.video-done .portal-niz,
.portal-fig.no-video .portal-figura, .portal-fig.no-video .portal-ton, .portal-fig.no-video .portal-niz{ opacity:1; }
.portal-ton, .portal-niz{ -webkit-mask:var(--fm) center bottom / contain no-repeat; mask:var(--fm) center bottom / contain no-repeat; pointer-events:none; }
.portal-ton{ background:rgba(var(--c),.10); }   /* без screen (28.09), чуть плотнее */   /* было .15 — юрист выглядел засветлённым (владелец 27.09) */
.portal-niz{ background:linear-gradient(to top, #0a0b0c 0%, rgba(10,11,12,.6) 12%, transparent 34%); }
.portal[data-side="ai"] .portal-fig{ left:4vw; }
.portal[data-side="human"] .portal-fig{ right:4vw; }
.portal.is-fig .portal-fig{ opacity:1; transform:none; filter:brightness(1); }
.portal.is-off{ transition:opacity .8s var(--easeio); opacity:0; }
.portal.is-off::before{ background:rgba(5,6,8,0); transition:background .7s var(--easeio); }   /* затемнение гаснет вместе с порталом, а не вспыхивало заново через 0,9 с после уборки (рецензия 28.09, № 17/9) */
body.portal-quick .portal.is-off::before{ transition-duration:.45s; }
/* после закрытия окна персонаж не нужен (владелец 28.09: «на мгновение появляется аватар»): фигура и клип
   гаснут за 0,15 с, затемнение сцены уходит плавно */
.portal.is-off .portal-fig{ opacity:0 !important; transition:opacity .15s !important; }
.portal-klip.is-off{ opacity:0 !important; transition:opacity .15s !important; }
/* панель отладки ?otladka=1 */
.otladka{ position:fixed; left:0; top:0; z-index:1000; margin:0; padding:6px 8px; max-width:100vw; white-space:pre-wrap; word-break:break-all; font:11px/1.35 ui-monospace, Menlo, Consolas, monospace; color:#9f9; background:rgba(0,0,0,.72); pointer-events:none; }
/* окно <dialog> живёт в top layer и своей подложкой накрыло бы персонажа: на время
   портала подложка окна прозрачная, а затемнение даёт сам портал */
.portal::before{ content:""; position:absolute; inset:0; background:rgba(5,6,8,0); transition:background 1.1s var(--easeio); }
.portal.is-on::before{ background:rgba(5,6,8,.62); }
body.portal-open dialog::backdrop{ background:transparent !important; -webkit-backdrop-filter:none !important; backdrop-filter:none !important; }
/* ТЕЛЕФОН (владелец 28.09): портал короткий — персонаж появляется быстро (клип ×1,75 или проявление 0,6 с),
   окно сразу за ним (1,5 с); все переходы портала укорочены. Класс ставит obekt.js на body для касания. */
body.portal-quick .portal::before{ transition-duration:.45s; }
body.portal-quick .portal-fig{ transition:opacity .2s, transform .7s var(--easeo), filter .6s var(--easeo); }
body.portal-quick .portal.is-on .portal-vspyshka{ animation-duration:.7s; }
body.portal-quick .portal.is-on .portal-volna{ animation-duration:1s; }
body.portal-quick .portal-klip.is-done{ transition-duration:.3s; }
body.portal-quick .portal-figura, body.portal-quick .portal-ton, body.portal-quick .portal-niz{ transition-duration:.3s; }
body.portal-quick .stage--obekt .ruki-scene, body.portal-quick .stage--obekt .ruki-in, body.portal-quick .stage--obekt .ruki-label, body.portal-quick .stage--obekt .dymka{ transition-duration:.5s; transition-delay:0s; }
/* сцена гаснет до 42 % за 1,2 с с −20 % насыщенности; чужая рука — до 15 % */
/* сцена гаснет через opacity (композитор), а не filter: фильтр яркости на слоях с холстами
   на iGPU тормозил всё появление персонажа (владелец 28.09). Итоговая яркость ≈ прежняя:
   opacity .45 × затемнение портала .62 */
.stage--obekt .ruki-scene, .stage--obekt .ruki-in, .stage--obekt .ruki-label, .stage--obekt .dymka{ transition:opacity 1.2s var(--easeio) .4s; }
.stage--obekt.is-portal .ruki-scene, .stage--obekt.is-portal .ruki-in, .stage--obekt.is-portal .ruki-label, .stage--obekt.is-portal .dymka{ opacity:.45; }
.stage--obekt.is-portal[data-hover="ai"] .ruki-hand--human, .stage--obekt.is-portal[data-hover="human"] .ruki-hand--ai{ opacity:.15; }
@media (max-width: 860px){
  .portal-fig{ height:64vh; left:50% !important; right:auto !important; transform:translate(-50%, 3vh) scale(1.05); }
  .portal.is-fig .portal-fig{ transform:translate(-50%, 0); }
  .portal-klip{ height:64vh; left:50% !important; right:auto !important; transform:translateX(-50%); }
}

/* ==========================================================================
   ТЕЛЕФОН, вариант «чипы» (предложение режиссёра, к выбору владельца):
   вместо карточек под руками — два чипа-ссылки напротив рук, зоны касания —
   верхняя/нижняя половины сцены. Включается классом m-chipy (?mob=chipy).
   ========================================================================== */
@media (max-width: 860px){
  .stage--obekt.m-chipy .ruki-side{
    position:absolute; left:0; right:0; width:100%; height:19%; padding:0 var(--gutter);
    display:flex; z-index:6; order:0;
  }
  /* зоны касания — верхняя и нижняя половины сцены; чип стоит у кончика пальца своей руки:
     у робота — справа от пальца (палец робота ≈ 49 vw / 29 vh), у человека — слева (≈ 64 vw / 57 vh) */
  /* сцена на экране 844 px: палец робота ≈ 36 vh, палец человека ≈ 56 vh, ядро между (46 vh);
     чип ИИ — на уровне пальца робота справа, чип человека — на уровне его пальца слева */
  .stage--obekt.m-chipy{ --axis:46%; }
  .stage--obekt.m-chipy .ruki-hand--ai{ top:37%; }
  .stage--obekt.m-chipy .ruki-hand--human{ top:57.5%; }
  .stage--obekt.m-chipy .ruki-side--ai{ top:26%; height:17%; justify-content:flex-end; align-items:center; }
  .stage--obekt.m-chipy .ruki-side--human{ top:43%; height:25%; justify-content:flex-start; align-items:center; text-align:left; }
  .stage--obekt.m-chipy .ruki-tag{ display:none; }
  .stage--obekt.m-chipy .ruki-label{
    display:inline-flex; align-items:center; gap:8px; width:auto; padding:9px 14px;
    border:1px solid var(--line-strong); border-radius:999px; background:rgba(10,11,12,.62);
    backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  }
  .stage--obekt.m-chipy .ruki-side--ai .ruki-label::before{ content:"\2190"; font-size:1rem; color:var(--fg); }
  .stage--obekt.m-chipy .ruki-side--human .ruki-label::after{ content:"\2192"; font-size:1rem; color:var(--fg); }
  .stage--obekt.m-chipy .ruki-tag{ font-size:.56rem; letter-spacing:.14em; }
  .stage--obekt.m-chipy .ruki-title{ font-size:.92rem; letter-spacing:-.02em; }
  .stage--obekt.m-chipy .ruki-text, .stage--obekt.m-chipy .ruki-cta{ display:none; }
  .stage--obekt.m-chipy .ruki-side--ai .ruki-label{ border-color:rgba(var(--holod),.45); }
  .stage--obekt.m-chipy .ruki-side--human .ruki-label{ border-color:rgba(var(--teplo),.45); }
  .stage--obekt.m-chipy .ruki-bottom{ padding-top:6px; }
  .stage--obekt.m-chipy .ruki-mid::after{ height:46vh; }
}
@media (prefers-reduced-motion: reduce){
  .stage--obekt .dymka, .stage--obekt .ruki-grain, .stage--obekt .ruki-hand, .stage--obekt .blik, .stage--obekt .ruki-hint .arrow{ animation:none !important; }
}
