/* Shared SVG choreography. All phases use one 7.2s clock per visible instance. */
.motion-diagram{--diagram-play-state:paused;--diagram-cycle:7.2s;--diagram-spring:cubic-bezier(.22,1.3,.36,1)}
.motion-diagram[data-diagram-state=running]{--diagram-play-state:running}
.motion-card{fill:url(#motion-glass);stroke:var(--cyan);stroke-opacity:.4;stroke-width:1;filter:url(#motion-pedestal)}
.motion-rim,.slab-rim{fill:none;stroke:url(#motion-rim);stroke-width:1;vector-effect:non-scaling-stroke;pointer-events:none}
.slab-face{fill:url(#motion-slab);stroke:#28516c;stroke-width:1}
.slab-wall{fill:url(#motion-side);stroke:#28516c;stroke-width:.7}
.slab-detail{fill:none;stroke:var(--cyan);stroke-width:1;opacity:.28}
.motion-label{font:9px var(--mono);letter-spacing:.4px;fill:var(--text)}
.motion-readout{font:6px var(--mono);font-variant-numeric:tabular-nums;fill:var(--cyan);opacity:.55;text-anchor:end}
.motion-status,.stack-status{fill:var(--cyan);opacity:.25}
.motion-bar-track{fill:none;stroke:var(--cyan);stroke-width:2;opacity:.12}
.motion-bar{fill:none;stroke:var(--cyan);stroke-width:2;transform:scaleX(.08);transform-box:fill-box;transform-origin:left center}
.motion-impact,.slab-completion{fill:none;stroke:var(--cyan);stroke-width:1.2;opacity:0;filter:url(#motion-bloom);pointer-events:none}
.motion-track,.motion-track path{fill:none;stroke:var(--cyan);stroke-width:1;stroke-dasharray:2 5;opacity:.25;stroke-linecap:round}
.motion-track path{opacity:1}
.motion-comet{opacity:0;offset-distance:0%;offset-rotate:auto;offset-anchor:0px 0px;transform-box:view-box;filter:url(#motion-bloom);pointer-events:none}
.motion-comet path{fill:none;stroke:url(#motion-comet);stroke-width:2.5;stroke-linecap:round}
.motion-comet circle{fill:var(--cyan)}
.motion-badge,.hub-node,.hub-core{transform-box:fill-box;transform-origin:center}

/* Stack: scan/lift → validate arrival (39%) → upgrade arrival (66%) → settle. */
.stack-top{animation:stack-lift var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.stack-middle{animation:stack-middle-lift var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.stack-scan{animation:stack-scan var(--diagram-cycle,7.2s) linear infinite}
.stack-spotlight{animation:stack-light var(--diagram-cycle,7.2s) ease-in-out infinite}
.stack-validate-comet{offset-path:path('M252 60C283 60 303 34 324 34');animation:stack-validate-transit var(--diagram-cycle,7.2s) cubic-bezier(.45,0,.2,1) infinite}
.stack-upgrade-comet{offset-path:path('M374 52C417 75 331 103 374 126');animation:stack-upgrade-transit var(--diagram-cycle,7.2s) cubic-bezier(.45,0,.2,1) infinite}
.validate-badge{animation:validate-impact var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.upgrade-badge{animation:upgrade-impact var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.validate-badge .motion-impact,.validate-badge .motion-status{animation:validate-light var(--diagram-cycle,7.2s) ease-out infinite}
.upgrade-badge .motion-impact,.upgrade-badge .motion-status,.slab-completion{animation:upgrade-light var(--diagram-cycle,7.2s) ease-out infinite}
.validate-badge .motion-bar{animation:validate-fill var(--diagram-cycle,7.2s) ease-out infinite}
.upgrade-badge .motion-bar{animation:upgrade-fill var(--diagram-cycle,7.2s) ease-out infinite}
@keyframes stack-lift{0%,5%,83%,100%{transform:translate3d(0,0,0)}17%{transform:translate3d(0,-10px,0)}24%,65%{transform:translate3d(0,-6px,0)}76%{transform:translate3d(0,1px,0)}}
@keyframes stack-middle-lift{0%,8%,78%,100%{transform:translate3d(0,0,0)}20%,63%{transform:translate3d(0,-4px,0)}72%{transform:translate3d(0,1px,0)}}
@keyframes stack-scan{0%,3%{opacity:0;transform:translate3d(0,40px,0)}7%{opacity:.8}23%{opacity:.8;transform:translate3d(0,-75px,0)}26%,100%{opacity:0;transform:translate3d(0,-75px,0)}}
@keyframes stack-light{0%,100%{opacity:.35}16%,30%,75%{opacity:1}48%{opacity:.5}}
@keyframes stack-validate-transit{0%,19%{offset-distance:0%;opacity:0}21%{opacity:1}38.8%{opacity:1}39%{offset-distance:100%;opacity:0}100%{offset-distance:100%;opacity:0}}
@keyframes stack-upgrade-transit{0%,46%{offset-distance:0%;opacity:0}48%{opacity:1}65.8%{opacity:1}66%,100%{offset-distance:100%;opacity:0}}
@keyframes validate-impact{0%,38.8%,49%,100%{transform:scale(1)}39%{transform:scale(.98)}42%{transform:scale(1.06)}46%{transform:scale(1)}}
@keyframes upgrade-impact{0%,65.8%,77%,100%{transform:scale(1)}66%{transform:scale(.98)}69%{transform:scale(1.06)}74%{transform:scale(1)}}
@keyframes validate-light{0%,38.8%,91%,100%{opacity:.15}39%,44%{opacity:1}56%,82%{opacity:.45}}
@keyframes upgrade-light{0%,65.8%,98%,100%{opacity:.12}66%,73%{opacity:1}85%{opacity:.5}}
@keyframes validate-fill{0%,38.8%,100%{transform:scaleX(.08)}46%,91%{transform:scaleX(1)}}
@keyframes upgrade-fill{0%,65.8%,100%{transform:scaleX(.08)}74%,94%{transform:scaleX(1)}}

/* Hub: paired ingress → processing/radar (33%) → paired egress → impact (65%). */
.hub-ingest-app{offset-path:path('M109 45C156 45 151 90 187 90')}
.hub-ingest-data{offset-path:path('M109 135C156 135 151 90 187 90')}
.hub-egress-logs{offset-path:path('M253 90C289 90 284 45 331 45')}
.hub-egress-dr{offset-path:path('M253 90C289 90 284 135 331 135')}
.hub-ingest-app,.hub-ingest-data{animation:hub-ingest var(--diagram-cycle,7.2s) cubic-bezier(.4,0,.18,1) infinite}
.hub-egress-logs,.hub-egress-dr{animation:hub-egress var(--diagram-cycle,7.2s) cubic-bezier(.4,0,.18,1) infinite}
.hub-app .motion-impact,.hub-data .motion-impact,.hub-app .motion-status,.hub-data .motion-status{animation:hub-source-light var(--diagram-cycle,7.2s) ease-out infinite}
.hub-app .motion-bar,.hub-data .motion-bar{animation:hub-source-fill var(--diagram-cycle,7.2s) ease-out infinite}
.hub-core{animation:hub-heartbeat var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.hub-core .motion-impact,.hub-core .motion-status,.hub-spotlight{animation:hub-process-light var(--diagram-cycle,7.2s) ease-out infinite}
.hub-core .motion-bar{animation:hub-process-fill var(--diagram-cycle,7.2s) ease-out infinite}
.hub-radar{fill:none;stroke:var(--cyan);stroke-width:.8;opacity:0;transform-origin:center;transform-box:fill-box;animation:hub-radar var(--diagram-cycle,7.2s) ease-out infinite}
.hub-logs{--impact-y:-1.5px}.hub-dr{--impact-y:1.5px}
.hub-logs,.hub-dr{animation:hub-target-impact var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.hub-logs .motion-impact,.hub-dr .motion-impact,.hub-logs .motion-status,.hub-dr .motion-status{animation:hub-target-light var(--diagram-cycle,7.2s) ease-out infinite}
.hub-logs .motion-bar,.hub-dr .motion-bar{animation:hub-target-fill var(--diagram-cycle,7.2s) ease-out infinite}
@keyframes hub-ingest{0%,11%{offset-distance:0%;opacity:0}13%{opacity:1}32.8%{opacity:1}33%,100%{offset-distance:100%;opacity:0}}
@keyframes hub-egress{0%,45%{offset-distance:0%;opacity:0}47%{opacity:1}64.8%{opacity:1}65%,100%{offset-distance:100%;opacity:0}}
@keyframes hub-source-light{0%,4%,92%,100%{opacity:.18}10%,25%{opacity:1}34%,80%{opacity:.3}}
@keyframes hub-source-fill{0%,4%,100%{transform:scaleX(.08)}13%,90%{transform:scaleX(1)}}
@keyframes hub-heartbeat{0%,32.8%,47%,100%{transform:scale(1)}33%{transform:scale(.95)}37%{transform:scale(1.05)}43%{transform:scale(1)}}
@keyframes hub-process-light{0%,32.8%,87%,100%{opacity:.12}33%,40%{opacity:1}56%{opacity:.4}}
@keyframes hub-process-fill{0%,32.8%,100%{transform:scaleX(.08)}42%,90%{transform:scaleX(1)}}
@keyframes hub-radar{0%,32.8%{opacity:0;transform:scale(.8)}33%{opacity:.8;transform:scale(.8)}63%,100%{opacity:0;transform:scale(1.65)}}
@keyframes hub-target-impact{0%,64.8%,79%,100%{transform:translate3d(0,0,0)}65%,69%{transform:translate3d(2.5px,var(--impact-y),0)}75%{transform:translate3d(-.5px,0,0)}}
@keyframes hub-target-light{0%,64.8%,98%,100%{opacity:.15}65%,72%{opacity:1}85%{opacity:.45}}
@keyframes hub-target-fill{0%,64.8%,100%{transform:scaleX(.08)}76%,94%{transform:scaleX(1)}}

/* Data plane: sync arrival → bottom-to-top replica fill → verify → guardrails. */
.data-flow{height:30px;min-width:12px;flex:1;border-top:0;transform:translateY(-19px)}
.plane-track{width:100%;height:30px;overflow:visible;position:absolute;inset:0;pointer-events:none}
.data-flow>span{top:-4px}
.plane-sync-comet,.plane-verify-comet{offset-path:path('M0 18C30 8 70 28 100 18')}
.plane-sync-comet{animation:plane-sync var(--diagram-cycle,7.2s) cubic-bezier(.45,0,.2,1) infinite}
.plane-verify-comet{animation:plane-verify var(--diagram-cycle,7.2s) cubic-bezier(.45,0,.2,1) infinite}
.plane-node .rack-icon{display:block;width:80px;height:72px;margin:0 auto 7px;position:relative}
.plane-node .rack-icon>svg{width:100%;height:100%;overflow:visible}
.plane-node .plane-meter{display:block;width:36px;height:2px;margin:0 auto 9px;background:var(--line);overflow:hidden}
.plane-meter i{display:block;width:100%;height:100%;background:var(--cyan);transform:scaleX(.08);transform-origin:left}
.plane-source .plane-meter i{animation:plane-source-fill var(--diagram-cycle,7.2s) ease-out infinite}
.plane-replica .plane-meter i{animation:plane-replica-fill var(--diagram-cycle,7.2s) ease-out infinite}
.plane-target .plane-meter i{animation:plane-target-fill var(--diagram-cycle,7.2s) ease-out infinite}
.source-slots{fill:none;stroke:var(--cyan);stroke-width:2;opacity:.6}
.replica-stripes{fill:none;stroke:var(--cyan);stroke-width:2;stroke-linecap:round}
.replica-stripe{opacity:.15;animation:replica-fill var(--diagram-cycle,7.2s) ease-out infinite}
.stripe-1{--stripe-start:0s}.stripe-2{--stripe-start:.43s}.stripe-3{--stripe-start:.86s}.stripe-4{--stripe-start:1.29s}
.replica-stripe{animation-delay:var(--stripe-start)}
.replica-halo{animation:replica-light var(--diagram-cycle,7.2s) ease-out infinite}
.plane-target .rack-icon{animation:plane-target-impact var(--diagram-cycle,7.2s) var(--diagram-spring,cubic-bezier(.22,1.3,.36,1)) infinite}
.target-guardrail{filter:url(#motion-bloom);animation:guardrail-light var(--diagram-cycle,7.2s) ease-out infinite}
.guardrail-check{fill:none;stroke:var(--cyan);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.target-halo{animation:guardrail-light var(--diagram-cycle,7.2s) ease-out infinite}
@keyframes plane-sync{0%,9%{offset-distance:0%;opacity:0}11%{opacity:1}32.8%{opacity:1}33%,100%{offset-distance:100%;opacity:0}}
@keyframes plane-verify{0%,51%{offset-distance:0%;opacity:0}53%{opacity:1}72.8%{opacity:1}73%,100%{offset-distance:100%;opacity:0}}
@keyframes plane-source-fill{0%,5%,100%{transform:scaleX(.08)}15%,90%{transform:scaleX(1)}}
@keyframes plane-replica-fill{0%,23%,100%{transform:scaleX(.08)}50%,94%{transform:scaleX(1)}}
@keyframes plane-target-fill{0%,72.8%,100%{transform:scaleX(.08)}82%,94%{transform:scaleX(1)}}
@keyframes replica-fill{0%,25%,96%,100%{opacity:.15}31%,89%{opacity:1}}
@keyframes replica-light{0%,24%,100%{opacity:.25}35%,54%{opacity:1}80%{opacity:.5}}
@keyframes plane-target-impact{0%,72.8%,87%,100%{transform:translate3d(0,0,0) scale(1)}73%{transform:translate3d(0,1px,0) scale(.97)}77%{transform:translate3d(0,-2.5px,0) scale(1.04)}84%{transform:translate3d(0,0,0) scale(1)}}
@keyframes guardrail-light{0%,72.8%,100%{opacity:.45}73%,81%{opacity:1}92%{opacity:.7}}

/* Custom properties inherit through SVG <use>, keeping each instance independent. */
.stack-top,.stack-middle,.stack-scan,.stack-spotlight,.motion-comet,.motion-badge,.motion-impact,.motion-status,.motion-bar,.slab-completion,.hub-core,.hub-spotlight,.hub-radar,.hub-logs,.hub-dr,.replica-stripe,.replica-halo,.plane-target .rack-icon,.target-guardrail,.target-halo,.plane-meter i{animation-play-state:var(--diagram-play-state,paused)}
.flow-line,.node-pulse,.scan-line,.pipeline-packet{animation-play-state:var(--diagram-play-state,running)}
@media(max-width:600px){.plane-node .rack-icon{width:61px;height:57px}.plane-node .plane-meter{width:29px}.data-flow{transform:translateY(-17px)}}
@media(prefers-reduced-motion:reduce){
 .svg-library *,.motion-diagram *{animation:none!important}
 .motion-comet,.stack-scan{display:none}
 .stack-top,.stack-middle,.hub-core,.hub-logs,.hub-dr,.plane-target .rack-icon{transform:none}
 .motion-impact,.slab-completion{opacity:.65}
 .motion-status,.stack-status,.replica-stripe,.target-guardrail,.target-halo,.replica-halo{opacity:1}
 .motion-bar,.plane-meter i{transform:scaleX(1)}
 .hub-radar{opacity:.25;transform:scale(1.2)}
}
