/* ==================================================================
   Novas — homepage motion layer  v2.0.0
   Engine: GSAP 3 + ScrollTrigger + SplitText (self-hosted)

   Rules of the house:
   • One easing family, short throws (24–44px). Nothing "flies in".
   • Reveals clear their own inline transforms on completion so the
     existing CSS hover lifts keep working afterwards.
   • Nothing is hidden unless JS is confirmed running AND has not yet
     finished setting up (html.nv-js:not(.nv-ready)).
   ================================================================== */

:root{
  --nv-m-ease:cubic-bezier(.22,.75,.28,1);
  --nv-m-out:cubic-bezier(.16,1,.3,1);
}

/* ==================================================================
   0. PRE-BOOT — stops a flash of un-animated content.
   Only applies while JS is running but not yet ready. A failsafe timer
   adds .nv-ready after 2.2s no matter what, so a script failure can
   never leave the page blank.
   ================================================================== */
html.nv-js:not(.nv-ready) .elementor-47 .elementor-widget-heading,
html.nv-js:not(.nv-ready) .elementor-47 .elementor-widget-text-editor,
html.nv-js:not(.nv-ready) .elementor-47 .elementor-widget-button,
html.nv-js:not(.nv-ready) .elementor-47 .elementor-widget-counter,
html.nv-js:not(.nv-ready) .elementor-47 .elementor-widget-icon-list,
html.nv-js:not(.nv-ready) .elementor-47 .elementor-widget-icon-box,
html.nv-js:not(.nv-ready) .elementor-47 .nv-cat-card,
html.nv-js:not(.nv-ready) .elementor-47 .nv-why-card,
html.nv-js:not(.nv-ready) .elementor-47 .nv-vcard,
html.nv-js:not(.nv-ready) .elementor-47 .nv-scard,
html.nv-js:not(.nv-ready) .elementor-47 .nv-mcard,
html.nv-js:not(.nv-ready) .elementor-47 .nv-chip,
html.nv-js:not(.nv-ready) .elementor-47 .nv-brand-tile,
html.nv-js:not(.nv-ready) .elementor-47 .nv-mission,
html.nv-js:not(.nv-ready) .elementor-47 .nv-vision,
html.nv-js:not(.nv-ready) .elementor-47 ul.nv-sector-list > li{
  opacity:0}

@media (prefers-reduced-motion:reduce){
  html.nv-js .elementor-47 *{opacity:1!important}
}

/* ==================================================================
   1. SplitText line masks
   GSAP names the mask wrapper `<linesClass>-mask` and gives it
   overflow:clip — which would shave descenders (g, y, p). The padding /
   negative-margin pair grows the clip box without touching layout.
   ================================================================== */
.nv-line{will-change:transform}
.nv-line-mask{
  padding-bottom:.18em;
  margin-bottom:-.18em}

/* ==================================================================
   2. Hero
   The photo is a container background, so JS lifts it into its own
   layer (.nv-hero-bg) that can be scaled and parallaxed independently
   of Elementor's gradient overlay.
   ================================================================== */
.nv-hero{overflow:hidden;position:relative}

.nv-hero > .nv-hero-bg{
  position:absolute;inset:0;z-index:0;
  background-position:center center;
  background-size:cover;
  background-repeat:no-repeat;
  transform-origin:50% 55%;
  will-change:transform;
  pointer-events:none}

/* once the layer exists, the container must stop painting the photo */
.nv-hero.nv-hero-split{background-image:none!important}

/* stacking: photo (0) → Elementor overlay (1) → glow (2) → content (3) */
.nv-hero::before{z-index:1}

.nv-hero::after{
  content:"";position:absolute;inset:-14%;z-index:2;pointer-events:none;
  background:
    radial-gradient(620px 440px at 22% 32%,rgba(26,183,140,.20),transparent 62%),
    radial-gradient(560px 400px at 80% 68%,rgba(40,82,164,.24),transparent 64%);
  animation:nvDrift 26s ease-in-out infinite alternate;
  will-change:transform}

.nv-hero > .e-con-inner{position:relative;z-index:3}

@keyframes nvDrift{
  from{transform:translate3d(-2.5%,-2%,0) scale(1)}
  to  {transform:translate3d(3.5%,2.5%,0) scale(1.14)}}

/* ==================================================================
   3. Ambient depth on the dark / coloured bands
   ================================================================== */
.nv-cta-dark,.nv-msup-sec,.nv-commit{position:relative;overflow:hidden}

.nv-cta-dark::after,.nv-msup-sec::after,.nv-commit::after{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(680px 420px at 12% 18%,rgba(26,183,140,.16),transparent 60%),
    radial-gradient(600px 460px at 88% 84%,rgba(120,170,255,.14),transparent 62%);
  animation:nvDrift2 34s ease-in-out infinite alternate;
  will-change:transform}

.nv-cta-dark  > .e-con-inner,
.nv-msup-sec  > .e-con-inner,
.nv-commit    > .e-con-inner{position:relative;z-index:1}

@keyframes nvDrift2{
  from{transform:translate3d(-3%,-2%,0) scale(1.05)}
  to  {transform:translate3d(3%,2%,0) scale(1.18)}}

/* ==================================================================
   4. Cursor spotlight on cards (desktop, fine pointers only)
   JS adds .nv-spot and keeps --nv-mx / --nv-my updated on rAF.
   ================================================================== */
.nv-spot{position:relative}
.nv-spot::after{
  content:"";position:absolute;inset:0;z-index:3;
  pointer-events:none;border-radius:inherit;
  background:radial-gradient(220px circle at var(--nv-mx,50%) var(--nv-my,50%),
             var(--nv-spot-tint,rgba(26,183,140,.13)),transparent 70%);
  opacity:0;
  transition:opacity .4s var(--nv-m-ease)}
.nv-spot:hover::after{opacity:1}

.nv-mcard.nv-spot{--nv-spot-tint:rgba(255,255,255,.10)}
.nv-chip.nv-spot {--nv-spot-tint:rgba(255,255,255,.12)}

@media (hover:none),(pointer:coarse){
  .nv-spot::after{display:none}
}

/* ==================================================================
   5. Buttons — sheen sweep + magnetic pull (JS handles the pull)
   ================================================================== */
.elementor-47 .elementor-button{
  position:relative;
  overflow:hidden;
  isolation:isolate}

.elementor-47 .elementor-button::after{
  content:"";position:absolute;top:0;left:-150%;
  width:55%;height:100%;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,
             transparent,rgba(255,255,255,.40),transparent);
  transform:skewX(-18deg)}

@media (hover:hover) and (pointer:fine){
  .elementor-47 .elementor-button:hover::after{
    animation:nvSheen .9s var(--nv-m-out) forwards}
}
@keyframes nvSheen{to{left:160%}}

/* ==================================================================
   6. Hover micro-interactions
   ================================================================== */
.nv-vc-icon .elementor-icon,
.nv-sv-icon .elementor-icon,
.nv-dk-icon .elementor-icon,
.nv-mico   .elementor-icon,
.nv-cc-icon .elementor-icon{
  transition:transform .38s var(--nv-m-out),background .32s var(--nv-m-ease)}

.nv-vcard:hover .nv-vc-icon .elementor-icon,
.nv-scard:hover .nv-sv-icon .elementor-icon,
.nv-mcard:hover .nv-mico   .elementor-icon{
  transform:scale(1.12) rotate(-5deg)}

/* arrow links nudge forward */
.nv-viewall,.nv-card-link,.nv-talk-link,.nv-allsvc a,.nv-cat-card-view-link{
  display:inline-block;
  transition:transform .3s var(--nv-m-out),color .2s var(--nv-m-ease)}
.nv-viewall:hover,.nv-card-link:hover,
.nv-talk-link:hover,.nv-allsvc a:hover,.nv-cat-card-view-link:hover{
  transform:translateX(5px)}

/* category imagery */
.nv-cat-card .nv-cat-photo,
.nv-cat-card .elementor-widget-image{overflow:hidden}
.nv-cat-card img{transition:transform .6s var(--nv-m-out)}
.nv-cat-card:hover img{transform:scale(1.07)}

/* brand logos */
.nv-brand-tile .elementor-widget-image img{
  transition:transform .38s var(--nv-m-out),
             opacity .38s var(--nv-m-ease),
             filter .38s var(--nv-m-ease);
  opacity:.86}
.nv-brand-tile:hover .elementor-widget-image img{
  transform:translateY(-3px) scale(1.05);opacity:1}

/* sector chips */
ul.nv-sector-list li{
  transition:border-color .28s var(--nv-m-ease),
             background .28s var(--nv-m-ease),
             transform .28s var(--nv-m-out)}
ul.nv-sector-list li:hover{
  border-color:rgba(26,183,140,.5)!important;
  background:rgba(26,183,140,.07)!important;
  transform:translateX(5px)}
ul.nv-sector-list li::before{transition:transform .28s var(--nv-m-out)}
ul.nv-sector-list li:hover::before{transform:translateX(3px)}

/* mission / vision */
.nv-mv-panel{transition:box-shadow .45s var(--nv-m-out)}
.nv-mv-panel:hover{box-shadow:0 28px 58px rgba(12,37,82,.28)}
.nv-mv-icon .elementor-icon{transition:transform .45s var(--nv-m-out)}
.nv-mission:hover .nv-mv-icon .elementor-icon,
.nv-vision:hover  .nv-mv-icon .elementor-icon{transform:scale(1.1)}

/* checklist ticks */
.nv-checks .elementor-icon-list-icon{
  transition:transform .3s var(--nv-m-out)}
.nv-checks .elementor-icon-list-item:hover .elementor-icon-list-icon{
  transform:scale(1.18)}

/* ==================================================================
   7. Accessibility
   ================================================================== */
@media (prefers-reduced-motion:reduce){
  .nv-hero::after,
  .nv-cta-dark::after,.nv-msup-sec::after,.nv-commit::after{
    animation:none!important}
  .nv-spot::after{display:none}
  .elementor-47 .elementor-button::after{display:none}
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
}
