/* ============================================================================
   SMART SUITE — ANIMATED BACKGROUND SYSTEM + MOTION
   ----------------------------------------------------------------------------
   HOW TO USE ON A NEW PAGE

   Every animated background is a self-contained layer you drop as the FIRST
   child of a `.section`, marked aria-hidden. It positions itself absolutely and
   sits behind content automatically:

     <section class="section on-dark">
       <div class="bg bg-grid" aria-hidden="true"></div>
       <div class="bg bg-aurora" aria-hidden="true"></div>
       <div class="wrap"> …content… </div>
     </section>

   You may stack up to TWO background layers per section. Three or more turns to
   noise and costs frame budget. Recommended pairings:

     Dark hero .............. bg-grid + bg-sweep
     Dark feature/CTA ....... bg-aurora + bg-nodes
     Light section .......... bg-lattice (alone)
     Light alternate band ... bg-rays (alone)

   PERFORMANCE CONTRACT
   Only `transform` and `opacity` are animated — never width/height/top/left,
   never box-shadow, never filter on large surfaces. Every loop is composited.
   All ambient loops are disabled under prefers-reduced-motion (bottom of file).
   ============================================================================ */

/* Base layer positioning. Always pair: <div class="bg bg-x"> */
.bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}

/* ---------------------------------------------------------------------------
   1. bg-grid — engineered perimeter grid that drifts upward.
   Reads as: site plan / geofence survey. Best on dark heroes.
   --------------------------------------------------------------------------- */
.bg-grid::before {
  content: "";
  position: absolute;
  inset: -80px -20px -20px;
  background-image:
    linear-gradient(to right, rgba(120, 176, 205, 0.10) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(120, 176, 205, 0.10) 1px, transparent 1px);
  background-size: 68px 68px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 30%, transparent 78%);
  will-change: transform;
}

.on-light .bg-grid::before,
.on-wash .bg-grid::before {
  background-image:
    linear-gradient(to right, rgba(11, 31, 51, 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(11, 31, 51, 0.07) 1px, transparent 1px);
}

/* ---------------------------------------------------------------------------
   2. bg-sweep — a slow teal scan beam crossing the section, like a sensor pass.
   Signature motion of the brand. Use once per page, on the hero.
   --------------------------------------------------------------------------- */
.bg-sweep::before {
  content: "";
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: -60%;
  width: 55%;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(41, 196, 176, 0.00) 20%,
    rgba(41, 196, 176, 0.13) 48%,
    rgba(255, 197, 61, 0.10) 56%,
    transparent 88%
  );
  transform: skewX(-14deg);
  will-change: transform;
}

/* ---------------------------------------------------------------------------
   3. bg-aurora — two large, slowly orbiting colour blooms (teal + amber).
   Provides depth on flat dark sections. Never use on top of a photo.
   --------------------------------------------------------------------------- */
.bg-aurora::before,
.bg-aurora::after {
  content: "";
  position: absolute;
  width: 58vw;
  height: 58vw;
  max-width: 780px;
  max-height: 780px;
  border-radius: 50%;
  will-change: transform;
}

.bg-aurora::before {
  top: -22%;
  left: -12%;
  background: radial-gradient(circle, rgba(41, 196, 176, 0.20) 0%, transparent 66%);
}

.bg-aurora::after {
  bottom: -30%;
  right: -14%;
  background: radial-gradient(circle, rgba(255, 197, 61, 0.16) 0%, transparent 66%);
}

/* ---------------------------------------------------------------------------
   4. bg-nodes — pulsing sensor-node dot field.
   --------------------------------------------------------------------------- */
.bg-nodes::before,
.bg-nodes::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(41, 196, 176, 0.55) 1.4px, transparent 1.6px);
  background-size: 46px 46px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 50%, #000 10%, transparent 72%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 50%, #000 10%, transparent 72%);
  opacity: 0.35;
}

.bg-nodes::after {
  background-image: radial-gradient(circle, rgba(255, 197, 61, 0.55) 1.4px, transparent 1.6px);
  background-position: 23px 23px;
  opacity: 0.18;
}

/* ---------------------------------------------------------------------------
   5. bg-lattice — quiet diagonal hairline lattice for LIGHT sections.
   --------------------------------------------------------------------------- */
.bg-lattice::before {
  content: "";
  position: absolute;
  inset: -40px;
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(11, 31, 51, 0.045) 0 1px,
    transparent 1px 22px
  );
  mask-image: linear-gradient(180deg, #000 0%, transparent 92%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 92%);
  will-change: transform;
}

/* ---------------------------------------------------------------------------
   6. bg-rays — soft radiating beams from the top, for light sections.
   --------------------------------------------------------------------------- */
.bg-rays::before {
  content: "";
  position: absolute;
  inset: -30% -30% 40%;
  background: conic-gradient(
    from 180deg at 50% 0%,
    transparent 0deg,
    rgba(41, 196, 176, 0.09) 25deg,
    transparent 52deg,
    transparent 128deg,
    rgba(255, 197, 61, 0.09) 155deg,
    transparent 182deg
  );
  will-change: transform;
}

/* ---------------------------------------------------------------------------
   7. bg-scrim — photo darkener. Not animated. Always place ABOVE a photo layer
   and below content: <img class="bg-photo"> then <div class="bg bg-scrim">.
   --------------------------------------------------------------------------- */
.bg-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.bg-scrim {
  background: var(--g-scrim);
  z-index: 1;
}

/* Adds a subtle horizontal falloff so left-aligned hero copy stays legible. */
.bg-scrim-left {
  background:
    linear-gradient(90deg, rgba(6, 20, 32, 0.94) 0%, rgba(6, 20, 32, 0.72) 42%, rgba(6, 20, 32, 0.30) 100%),
    var(--g-scrim);
  z-index: 1;
}

/* ---------------------------------------------------------------------------
   8. Element-level motion: the animated perimeter frame (brand signature).
   Wrap any hero/feature image in .frame to get a drawing perimeter + corner
   ticks. See components.css → "Framed media".
   --------------------------------------------------------------------------- */
.frame-line {
  fill: none;
  stroke: var(--c-pulse);
  stroke-width: 1.5;
  stroke-dasharray: 14 10;
  opacity: 0.75;
}

/* ============================================================================
   KEYFRAMES + ACTIVATION
   Everything below only runs when the visitor has NOT asked for reduced motion.
   Keep it that way: define static appearance above, motion below.
   ============================================================================ */
@media (prefers-reduced-motion: no-preference) {
  @keyframes ss-grid-drift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, 68px, 0); }
  }

  @keyframes ss-sweep {
    from { transform: translate3d(0, 0, 0) skewX(-14deg); }
    to   { transform: translate3d(320%, 0, 0) skewX(-14deg); }
  }

  @keyframes ss-orbit-a {
    0%   { transform: translate3d(0, 0, 0) scale(1); }
    50%  { transform: translate3d(14%, 8%, 0) scale(1.12); }
    100% { transform: translate3d(0, 0, 0) scale(1); }
  }

  @keyframes ss-orbit-b {
    0%   { transform: translate3d(0, 0, 0) scale(1.05); }
    50%  { transform: translate3d(-12%, -10%, 0) scale(0.92); }
    100% { transform: translate3d(0, 0, 0) scale(1.05); }
  }

  @keyframes ss-node-pulse {
    0%, 100% { opacity: 0.14; }
    50%      { opacity: 0.42; }
  }

  @keyframes ss-lattice-slide {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(31px, 31px, 0); }
  }

  @keyframes ss-rays-turn {
    from { transform: rotate(-6deg); }
    to   { transform: rotate(6deg); }
  }

  @keyframes ss-dash {
    to { stroke-dashoffset: -240; }
  }

  @keyframes ss-marquee {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
  }

  .bg-grid::before    { animation: ss-grid-drift 14s linear infinite; }
  .bg-sweep::before   { animation: ss-sweep 11s cubic-bezier(0.4, 0, 0.2, 1) infinite; }
  .bg-aurora::before  { animation: ss-orbit-a 34s ease-in-out infinite; }
  .bg-aurora::after   { animation: ss-orbit-b 42s ease-in-out infinite; }
  .bg-nodes::before   { animation: ss-node-pulse 6s ease-in-out infinite; }
  .bg-nodes::after    { animation: ss-node-pulse 6s ease-in-out infinite 3s; }
  .bg-lattice::before { animation: ss-lattice-slide 22s linear infinite; }
  .bg-rays::before    { animation: ss-rays-turn 26s ease-in-out infinite alternate; }
  .frame-line         { animation: ss-dash 18s linear infinite; }
  .marquee-track      { animation: ss-marquee 34s linear infinite; }

  /* Scroll reveal — JS (theme.js) adds .is-in when the element enters view.
     Add data-reveal to any element; add style="--i:2" to stagger it. */
  [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 22px, 0);
    transition:
      opacity var(--d-reveal) var(--ease),
      transform var(--d-reveal) var(--ease);
    transition-delay: calc(var(--i, 0) * 80ms);
  }

  [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }

  /* Hero entrance choreography — runs once on load, driven by .is-ready on body. */
  .hero-anim { opacity: 0; transform: translate3d(0, 26px, 0); }

  body.is-ready .hero-anim {
    opacity: 1;
    transform: none;
    transition:
      opacity 900ms var(--ease) calc(var(--i, 0) * 120ms),
      transform 900ms var(--ease) calc(var(--i, 0) * 120ms);
  }
}

/* Reduced motion: everything is present and still. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .bg-sweep, .bg-nodes { display: none; }
  [data-reveal], .hero-anim { opacity: 1; transform: none; }
}
