/* =========================================================
   9. ANIMATIONS — LockSys motion language
   Reveal states only apply when JS is running (html.js).
   ========================================================= */

/* Masked headline lines */
.mask-line{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.mask-line>span{display:block}
.js .mask-line>span{transform:translateY(105%);transition:transform var(--d-hero) var(--ease-out)}
.js .mask-line:nth-child(2)>span{transition-delay:90ms}
.js .is-revealed .mask-line>span,
.js .mask-line.is-revealed>span{transform:none}

/* Hero sequence */
.js [data-hero]{opacity:0;transform:translateY(16px);transition:opacity var(--d-reveal) var(--ease-out),transform var(--d-reveal) var(--ease-out)}
.js .hero.is-revealed [data-hero]{opacity:1;transform:none}
.js .hero.is-revealed [data-hero="1"]{transition-delay:0ms}
.js .hero.is-revealed [data-hero="2"]{transition-delay:260ms}
.js .hero.is-revealed [data-hero="3"]{transition-delay:360ms}
.js .hero.is-revealed [data-hero="4"]{transition-delay:460ms}
.js .hero.is-revealed [data-hero="5"]{transition-delay:200ms;transition-duration:var(--d-hero)}

/* Hero L outline draws in */
.js .hero__l use{stroke-dasharray:420;stroke-dashoffset:420;transition:stroke-dashoffset 1800ms var(--ease-in-out) 150ms}
.js .hero.is-revealed .hero__l use{stroke-dashoffset:0}

/* Ops panel bars fill */
.js .ops__list em::after{transform:scaleX(0);transition:transform 900ms var(--ease-out)}
.js .hero.is-revealed .ops__list em::after{transform:scaleX(1)}
.js .hero.is-revealed .ops__list li:nth-child(1) em::after{transition-delay:500ms}
.js .hero.is-revealed .ops__list li:nth-child(2) em::after{transition-delay:580ms}
.js .hero.is-revealed .ops__list li:nth-child(3) em::after{transition-delay:660ms}
.js .hero.is-revealed .ops__list li:nth-child(4) em::after{transition-delay:740ms}
.js .hero.is-revealed .ops__list li:nth-child(5) em::after{transition-delay:820ms}
.js .hero__foot-bar{transform:scaleX(0);transform-origin:right;transition:transform 1000ms var(--ease-out) 600ms}
.js .hero.is-revealed .hero__foot-bar{transform:none}
.ops__links path{stroke-dasharray:3 4;animation:flow 1.6s linear infinite}
@keyframes flow{to{stroke-dashoffset:-14}}
.ops__status i{animation:pulse 2.4s var(--ease-in-out) infinite}
@keyframes pulse{50%{box-shadow:0 0 0 7px rgba(31,122,77,0)}}

/* Generic reveal: fade + rise */
.js [data-reveal]{opacity:0;transform:translateY(22px);transition:opacity var(--d-reveal) var(--ease-out),transform var(--d-reveal) var(--ease-out);transition-delay:var(--delay,0ms)}
.js [data-reveal].is-in{opacity:1;transform:none}
/* cards keep their own hover transform once revealed */
.js .card[data-reveal].is-in{transition:opacity var(--d-reveal) var(--ease-out) var(--delay,0ms),transform var(--d-ui) var(--ease-out),border-color var(--d-ui),box-shadow var(--d-ui)}
.js .card[data-reveal].is-in:hover{transform:translateY(-3px)}

/* Section separator line drawing */
.js [data-draw]{transform:scaleX(0);transform-origin:right;transition:transform 1200ms var(--ease-out)}
.js [data-draw].is-in{transform:none}

/* Hub spokes */
.hub__svg .spoke-live{animation:flow 2.4s linear infinite}

/* Pattern drift — slow and quiet */
.band-pattern{animation:drift 60s linear infinite}
@keyframes drift{to{background-position:220px 0}}

/* Preloader */
.intro .preloader__mark{opacity:0;transform:translateY(10px);animation:plMark 600ms var(--ease-out) 80ms forwards}
.intro .preloader__line{animation:plLine 600ms var(--ease-out) 420ms forwards}
.intro .preloader__name{opacity:0;animation:plName 500ms var(--ease-out) 760ms forwards}
.preloader.is-leaving{opacity:0;visibility:hidden;transition:opacity 420ms var(--ease-out),visibility 0s linear 420ms}
@keyframes plMark{to{opacity:1;transform:none}}
@keyframes plLine{to{transform:scaleX(1)}}
@keyframes plName{to{opacity:1}}

/* Brand mark hover */
.brand:hover .brand__mark{transform:translateY(-1px)}

/* View Transitions (progressive enhancement) */
@supports (view-transition-name:none){
  ::view-transition-old(root),::view-transition-new(root){animation-duration:280ms}
}
