/* Orbit Interactive motion timings, adapted to Nova OG's existing branding. */
:root{--spring:cubic-bezier(.18,.85,.28,1.2)}
html{background:var(--bg)}
body{isolation:isolate;overflow-x:clip}
.letter-run,.bubble-word,.bubble-letter{display:inline-block}
.letter-run{vertical-align:baseline;white-space:pre-wrap}
.bubble-word{white-space:nowrap}
.bubble-letter{transform-origin:50% 80%}
.reading-progress{position:fixed;inset:0 0 auto;height:3px;z-index:90;pointer-events:none}
.reading-progress>div{height:100%;background:var(--purple);transform:scaleX(0);transform-origin:left}
.cursor-magic{position:fixed;inset:0;width:100%;height:100%;z-index:80;pointer-events:none}
.motion-background{position:fixed;inset:-10%;z-index:-1;pointer-events:none;background:linear-gradient(135deg,transparent 0 47%,color-mix(in srgb,var(--purple) 4%,transparent) 47% 60%,transparent 60%);background-size:115% 115%;animation:background-cruise 32s ease-in-out infinite alternate}
[data-motion-zone]{--motion-play-state:paused}
[data-motion-zone][data-in-view=true]{--motion-play-state:running}
.hero-art{mix-blend-mode:screen}
:root[data-theme=light] .hero-art{mix-blend-mode:multiply}
.art-logo,:root[data-theme=light] .art-logo{mix-blend-mode:normal}
.art-inner{translate:var(--orbit-x,0px) calc(var(--orbit-y,0px) + var(--orbit-scroll,0px));transition:translate .65s cubic-bezier(.2,.8,.2,1)}
.art-logo{animation:planet-cruise 8s ease-in-out infinite;animation-play-state:var(--motion-play-state,running);transform-origin:50% 55%}
.comic-star{animation:star-dance 7s ease-in-out infinite;animation-play-state:var(--motion-play-state,running);transform-origin:center;pointer-events:none}
.star-b{animation-delay:-3.4s;animation-duration:9s}
.hero h1>.letter-run,.hero h1>.hero-accent>.letter-run{animation:headline-float 7s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.hero h1>.hero-accent>.letter-run{animation-delay:-2.3s}
.hero .sticker{transform-origin:12% 60%;animation:label-rock 9s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}

/* Two identical groups keep the moving ribbon seamless at every viewport. */
.signal-strip{height:64px;padding:0;margin:12px 0 4px;pointer-events:none}
.motion-ribbon{display:flex;width:max-content;height:100%;animation:shape-loop 38s linear infinite;animation-play-state:var(--motion-play-state,running);will-change:transform}
.ribbon-group{display:flex;flex:0 0 auto;width:max(calc(100vw + 40px),1280px);height:100%;align-items:center;justify-content:space-around}
.ribbon-shape{display:grid;place-items:center;flex:0 0 auto;width:48px;height:48px;color:#06101f}
.ribbon-shape svg{width:36px;height:36px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linejoin:round;overflow:visible;animation:ribbon-turn 16s linear infinite;animation-play-state:var(--motion-play-state,running);transform-origin:50% 50%}
.ribbon-shape:nth-child(2n) svg{animation-direction:reverse;animation-duration:21s}
.ribbon-shape:nth-child(3n) svg{animation-delay:-5s}
.ribbon-shape:nth-child(4n) svg{animation-delay:-11s}

/* Stable layout boxes, with the same small magnetic and spring response. */
.motion-magnet{translate:var(--magnet-x,0px) var(--magnet-y,0px);transition:translate .4s var(--spring),transform .25s var(--spring),box-shadow .25s,background .25s,color .25s}
.btn,.copy-button,.theme{position:relative;isolation:isolate}
.hero-actions .btn:after,.discord-banner .btn:after{content:'';position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;background:linear-gradient(110deg,transparent 25%,#ffffff6b 50%,transparent 75%);background-size:280% 100%;animation:button-sheen 7s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.btn .icon,.text-link .icon{transition:translate .45s var(--spring),rotate .45s var(--spring)}
.btn:is(:hover,:focus-visible) .icon,.text-link:is(:hover,:focus-visible) .icon{translate:3px -2px}
.nav a:after{transform-origin:left;transition:transform .45s var(--spring)}
.brand-logo{animation:brand-rock 9s ease-in-out infinite;animation-play-state:var(--motion-play-state,running);transform-origin:50% 70%;transition:rotate .45s var(--spring)}
.brand:is(:hover,:focus-visible) .brand-logo{animation-play-state:paused;rotate:-6deg}
.footer-brand .letter-run{animation:headline-float 7.5s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.footer-brand:is(:hover,:focus-visible){color:#62d1ff}
.footer-brand:focus-visible{outline:2px solid #62d1ff;outline-offset:7px;border-radius:3px}

/* Nova's status, player and update cards use Orbit's project-card motion. */
.card,.update-row,.player,.stat-block,.status-main-panel,.connection-panel{position:relative;isolation:isolate;transform-style:preserve-3d;transition:transform .45s var(--spring),box-shadow .3s,background .3s}
.card:after,.update-row:after,.player:after{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:-1;background:linear-gradient(115deg,transparent 25%,#ffffff0c 46%,#ffffff16 50%,transparent 65%);background-size:270% 100%;background-position:140% 0;opacity:0;transition:opacity .3s,background-position .8s}
.card:is(:hover,:focus-within):after,.update-row:is(:hover,:focus-within):after,.player:is(:hover,:focus-within):after{opacity:1;background-position:-30% 0}
.card-head>.icon{animation:icon-hover 6.4s ease-in-out infinite;animation-play-state:var(--motion-play-state,running);transform-origin:50% 65%}
.card-purple .card-head>.icon{animation-delay:-2.1s;animation-duration:7.1s}
.card-yellow .card-head>.icon{animation-delay:-4.2s;animation-duration:7.6s}
.file-art{animation:lock-float 6s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.player-avatar{animation:avatar-rock 8s ease-in-out infinite;animation-play-state:var(--motion-play-state,running);transform-origin:50% 75%}
.stat-number{animation:count-rock 8s ease-in-out infinite;animation-play-state:var(--motion-play-state,running);transform-origin:left}
.card-bottom>.tiny-pill{animation:value-hop 7s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.card-purple .tiny-pill{animation-delay:-4.7s}
.card-yellow .tiny-pill{animation-delay:-2.4s}
.empty-state>.icon{animation:lock-float 6s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.search,select{transition:border-color .25s,box-shadow .3s,translate .3s var(--spring)}
.search:focus-within,select:focus-visible{translate:0 -2px;box-shadow:4px 4px 0 var(--ink)}
[data-refresh][aria-busy=true]{animation:busy-breathe 1.5s ease-in-out infinite}
.history-tooltip{animation:tooltip-pop .25s var(--spring);transform-origin:center bottom}
.copy-fallback[open]{animation:tooltip-pop .25s var(--spring)}
.section-heading>.text-link .icon{animation:arrow-hop 3s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.discord-banner>.btn{animation:arcade-invite 7s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}
.dot.online{animation:signal-pulse 3s ease-in-out infinite;animation-play-state:var(--motion-play-state,running)}

@keyframes background-cruise{from{transform:translate3d(-1.5%,0,0)}to{transform:translate3d(1.5%,-2%,0)}}
@keyframes planet-cruise{0%,100%{transform:translate(-50%,-49%) rotate(-2deg)}35%{transform:translate(-49%,-51.5%) rotate(1.5deg)}70%{transform:translate(-51%,-50.5%) rotate(-.5deg)}}
@keyframes star-dance{0%,100%{scale:1;rotate:-7deg;translate:0 0}50%{scale:1.1;rotate:10deg;translate:0 -6px}}
@keyframes headline-float{0%,100%{translate:0 0}50%{translate:0 -3px}}
@keyframes label-rock{0%,75%,100%{rotate:0deg}82%{rotate:1.5deg}91%{rotate:-1deg}}
@keyframes shape-loop{to{transform:translateX(-50%)}}
@keyframes ribbon-turn{to{rotate:360deg}}
@keyframes icon-hover{0%,100%{translate:0 2px;rotate:-1.5deg}50%{translate:0 -7px;rotate:2deg}}
@keyframes button-sheen{0%,65%,100%{background-position:150% 0}85%{background-position:-55% 0}}
@keyframes brand-rock{0%,78%,100%{rotate:0deg}86%{rotate:5deg}93%{rotate:-3deg}}
@keyframes avatar-rock{0%,100%{rotate:-1deg;translate:0 0}50%{rotate:2deg;translate:0 -3px}}
@keyframes value-hop{0%,78%,100%{translate:0 0;rotate:0deg}85%{translate:0 -4px;rotate:-3deg}93%{translate:0 0;rotate:1deg}}
@keyframes arrow-hop{0%,100%{translate:0 0}50%{translate:4px 0}}
@keyframes arcade-invite{0%,78%,100%{rotate:0deg;translate:0 0}84%{rotate:-3deg;translate:0 -3px}91%{rotate:2deg;translate:0 -1px}}
@keyframes lock-float{0%,100%{translate:0 0;rotate:-2deg}50%{translate:0 -5px;rotate:2deg}}
@keyframes count-rock{0%,100%{rotate:-1deg}50%{rotate:1.5deg}}
@keyframes busy-breathe{0%,100%{opacity:1}50%{opacity:.65}}
@keyframes tooltip-pop{from{opacity:0;scale:.9;translate:0 5px}to{opacity:1;scale:1;translate:0 0}}
@keyframes signal-pulse{0%,100%{opacity:.5}50%{opacity:1}}
@keyframes page-leave{to{opacity:0}}
@keyframes page-enter{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:translateY(0)}}
@view-transition{navigation:auto}
::view-transition-old(root){animation:page-leave .16s ease-out both}
::view-transition-new(root){animation:page-enter .32s ease-out both}

@media(hover:hover) and (pointer:fine){
 .card:is(:hover,:focus-within){transform:perspective(900px) rotateX(var(--tilt-x,0deg)) rotateY(var(--tilt-y,0deg)) translateY(-7px);box-shadow:9px 13px 0 var(--ink)}
 .update-row:is(:hover,:focus-within),.player:is(:hover,:focus-within),.stat-block:is(:hover,:focus-within),.status-main-panel:is(:hover,:focus-within),.connection-panel:is(:hover,:focus-within){transform:perspective(900px) rotateX(var(--tilt-x,0deg)) rotateY(var(--tilt-y,0deg)) translateY(-5px)}
 .btn:is(:hover,:focus-visible){transform:translate(-2px,-3px) rotate(-1.5deg);box-shadow:6px 7px 0 var(--ink)}
 .btn:active{transform:translate(3px,3px);box-shadow:1px 1px 0 var(--ink)}
}
@media(max-width:800px){.signal-strip{height:60px}}
@media(max-width:560px){.signal-strip{height:56px}.ribbon-shape svg{width:32px;height:32px}}
@media(hover:none),(pointer:coarse){.cursor-magic{display:none}.card:hover{transform:none}}
:root[data-nova-motion=paused] *,:root[data-nova-motion=paused] *:before,:root[data-nova-motion=paused] *:after{animation-play-state:paused!important}
:root[data-nova-motion=paused] .cursor-magic{visibility:hidden}
@media(prefers-reduced-motion:reduce){
 html{scroll-behavior:auto}
 *,*:before,*:after{animation:none!important;transition:none!important}
 .reading-progress,.cursor-magic{display:none}
 .art-inner,.motion-magnet{translate:none!important}
 .art-logo{transform:translate(-50%,-50%)!important}
 .card:is(:hover,:focus-within),.update-row:is(:hover,:focus-within),.player:is(:hover,:focus-within),.stat-block:is(:hover,:focus-within),.status-main-panel:is(:hover,:focus-within),.connection-panel:is(:hover,:focus-within),.btn:is(:hover,:focus-visible){transform:none!important}
 .bubble-letter,.letter-run{translate:none!important;rotate:none!important;scale:none!important}
 ::view-transition-old(root),::view-transition-new(root){animation:none!important}
}
