/* ============================================================
   site-animations.css
   Centralized, NON-OWL animations & transitions only
   (Keep owl animations in your owl-specific CSS files)
   ============================================================ */

/* -------- Global animation props / tokens -------- */
@property --ang {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

:root {
  --accent: #00d5ff; /* reused by multiple effects */
}

/* ============================================================
   1) HERO: rating stars twinkle
   ============================================================ */
.hero-rating .star {
  display: inline-block;
  animation: starTwinkle 3.8s ease-in-out infinite;
  will-change: transform, filter;
}

/* sequence the delays across the four visible stars */
.hero-rating .star:nth-child(1){ animation-delay: 0s;   }
.hero-rating .star:nth-child(2){ animation-delay: .35s; }
.hero-rating .star:nth-child(3){ animation-delay: .7s;  }
.hero-rating .star:nth-child(4){ animation-delay: 1.05s;}

@keyframes starTwinkle {
  0%, 12%, 100% {
    transform: scale(1);
    filter: brightness(1) drop-shadow(0 0 0 rgba(0,213,255,0));
  }
  16%, 20% {
    transform: scale(1.06);
    filter: brightness(1.25) drop-shadow(0 0 6px rgba(0,213,255,.35));
  }
  28% {
    transform: scale(1);
    filter: brightness(1) drop-shadow(0 0 0 rgba(0,213,255,0));
  }
}

@media (prefers-reduced-motion: reduce){
  .hero-rating .star { animation: none; }
}

/* ============================================================
   2) HERO: ambient spotlight (mouse-reactive, JS sets --hx/--hy)
   ============================================================ */
.hero {
  position: relative;
  overflow: visible; /* allow soft glow to extend past bottom */
}

@media (pointer: fine){
  .hero::before{
    content:"";
    position:absolute; inset:0;
    pointer-events:none;
    background:
      radial-gradient(600px 420px at var(--hx,50%) var(--hy,40%),
        rgba(0,213,255,.08), transparent 60%),
      radial-gradient(800px 520px at calc((var(--hx,50%))*1.05) calc((var(--hy,40%))*1.1),
        rgba(40,224,184,.05), transparent 65%);
    /* fade out before the bottom edge to avoid a hard cut */
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 86%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 86%, transparent 100%);
    opacity: 0;
    transition: opacity .28s ease;
  }

  .hero.hover-light::before{ opacity: 1; }
}

/* reduced-motion fallback (static glow) */
@media (prefers-reduced-motion: reduce){
  .hero::before{
    content:""; position:absolute; inset:-10vh -2vw -14vh; pointer-events:none;
    background: radial-gradient(700px 480px at 50% 40%, rgba(0,213,255,.05), transparent 60%);
    opacity:.8;
  }
}

/* ============================================================
   3) HERO: headline clip-reveal (JS toggles .in per .line)
   ============================================================ */
.hero h1 { position: relative; }

.hero h1 .line {
  display: block;
  overflow: hidden;     /* acts as the clip container */
}

.hero h1 .line-inner {
  display: block;
  transform: translateY(18px);
  filter: blur(6px);
  opacity: 0;
  transition:
    transform 600ms cubic-bezier(.22,.61,.36,1),
    filter    600ms cubic-bezier(.22,.61,.36,1),
    opacity   600ms cubic-bezier(.22,.61,.36,1);
  will-change: transform, filter, opacity;
}

/* toggled by JS when line enters view */
.hero h1 .line.in .line-inner {
  transform: translateY(0);
  filter: blur(0);
  opacity: 1;
}

/* tiny stagger between lines */
.hero h1 .line:nth-child(2) .line-inner { transition-delay: .08s; }

@media (prefers-reduced-motion: reduce){
  .hero h1 .line-inner,
  .hero h1 .line.in .line-inner {
    transform: none; filter: none; opacity: 1; transition: none;
  }
}

/* ============================================================
   4) SERVICES: Ultra-Premium card effect (ring + cursor light)
   ============================================================ */
.service-card{
  position: relative;
  isolation: isolate;              /* keep glows on this card only */
  transform: translateZ(0);        /* new layer for perf */
  transition:
    transform .24s cubic-bezier(.22,.61,.36,1),
    box-shadow .24s cubic-bezier(.22,.61,.36,1);
  /* cursor light position (updated via JS) */
  --mx: 50%;
  --my: 50%;
}

/* lift */
.service-card:hover,
.service-card:focus-within{
  transform: translateY(-6px);
  box-shadow: 0 18px 48px rgba(0,0,0,.35);
}

/* LAYER 1 — Animated conic ring around the edge */
.service-card::before{
  content: "";
  position: absolute;
  inset: -1px;                      /* sit on the edge */
  border-radius: inherit;

  /* Draw only the stroke with a mask */
  background:
    conic-gradient(from 0deg,
      var(--accent) 0 var(--ang),
      transparent var(--ang) 360deg);

  /* WebKit/Safari + Chromium: keep only a 1px ring */
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;

  /* Standard syntax (Firefox and modern engines) */
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;

  padding: 1px;                     /* ring thickness */
  opacity: .38;
  pointer-events: none;
  transition:
    --ang 720ms cubic-bezier(.22,.61,.36,1),
    opacity .24s ease;
}
.service-card:hover::before,
.service-card:focus-within::before{
  --ang: 360deg;                    /* animate the sweep */
  opacity: .60;
}

/* LAYERS 2–4 — cursor light + subtle sheen + ambient halo */
.service-card::after{
  content:"";
  position:absolute; inset:-2px;
  border-radius: inherit;
  pointer-events:none;

  /* TOP: cursor-reactive teal light (soft)
     MID: diagonal sheen (very subtle whites)
     BOT: ambient halo */
  background:
    radial-gradient(120px 120px at var(--mx) var(--my),
      rgba(0,213,255,.10), transparent 60%),
    linear-gradient(110deg,
      transparent 44%,
      rgba(255,255,255,.08) 50%,
      rgba(255,255,255,.02) 56%,
      transparent 62%),
    radial-gradient(120% 160% at 50% 110%,
      rgba(0,213,255,.05), transparent 60%);

  background-size:
    auto,                 /* cursor light */
    220% 220%,            /* sheen travel area */
    100% 100%;            /* halo */
  background-position:
    var(--mx) var(--my),
    -120% 0%,             /* start off-screen left */
    50% 100%;

  opacity: 0;
  filter: blur(.2px);
  transition:
    opacity .26s ease,
    background-position 900ms cubic-bezier(.22,.61,.36,1);
}
.service-card:hover::after,
.service-card:focus-within::after{
  opacity: 1;
  /* sheen runs once per hover; cursor light keeps tracking */
  background-position:
    var(--mx) var(--my),
    120% 0%,
    50% 100%;
}

/* Reduced motion: static tasteful state */
@media (prefers-reduced-motion: reduce){
  .service-card{ transform:none; box-shadow:none; }
  .service-card::before{ transition:none; --ang:360deg; opacity:.5; }
  .service-card::after{
    transition:none; opacity:.55;
    background-position: 50% 50%, 50% 0%, 50% 100%;
  }
}

/* ============================================================
   5) TESTIMONIALS: 3D tilt + reveal composition (JS sets --rx/--ry/--mx/--my)
   ============================================================ */
@media (pointer: fine) {
  /* base 3D */
  .testimonial-card{
    position: relative;
    transform: perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
    transform-style: preserve-3d;
    transition: transform 180ms cubic-bezier(.22,.61,.36,1), box-shadow 180ms ease;
    will-change: transform;
  }
  .testimonial-card:hover{ box-shadow: 0 18px 48px rgba(0,0,0,.35); }

  /* COMPOSE with reveal: keep the same 3D + add the reveal translate */
  .testimonial-card.reveal{
    transform: perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(16px);
  }
  .testimonial-card.reveal.in{
    transform: perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(0);
  }

  /* full-card soft highlight that follows cursor */
  .testimonial-card::after{
    content:"";
    position:absolute; inset:-1px; border-radius: inherit;
    pointer-events:none;
    background: radial-gradient(180px 180px at var(--mx,50%) var(--my,50%),
                 rgba(255,255,255,.08), transparent 60%);
    opacity: 0; filter: blur(.3px);
    transition: opacity 160ms ease;
  }
  .testimonial-card:hover::after{ opacity: 1; }
}

/* reduce motion: keep flat */
@media (prefers-reduced-motion: reduce){
  .testimonial-card{ transform:none !important; transition:none !important; }
  .testimonial-card::after{ display:none !important; }
}

/* ============================================================
   6) Generic scroll-reveal utility (optional; used by JS)
   ============================================================ */
/* If you’re using .reveal on groups, this gives them a baseline animation.
   JS toggles .in to play the reveal; rows enter/leave together. */
.reveal { 
  opacity: 0; 
  transform: translateY(16px); 
  transition: opacity .5s ease, transform .5s ease; 
}
.reveal.in { 
  opacity: 1; 
  transform: translateY(0); 
}

@media (prefers-reduced-motion: reduce){
  .reveal, .reveal.in { opacity:1; transform:none; transition:none; }
}

/* ============================================================
   7) Magnetic hover helper (buttons/links with .magnetic-inner)
   ============================================================ */
.magnetic .magnetic-inner {
  transition: transform .18s ease;
  will-change: transform;
}
