/* ==========================================================================
   home.css
   Homepage hero overrides. Kept out of vdim.webflow.css, which is Webflow
   regenerated output - anything written there is lost on the next export.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero typography

   The uppercase treatment on .service-head is the brand look and is left
   alone. Only the justification is overridden: justified text without
   hyphenation opens visible rivers of white space in this paragraph, and the
   measure cap keeps the line length readable.
   -------------------------------------------------------------------------- */

.intro-div {
  text-align: left;
}

.sub-title {
  text-align: left;
  max-width: 46ch;      /* measure, not an arbitrary pixel width */
}

/* --------------------------------------------------------------------------
   Hero entrance, without JavaScript

   The hero used to ship as style="opacity:0" and was revealed only when
   Webflow's IX2 engine ran, so a blocked or slow webflow.js left the first
   screen blank. The inline style and data-w-id are gone from the markup and
   the motion lives here, so the hero paints from HTML and CSS alone.

   The image is deliberately excluded from the opacity fade. It is the LCP
   element, and LCP is recorded when the element actually paints - starting it
   at opacity 0 would push the metric out by the whole animation duration and
   undo the eager + fetchpriority="high" work in the markup. A transform still
   paints immediately, so it gets movement only.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .intro-div > .service-head.load-anim,
  .intro-div > .sub-title,
  .intro-div > .div-block-31 {
    animation: hero-rise .32s cubic-bezier(.22, .61, .36, 1) both;
  }

  .intro-div > .sub-title     { animation-delay: 80ms; }
  .intro-div > .div-block-31  { animation-delay: 160ms; }

  .intro-div > .img-wrapper {
    animation: hero-settle .32s cubic-bezier(.22, .61, .36, 1) 120ms both;
  }

  @keyframes hero-rise {
    from { opacity: 0; transform: translate3d(0, 16px, 0); }
    to   { opacity: 1; transform: none; }
  }

  /* No opacity here - see the LCP note above. */
  @keyframes hero-settle {
    from { transform: translate3d(0, 12px, 0); }
    to   { transform: none; }
  }
}

/* --------------------------------------------------------------------------
   Hover and focus

   .c-button has no visible focus ring in vdim.webflow.css, which leaves
   keyboard users with no idea where they are. The lift matches the
   translateY(-6px) idiom already used by .project-card.
   -------------------------------------------------------------------------- */

.c-button {
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}

.c-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px #23303426;
}

.c-button:focus-visible,
.service-learn-more:focus-visible,
.nav-link:focus-visible {
  outline: 2px solid #b29e84;
  outline-offset: 3px;
}

.main-service,
.choose-us {
  transition: transform .15s ease, box-shadow .15s ease;
}

.main-service:hover,
.choose-us:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px #2330341f;
}

@media (prefers-reduced-motion: reduce) {
  .c-button,
  .main-service,
  .choose-us {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Scroll reveals, as progressive enhancement

   The 4 "Why choose us?" cards and .f-section-large used to ship as inline
   opacity:0 with a 100px offset, revealed only by Webflow IX2. If that JS was
   blocked or errored, the content stayed invisible permanently.

   Inverted here: the default state below is fully visible, so no-JS means
   "no animation" rather than "no content". The animation is defined only
   under .reveal-ready, a class our own script adds once it is running, so it
   can never hide anything that JS is not about to reveal.
   -------------------------------------------------------------------------- */

/* !important is load-bearing here, not laziness.

   Webflow's IX2 interaction for these cards targets them by CLASS, not by the
   element's data-w-id:

       target: { selector: ".choose-us", appliesTo: "CLASS" }

   So stripping data-w-id from the markup did not stop it - webflow.js still
   finds them and writes inline `opacity: 0` at runtime, and an inline style
   outranks any class selector we can write. Without !important the cards stay
   invisible exactly as before.

   The default below therefore forces them visible, which is what makes the
   no-JS case safe: even if webflow.js hides them, this wins. */
.js-reveal {
  opacity: 1 !important;
  transform: none !important;
}

@media (prefers-reduced-motion: no-preference) {
  .reveal-ready .js-reveal {
    transition: opacity .4s ease-out, transform .4s cubic-bezier(.22, .61, .36, 1);
  }

  /* Only hidden once our own script is confirmed running and the element has
     not yet scrolled into view. */
  .reveal-ready .js-reveal:not(.is-revealed) {
    opacity: 0 !important;
    transform: translate3d(0, 24px, 0) !important;
  }
}

/* --------------------------------------------------------------------------
   Hero image
   -------------------------------------------------------------------------- */

.image-20 {
  display: block;
  width: 100%;
  height: auto;         /* honour the width/height attributes -> no layout shift */
}

/* --------------------------------------------------------------------------
   Horizontal overflow

   The "Why choose us?" marquee was dragging the whole document sideways
   (scrollWidth 1501 vs clientWidth 1425). The inner content was not the
   culprit - vdim.webflow.css already clips it with overflow: hidden. The
   element itself is the problem:

       .c-large-header { width: 100vw; max-width: 100vw; margin-left: -5vw; }

   100vw resolves to the full viewport *including* the scrollbar (1440) while
   the usable content area is only 1425, so a 100vw block always overhangs by
   the scrollbar width on a scrolling page. The -5vw pull made it worse.

   Constraining the marquee to its container removes the overflow outright and
   lines it up with the "Why choose us?" heading above it. Note this is
   deliberately not `body { overflow-x: hidden }` - that would create a scroll
   container and break the position: sticky CTA used elsewhere on the site.
   -------------------------------------------------------------------------- */

.c-large-header {
  width: 100%;
  max-width: 100%;
  margin-left: 0;
}

/* --------------------------------------------------------------------------
   Mobile: put the buttons above the fold

   Source order is H1 -> sub -> image -> CTAs, which pushed the primary button
   to y=727 on a 390x844 screen, in the bottom 14% and under the reCAPTCHA
   badge. Reordering to H1 -> sub -> CTAs -> image moves it to roughly y=460.
   Targeted by class because the Webflow w-node-* ids change on re-export.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .intro-div {
    display: flex;
    flex-direction: column;
  }

  .service-head.load-anim { order: 1; }
  .sub-title              { order: 2; }
  .div-block-31           { order: 3; margin-bottom: 28px; }
  .img-wrapper            { order: 4; }

  .sub-title {
    max-width: none;
  }

  /* Full-width stacked buttons are easier to hit than inline ones at this size */
  .div-block-31 {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
}

/* --------------------------------------------------------------------------
   Hero slideshow
   Slide 1 sits in normal flow so it still defines the box and remains the
   LCP element with no layout shift; the rest are stacked over it and fade.
   Without JS the first slide simply stays visible.
   -------------------------------------------------------------------------- */

.hero-slider {
  position: relative;
}

.hero-slide {
  opacity: 0;
  transition: opacity .9s ease;
}

.hero-slide:first-of-type {
  position: relative;
}

.hero-slide:not(:first-of-type) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-slide.is-active {
  opacity: 1;
}

.hero-slider__dots {
  position: absolute;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  display: flex;
  gap: 9px;
  z-index: 2;
}

.hero-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .45);
  cursor: pointer;
  transition: background .2s ease, transform .2s ease;
  -webkit-appearance: none;
  appearance: none;
}

.hero-dot:hover {
  background: rgba(255, 255, 255, .75);
}

.hero-dot.is-active {
  background: #fff;
  transform: scale(1.35);
}

.hero-dot:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .hero-slide {
    transition-duration: .01ms;
  }

  .hero-dot {
    transition-duration: .01ms;
  }
}

/* --------------------------------------------------------------------------
   Service images: always visible

   The three .image-home images were computing to opacity 0 and staying there.
   Webflow's IX2 targets them by CLASS (the same pattern documented above for
   .choose-us), so it writes inline opacity at runtime and no amount of
   class-selector CSS wins without !important.

   Routing them through .js-reveal did not hold either — with the reveal
   script running they kept resolving to 0, so rather than keep racing IX2
   they are taken out of the animation system altogether. These carry the
   actual service imagery, so being reliably visible matters more than
   fading in: an element-plus-class selector with !important, and animation
   and transition shut off so nothing can drive the value back down.
   -------------------------------------------------------------------------- */

img.image-home,
img.image-home-background {
  opacity: 1 !important;
  transform: none !important;
  animation: none !important;
  transition: none !important;
}

/* --------------------------------------------------------------------------
   Section banding, inverted for this page

   Webflow made the homepage's FIRST section a .section.background, which now
   carries the white band — so the hero was the one white screen on a site
   whose every other page opens on sand, with a visible seam right under the
   floating nav.

   Inverting the pair here (rather than re-classing five sections in the
   markup) puts the hero back on sand and keeps the alternation intact:
   sand, white, sand, white.
   -------------------------------------------------------------------------- */

.section.background {
  background-color: var(--vd-paper);
}

.section:not(.background) {
  background-color: #fff;
}
