/* Custom overrides that go beyond Tailwind utility classes */
body {
  -webkit-font-smoothing: antialiased;
}

/* ==========================================================================
   Brand texture + decorative graphics — recovered from the client-approved
   design reference (designrefrence/Home.png). texture-grid.png is a subtle
   tileable checkerboard used on every solid-green section; decorative-circle
   is the concentric lime ring used behind the hero photo and on service/
   icon cards, anchored to whichever corner fits (flip with .decorative-circle--bl
   etc.); ghost-text is the oversized faint section-name watermark behind
   "Premium Services".
   ========================================================================== */
.brand-texture {
  background-image: url('../images/texture-grid.png');
  background-repeat: repeat;
}

.decorative-circle {
  position: absolute;
  background-image: url('../images/decorative-circle.png');
  background-repeat: no-repeat;
  background-size: 100% 100%;
  pointer-events: none;
}
.decorative-circle--br { bottom: 0; right: 0; transform: scaleX(1) scaleY(1); }
.decorative-circle--bl { bottom: 0; left: 0; transform: scaleX(-1) scaleY(1); }

.ghost-text {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -38%);
  white-space: nowrap;
  font-weight: 800;
  color: #17301f;
  opacity: .05;
  pointer-events: none;
  line-height: 1;
  z-index: 0;
}

/* ==========================================================================
   Hero slide text entrance animations — admin picks one per slide from
   admin/hero-slide-edit.php's "Text Animation Style" dropdown, stored in
   hero_slides.text_animation. index.php renders the heading/subtitle/button
   wrapper with class="hero-text-anim" and data-animation="<the value>";
   the slider's JS toggles the .anim-play class on/off (with a reflow in
   between) each time a slide becomes active, so the animation replays on
   every rotation, not just once on page load.
   ========================================================================== */
.hero-text-anim:not([data-animation="none"]) > * { opacity: 0; }

.hero-text-anim.anim-play > *:nth-child(1) { animation-delay: 0s; }
.hero-text-anim.anim-play > *:nth-child(2) { animation-delay: .15s; }
.hero-text-anim.anim-play > *:nth-child(3) { animation-delay: .3s; }

.hero-text-anim.anim-play[data-animation="fade-in"] > * { animation: heroFadeIn .8s ease both; }
.hero-text-anim.anim-play[data-animation="fade-in-up"] > * { animation: heroFadeInUp .8s ease both; }
.hero-text-anim.anim-play[data-animation="fade-in-down"] > * { animation: heroFadeInDown .8s ease both; }
.hero-text-anim.anim-play[data-animation="slide-in-left"] > * { animation: heroSlideInLeft .8s ease both; }
.hero-text-anim.anim-play[data-animation="slide-in-right"] > * { animation: heroSlideInRight .8s ease both; }
.hero-text-anim.anim-play[data-animation="zoom-in"] > * { animation: heroZoomIn .8s ease both; }
.hero-text-anim.anim-play[data-animation="bounce-in"] > * { animation: heroBounceIn .9s ease both; }

@keyframes heroFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes heroFadeInUp {
  from { opacity: 0; transform: translateY(24px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes heroFadeInDown {
  from { opacity: 0; transform: translateY(-24px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes heroSlideInLeft {
  from { opacity: 0; transform: translateX(-40px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes heroSlideInRight {
  from { opacity: 0; transform: translateX(40px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes heroZoomIn {
  from { opacity: 0; transform: scale(.85); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes heroBounceIn {
  0% { opacity: 0; transform: scale(.7); }
  60% { opacity: 1; transform: scale(1.05); }
  80% { transform: scale(.97); }
  100% { transform: scale(1); }
}

/* ==========================================================================
   Scroll-reveal entrance animations — generic, site-wide version of the
   hero-slide animations above (same keyframes, reused). Any element with
   data-reveal="fade-in-up" (etc.) starts hidden; assets/js/scroll-reveal.js
   watches the page with an IntersectionObserver and adds .revealed the
   moment the element scrolls into view, optionally after data-reveal-delay
   milliseconds — matching the staggered fade/slide-in effect used across
   the reference design (designrefrence/Home.png + the live reference site).
   ========================================================================== */
[data-reveal] { opacity: 0; }
[data-reveal].revealed {
  opacity: 1;
  animation-duration: .8s;
  animation-timing-function: ease;
  animation-fill-mode: both;
}
[data-reveal="fade-in"].revealed { animation-name: heroFadeIn; }
[data-reveal="fade-in-up"].revealed { animation-name: heroFadeInUp; }
[data-reveal="fade-in-down"].revealed { animation-name: heroFadeInDown; }
[data-reveal="fade-in-left"].revealed { animation-name: heroSlideInLeft; }
[data-reveal="fade-in-right"].revealed { animation-name: heroSlideInRight; }
[data-reveal="zoom-in"].revealed { animation-name: heroZoomIn; }
[data-reveal="bounce-in"].revealed { animation-name: heroBounceIn; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; animation: none !important; }
}

/* ==========================================================================
   Infinite marquee — continuously scrolls a row right-to-left (new items
   enter from the right, exit on the left). Used by the Global Team flag
   strip. Markup must render the item list TWICE back-to-back inside
   .marquee-track so translateX(-50%) loops seamlessly with no visible seam;
   pauses on hover so it's readable if someone wants to stop and look.
   ========================================================================== */
.marquee-viewport { overflow: hidden; }
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee-scroll 25s linear infinite;
}
.marquee-viewport:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ==========================================================================
   Hero slider motion — Ken Burns zoom on the active slide's photo, animated
   progress-bar slide indicators (fill left-to-right over the 6s dwell time,
   replacing plain dots), and slow ambient floating blobs behind the text.
   All three are purely decorative; renderer.js/index.php just toggle classes.
   ========================================================================== */
@keyframes heroKenBurns {
  from { transform: scale(1); }
  to { transform: scale(1.12); }
}
.hero-slide.is-active .hero-slide-bg {
  animation: heroKenBurns 7s ease-out forwards;
}

@keyframes heroProgressFill {
  from { width: 0%; }
  to { width: 100%; }
}
.hero-progress-fill.is-filling {
  animation: heroProgressFill 6s linear forwards;
}

@keyframes heroFloat {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(10px, -20px); }
}
.hero-float-blob {
  animation: heroFloat 9s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .hero-slide.is-active .hero-slide-bg,
  .hero-progress-fill.is-filling,
  .hero-float-blob { animation: none; }
}
