/* KYEHR connected-hub animation — 10 s seamless loop, CSS keyframes on one shared clock */
.hub-sec{background:linear-gradient(180deg,var(--bg-2),#fff 60%);overflow:hidden}
.hub-wrap{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:48px;align-items:center}
@media(max-width:900px){.hub-wrap{grid-template-columns:1fr}}
.hub-copy h2{font-size:clamp(32px,4.4vw,46px)}
.scenes{margin:28px 0 0;padding:0;list-style:none;display:grid;gap:10px}
.scenes li{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:baseline;color:var(--ink-4);transition:color .4s}
.scenes li b{font-weight:600;color:inherit}.scenes li span{display:block;font-size:14px}
.scenes li i{font-style:normal;font-family:var(--font-mono);font-size:12px;width:46px;white-space:nowrap;color:var(--ink-4)}
.scenes li::after{content:"";grid-column:2;height:2px;background:var(--line);border-radius:2px;overflow:hidden;display:block;margin-top:6px}
.scenes li{position:relative}.scenes li .fill{position:absolute;left:58px;right:0;bottom:0;height:2px;background:var(--blue);border-radius:2px;transform-origin:0 50%;transform:scaleX(0);animation:sc-fill var(--T) linear infinite}
.scenes li.s1 .fill{animation-name:sc1}.scenes li.s2 .fill{animation-name:sc2}.scenes li.s3 .fill{animation-name:sc3}.scenes li.s4 .fill{animation-name:sc4}
.scenes li.s1{animation:sc-on1 var(--T) linear infinite}.scenes li.s2{animation:sc-on2 var(--T) linear infinite}.scenes li.s3{animation:sc-on3 var(--T) linear infinite}.scenes li.s4{animation:sc-on4 var(--T) linear infinite}
@keyframes sc1{0%,20%{transform:scaleX(0)}40%,100%{transform:scaleX(1)}}
@keyframes sc2{0%,40%{transform:scaleX(0)}60%,100%{transform:scaleX(1)}}
@keyframes sc3{0%,60%{transform:scaleX(0)}80%,100%{transform:scaleX(1)}}
@keyframes sc4{0%,80%{transform:scaleX(0)}96%,100%{transform:scaleX(1)}}
@keyframes sc-on1{0%,19%{color:var(--ink-4)}20%,40%{color:var(--ink)}41%,100%{color:var(--ink-3)}}
@keyframes sc-on2{0%,39%{color:var(--ink-4)}40%,60%{color:var(--ink)}61%,100%{color:var(--ink-3)}}
@keyframes sc-on3{0%,59%{color:var(--ink-4)}60%,80%{color:var(--ink)}81%,100%{color:var(--ink-3)}}
@keyframes sc-on4{0%,79%{color:var(--ink-4)}80%,100%{color:var(--ink)}}
/* stage */
.hub-stage{--T:10s;--R:34%;--R2:46%;position:relative;width:min(100%,600px);aspect-ratio:1;margin:0 auto;container-type:inline-size;font-size:clamp(9px,2.2cqw,13px);perspective:1400px}
.hub-stage .tilt{position:absolute;inset:0;transform:rotateX(8deg);transform-style:preserve-3d;animation:stage-float 9s ease-in-out infinite}
@keyframes stage-float{0%,100%{transform:rotateX(8deg) translateY(0)}50%{transform:rotateX(8deg) translateY(-6px)}}
.hub-stage.paused *{animation-play-state:paused!important}
.ring{position:absolute;left:50%;top:50%;border-radius:50%;border:1px dashed rgba(0,128,254,.22);translate:-50% -50%}
.ring.a{width:72%;height:72%;animation:spin 70s linear infinite}.ring.b{width:94%;height:94%;border-color:rgba(11,15,26,.08);animation:spin 110s linear infinite reverse}
.ring i{position:absolute;width:7px;height:7px;border-radius:50%;background:var(--cyan);left:50%;top:-4px;translate:-50% 0;box-shadow:0 0 12px var(--cyan)}.ring.b i{background:var(--violet);box-shadow:0 0 12px var(--violet);top:auto;bottom:-4px}
@keyframes spin{to{rotate:360deg}}
.lines{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.lines line{stroke:url(#lg2);vector-effect:non-scaling-stroke;stroke-width:1.2;stroke-linecap:round;pathLength:1;stroke-dasharray:1;stroke-dashoffset:1;opacity:.55;animation:var(--T) linear infinite;filter:drop-shadow(0 0 3px rgba(0,128,254,.35))}
.lines .ga{animation-name:ln-a}.lines .gb{animation-name:ln-b}.lines .gc{animation-name:ln-c}
@keyframes ln-a{0%,22%{stroke-dashoffset:1;opacity:.5}30%{stroke-dashoffset:0}80%{opacity:.5}86%,92%{opacity:1;stroke-width:2}96%,100%{stroke-dashoffset:0;opacity:0}}
@keyframes ln-b{0%,42%{stroke-dashoffset:1;opacity:.5}50%{stroke-dashoffset:0}80%{opacity:.5}86%,92%{opacity:1;stroke-width:2}96%,100%{stroke-dashoffset:0;opacity:0}}
@keyframes ln-c{0%,62%{stroke-dashoffset:1;opacity:.5}70%{stroke-dashoffset:0}80%{opacity:.5}86%,92%{opacity:1;stroke-width:2}96%,100%{stroke-dashoffset:0;opacity:0}}
.lines .pulse{fill:var(--blue);r:1;opacity:0;offset-rotate:0deg}
/* hub */
.hub{position:absolute;left:50%;top:50%;width:22%;aspect-ratio:1;translate:-50% -50%;animation:hub-in var(--T) cubic-bezier(.2,.7,.2,1) infinite;transform-style:preserve-3d}
.hub-core{position:absolute;inset:0;border-radius:26%;background:linear-gradient(145deg,#2F8BFF 0%,#0080FE 45%,#005FC2 100%);box-shadow:0 30px 60px -10px rgba(0,96,194,.55),0 10px 24px rgba(0,0,0,.18),inset 0 1px 0 rgba(255,255,255,.5),inset 0 -8px 20px rgba(0,0,0,.18);display:grid;place-items:center}
.hub-core::before{content:"";position:absolute;inset:6% 6% 50%;border-radius:22% 22% 50% 50%;background:linear-gradient(180deg,rgba(255,255,255,.35),transparent)}
.hub-core svg{width:62%;height:62%;position:relative}
.hub-shadow{position:absolute;left:50%;top:118%;width:90%;height:14%;translate:-50% 0;border-radius:50%;background:radial-gradient(ellipse,rgba(0,96,194,.35),transparent 70%);filter:blur(4px)}
.hub-glow{position:absolute;inset:-40%;border-radius:50%;background:radial-gradient(circle,rgba(51,195,245,.35),transparent 60%);animation:glow var(--T) ease-in-out infinite;z-index:-1}
@keyframes hub-in{0%{transform:scale(.86);opacity:.6}8%{transform:scale(1.04);opacity:1}14%,96%{transform:scale(1);opacity:1}100%{transform:scale(.86);opacity:.6}}
@keyframes glow{0%,14%{opacity:.4}80%{opacity:.5}88%{opacity:1}100%{opacity:.4}}
/* cards */
.hc{position:absolute;left:calc(50% + var(--x));top:calc(50% + var(--y));width:21%;translate:-50% -50%;opacity:0;animation:var(--T) cubic-bezier(.2,.7,.2,1) infinite;transform-style:preserve-3d}
.hc .r{display:flex;align-items:center;gap:.3em .5em;flex-wrap:wrap}
.hc.ga{animation-name:hc-a}.hc.gb{animation-name:hc-b}.hc.gc{animation-name:hc-c}
@keyframes hc-a{0%,20%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.82)}30%{opacity:1;transform:translate(0,0) scale(1)}96%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.96)}}
@keyframes hc-b{0%,40%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.82)}50%{opacity:1;transform:translate(0,0) scale(1)}96%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.96)}}
@keyframes hc-c{0%,60%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.82)}70%{opacity:1;transform:translate(0,0) scale(1)}96%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.96)}}
.hc .in{background:#fff;border-radius:1em;padding:.6em .75em;box-shadow:0 1px 0 rgba(255,255,255,.9) inset,0 18px 40px -12px rgba(11,15,26,.28),0 4px 10px rgba(11,15,26,.06);border:1px solid rgba(11,15,26,.06);display:grid;gap:.45em;animation:card-float var(--F,4s) ease-in-out infinite var(--fd,0s);position:relative}
.hc .in::before{content:"";position:absolute;inset:0 0 55%;border-radius:1.1em 1.1em 0 0;background:linear-gradient(180deg,rgba(255,255,255,.7),transparent);pointer-events:none}
@keyframes card-float{0%,100%{translate:0 0}50%{translate:0 -5px}}
.hc .t{display:flex;align-items:center;gap:.5em;font-size:.95em;white-space:nowrap;font-weight:600;color:var(--ink)}
.hc .t i{width:2em;height:2em;border-radius:.6em;display:grid;place-items:center;flex-shrink:0;color:#fff;background:var(--c,var(--blue));box-shadow:inset 0 1px 0 rgba(255,255,255,.4),0 4px 8px -2px color-mix(in srgb,var(--c,var(--blue)) 50%,transparent)}
.hc .t i svg{width:1.15em;height:1.15em}
.hc .v{font-family:var(--font-mono);font-size:1em;font-weight:500;color:var(--ink);font-feature-settings:"tnum"}
.hc .s{font-size:.85em;color:var(--ink-3)}
.hc .bars{display:flex;gap:.3em;align-items:flex-end;height:1.6em}.hc .bars b{flex:1;background:linear-gradient(180deg,#5AA9FF,var(--blue));border-radius:.25em .25em 0 0;height:var(--h);transform-origin:bottom;animation:bar var(--T) ease-out infinite}
@keyframes bar{0%,48%{transform:scaleY(.1)}56%,96%{transform:scaleY(1)}100%{transform:scaleY(.6)}}
.hc .avs{display:flex}.hc .avs b{width:1.7em;height:1.7em;border-radius:50%;border:2px solid #fff;margin-left:-.45em;background:var(--a);display:grid;place-items:center;font-size:.65em;color:#fff;font-weight:700}.hc .avs b:first-child{margin:0}
.badge{display:inline-flex;align-items:center;gap:.35em;font-size:.75em;font-weight:600;padding:.25em .55em;border-radius:999px;justify-self:start;white-space:nowrap;max-width:100%}
.badge.ok{background:var(--mint-bg);color:var(--mint)}.badge.wait{background:var(--amber-bg);color:var(--amber)}.badge.open{background:var(--coral-bg);color:var(--coral)}
.badge svg{width:1em;height:1em}
.spring{transform:scale(0);animation:var(--T) cubic-bezier(.34,1.56,.64,1) infinite}
.spring.sa{animation-name:sp-a}.spring.sb{animation-name:sp-b}.spring.sc{animation-name:sp-c}
@keyframes sp-a{0%,33%{transform:scale(0)}37%{transform:scale(1.18)}40%,96%{transform:scale(1)}100%{transform:scale(0)}}
@keyframes sp-b{0%,53%{transform:scale(0)}57%{transform:scale(1.18)}60%,96%{transform:scale(1)}100%{transform:scale(0)}}
@keyframes sp-c{0%,76%{transform:scale(0)}80%{transform:scale(1.18)}83%,96%{transform:scale(1)}100%{transform:scale(0)}}
/* ticket workflow chips */
.flowchips{display:grid}.flowchips .badge{grid-area:1/1;opacity:0;animation:var(--T) linear infinite}
.flowchips .c1{animation-name:ch1}.flowchips .c2{animation-name:ch2}.flowchips .c3{animation-name:ch3}
@keyframes ch1{0%,60%{opacity:0}62%,68%{opacity:1}70%,100%{opacity:0}}
@keyframes ch2{0%,69%{opacity:0}71%,75%{opacity:1}77%,100%{opacity:0}}
@keyframes ch3{0%,76%{opacity:0}78%,96%{opacity:1}100%{opacity:0}}
/* positions: 8 at 45° — x,y as % of stage; dx,dy = outward entry offset */
.p1{--x:0%;--y:calc(var(--R)*-1);--dx:0;--dy:-14%}
.p2{--x:calc(var(--R2)*.72);--y:calc(var(--R2)*-.72);--dx:10%;--dy:-10%}
.p3{--x:var(--R);--y:0%;--dx:14%;--dy:0}
.p4{--x:calc(var(--R2)*.72);--y:calc(var(--R2)*.72);--dx:10%;--dy:10%}
.p5{--x:0%;--y:var(--R);--dx:0;--dy:14%}
.p6{--x:calc(var(--R2)*-.72);--y:calc(var(--R2)*.72);--dx:-10%;--dy:10%}
.p7{--x:calc(var(--R)*-1);--y:0%;--dx:-14%;--dy:0}
.p8{--x:calc(var(--R2)*-.72);--y:calc(var(--R2)*-.72);--dx:-10%;--dy:-10%}
@media(max-width:480px){.hub-stage{--R:34%;--R2:46%}.hc{width:25%}}
@media(prefers-reduced-motion:reduce){.hub-stage *{animation:none!important}.hc{opacity:1;transform:none}.lines line{stroke-dashoffset:0;opacity:.6}.spring{transform:scale(1)}.flowchips .c3{opacity:1}.hc .bars b{transform:none}.scenes li{color:var(--ink-3)}.scenes li .fill{transform:scaleX(1)}}

/* module tile micro-illustrations */
.mod-ic{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;color:var(--c);background:color-mix(in srgb,var(--c) 10%,#fff);border:1px solid color-mix(in srgb,var(--c) 18%,#fff);box-shadow:inset 0 1px 0 #fff;margin-bottom:6px;position:relative}
.mod-ic svg{width:24px;height:24px;overflow:visible}
.mod-ic .k{transition:all .45s cubic-bezier(.2,.7,.2,1);transform-origin:center}
.modules a:hover .mod-ic{box-shadow:inset 0 1px 0 #fff,0 8px 20px -8px color-mix(in srgb,var(--c) 60%,transparent)}
.mod-ic.pin::after{content:"";position:absolute;inset:8px;border-radius:50%;border:1.5px solid var(--c);opacity:0;transform:scale(.5)}
.modules a:hover .pin::after{animation:mod-ping 1.2s ease-out infinite}
@keyframes mod-ping{0%{opacity:.6;transform:scale(.5)}100%{opacity:0;transform:scale(1.6)}}
.tick .k{stroke-dasharray:14;stroke-dashoffset:14}.modules a:hover .tick .k{stroke-dashoffset:0}
.lines .k{stroke-dasharray:8;stroke-dashoffset:8}.modules a:hover .lines .k{stroke-dashoffset:0}
.modules a:hover .move .k{transform:translate(4px,-3px)}
.grow .k{transform:scaleY(.3);transform-box:fill-box;transform-origin:bottom}.modules a:hover .grow .k{transform:scaleY(1)}
.stamp .k{fill:var(--c);fill-opacity:0;transform:scale(0);transform-box:fill-box;transform-origin:center}.modules a:hover .stamp .k{fill-opacity:.9;transform:scale(1);transition-timing-function:cubic-bezier(.34,1.56,.64,1)}
.modules a:hover .slide .k{transform:translateY(-3px)}
.pop .k{transform:scale(0);transform-box:fill-box;transform-origin:center}.modules a:hover .pop .k{transform:scale(1);transition-timing-function:cubic-bezier(.34,1.56,.64,1)}
/* play the same reveal when tiles scroll in (touch devices have no hover) */
.modules.in a .mod-ic .k{animation:mod-once 1.2s cubic-bezier(.2,.7,.2,1) 1}
@keyframes mod-once{0%{stroke-dashoffset:14}100%{stroke-dashoffset:0}}
@media(prefers-reduced-motion:reduce){.mod-ic .k{transition:none;transform:none;stroke-dashoffset:0;fill-opacity:.9}.modules a:hover .pin::after{animation:none}}
