.v3{background:#FFFFFF;border:1px solid var(--rule);border-radius:18px;padding:18px;max-width:980px;margin-top:28px}
.v3 h3{font-size:20px;margin:0 0 6px}
.v3 p.cap{color:var(--ink-2);margin:0 0 14px}
.anim svg *{animation-fill-mode:backwards}
/* strike v2: 10s */
.s-tag{animation:s-tag 9s ease infinite}
@keyframes s-tag{0%{opacity:0;transform:translateY(4px)}6%,100%{opacity:1;transform:none}}
/* frameworks: lines 3s, controls 12s */
.f-ctl{animation:f-ctl 12s ease infinite;opacity:0}
.f-ctl:first-of-type{opacity:1}
@keyframes f-ctl{0%{opacity:0}3%,22%{opacity:1}25%,100%{opacity:0}}
.f-line{stroke-dasharray:1;stroke-dashoffset:0;animation:f-line 3s ease infinite}
@keyframes f-line{0%{stroke-dashoffset:1}35%,100%{stroke-dashoffset:0}}
.f-node{transform-origin:center;animation:f-node 3s ease infinite}
@keyframes f-node{0%{opacity:.35;transform:scale(.97)}25%{opacity:1;transform:scale(1.03)}35%,100%{opacity:1;transform:none}}
/* dpdp: 8s */
.d-pkt{animation:d-pkt 8s ease-in-out infinite}
@keyframes d-pkt{0%{transform:translateX(-540px)}62%,100%{transform:none}}
.d-st{transform-origin:center;animation:d-st 8s ease infinite}
@keyframes d-st{0%{opacity:.25;transform:scale(.8)}8%{opacity:1;transform:scale(1.15)}14%,100%{opacity:1;transform:none}}
.d-badge{animation:d-badge 8s ease infinite}
@keyframes d-badge{0%,66%{opacity:0;transform:translateY(6px)}74%,100%{opacity:1;transform:none}}
/* route: 8s */
.r-a{animation:r-a 8s ease infinite;opacity:0}
@keyframes r-a{0%{opacity:0}6%,36%{opacity:1}44%,100%{opacity:0}}
.r-b{stroke-dasharray:200;stroke-dashoffset:0;animation:r-b 8s ease infinite}
@keyframes r-b{0%,44%{stroke-dashoffset:200}58%,100%{stroke-dashoffset:0}}
.r-founder{animation:r-founder 8s ease infinite}
@keyframes r-founder{0%,8%{stroke-width:1.6}20%,38%{stroke-width:4}48%,100%{stroke-width:1.6}}
.r-ok{transform-origin:center;animation:r-ok 8s ease infinite}
@keyframes r-ok{0%,60%{opacity:0;transform:scale(.6)}68%,100%{opacity:1;transform:none}}
.r-p1{animation:r-p1 8s ease infinite;opacity:.25}
@keyframes r-p1{0%,4%{opacity:0}10%,40%{opacity:1}48%,100%{opacity:.25}}
.r-p2{animation:r-p2 8s ease infinite}
@keyframes r-p2{0%,52%{opacity:0}60%,100%{opacity:1}}
/* cloud map: attack 8s, platform 16s */
.p-aws{opacity:0;animation:p-aws 16s ease infinite}
@keyframes p-aws{0%,47%{opacity:0}50%,97%{opacity:1}100%{opacity:0}}
.p-az{animation:p-az 16s ease infinite}
@keyframes p-az{0%,47%{opacity:1}50%,97%{opacity:0}100%{opacity:1}}
.m-atk{opacity:0;animation:m-atk 8s linear infinite}
@keyframes m-atk{0%{opacity:0;stroke-dashoffset:0}6%,52%{opacity:1}58%,100%{opacity:0;stroke-dashoffset:-60}}
.m-blk{transform-origin:center;opacity:0;animation:m-blk 8s ease infinite}
@keyframes m-blk{0%,54%{opacity:0;transform:scale(.5)}60%,80%{opacity:1;transform:scale(1.15)}88%,100%{opacity:0}}
.m-risk{opacity:0;animation:m-risk 8s ease infinite}
@keyframes m-risk{0%,8%{opacity:0}14%,54%{opacity:1}60%,100%{opacity:0}}
.m-fix{transform-origin:center;animation:m-fix 8s ease infinite}
@keyframes m-fix{0%,58%{opacity:0;transform:scale(.9)}64%,100%{opacity:1;transform:none}}
.m-lock{transform-origin:center;animation:m-lock 8s ease infinite}
@keyframes m-lock{0%,58%{opacity:0;transform:translateY(-6px)}64%,100%{opacity:1;transform:none}}
.m-add{animation:m-add 8s ease infinite}
@keyframes m-add{0%,56%{opacity:0}62%,100%{opacity:1}}
@media (prefers-reduced-motion:reduce){.anim *{animation:none!important}}
