/* Motion: the music is alive, so the page moves a little. Everything here is off for prefers-reduced-motion. */
:root{--pulse:0;--hit:0}

/* ambient light: two slow glows that drift, and brighten with the loudness of what plays (--pulse, set by live.js) */
body::before{content:"";position:fixed;inset:-20vmax;z-index:-1;pointer-events:none;
  background:radial-gradient(42vmax 30vmax at 18% 12%,rgba(247,156,31,calc(.045 + .11*var(--pulse))),transparent 70%),
             radial-gradient(46vmax 36vmax at 86% 82%,rgba(91,141,239,calc(.035 + .09*var(--pulse))),transparent 70%);
  animation:drift 30s ease-in-out infinite alternate;will-change:transform}
@keyframes drift{to{transform:translate3d(-4vmax,3vmax,0) scale(1.1)}}

/* first paint */
.kicker,h1,p.lead,#preview{animation:rise .9s cubic-bezier(.2,.7,.2,1) both}
h1{animation-delay:.07s}p.lead{animation-delay:.15s}#preview{animation-delay:.25s}
@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.kbars{display:inline-flex;gap:2px;align-items:flex-end;height:12px;margin-left:9px;vertical-align:-1px}
.kbars i{width:2px;height:35%;background:var(--accent);border-radius:1px;transform-origin:bottom;animation:kb 1.3s ease-in-out infinite}
.kbars i:nth-child(2){animation-duration:.9s;animation-delay:-.3s}.kbars i:nth-child(3){animation-duration:1.5s;animation-delay:-.7s}
.kbars i:nth-child(4){animation-duration:1.1s;animation-delay:-.2s}.kbars i:nth-child(5){animation-duration:1.7s;animation-delay:-.9s}
@keyframes kb{0%,100%{height:25%}50%{height:100%}}
body.playing .kbars i{animation-duration:.45s}

/* processing: a channel meter with VU ballistics (fast attack, slow release), locked to a 120 bpm grid (beat = .5 s) */
.eqload{display:flex;gap:4px;align-items:flex-end;height:30px;margin-top:12px}
.eqload[hidden]{display:none}
.eqload i{width:6px;height:30px;border-radius:1px;
  background:linear-gradient(to top,var(--accent) 0,var(--accent) 70%,#ff7b72 100%);
  -webkit-mask:repeating-linear-gradient(to top,#000 0 3px,transparent 3px 5px);mask:repeating-linear-gradient(to top,#000 0 3px,transparent 3px 5px);
  clip-path:inset(70% 0 0 0);animation:vu 1s linear infinite}
.eqload i:nth-child(3n){animation-duration:.5s;animation-name:vu2}.eqload i:nth-child(4n+1){animation-duration:2s;animation-delay:-.5s}
.eqload i:nth-child(5n){animation-duration:1.5s;animation-delay:-1s;animation-name:vu2}.eqload i:nth-child(7n){animation-duration:1s;animation-delay:-.25s}
@keyframes vu{0%{clip-path:inset(85% 0 0 0)}8%{clip-path:inset(6% 0 0 0)}30%{clip-path:inset(40% 0 0 0)}45%{clip-path:inset(30% 0 0 0)}100%{clip-path:inset(85% 0 0 0)}}
@keyframes vu2{0%{clip-path:inset(80% 0 0 0)}15%{clip-path:inset(28% 0 0 0)}25%{clip-path:inset(50% 0 0 0)}100%{clip-path:inset(80% 0 0 0)}}
.drop.busy{animation:busy 1s steps(1,end) infinite;position:relative;overflow:hidden}
@keyframes busy{0%{border-color:var(--accent);box-shadow:0 0 30px rgba(247,156,31,.2)}20%{border-color:rgba(247,156,31,.5);box-shadow:0 0 14px rgba(247,156,31,.08)}60%{border-color:rgba(247,156,31,.35);box-shadow:none}}

/* drop zone as an input jack: level bars + ring while a file hovers, a scan sweep while uploading */
.drop{position:relative;overflow:hidden}
.drop::before{content:"";position:absolute;left:0;right:0;bottom:0;height:46%;pointer-events:none;opacity:0;transition:opacity .25s;
  background:repeating-linear-gradient(90deg,rgba(247,156,31,.5) 0 3px,transparent 3px 9px);
  -webkit-mask:linear-gradient(to top,#000,transparent);mask:linear-gradient(to top,#000,transparent)}
.drop.over::before{opacity:1;animation:jack .5s ease-in-out infinite alternate}
@keyframes jack{from{transform:scaleY(.35);transform-origin:bottom}to{transform:scaleY(1);transform-origin:bottom}}
.drop::after{content:"";position:absolute;top:0;bottom:0;left:0;width:30%;pointer-events:none;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(247,156,31,.16),transparent)}
.drop.busy::after{opacity:1;animation:scan 2s linear infinite}
@keyframes scan{from{transform:translateX(-100%)}to{transform:translateX(340%)}}
.drop.hit{animation:hit .6s ease-out}
@keyframes hit{0%{box-shadow:0 0 0 0 rgba(247,156,31,.6),inset 0 0 40px rgba(247,156,31,.2)}100%{box-shadow:0 0 0 18px rgba(247,156,31,0),inset 0 0 0 rgba(247,156,31,0)}}
.drop.over{box-shadow:inset 0 0 40px rgba(247,156,31,.1)}

/* hero oscilloscope (canvas added by motion.js) */
#mscope{position:absolute;left:0;top:0;width:100%;height:0;z-index:-1;pointer-events:none;opacity:0;transition:opacity 1.2s .3s;
  -webkit-mask:linear-gradient(90deg,transparent,#000 18%,#000 82%,transparent);mask:linear-gradient(90deg,transparent,#000 18%,#000 82%,transparent)}
#mscope.on{opacity:1}
main{position:relative}

/* playhead scan that accompanies a chart reveal */
.mscan{position:absolute;overflow:hidden;pointer-events:none;z-index:5}
.mscan i{position:absolute;top:0;bottom:0;left:0;width:2px;background:var(--accent);box-shadow:0 0 14px 2px rgba(247,156,31,.7);
  animation:mscan 1.1s cubic-bezier(.2,.7,.2,1) both;animation-duration:var(--d,1.1s)}
@keyframes mscan{from{transform:translateX(0);opacity:1}88%{opacity:1}to{transform:translateX(var(--w));opacity:0}}

/* results arrive */
#results:not([hidden]){animation:rise .7s cubic-bezier(.2,.7,.2,1) both}
#dock:not([hidden]){animation:dockin .55s cubic-bezier(.2,.8,.2,1) both}
@keyframes dockin{from{transform:translateY(105%)}}
.rv{opacity:0;transform:translateY(14px);transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1)}
.rv.in{opacity:1;transform:none}
.rv.wipe{transform:none;opacity:1;clip-path:inset(0 100% 0 0 round 8px);transition:clip-path 1.1s cubic-bezier(.2,.7,.2,1)}
.rv.wipe.in{clip-path:inset(0 0 0 0 round 8px)}
.chk.rv .dot{transform:scale(0)}.chk.rv.in .dot{transform:none;transition:transform .5s .12s cubic-bezier(.3,1.7,.5,1)}
.chk.rv.in .dot.ok,.chk.rv.in .dot.info{animation:led .9s .15s ease-out backwards}
@keyframes led{0%{box-shadow:0 0 0 0 currentColor,0 0 16px 4px var(--ink);filter:brightness(2.4)}100%{box-shadow:0 0 0 0 transparent;filter:none}}
td.tick{color:var(--accent)}td{font-variant-numeric:tabular-nums}
.dot.warn,.dot.fail{animation:ring 2.6s ease-in-out infinite}
@keyframes ring{0%{box-shadow:0 0 0 0 rgba(247,156,31,.5)}60%,100%{box-shadow:0 0 0 7px rgba(247,156,31,0)}}
.dot.fail{animation-name:ringf}@keyframes ringf{0%{box-shadow:0 0 0 0 rgba(255,123,114,.55)}60%,100%{box-shadow:0 0 0 7px rgba(255,123,114,0)}}

/* hardware panels: steps and tiers get a status LED and lift on hover */
.grid>.panel{position:relative;transition:transform .25s,border-color .25s,box-shadow .25s}
.grid>.panel::after{content:"";position:absolute;top:12px;right:12px;width:5px;height:5px;border-radius:50%;background:#2a2012;box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);transition:background .25s,box-shadow .25s}
.grid>.panel:hover{transform:translateY(-2px);border-color:var(--line2);box-shadow:0 10px 30px rgba(0,0,0,.4),inset 0 1px 0 rgba(255,255,255,.05)}
.grid>.panel:hover::after{background:var(--accent);box-shadow:0 0 8px 1px rgba(247,156,31,.8)}
.grid>.panel.tier.hot::after{background:var(--accent);box-shadow:0 0 6px rgba(247,156,31,.6)}
.grid>.panel.rv.in{transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1),border-color .25s,box-shadow .25s}

/* hands */
button,.btn,.chips button,.vbtn,select{transition:transform .15s,border-color .15s,background-color .2s,color .2s,box-shadow .2s}
button:active:not(:disabled){transform:scale(.96)}
#play:active,#ab button:active,.segctl button:active,.tlview button:active{transform:translateY(1px) scale(.95);box-shadow:inset 0 2px 6px rgba(0,0,0,.5)}
.tgl:active{transform:scale(.95)}
#ab button{transition:transform .12s,color .2s}
.chips button:hover,.vbtn:hover,.btn:hover{transform:translateY(-1px)}
.drop:hover{border-color:var(--line2);background:rgba(255,255,255,.015)}
.vbtn.on{box-shadow:0 0 18px rgba(247,156,31,.35)}
.playhead{box-shadow:0 0 12px rgba(247,156,31,calc(.15 + .6*var(--hit,0)))}
.dockhead{box-shadow:0 0 14px rgba(247,156,31,calc(.2 + .7*var(--hit,0)))}
body.playing #dock{border-top-color:rgba(247,156,31,calc(.25 + .45*var(--pulse)));box-shadow:0 -10px 50px rgba(247,156,31,calc(.03 + .16*var(--pulse)))}
.lvt{transition:border-color .3s}body.playing .lvt{border-color:rgba(247,156,31,.18)}

@media (max-width:560px){#mscope{display:none}.grid>.panel:hover{transform:none}}
@media (prefers-reduced-motion:reduce){
  #mscope,.mscan,.drop::before,.drop::after{display:none}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .rv,.rv.wipe{opacity:1;transform:none;clip-path:none}
  .chk.rv .dot{transform:none}
}
