/* ═══════════════════════════════════════════════════════════════════════════
   AMBIENT MARINE FX — the plankton and tuna schools from the homepage hero.
   Inline SVG silhouette from PhyloPic (CC0 / public domain).

   ONE source for the whole marketing site. Every page used to carry its own
   copy of this inline, so a change to the fish meant editing it in as many
   places as there were pages. Pair with /assets/fx.js, which builds the markup
   so pages do not carry a copy of that either.

   Everything is prefixed `fx-` and nothing else on the site uses that prefix
   (checked across every page), so this file can only ever add, never override.

   🚫 THE HOMEPAGE AND 404 DELIBERATELY KEEP THEIR OWN INLINE COPIES. The
   homepage's scene is bound to the hero block, so it scrolls away with the
   hero; `fx--full` here is pinned to the viewport and follows the reader down
   the page. Same look at rest, different behaviour on scroll. Do not "finish
   the job" by migrating index.html without deciding you want that change.

   TWO VARIANTS, set by data-fx on the script tag:
     full  A whole screen with nothing to read over it. Homepage hero, 404,
           account confirmed. Homepage proportions.
     band  A strip across the masthead that stops before the article starts.
           Guides, features, support. Motion must never sit beside body text.
   ═══════════════════════════════════════════════════════════════════════════ */

.fx-layer { position: absolute; pointer-events: none; overflow: hidden; }

/* ── full ───────────────────────────────────────────────────────────────── */
.fx-layer.fx--full { position: fixed; inset: 0; z-index: 0; }

/* ── band ───────────────────────────────────────────────────────────────── */
/* Anchored to the top of the DOCUMENT, so it scrolls away with the masthead
   rather than following the reader down the page. */
.fx-layer.fx--band { top: var(--fx-nav, 0px); left: 0; width: 100%; height: 300px; z-index: 0; }
/* --fx-nav is set by fx.js from the real nav height. The nav is opaque, so a
   scene drawn behind it is simply thrown away. */

/* The page's own content sits above the scene. These pages paint no background
   of their own on these elements, so without this the fish swim over the words. */
body > nav, body > header, body > main, body > footer,
body > .nav, body > .container, body > .wrap { position: relative; z-index: 1; }

.fx-plankton { position: absolute; inset: 0; pointer-events: none; }
.fx-plankton span {
  position: absolute; width: 2px; height: 2px; border-radius: 50%;
  background: rgba(138, 175, 196, 0.55);
  box-shadow: 0 0 3px rgba(0, 212, 255, 0.35);
  animation: fx-sink linear infinite;
}
/* Band particles dissolve towards the bottom instead of ending on a hard line. */
.fx--band .fx-plankton { mask-image: linear-gradient(to bottom, #000 50%, transparent 100%); -webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent 100%); }

/* Full falls a whole screen; band falls only as far as its strip. */
@keyframes fx-sink {
  0%   { transform: translateY(-40px) translateX(0);   opacity: 0; }
  8%   { opacity: 0.7; }
  50%  { transform: translateY(50vh) translateX(18px); }
  92%  { opacity: 0.5; }
  100% { transform: translateY(110vh) translateX(-8px); opacity: 0; }
}
@keyframes fx-sink-band {
  0%   { transform: translateY(-40px) translateX(0);   opacity: 0; }
  8%   { opacity: 0.7; }
  50%  { transform: translateY(150px) translateX(18px); }
  92%  { opacity: 0.5; }
  100% { transform: translateY(360px) translateX(-8px); opacity: 0; }
}
.fx--band .fx-plankton span { animation-name: fx-sink-band; }

.fx-life { position: absolute; inset: 0; pointer-events: none; }
.fx-creature { position: absolute; pointer-events: none; color: rgba(180, 210, 225, 0.32); }
.fx-creature svg { display: block; width: 100%; height: 100%; overflow: visible; }

.fx-fish-school { left: 0; }
.fx-fish-school .fx-fish { position: absolute; }
.fx-fish-school .fx-fish svg { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(90deg); }
@keyframes fx-fish-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(3px); } }

.fx-fish-school.fx--mid {
  width: 110px; height: 60px; color: rgba(180, 210, 225, 0.30);
  animation: fx-school-swim-b 52s linear infinite;
}
.fx-fish-school.fx--mid .fx-fish { width: 24px; height: 12px; }
.fx-fish-school.fx--mid .fx-fish svg { width: 12px; height: 24px; }
.fx-fish-school.fx--mid .fx-fish:nth-child(1) { top: 0;    left: 20px; animation: fx-fish-bob 3.2s ease-in-out infinite; }
.fx-fish-school.fx--mid .fx-fish:nth-child(2) { top: 12px; left: 0;    animation: fx-fish-bob 3.6s ease-in-out infinite -0.4s; }
.fx-fish-school.fx--mid .fx-fish:nth-child(3) { top: 24px; left: 34px; animation: fx-fish-bob 3.4s ease-in-out infinite -0.8s; }
.fx-fish-school.fx--mid .fx-fish:nth-child(4) { top: 36px; left: 14px; animation: fx-fish-bob 3.0s ease-in-out infinite -1.2s; }
.fx-fish-school.fx--mid .fx-fish:nth-child(5) { top: 6px;  left: 60px; animation: fx-fish-bob 3.8s ease-in-out infinite -1.6s; }

.fx-fish-school.fx--far {
  width: 75px; height: 40px; color: rgba(180, 210, 225, 0.18);
  filter: blur(0.6px);
  animation: fx-school-swim-c 85s linear infinite;
  animation-delay: -6s;
}
.fx-fish-school.fx--far .fx-fish { width: 16px; height: 8px; }
.fx-fish-school.fx--far .fx-fish svg { width: 8px; height: 16px; }
.fx-fish-school.fx--far .fx-fish:nth-child(1) { top: 0;    left: 14px; animation: fx-fish-bob 3.2s ease-in-out infinite; }
.fx-fish-school.fx--far .fx-fish:nth-child(2) { top: 8px;  left: 0;    animation: fx-fish-bob 3.6s ease-in-out infinite -0.4s; }
.fx-fish-school.fx--far .fx-fish:nth-child(3) { top: 16px; left: 24px; animation: fx-fish-bob 3.4s ease-in-out infinite -0.8s; }
.fx-fish-school.fx--far .fx-fish:nth-child(4) { top: 24px; left: 40px; animation: fx-fish-bob 3.0s ease-in-out infinite -1.2s; }

/* Heights. Full keeps the homepage's percentages; band uses pixels, because a
   percentage of a 340px strip would bunch both schools together. */
.fx--full .fx-fish-school.fx--mid { top: 38%; }
.fx--full .fx-fish-school.fx--far { top: 20%; }
.fx--band .fx-fish-school.fx--mid { top: 96px; }
.fx--band .fx-fish-school.fx--far { top: 14px; }

@keyframes fx-school-swim-b {
  0%   { transform: translateX(-120px) translateY(0); opacity: 0; }
  6%   { opacity: 1; }
  62%  { transform: translateX(calc(100vw + 20px)) translateY(-10px); opacity: 1; }
  68%  { opacity: 0; }
  100% { transform: translateX(calc(100vw + 20px)); opacity: 0; }
}
@keyframes fx-school-swim-c {
  0%   { transform: translateX(-90px) translateY(0); opacity: 0; }
  4%   { opacity: 1; }
  65%  { transform: translateX(calc(100vw + 20px)) translateY(-6px); opacity: 1; }
  72%  { opacity: 0; }
  100% { transform: translateX(calc(100vw + 20px)); opacity: 0; }
}

/* Mobile: keep both schools, drop the blur. It is a real GPU cost on mid-range
   phones and invisible at that size anyway. */
@media (max-width: 768px) {
  .fx-fish-school.fx--far { filter: none; }
  /* A shorter masthead on a narrow screen, so the band follows it up. */
  .fx-layer.fx--band { height: 250px; }
  .fx--band .fx-fish-school.fx--mid { top: 84px; }
  .fx--band .fx-fish-school.fx--far { top: 12px; }
}

/* Anyone asking for less motion gets no scene at all, rather than a frozen
   frame. Matches what the homepage already did. */
@media (prefers-reduced-motion: reduce) {
  .fx-layer { display: none; }
}
