/* =====================================================================
   EMVIGO HOME � HERO + REVEAL TEXT
   Single stylesheet. Paste into Elementor > Site Settings > Custom CSS.

   Layout, background and animation only. Typography, colours and spacing
   are set in the Elementor panel � the only type rules here are ones the
   panel cannot express (counter suffix, italic <i> in the title).

   Expected structure:

     Container  .emv-dark-band          <- canvas, background, full-bleed
     |-- HTML   .emv-runtime            <- canvas + scripts (FIRST child)
     |-- Container  #hero               <- CSS ID, not a class
     |   |-- Container  .emv-container
     |   |   \-- Container  .hero-content
     |   |       |-- Icon List    .hero-eyebrow
     |   |       |-- Heading      .hero-title
     |   |       |-- Text Editor  .hero-desc
     |   |       \-- Button       .btn-ghost
     |   \-- Grid   .emv-counters       <- sibling of .emv-container
     \-- Container  .emv-reveal-wrap
         \-- Container  .emv-reveal
             \-- 3x Text Editor  .emv-reveal-line

   Panel settings that matter:
     .emv-dark-band  -> Full Width, Padding 0, Overflow DEFAULT (not Hidden)
     #hero           -> Full Width, Padding 0, Min Height EMPTY
     .emv-reveal-wrap / .emv-reveal -> Background TRANSPARENT

   Everything is scoped to .emv-dark-band, #hero or .emv-reveal* � nothing
   here can reach your header, footer or any other page.
   ================================================================== */

/* =================================================================
   0. DARK BAND - shared wrapper around Hero + Reveal
   Holds the canvas so one particle field spans both sections and ends
   cleanly before section 3.

   Panel settings: Content Width = Full Width, Padding = 0,
   Layout > Additional Options > Overflow = Default.
   Overflow: Hidden here makes this the scroll container and the reveal
   section's sticky pin stops working.
   ============================================================== */

.emv-dark-band {
  position: relative;
  background-color: #040404;   /* fallback, so no white flash before JS */
  z-index: 1;                  /* below a sticky site header */
  width: 100%;
  max-width: 100%;
  margin-left: 0;
  margin-right: 0;
}

.emv-dark-band > .e-con-inner {
  width: 100%;
  max-width: none;
  padding: 0;
  gap: 0;
  display: block;
}

/* ---- particle canvas ----
   The canvases live in .emv-canvas-holder, which is absolutely positioned
   to fill the band. Being out of flow, it contributes no height, and the
   sticky canvases inside are constrained by IT � so they can never extend
   past the band onto the sections below.

   The earlier margin-bottom:-100vh approach failed because sticky is
   constrained by the MARGIN box: a -100vh bottom margin let the canvas
   keep sticking a full viewport past the band's real end.

   Do NOT add overflow:hidden here � that would make the holder a scroll
   container and the sticky canvases would stop moving. */
.emv-dark-band .emv-canvas-holder {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.emv-dark-band .emv-canvas-holder canvas {
  position: sticky;
  top: 0;
  display: block;
  width: 100%;
  height: 100vh;
  pointer-events: none;
}

/* Both canvases stack in the same sticky slot. */
.emv-dark-band #logo-canvas {
  margin-top: -100vh;   /* overlay the 2D field, not sit below it */
}

/* The HTML widget holding the canvas must not create a layout box. */
.emv-dark-band .emv-runtime,
.emv-dark-band .emv-runtime > .elementor-widget-container { display: contents; }

/* Both sections sit above the canvas and let it show through. */
.emv-dark-band > .e-con-inner > .e-con {
  position: relative;
  z-index: 2;
  background-color: transparent;
}

/* =================================================================
   1. SHARED - 1200px content width
   ============================================================== */

.emv-container {
  max-width: 1200px;
  width: calc(100% - 50px);
  margin: 0 auto;
}

@media (max-width: 1199px) {
  .emv-container { width: calc(100% - 100px); }
}

@media (max-width: 767px) {
  .emv-container { width: calc(100% - 40px); }
}

/* =================================================================
   2. HERO - layout only
   ============================================================== */

#hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  /* padding-top: 130px;         
  padding-bottom: 40px; */ 
}

/* @media (max-width: 1366px) {
  #hero { padding-top: 110px; padding-bottom: 30px; }
}

@media (max-width: 767px) {
  #hero { padding-top: 90px; padding-bottom: 24px; }
} */

/* Elementor's inner wrapper must be full width or the flex column
   collapses and the counters won't sit at the bottom. */
#hero > .e-con-inner {
  width: 100%;
  max-width: none;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1;
  gap: 0;
}

/* Push the counter row to the bottom of the viewport. */
#hero .emv-counters { margin-top: auto; }

@media (max-width: 1366px) {
  #hero .emv-counters { margin-top: 20px; }
}

/* OPTIONAL - the italic blue span in the title.
   Elementor's Heading colour control paints the whole heading, so the <i>
   needs its own rule. Delete if you don't use <i> in the title. */
#hero .hero-title .elementor-heading-title i,
#hero .hero-title .elementor-heading-title em {
  color: #0270fe;
  font-style: italic;
}

/* =================================================================
   3. REVEAL TEXT
   ============================================================== */

/* Tall outer container: its height IS the scroll distance the pin lasts.
   Transparent so the band's canvas shows through. */
.emv-reveal-wrap {
  position: relative;
  background-color: transparent;
  min-height: 210vh;
}

/* Inner container pins while the outer scrolls past. */
.emv-reveal {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.emv-reveal > .e-con-inner {
  width: 100%;
  display: flex;
  flex-direction: column;      /* three widgets stack, not sit in a row */
  align-items: center;
  justify-content: center;
}

/* Flex items default to min-width:auto, so a Text Editor won't shrink below
   its content width and the lines run off the right edge instead of wrapping.
   These two lines are what stop that. */
.emv-reveal > .e-con-inner > * {
  min-width: 0;
  width: 100%;
}

/* Lines. Three ways to build them, all supported:
   - THREE widgets (Text Editor or Heading), each class .emv-reveal-line  <- current
   - ONE Text Editor, class .emv-reveal-text, three paragraphs
   - ONE HTML widget, class .emv-reveal-text, three <span> elements

   Typography, colour and spacing are all yours in the Elementor panel.
   The only rules here are the ones the panel cannot express. */
.emv-reveal-text {
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
}

/* Only needed for the HTML-widget option: <span> is inline by default, so
   without this the three lines run together on one line. Paragraphs from a
   Text Editor are already block-level and are unaffected. */
.emv-reveal-text span { display: block; } 

/* ---- reveal animation ----
   Scroll-scrubbed: the script writes opacity / filter / transform inline on
   every frame, so each scroll position maps to exactly one state and the
   sequence reverses precisely when you scroll back up.

   Lines fade IN first-to-last, then OUT last-to-first.

   Visible by default. The script adds .emv-scrub before it takes over, so
   if it never runs you get three static lines rather than a blank screen. */
.emv-reveal-line,
.emv-reveal-text span,
.emv-reveal-text p {
  opacity: 1;
  filter: none;
  transform: none;
}

/* Transitions must be OFF while scrubbing � with the scroll position acting
   as the timeline, a transition on top of it causes lag and overshoot. */
.emv-reveal.emv-scrub .emv-reveal-line,
.emv-reveal.emv-scrub .emv-reveal-text span,
.emv-reveal.emv-scrub .emv-reveal-text p {
  transition: none;
  will-change: transform, opacity, filter;
}

/* =================================================================
   4. REDUCED MOTION
   ============================================================== */

@media (prefers-reduced-motion: reduce) {
  .emv-dark-band .emv-canvas-holder { display: none; }

  /* Scrubbing is motion; show the lines statically instead. */
  .emv-reveal.emv-scrub .emv-reveal-line,
  .emv-reveal.emv-scrub .emv-reveal-text span,
  .emv-reveal.emv-scrub .emv-reveal-text p {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }

  .emv-reveal { position: static; min-height: 0; }
  .emv-reveal-wrap { min-height: 0; }
}


/* =====================================================================
   5. DETAIL FIXES
   Things the Elementor panel has no control for.
   ================================================================== */
/* ---- 1. Counter suffix: "42 Months", not "42Months" ----
   Elementor's Counter has ONE typography control covering the whole number
   wrapper, so the suffix inherits the 22px bold. The design wants it small,
   lighter, and baseline-aligned. */
#hero .emv-counters .elementor-counter-number-wrapper {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
}

#hero .emv-counters .elementor-counter-number-suffix {
  font-size: 13px;
  font-weight: 400;
  opacity: .8;
  flex: none;
}

/* A "+" should stay tight to the digits � no gap, full size. */
#hero .emv-counters .elementor-counter-number-suffix:not(:empty) { margin-left: 0; }

@media (max-width: 1366px) {
  #hero .emv-counters .elementor-counter-number-suffix { font-size: 11px; }
}

/* ---- 2. Vertical dividers between counters ----
   The design used <div class="divider"> spacers. A Grid has no spacer
   elements, so each counter after the first draws its own. */
#hero .emv-counters > * {
  position: relative;
}

#hero .emv-counters > * + *::before {
  content: "";
  position: absolute;
  left: -15px;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 70px;
  background: linear-gradient(352deg,
    rgba(255,255,255,0) 0%,
    rgb(255,255,255) 50%,
    rgba(255,255,255,0) 100%);
}

@media (max-width: 1366px) {
  #hero .emv-counters > * + *::before { height: 50px; left: -8px; }
}

@media (max-width: 767px) {
  #hero .emv-counters > * + *::before { display: none; }
}

/* ---- 3. Counter row pinned to the bottom of the viewport ----
   Reinforces the base rules in case a panel Min Height gets set on #hero. */
#hero > .e-con-inner { min-height: inherit; }


/* =====================================================================
   EMVIGO � INDUSTRIES (section 6)
   Append to emvigo-hero.css, or paste as its own block.

   Structure:

     Container  .what-we-do                  <- black, position: relative
     |-- HTML   .emv-spline                  <- the 3D robot iframe
     \-- Container  .emv-container            <- 1200px, sits above iframe
         |-- Container  .title-block
         |   |-- Container            (Heading + Text Editor)
         |   \-- Button  .boder-btn
         \-- Container  .what-we-do-list-wrap
             |-- Icon List  .what-we-do-list
             \-- Icon List  .what-we-do-list we-do-list-right

   Panel: .what-we-do -> Full Width, Padding 0.
          Both Icon Lists -> Layout Default (vertical), icons left EMPTY.
   ================================================================== */

.what-we-do {
  position: relative;
  z-index: 9;
  padding: 70px 0 0 0;
  background: #000;
  overflow: hidden;
}

/* ---- FULL-BLEED ----
   Same two options as the hero band. Default fills the parent, which is
   correct on an Elementor Full Width page template. */
.what-we-do {
  width: 100%;
  max-width: 100%;
  margin-left: 0;
  margin-right: 0;
}

.what-we-do > .e-con-inner {
  position: relative;
  z-index: 99;
  max-width: none;
  padding: 0;
}

/* ---- 3D robot ----
   Absolutely positioned behind everything, 110% tall so the crop sits
   below the fold as in the design.

   pointer-events is ON so the robot tracks the cursor. The scroll-hijack
   problem that normally comes with that is handled in JS instead: the
   script switches pointer-events off while the page is scrolling and back
   on ~180ms after it stops. Hover works; the wheel is never captured. */
.what-we-do .emv-spline {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: auto;
}

/* Added by the script during scroll. */
.what-we-do .emv-spline.emv-scrolling,
.what-we-do .emv-spline.emv-scrolling iframe {
  pointer-events: none;
}

/* Links and buttons must stay clickable above the robot. */
.what-we-do .emv-container,
.what-we-do .title-block,
.what-we-do .what-we-do-list-wrap {
  pointer-events: none;
}

.what-we-do .emv-container a,
.what-we-do .emv-container button,
.what-we-do .what-we-do-list .elementor-icon-list-item {
  pointer-events: auto;
}

.what-we-do .emv-spline > .elementor-widget-container {
  height: 100%;
}

.what-we-do .emv-spline iframe {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 110%;
  border: 0;
  object-fit: cover;
  pointer-events: auto;

  /* Promote the iframe to its own compositor layer. Without this the
     browser repaints the section's whole stacking context as it scrolls
     past, which is the other half of the jank. */
  transform: translateZ(0);
  backface-visibility: hidden;

  /* Fades in once loaded, so you never see a blank rectangle pop. */
  opacity: 0;
  transition: opacity .6s ease;
}

.what-we-do .emv-spline iframe.is-ready { opacity: 1; }

/* Isolate the section so layout and paint inside it can't invalidate the
   rest of the page while scrolling. */
.what-we-do {
  contain: paint;
}

@media (prefers-reduced-motion: reduce) {
  .what-we-do .emv-spline iframe { transition: none; }
}

/* ---- 1200px content column ---- */
.what-we-do .emv-container {
  position: relative;
  z-index: 99;
  max-width: 1200px;
  width: calc(100% - 50px);
  margin: 0 auto;
  height: 100%;
}

@media (max-width: 1199px) { .what-we-do .emv-container { width: calc(100% - 100px); } }
@media (max-width: 767px)  { .what-we-do .emv-container { width: calc(100% - 40px); } }

/* ---- title block ---- */
.what-we-do .title-block {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  z-index: 99;
  gap: 24px;
}

.what-we-do .title-block > .e-con-inner > * { max-width: 540px; }

@media (max-width: 767px) {
  .what-we-do .title-block {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }
}

/* Outline button � Elementor's Button widget can't do the fill-on-hover
   swap to a different border colour in one control. */
.what-we-do .boder-btn .elementor-button {
  display: inline-block;
  padding: 9px 24px 10px 24px;
  border-radius: 10px;
  border: 1px solid #FFF;
  background: transparent;
  color: #FFF;
  text-decoration: none;
  transition: all 0.3s ease;
}

.what-we-do .boder-btn .elementor-button:hover {
  background-color: #0350FE;
  border-color: #0350FE;
  color: #FFF;
}

/* ---- the two link columns ---- */
.what-we-do .what-we-do-list-wrap {
  height: 70vh;
  position: relative;
  z-index: 9;
  gap: 20px;
}

@media (max-width: 1024px) {
  .what-we-do .what-we-do-list-wrap { height: 55vh; }
}

@media (max-width: 767px) {
  .what-we-do .what-we-do-list-wrap {
    height: auto;
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
    padding: 40px 0 60px;
  }
}

/* Icon List renders <ul><li><a> � the design's own selectors, so most of
   this maps straight across. */
.what-we-do .what-we-do-list .elementor-icon-list-items {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: flex-start;
  position: relative;
  z-index: 9;
  padding: 0;
  margin: 0;
}

.what-we-do .we-do-list-right .elementor-icon-list-items {
  justify-content: flex-end;
  margin: auto;
  margin-right: 0;
}

.what-we-do .what-we-do-list .elementor-icon-list-item {
  margin: 0;
  padding: 0;
}

/* The pill itself. Elementor makes the <a> a flex row for its icon slot �
   overridden to a centred block, as designed. */
.what-we-do .what-we-do-list .elementor-icon-list-item > a {
  min-width: 290px;
  padding: 14px 20px;
  border-radius: 10px;
  background: #191717;
  color: #FFF;
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  line-height: 24px;
  letter-spacing: -0.16px;
  text-transform: uppercase;
  display: block;
  transition: all 0.3s ease;
}

.what-we-do .what-we-do-list .elementor-icon-list-item > a:hover {
  background: linear-gradient(90deg, #019FFD 0%, #0350FE 100%);
}

/* No icons in this design � hide the slot so text centres properly. */
.what-we-do .what-we-do-list .elementor-icon-list-icon { display: none; }

.what-we-do .what-we-do-list .elementor-icon-list-text {
  padding: 0;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  width: 100%;
}

@media (max-width: 1366px) {
  .what-we-do .what-we-do-list .elementor-icon-list-item > a {
    min-width: 240px;
    font-size: 13px;
    line-height: 1.5;
  }
}

@media (max-width: 767px) {
  .what-we-do .what-we-do-list .elementor-icon-list-items,
  .what-we-do .we-do-list-right .elementor-icon-list-items {
    margin: 0;
    justify-content: flex-start;
  }
  .what-we-do .what-we-do-list .elementor-icon-list-item > a {
    min-width: 0;
    width: 100%;
  }
}

/* =====================================================================
   EMVIGO � TESTIMONIALS (section 7)
   For the Elementor Pro CAROUSEL widget with free-form slides
   (Icon + Text Editor + Author Box).

   Structure:

     Container  .testimonial-section
     |-- HTML   .emv-cursor-runtime            <- follow-cursor script
     \-- Container  .emv-container
         |-- Container  .testimonial-header
         |   |-- Container        (Heading + Text Editor)
         |   \-- Button           .gradient-btn
         \-- Carousel   .testimonial-carousel
             \-- (each Slide) Container  .testimonial-card
                 |-- Icon         .tm-quote
                 |-- Text Editor  .tm-text
                 \-- Author Box   .tm-author

   Card background, padding, radius and all typography are set in the
   Elementor panel. Only what the panel can't express lives here.
   ================================================================== */

.testimonial-section {
  position: relative;
  width: 100%;
  padding: 80px 0;
  background: #fff;
  z-index: 11;
  overflow: hidden;
}

@media (max-width: 1366px) { .testimonial-section { padding: 60px 0; } }
@media (max-width: 767px)  { .testimonial-section { padding: 50px 0 80px; } }

.testimonial-section > .e-con-inner { max-width: none; padding: 0; }

.testimonial-section .emv-container {
  max-width: 1200px;
  width: calc(100% - 50px);
  margin: 0 auto;
}

@media (max-width: 1199px) { .testimonial-section .emv-container { width: calc(100% - 100px); } }
@media (max-width: 767px)  { .testimonial-section .emv-container { width: calc(100% - 40px); } }

/* ---- header row ---- */
.testimonial-section .testimonial-header {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
}

@media (max-width: 767px) {
  .testimonial-section .testimonial-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
  }
}

/* Gradient-border button � no Button widget equivalent. */
.testimonial-section .gradient-btn .elementor-button {
  display: inline-block;
  border: 2px solid transparent;
  border-radius: 10px;
  background: linear-gradient(#fff, #fff) padding-box,
              linear-gradient(90deg, #019FFD 0%, #0350FE 100%) border-box;
  padding: 9px 24px 10px 24px;
  transition: all 0.4s ease;
  text-decoration: none;
}

.testimonial-section .gradient-btn .elementor-button:hover {
  background: linear-gradient(90deg, #019FFD 0%, #0350FE 100%) padding-box,
              linear-gradient(90deg, #019FFD 0%, #0350FE 100%) border-box;
  color: #fff !important;
}

/* ---- carousel shell ---- */
.testimonial-section .testimonial-carousel {
  position: relative;
  margin-top: 40px;
  cursor: none;          /* replaced by the custom cursor */
}

@media (hover: none), (pointer: coarse) {
  .testimonial-section .testimonial-carousel { cursor: auto; }
}

/* Arrows are driven programmatically by the cursor script, so they're
   hidden rather than disabled � the widget still needs to render them. */
.testimonial-section .elementor-swiper-button,
.testimonial-section .swiper-button-prev,
.testimonial-section .swiper-button-next {
  opacity: 0;
  pointer-events: none;
}

/* Equal-height slides so cards line up regardless of quote length. */
.testimonial-section .swiper-slide { height: auto; }

.testimonial-section .swiper-slide > .e-con,
.testimonial-section .testimonial-card { height: 100%; }

/* ---- focus effect ----
   The design dims all but the centred card. With 3 per view the middle
   slide is .swiper-slide-next in Swiper's DOM (NOT -active, which is the
   leftmost). Change this if you use a different slides-per-view. */
.testimonial-section .testimonial-card {
  opacity: 0.5;
  transition: opacity 0.5s ease, box-shadow 0.4s ease;
}

.testimonial-section .swiper-slide-next .testimonial-card { opacity: 1; }

.testimonial-section .testimonial-card:hover {
  box-shadow: 0 8px 32px rgba(3, 80, 254, 0.06);
}

@media (max-width: 1024px) {
  /* 2 per view: highlight the first visible instead. */
  .testimonial-section .swiper-slide-next .testimonial-card { opacity: 0.5; }
  .testimonial-section .swiper-slide-active .testimonial-card { opacity: 1; }
}

@media (max-width: 767px) {
  .testimonial-section .testimonial-card { opacity: 1; }
}

/* ---- quote text ----
   min-height keeps card heights even when quotes differ in length.
   Raise it if your real quotes run longer than the samples. */
.testimonial-section .tm-text { min-height: 75px; }

@media (max-width: 767px) {
  .testimonial-section .tm-text { min-height: 0; }
}

/* ---- author box ----
   Elementor's Author Box has no avatar-size control below 100px and
   floats the avatar; this pins it to the design's 42px inline row. */
.testimonial-section .tm-author .elementor-author-box {
  display: flex;
  align-items: center;
  gap: 16px;
  text-align: left;
}

.testimonial-section .tm-author .elementor-author-box__avatar {
  margin: 0;
  flex: none;
}

.testimonial-section .tm-author .elementor-author-box__avatar img {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.testimonial-section .tm-author .elementor-author-box__text { margin: 0; }

.testimonial-section .tm-author .elementor-author-box__name { margin-bottom: 2px; }

.testimonial-section .tm-author .elementor-author-box__bio { margin: 0; }

/* ---- floating cursor ---- */
.testimonial-section .testimonial-cursor {
  position: absolute;
  top: 0;
  left: 0;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: rgba(3, 80, 254, 0.85);
  border: 1.5px solid rgba(255, 255, 255, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 50;
  opacity: 0;
  transform: scale(0.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 4px 24px rgba(3, 80, 254, 0.35);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.testimonial-section .testimonial-cursor.is-visible {
  opacity: 1;
  transform: scale(1);
}

.testimonial-section .testimonial-cursor .cursor-arrow { display: none; }
.testimonial-section .testimonial-cursor.dir-left  .cursor-arrow--left  { display: block; }
.testimonial-section .testimonial-cursor.dir-right .cursor-arrow--right { display: block; }

@media (hover: none), (pointer: coarse) {
  .testimonial-section .testimonial-cursor { display: none !important; }
}