/* ═══════════════════════════════════════════════════════════
   Ambient Background — refrigeration-inspired AIRFLOW, reused across
   every homepage section that would otherwise sit on a flat, generic
   background (range-marquee, featured-rotator, our-promise,
   industrial-cta — same .ambient-bg / .ambient-bg__glow markup in
   each, already in index.php; only this file changed to replace what
   renders through those hooks). The homepage hero's own airflow
   (assets/css/hero-showcase.css) uses the identical technique so the
   whole landing page reads as one consistent effect instead of two
   unrelated animations.

   Replaces the previous implementation: soft drifting blue circles
   that scaled/nudged back and forth with no consistent direction.
   This is deliberately not that "+ more" — it's a different technique
   entirely, built around real air movement rather than glow blobs.

   Technique: each .ambient-bg__glow is ONE element, twice the width
   of its section, carrying the same soft elongated streak baked into
   its background TWICE (as two radial-gradient layers, positioned a
   half-width apart). Animating transform: translateX from 0 to -50%
   moves it by exactly one section-width — and because the pattern
   repeats every half of the element's own width, the frame at -50%
   is pixel-identical to the frame at 0%, so the loop has no visible
   seam or reset. transform is the only animated property (GPU
   compositor only, never triggers paint/layout), which is what makes
   this cheap eneough to run continuously on 4+ sections at once.

   Configurable via custom properties below — intensity/speed/density
   can be tuned per call site without touching the animation logic:
     --airflow-color     streak colour (theme-adaptive, see :root)
     --airflow-opacity   overall element opacity
     --airflow-blur      softness of each streak
     --airflow-speed     seconds per full right-to-left pass
   ═══════════════════════════════════════════════════════════ */

:root {
  /* Light mode: a cool, subtle tint — enough to read as motion
     without competing with foreground text/product imagery. */
  --airflow-color: rgba(0, 163, 255, 0.22);
  --airflow-opacity: 0.85;
}

/* Dark mode: same accent hue, brighter and slightly more luminous so
   it still reads clearly against a dark surface — the same concept
   adapted, not a second unrelated treatment. Both selectors kept in
   sync with the identical dark-theme pattern already used everywhere
   else in this codebase (base.css) — the media query drives an OS
   "system" preference, the attribute selector drives an explicit
   in-app toggle. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --airflow-color: rgba(77, 195, 255, 0.34);
    --airflow-opacity: 0.95;
  }
}

:root[data-theme="dark"] {
  --airflow-color: rgba(77, 195, 255, 0.34);
  --airflow-opacity: 0.95;
}

.ambient-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.ambient-bg__glow {
  position: absolute;
  left: 0;
  /* 2x width = one full section-width of travel per loop (see the
     technique note above) — this is what makes the wrap invisible. */
  width: 200%;
  height: 130px;
  /* Two copies of one soft horizontal streak, a half-width apart.
     Elongated ellipse (not round) so it reads as a moving current of
     air rather than a glowing orb. */
  background-image:
    radial-gradient(ellipse 16% 60% at 25% 50%, var(--airflow-color) 0%, transparent 72%),
    radial-gradient(ellipse 16% 60% at 75% 50%, var(--airflow-color) 0%, transparent 72%);
  filter: blur(var(--airflow-blur, 34px));
  opacity: var(--airflow-opacity);
  will-change: transform;
  /* translateX only — right to left. Small Y stops along the way
     (not present at 0%/100%, so the loop still closes cleanly) give
     the pass a gentle organic drift instead of a ruler-straight line,
     without a second competing animation on the same property. */
  animation: airflowPass var(--airflow-speed, 30s) linear infinite;
}

@keyframes airflowPass {
  0%   { transform: translate(0%, 0); }
  22%  { transform: translate(-11%, -5px); }
  48%  { transform: translate(-24%, 4px); }
  74%  { transform: translate(-37%, -3px); }
  100% { transform: translate(-50%, 0); }
}

/* Slightly different vertical wander per layer so three streams at
   different heights don't move in lockstep — reads as natural
   variation, not one pattern copy-pasted three times. */
@keyframes airflowPassAlt {
  0%   { transform: translate(0%, 0); }
  30%  { transform: translate(-15%, 6px); }
  55%  { transform: translate(-27%, -4px); }
  80%  { transform: translate(-40%, 3px); }
  100% { transform: translate(-50%, 0); }
}

.ambient-bg__glow--1 {
  top: 12%;
  height: 150px;
  --airflow-blur: 38px;
  animation-name: airflowPass;
  animation-duration: 32s;
}

.ambient-bg__glow--2 {
  top: 46%;
  height: 110px;
  --airflow-blur: 30px;
  animation-name: airflowPassAlt;
  animation-duration: 26s;
  animation-delay: -9s;
  opacity: calc(var(--airflow-opacity) * 0.8);
}

.ambient-bg__glow--3 {
  top: 74%;
  height: 90px;
  --airflow-blur: 26px;
  animation-name: airflowPass;
  animation-duration: 22s;
  animation-delay: -15s;
  opacity: calc(var(--airflow-opacity) * 0.65);
}

/* On light sections the same tint reads more present than on the
   dark-glass sections it was originally tuned for — hold it back
   slightly so it stays a hint, not a wash, matching the previous
   file's own per-section calibration. */
.range-marquee .ambient-bg__glow {
  opacity: calc(var(--airflow-opacity) * 0.75);
}

/* Static fallback: motion off, streaks stay visible at rest (0%
   keyframe position) rather than disappearing — satisfies "provide a
   static fallback" without a special-cased extra rule set. */
@media (prefers-reduced-motion: reduce) {
  .ambient-bg__glow {
    animation: none;
  }
}

@media (max-width: 767.98px) {
  .ambient-bg__glow {
    --airflow-blur: 22px;
    height: 80px;
  }
}

/* ── Fluid cursor layer (assets/js/splash-cursor.js) ─────────────
   Fixed/full-viewport so it isn't tied to any one section's scroll
   position. z-index: 35 sits above every section's own content
   (.ambient-bg is 0, section inners are 1) but below .site-header's
   fixed nav (z-index: 40, site-header.css) — the WebGL layer never
   renders over the nav, and pointer-events: none means it can never
   block a click/tap regardless of stacking order anyway. */
.fluid-cursor-layer {
  position: fixed;
  inset: 0;
  z-index: 35;
  pointer-events: none;
}

.fluid-cursor-layer canvas {
  display: block;
  width: 100%;
  height: 100%;
}
