/* ---------- анимация: 3D-фон, пакеты на рёбрах, свечение узлов, каскадное появление ---------- */
#bg3d{position:fixed;inset:0;width:100%;height:100%;z-index:-1;pointer-events:none;opacity:0;transition:opacity 1.6s ease}
#bg3d.ready{opacity:1}

/* пакеты на рёбрах */
.flow .pkt{fill:var(--accent);stroke:var(--accent);stroke-opacity:.28;stroke-width:5;pointer-events:none;transition:opacity .3s}
.flow .pkt.pending{opacity:.4}
.flow .pkt.on{fill:#fff;r:4;stroke-opacity:.5}
.flow .pkt.dim{opacity:.08}

/* свечение и «дыхание» узлов в цвет вида */
.node{--glow:var(--accent);transition:filter .25s;cursor:pointer;transform-box:fill-box;transform-origin:center}
.node.k-llm{--glow:#a77bff}.node.k-gateway{--glow:#ffb020}.node.k-new{--glow:#ff5fa2}
.node.k-app{--glow:#3ecf8e}.node.k-script{--glow:#26c6da}.node.k-edge{--glow:#f5b942}.node.k-actor{--glow:#6f93ff}
.node.k-data,.node.k-other{--glow:var(--stroke)}
.node:hover,.node:focus-visible,.node.on{filter:drop-shadow(0 0 12px var(--glow)) drop-shadow(0 0 3px var(--glow))}
.node:focus{outline:none}
.node rect{transition:stroke .25s,stroke-width .25s}
.node:hover rect,.node:focus-visible rect{stroke:var(--glow);stroke-width:2.4}
.edge.on path{filter:drop-shadow(0 0 4px var(--accent))}

/* каскадное появление */
@keyframes i-fade{from{opacity:0}to{opacity:1}}
@keyframes i-pop{from{opacity:0;transform:scale(.8)}to{opacity:1;transform:none}}
@keyframes i-draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
.intro .i-in{animation:i-fade .5s ease-out var(--d,0ms) backwards}
.intro .i-pop{animation:i-pop .55s cubic-bezier(.2,1.3,.4,1) var(--d,0ms) backwards}
.intro .i-draw{animation:i-fade .3s ease-out var(--d,0ms) backwards}
.intro .i-draw path{stroke-dasharray:1;stroke-dashoffset:0;animation:i-draw .6s ease-out var(--d,0ms) backwards}
.intro .i-draw .badge,.intro .i-draw .tag{animation:i-fade .4s ease-out calc(var(--d,0ms) + 450ms) backwards}

@media (prefers-reduced-motion:reduce){
  #bg3d{display:none}
  .node,.edge,.flow *{transition:none}
}

/* ---------- второй слой эффектов ---------- */
.flow .pkt.tail{stroke:none}
.flow .pkt.tail.on{fill:var(--accent)}

/* прожектор за курсором + бегущая рамка */
.diagram-wrap{position:relative;border:1.5px solid transparent;
  background:linear-gradient(color-mix(in srgb,var(--card) 82%,transparent),color-mix(in srgb,var(--card) 82%,transparent)) padding-box,
    conic-gradient(from 200deg,transparent 0 70%,var(--accent) 85%,#ff5fa2 93%,transparent 100%) border-box}
.diagram-wrap::after{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:radial-gradient(260px circle at var(--mx,-999px) var(--my,-999px),color-mix(in srgb,var(--accent) 16%,transparent),transparent 70%)}

/* ударные волны на узлах */
.shock{fill:none;stroke:var(--accent);stroke-width:2;pointer-events:none;transform-box:fill-box;transform-origin:center}
.shock.hover{animation:shock .8s ease-out forwards}
.shock.click{stroke:#ff5fa2;stroke-width:3;animation:shock 1.1s cubic-bezier(.1,.7,.3,1) forwards}
@keyframes shock{from{opacity:.9;transform:scale(1)}to{opacity:0;transform:scale(1.55)}}

/* заголовок: курсор терминала и глитч */
main h1{position:relative;display:inline-block}
main h1::before{content:"$ ";color:var(--accent);font-family:ui-monospace,monospace}
main h1.typing::after{content:"▋";margin-left:3px;color:var(--accent);animation:blink .8s steps(2) infinite}
@keyframes blink{50%{opacity:0}}
main h1[data-text]:not(.typing):hover{animation:glitch .5s steps(2) 1}
main h1[data-text]:not(.typing):hover::after{content:attr(data-text);position:absolute;left:0;top:0;color:#ff5fa2;mix-blend-mode:screen;clip-path:inset(0 0 55% 0);animation:glitch2 .5s steps(2) 1;pointer-events:none}
@keyframes glitch{0%{transform:translate(0)}25%{transform:translate(-2px,1px)}50%{transform:translate(2px,-1px)}75%{transform:translate(-1px,0)}100%{transform:none}}
@keyframes glitch2{0%{transform:translate(3px,0)}50%{transform:translate(-3px,1px)}100%{transform:translate(0)}}

/* панель документации: «сканирующий» луч при открытии */
.docs:not([hidden]){animation:docs-in .35s cubic-bezier(.2,.9,.3,1)}
.docs:not([hidden])::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;pointer-events:none;z-index:5;
  background:linear-gradient(90deg,transparent,var(--accent),transparent);box-shadow:0 0 14px var(--accent);animation:scan 1s ease-out forwards}
@keyframes docs-in{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}
@keyframes scan{from{top:0;opacity:1}to{top:100%;opacity:0}}

@media (prefers-reduced-motion:reduce){
  .diagram-wrap::after,.shock{display:none}
  .docs:not([hidden]),.docs:not([hidden])::before{animation:none}
}

/* страница «уснула» (вкладка скрыта, нет активности 30 с или анимации выключены): все CSS-анимации и переходы остановлены */
html.calm *,html.calm *::before,html.calm *::after{animation:none!important;transition:none!important}
html.calm #bg3d{opacity:.55}
.motion-bar{display:flex;align-items:center;gap:10px;font-size:13px}
.motion-bar button{padding:3px 10px;font-size:13px}
