/* ==========================================================================
   First Page Fox — 3D, motion and map-animation layer
   --------------------------------------------------------------------------
   Loaded after style.css. Everything here is additive and hooks onto class
   names that already exist in the markup, so all 20 pages pick it up without
   any per-page edits.

   Every effect is disabled under `prefers-reduced-motion` at the bottom of
   this file.
   ========================================================================== */

:root {
  --ease-out-quint: cubic-bezier(.22, 1, .36, 1);
  --ease-spring:    cubic-bezier(.34, 1.56, .64, 1);
  --depth: 1100px;
}

/* ==========================================================================
   1. Scroll progress bar (injected by effects.js)
   ========================================================================== */
.scroll-progress {
  position: fixed;
  inset: 0 auto auto 0;
  z-index: 200;
  height: 3px;
  width: 100%;
  transform: scaleX(var(--progress, 0));
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--brand) 0%, var(--accent) 60%, #22d3ee 100%);
  box-shadow: 0 0 12px rgba(79, 70, 229, .55);
  pointer-events: none;
  will-change: transform;
}

/* ==========================================================================
   2. Ambient depth — drifting aurora orbs behind hero and page headers
   ========================================================================== */
.hero, .page-head, .cta-band, .section--ink { position: relative; }
.page-head { overflow: hidden; }

.hero::before,
.page-head::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto;
  height: 130%;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(38% 44% at 18% 28%, rgba(99, 102, 241, .34), transparent 68%),
    radial-gradient(34% 40% at 82% 18%, rgba(6, 182, 212, .30), transparent 66%),
    radial-gradient(30% 36% at 62% 74%, rgba(168, 85, 247, .22), transparent 68%);
  filter: blur(28px);
  animation: aurora 22s ease-in-out infinite alternate;
}
.page-head::before { animation-duration: 30s; opacity: .8; }
.page-head > .container { position: relative; z-index: 1; }

@keyframes aurora {
  0%   { transform: translate3d(0, 0, 0)        scale(1);    }
  33%  { transform: translate3d(4%, -3%, 0)     scale(1.09); }
  66%  { transform: translate3d(-3%, 3%, 0)     scale(.96);  }
  100% { transform: translate3d(2%, -2%, 0)     scale(1.05); }
}

/* Floating light orbs in the dark CTA band */
.cta-band::before,
.cta-band::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  filter: blur(48px);
}
.cta-band::before {
  width: 320px; height: 320px;
  top: -120px; left: -80px;
  background: radial-gradient(circle, rgba(99, 102, 241, .75), transparent 70%);
  animation: float-orb 16s ease-in-out infinite;
}
.cta-band::after {
  width: 280px; height: 280px;
  bottom: -110px; right: -60px;
  background: radial-gradient(circle, rgba(6, 182, 212, .6), transparent 70%);
  animation: float-orb 20s ease-in-out infinite reverse;
}
.cta-band > * { position: relative; z-index: 1; }

@keyframes float-orb {
  0%, 100% { transform: translate3d(0, 0, 0)      scale(1);   }
  50%      { transform: translate3d(40px, 30px, 0) scale(1.18); }
}

/* ==========================================================================
   3. 3D reveal on scroll — replaces the flat translateY from style.css
   ========================================================================== */
.reveal {
  transform: perspective(var(--depth)) translate3d(0, 30px, -40px) rotateX(8deg);
  transform-origin: 50% 100%;
  transition:
    opacity   .7s var(--ease-out-quint),
    transform .8s var(--ease-out-quint);
  will-change: transform, opacity;
}
.reveal.is-visible {
  transform: perspective(var(--depth)) translate3d(0, 0, 0) rotateX(0deg);
}

/* ==========================================================================
   4. 3D tilt — pointer-tracked. effects.js sets --rx / --ry / --mx / --my.
   ========================================================================== */
.tilt {
  transform-style: preserve-3d;
  transition: transform .45s var(--ease-out-quint), box-shadow .45s ease, border-color .3s ease;
  will-change: transform;
}
.tilt.is-tilting {
  transition: transform .12s linear, box-shadow .3s ease, border-color .3s ease;
}

/* One transform for the whole tilt family, so nothing fights the base styles. */
.card.tilt,
.plan.tilt,
.quote.tilt,
.case.tilt,
.step.tilt,
.city-card.tilt {
  transform:
    perspective(var(--depth))
    rotateX(var(--rx, 0deg))
    rotateY(var(--ry, 0deg))
    translate3d(0, var(--lift, 0px), 0);
}

.card--hover.tilt:hover,
.plan.tilt:hover,
.quote.tilt:hover,
.case.tilt:hover,
.step.tilt:hover,
.city-card.tilt:hover {
  --lift: -6px;
  box-shadow: var(--shadow-lg);
  border-color: var(--brand-300);
}

/* Cursor-following sheen inside tilted cards */
.tilt.has-sheen::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .35s ease;
  background: radial-gradient(
    320px circle at var(--mx, 50%) var(--my, 50%),
    rgba(99, 102, 241, .13),
    transparent 62%
  );
}
.tilt.has-sheen { position: relative; overflow: hidden; }
.tilt.has-sheen:hover::after { opacity: 1; }

/* Push inner content forward so the parallax reads as real depth */
.card.tilt > *,
.plan.tilt > * { transform: translateZ(18px); }
.card.tilt .card__icon { transform: translateZ(38px); }

/* ==========================================================================
   5. Logo — SVG mark with a 3D flip
   ========================================================================== */
.logo {
  perspective: 600px;
  transition: transform .4s var(--ease-out-quint);
}
.logo__mark {
  background-image:
    url("../img/fox-white.svg"),
    linear-gradient(135deg, #6366f1 0%, #4f46e5 52%, #06b6d4 100%);
  background-size: 76% 76%, cover;
  background-position: center, center;
  background-repeat: no-repeat;
  font-size: 0;                 /* hides the "S" fallback character */
  color: transparent;
  transform-style: preserve-3d;
  transition: transform .65s var(--ease-spring), box-shadow .4s ease;
  animation: mark-breathe 6s ease-in-out infinite;
}
.logo:hover .logo__mark {
  transform: rotateY(360deg) scale(1.08);
  box-shadow: 0 8px 20px -3px rgba(79, 70, 229, .65);
  animation-play-state: paused;
}
.site-footer .logo__mark { animation: none; }

@keyframes mark-breathe {
  0%, 100% { transform: translateY(0)     rotateX(0deg);   }
  50%      { transform: translateY(-2.5px) rotateX(9deg);  }
}

/* ==========================================================================
   6. Buttons — 3D press and a travelling shine
   ========================================================================== */
.btn {
  position: relative;
  overflow: hidden;
  transform-style: preserve-3d;
}
.btn > * { position: relative; z-index: 1; }

.btn--primary::before,
.btn--light::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 -70%;
  width: 55%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .42), transparent);
  transform: skewX(-22deg);
  transition: left .65s var(--ease-out-quint);
}
.btn--primary:hover::before,
.btn--light:hover::before { left: 130%; }

.btn--primary:hover { transform: translateY(-3px) scale(1.02); }
.btn:active { transform: translateY(1px) scale(.985); }

/* Magnetic pull — effects.js sets --bx / --by on large buttons */
.btn--lg { transition: transform .3s var(--ease-out-quint), box-shadow .3s ease, background .2s ease; }
.btn--lg.is-magnetic { transform: translate3d(var(--bx, 0px), var(--by, 0px), 0) scale(1.03); }

/* ==========================================================================
   7. Gradient text — slow animated sweep
   ========================================================================== */
.hero h1 .grad,
.stat__num {
  background-size: 220% 100%;
  animation: grad-pan 9s ease-in-out infinite;
}
@keyframes grad-pan {
  0%, 100% { background-position:   0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* ==========================================================================
   8. Header — depth on scroll
   ========================================================================== */
.site-header { transition: background .3s ease, border-color .3s ease, box-shadow .3s ease; }
.site-header.is-stuck {
  background: rgba(255, 255, 255, .82);
  box-shadow: 0 4px 24px -8px rgba(16, 20, 45, .18);
}
.nav__links a {
  position: relative;
  transition: color .2s ease, transform .2s var(--ease-out-quint);
}
.nav__links a::after {
  content: "";
  position: absolute;
  left: 14px; right: 14px; bottom: 3px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .32s var(--ease-out-quint);
}
.nav__links a:hover::after,
.nav__links a[aria-current="page"]::after { transform: scaleX(1); }
.nav__links a:hover { transform: translateY(-1px); }
.nav__links .btn::after { display: none; }

/* ==========================================================================
   9. MAP ANIMATION — the geo-grid scan
   --------------------------------------------------------------------------
   A tilted 3D map plane with a rotating radar sweep, drawn routes and rank
   pins that pop in sequence. This mirrors the geo-grid scan we actually sell.
   ========================================================================== */
.geo {
  position: absolute;
  inset: auto -6% -14% -6%;
  height: 320px;
  perspective: 1200px;
  perspective-origin: 50% 0%;
  pointer-events: none;
  z-index: 0;
}
.geo__plane {
  position: absolute;
  inset: 0;
  transform: rotateX(64deg) rotateZ(-18deg) scale(1.35);
  transform-style: preserve-3d;
  border-radius: 24px;
  overflow: hidden;
  background:
    radial-gradient(60% 60% at 50% 50%, rgba(79, 70, 229, .10), transparent 72%),
    var(--surface-2);
  mask-image: radial-gradient(72% 70% at 50% 42%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(72% 70% at 50% 42%, #000 30%, transparent 78%);
}

/* Streets grid, slowly drifting */
.geo__grid {
  position: absolute;
  inset: -50%;
  background-image:
    linear-gradient(rgba(79, 70, 229, .17) 1.5px, transparent 1.5px),
    linear-gradient(90deg, rgba(79, 70, 229, .17) 1.5px, transparent 1.5px),
    linear-gradient(rgba(79, 70, 229, .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(79, 70, 229, .07) 1px, transparent 1px);
  background-size: 96px 96px, 96px 96px, 24px 24px, 24px 24px;
  animation: grid-drift 26s linear infinite;
}
@keyframes grid-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(96px, 96px, 0); }
}

/* Radar sweep */
.geo__radar {
  position: absolute;
  top: 50%; left: 50%;
  width: 150%; aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    rgba(6, 182, 212, .34) 0deg,
    rgba(6, 182, 212, .12) 24deg,
    transparent 62deg,
    transparent 360deg
  );
  animation: radar-sweep 5.5s linear infinite;
}
@keyframes radar-sweep {
  to { rotate: 360deg; }
}

/* Expanding range rings */
.geo__ring {
  position: absolute;
  top: 50%; left: 50%;
  width: 90px; aspect-ratio: 1;
  translate: -50% -50%;
  border: 1.5px solid rgba(6, 182, 212, .5);
  border-radius: 50%;
  opacity: 0;
  animation: ring-pulse 4s ease-out infinite;
}
.geo__ring:nth-child(2) { animation-delay: 1.33s; }
.geo__ring:nth-child(3) { animation-delay: 2.66s; }
@keyframes ring-pulse {
  0%   { transform: scale(.35); opacity: 0;   }
  18%  {                        opacity: .85; }
  100% { transform: scale(4.2); opacity: 0;   }
}

/* Route lines drawing themselves */
.geo__routes {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
}
.geo__routes path {
  fill: none;
  stroke: url(#route-grad);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 320;
  stroke-dashoffset: 320;
  animation: route-draw 7s var(--ease-out-quint) infinite;
}
.geo__routes path:nth-child(2) { animation-delay: 1.1s; }
.geo__routes path:nth-child(3) { animation-delay: 2.2s; }
@keyframes route-draw {
  0%       { stroke-dashoffset: 320; opacity: 0;   }
  12%      {                          opacity: .95; }
  55%, 72% { stroke-dashoffset: 0;   opacity: .95; }
  100%     { stroke-dashoffset: -320; opacity: 0;  }
}

/* Rank pins popping in across the grid */
.geo__pin {
  position: absolute;
  width: 13px; height: 13px;
  border-radius: 50%;
  translate: -50% -50%;
  background: var(--brand);
  box-shadow: 0 0 0 4px rgba(79, 70, 229, .2), 0 0 14px rgba(79, 70, 229, .7);
  opacity: 0;
  animation: pin-pop 4.2s var(--ease-spring) infinite;
}
.geo__pin--win {
  background: var(--success);
  box-shadow: 0 0 0 5px rgba(16, 185, 129, .22), 0 0 18px rgba(16, 185, 129, .8);
  width: 16px; height: 16px;
}
@keyframes pin-pop {
  0%        { transform: scale(0) translateZ(0);  opacity: 0; }
  12%       { transform: scale(1.5);              opacity: 1; }
  20%, 76%  { transform: scale(1);                opacity: 1; }
  100%      { transform: scale(0);                opacity: 0; }
}

/* ==========================================================================
   10. Hero scene — SERP card floating above the map
   ========================================================================== */
.scene {
  position: relative;
  perspective: 1400px;
  transform-style: preserve-3d;
}
.scene .serp {
  position: relative;
  z-index: 2;
  transform:
    perspective(1400px)
    rotateX(var(--srx, 4deg))
    rotateY(var(--sry, -7deg))
    translate3d(0, 0, 0);
  transition: transform .8s var(--ease-out-quint);
  transform-style: preserve-3d;
  animation: serp-float 8s ease-in-out infinite;
  will-change: transform;
}
@keyframes serp-float {
  0%, 100% { translate: 0 0;    }
  50%      { translate: 0 -14px; }
}
.scene:hover .serp { animation-play-state: paused; }

/* The winning result lifts off the card surface */
.serp__item--you {
  transform: translateZ(42px) scale(1.02);
  box-shadow: 0 18px 34px -12px rgba(79, 70, 229, .45);
  transition: transform .5s var(--ease-out-quint);
}
.serp__item--you .serp__rank { animation: rank-glow 3s ease-in-out infinite; }
@keyframes rank-glow {
  0%, 100% { box-shadow: 0 0 0 0   rgba(79, 70, 229, .55); }
  50%      { box-shadow: 0 0 0 9px rgba(79, 70, 229, 0);   }
}
.serp__badge { transform: translateZ(26px); }
.serp__bar   { transform: translateZ(14px); }

/* Live dot on the availability pill */
.pill .dot { animation: dot-pulse 2.2s ease-in-out infinite; }
@keyframes dot-pulse {
  0%, 100% { box-shadow: 0 0 0 0   rgba(16, 185, 129, .55); }
  50%      { box-shadow: 0 0 0 7px rgba(16, 185, 129, 0);   }
}

/* Glass panels drifting behind the SERP card */
.scene__glass {
  position: absolute;
  border-radius: 18px;
  background: linear-gradient(135deg, rgba(255, 255, 255, .72), rgba(255, 255, 255, .28));
  border: 1px solid rgba(255, 255, 255, .8);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  box-shadow: 0 16px 40px -18px rgba(16, 20, 45, .3);
  pointer-events: none;
  z-index: 1;
}
.scene__glass--a {
  width: 132px; height: 88px;
  top: -26px; right: -24px;
  animation: drift-a 11s ease-in-out infinite;
}
.scene__glass--b {
  width: 104px; height: 104px;
  bottom: 44px; left: -40px;
  animation: drift-b 14s ease-in-out infinite;
}
@keyframes drift-a {
  0%, 100% { transform: translate3d(0, 0, 0)        rotate(-7deg); }
  50%      { transform: translate3d(-14px, 18px, 0) rotate(3deg);  }
}
@keyframes drift-b {
  0%, 100% { transform: translate3d(0, 0, 0)        rotate(9deg);  }
  50%      { transform: translate3d(16px, -20px, 0) rotate(-4deg); }
}

/* ==========================================================================
   11. Logo marquee — seamless infinite scroll (row duplicated by effects.js)
   ========================================================================== */
.marquee { overflow: hidden; }
.marquee__viewport {
  display: flex;
  width: max-content;
  animation: marquee-scroll 34s linear infinite;
}
.marquee__viewport .marquee__row {
  flex: 0 0 auto;
  flex-wrap: nowrap;
  padding-right: 44px;
}
.marquee:hover .marquee__viewport { animation-play-state: paused; }
.marquee__viewport span { transition: color .25s ease, opacity .25s ease; }
.marquee__viewport span:hover { color: var(--brand); opacity: 1; }
@keyframes marquee-scroll {
  from { transform: translate3d(0, 0, 0);     }
  to   { transform: translate3d(-50%, 0, 0);  }
}
/* Fade the edges so items don't pop in */
.marquee__mask {
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

/* ==========================================================================
   12. Numbered process steps — 3D badges
   ========================================================================== */
.step { transform-style: preserve-3d; }
.step::before {
  transition: transform .45s var(--ease-spring), box-shadow .35s ease;
  transform-style: preserve-3d;
}
.step:hover::before {
  transform: translateZ(30px) rotateY(-16deg) scale(1.12);
  box-shadow: 0 12px 22px -8px rgba(79, 70, 229, .55);
}

/* ==========================================================================
   13. Service icons — 3D lift
   ========================================================================== */
.card__icon {
  transition: transform .5s var(--ease-spring), background .3s ease;
  transform-style: preserve-3d;
}
.card--hover:hover .card__icon {
  transform: translateZ(45px) rotateY(-14deg) rotateX(6deg) scale(1.08);
}

/* ==========================================================================
   14. Featured pricing plan — permanent lift
   ========================================================================== */
.plan--featured {
  transform: perspective(var(--depth)) translateZ(30px) scale(1.015);
  z-index: 2;
}
.plan__tag { animation: tag-bob 3.4s ease-in-out infinite; }
@keyframes tag-bob {
  0%, 100% { transform: translateX(-50%) translateY(0);     }
  50%      { transform: translateX(-50%) translateY(-3.5px); }
}

/* ==========================================================================
   15. FAQ — smooth open
   ========================================================================== */
.faq details > div { animation: faq-open .42s var(--ease-out-quint); }
@keyframes faq-open {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none;             }
}
.faq summary::after { transition: transform .3s var(--ease-spring), color .2s ease; }

/* ==========================================================================
   17. Stats
   --------------------------------------------------------------------------
   .stats has overflow:hidden to keep its 1px grid borders clean, which would
   clip a 3D pop — so stats get a flat highlight instead of a tilt.
   ========================================================================== */
.stat { transition: background .35s ease; }
.stat:hover { background: var(--surface-2); }
.section--ink .stat:hover { background: #1a2038; }

/* ==========================================================================
   18. Forms — focus lift
   ========================================================================== */
.field input,
.field select,
.field textarea { transition: border-color .2s ease, box-shadow .2s ease, transform .2s var(--ease-out-quint); }
.field input:focus,
.field select:focus,
.field textarea:focus { transform: translateY(-1.5px); }
.form-card { transition: box-shadow .4s ease; }
.form-card:focus-within { box-shadow: var(--shadow-lg); }

/* ==========================================================================
   19. Page-load entrance for above-the-fold content
   ========================================================================== */
.hero .pill,
.hero h1,
.hero .lede,
.hero .btn-row,
.hero__trust {
  animation: enter-up .85s var(--ease-out-quint) backwards;
}
.hero .pill      { animation-delay: .05s; }
.hero h1         { animation-delay: .14s; }
.hero .lede      { animation-delay: .24s; }
.hero .btn-row   { animation-delay: .34s; }
.hero__trust     { animation-delay: .44s; }

.scene { animation: enter-scene 1.1s var(--ease-out-quint) .3s backwards; }

@keyframes enter-up {
  from { opacity: 0; transform: translate3d(0, 26px, 0); }
  to   { opacity: 1; transform: none;                    }
}
@keyframes enter-scene {
  from { opacity: 0; transform: perspective(1400px) translate3d(0, 40px, -140px) rotateX(12deg); }
  to   { opacity: 1; transform: perspective(1400px) translate3d(0, 0, 0)         rotateX(0deg);  }
}

/* ==========================================================================
   20. Responsive — flatten the heavy 3D on small screens
   ========================================================================== */
@media (max-width: 1000px) {
  .geo { height: 240px; inset: auto -12% -18% -12%; }
  .scene__glass { display: none; }
}

@media (max-width: 880px) {
  /* Pointer tilt is meaningless on touch, and preserve-3d is expensive. */
  .card.tilt, .plan.tilt, .quote.tilt, .case.tilt,
  .step.tilt, .city-card.tilt {
    transform: none;
    transform-style: flat;
  }
  .card.tilt > *, .plan.tilt > * { transform: none; }
  .plan--featured { transform: none; }
  .geo { height: 180px; opacity: .7; }
  .scene .serp { transform: none; }
  .reveal { transform: translate3d(0, 24px, 0); }
  .reveal.is-visible { transform: none; }
}

@media (max-width: 560px) {
  .geo { display: none; }
  .hero::before, .page-head::before { filter: blur(38px); opacity: .6; }
}

/* ==========================================================================
   22. Deeper card 3D
   --------------------------------------------------------------------------
   The tilt was subtle enough to read as a wobble. These give it real depth:
   a stronger rotation, a shadow that moves opposite the tilt so the card
   looks lifted rather than skewed, and a specular edge along the top.
   ========================================================================== */
.card.tilt, .plan.tilt, .quote.tilt, .case.tilt, .city-card.tilt {
  --depth: 900px;
  box-shadow: var(--shadow-sm);
}

.card--hover.tilt:hover,
.plan.tilt:hover,
.quote.tilt:hover,
.case.tilt:hover,
.city-card.tilt:hover {
  --lift: -10px;
  box-shadow:
    0 2px 4px rgba(16, 20, 45, .04),
    0 12px 24px -8px rgba(16, 20, 45, .12),
    0 32px 60px -16px rgba(79, 70, 229, .28);
}

/* Specular highlight along the lit edge, so the surface reads as a plane
   catching light rather than a flat rectangle that happens to rotate. */
.tilt.has-sheen::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .9), transparent);
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
  z-index: 2;
}
.tilt.has-sheen:hover::before { opacity: 1; }

/* Content sits on stacked Z planes — the further forward, the more it shifts
   as the card turns, which is what sells the depth. */
.card.tilt .card__icon { transform: translateZ(55px); }
.card.tilt h3         { transform: translateZ(34px); }
.card.tilt p          { transform: translateZ(22px); }
.card.tilt .card__link { transform: translateZ(40px); }
.card.tilt .checks     { transform: translateZ(18px); }

.plan.tilt .plan__price { transform: translateZ(46px); }
.plan.tilt .plan__name  { transform: translateZ(34px); }
.plan.tilt .btn         { transform: translateZ(40px); }

.case.tilt .case__metrics { transform: translateZ(30px); }
.quote.tilt .quote__avatar { transform: translateZ(38px); }

/* ==========================================================================
   23. Staggered entrance
   --------------------------------------------------------------------------
   effects.js already delays each revealed element by its index. This gives
   grid children their own offset so a row of cards cascades rather than
   arriving as one block.
   ========================================================================== */
.grid > .reveal:nth-child(2)  { transition-delay: .07s; }
.grid > .reveal:nth-child(3)  { transition-delay: .14s; }
.grid > .reveal:nth-child(4)  { transition-delay: .21s; }
.grid > .reveal:nth-child(5)  { transition-delay: .28s; }
.grid > .reveal:nth-child(6)  { transition-delay: .35s; }

.steps > .step { animation: none; }
.steps .step:nth-child(2) { transition-delay: .08s; }
.steps .step:nth-child(3) { transition-delay: .16s; }
.steps .step:nth-child(4) { transition-delay: .24s; }

/* ==========================================================================
   24. Section heading underline sweep
   ========================================================================== */
.section-head h2 {
  position: relative;
  padding-bottom: 14px;
}
.section-head h2::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 56px; height: 3px;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform .6s var(--ease-out-quint) .15s;
}
.section-head--center h2::after { left: 50%; translate: -50% 0; transform-origin: 50% 50%; }
.reveal.is-visible .section-head h2::after,
.section-head.reveal.is-visible h2::after,
.is-visible > .section-head h2::after { transform: scaleX(1); }
/* Sections whose head isn't inside a .reveal still get the underline. */
.section-head:not(.reveal) h2::after { transform: scaleX(1); }

/* ==========================================================================
   25. Link and list micro-motion
   ========================================================================== */
.checks li {
  transition: transform .25s var(--ease-out-quint);
}
.card:hover .checks li,
.plan:hover .checks li { transform: translateX(2px); }

.footer__col a {
  display: inline-block;
  transition: color .2s ease, transform .2s var(--ease-out-quint);
}
.footer__col a:hover { transform: translateX(3px); }

.city-card svg { transition: transform .3s var(--ease-spring); }
.city-card:hover svg { transform: scale(1.2) translateY(-2px); }

/* ==========================================================================
   26. Form field focus depth
   ========================================================================== */
.field input, .field select, .field textarea {
  transition: border-color .2s ease, box-shadow .25s ease, transform .25s var(--ease-out-quint);
}
.field input:focus, .field select:focus, .field textarea:focus {
  transform: translateY(-2px);
  box-shadow: 0 0 0 3px rgba(79, 70, 229, .13), 0 8px 18px -8px rgba(79, 70, 229, .4);
}

/* ==========================================================================
   21. Reduced motion — turn all of it off
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .hero::before, .page-head::before,
  .cta-band::before, .cta-band::after,
  .logo__mark, .pill .dot,
  .geo__grid, .geo__radar, .geo__ring,
  .geo__routes path, .geo__pin,
  .scene, .scene .serp, .scene__glass,
  .marquee__viewport, .plan__tag,
  .serp__item--you .serp__rank,
  .hero h1 .grad, .stat__num,
  .hero .pill, .hero h1, .hero .lede, .hero .btn-row, .hero__trust,
  .faq details > div {
    animation: none !important;
  }

  .reveal,
  .card.tilt, .plan.tilt, .quote.tilt, .case.tilt,
  .step.tilt, .city-card.tilt,
  .card.tilt .card__icon, .card.tilt h3, .card.tilt p,
  .card.tilt .card__link, .card.tilt .checks,
  .plan.tilt .plan__price, .plan.tilt .plan__name, .plan.tilt .btn,
  .case.tilt .case__metrics, .quote.tilt .quote__avatar,
  .plan--featured, .scene .serp, .serp__item--you {
    transform: none !important;
  }

  .grid > .reveal, .steps .step, .section-head h2::after { transition-delay: 0s !important; }
  .section-head h2::after { transform: scaleX(1) !important; }

  .scroll-progress { display: none; }
  .geo__routes path { stroke-dashoffset: 0; opacity: .8; }
  .geo__pin { opacity: 1; transform: scale(1); }
}
