/* ==========================================================================
   SUMA — Ambient backgrounds & movement (web library)
   --------------------------------------------------------------------------
   Styles for web/ambient.js. Load AFTER styles.css:

     <link rel="stylesheet" href="styles.css">
     <link rel="stylesheet" href="web/ambient.css">
     <script src="web/ambient.js" defer></script>

   Everything here is background-only, GPU-composited (transform/opacity),
   sits behind content (z-index 0, pointer-events none), and freezes under
   prefers-reduced-motion. See web/README.md for the effect menu and the
   variety rules — never repeat the same ambient on adjacent bands.
   ========================================================================== */

/* ---- layer scaffold ---------------------------------------------------- */
.sa-layer{ position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:0; }
/* lift content above the layer — :where() keeps specificity at zero so any
   author rule (e.g. an absolutely-positioned hero image or caption) wins */
:where([data-ambient] > :not(.sa-layer)){ position:relative; z-index:1; }

/* ---- paper grain (whole page) — <body data-grain> ----------------------- */
body[data-grain]::before{
  content:""; position:fixed; inset:0; z-index:6; pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url%28%23n%29'/%3E%3C/svg%3E");
  background-size:220px 220px; opacity:0.11;
}

/* ---- aurora / mesh blobs ------------------------------------------------ */
.sa-blob{
  position:absolute; border-radius:50%;
  will-change:transform, opacity;
}
.sa-aurora .sa-blob{ filter:blur(72px); mix-blend-mode:screen; }
.sa-mesh   .sa-blob{ filter:blur(56px); mix-blend-mode:multiply; }
@keyframes saDrift1{ 0%,100%{ transform:translate3d(0,0,0) scale(1); opacity:0.9; }
  50%{ transform:translate3d(84px,56px,0) scale(1.16); opacity:1; } }
@keyframes saDrift2{ 0%,100%{ transform:translate3d(0,0,0) scale(1.07); opacity:1; }
  50%{ transform:translate3d(-72px,44px,0) scale(0.88); opacity:0.76; } }
@keyframes saDrift3{ 0%,100%{ transform:translate3d(0,0,0) scale(1); opacity:0.82; }
  33%{ transform:translate3d(-50px,-40px,0) scale(1.1); opacity:0.95; }
  66%{ transform:translate3d(42px,-68px,0) scale(1.2); opacity:1; } }

/* ---- drifting data grid + scan sweep (cream bands) ---------------------- */
.sa-grid::before{
  content:""; position:absolute; inset:-32%;
  background-image:
    linear-gradient(to right, rgba(16,49,42,0.072) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(16,49,42,0.072) 1px, transparent 1px);
  background-size:48px 48px;
  -webkit-mask-image:radial-gradient(125% 95% at var(--sa-grid-focus,82% 6%), #000 0%, rgba(0,0,0,0.4) 52%, transparent 84%);
  mask-image:radial-gradient(125% 95% at var(--sa-grid-focus,82% 6%), #000 0%, rgba(0,0,0,0.4) 52%, transparent 84%);
  animation:saGridPan 72s linear infinite;
}
.sa-grid.has-cv::before{ display:none; }
.sa-grid .sa-grid-cv{ position:absolute; inset:0; width:100%; height:100%; }
@keyframes saGridPan{ from{ transform:translate3d(0,0,0); } to{ transform:translate3d(48px,48px,0); } }

.sa-sweep::after, .sa-grid.sa-sweep-on::after{
  content:""; position:absolute; top:-60%; left:0; width:46%; height:220%;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,0.6) 50%, transparent);
  transform:translateX(-140%) rotate(13deg); filter:blur(34px);
  mix-blend-mode:soft-light;
  animation:saSweep 19s ease-in-out infinite;
}
@keyframes saSweep{
  0%{ transform:translateX(-140%) rotate(13deg); opacity:0; }
  14%{ opacity:1; } 52%{ opacity:1; }
  72%,100%{ transform:translateX(320%) rotate(13deg); opacity:0; } }

/* ---- floating particles -------------------------------------------------- */
.sa-particles .sa-pt{
  position:absolute; border-radius:50%; will-change:transform, opacity;
  animation:saPtDrift var(--d,22s) ease-in-out infinite, saPtTwinkle var(--t,7s) ease-in-out infinite;
}
@keyframes saPtDrift{
  0%,100%{ transform:translate3d(0,0,0); }
  50%{ transform:translate3d(var(--dx,22px), var(--dy,-26px), 0); } }
@keyframes saPtTwinkle{
  0%,100%{ opacity:calc(var(--o,0.5) * 0.35); }
  50%{ opacity:var(--o,0.5); } }

/* ---- canvases (canopy, trail) ------------------------------------------- */
.sa-cv{ position:absolute; inset:0; width:100%; height:100%; }

/* ---- reveal on scroll ----------------------------------------------------
   Content is visible by default; ambient.js "arms" only elements confirmed
   below the fold. Nothing ever depends on JS to BECOME visible. */
.reveal{ transition:opacity .7s ease, transform .7s cubic-bezier(.2,.72,.18,1); }
.reveal.armed{ opacity:0; transform:translateY(22px); }
.reveal.rv-left.armed{ opacity:0; transform:translateX(-46px); }
.reveal.rv-right.armed{ opacity:0; transform:translateX(46px); }
.reveal.rv-pop.armed{ opacity:0; transform:translateY(36px) scale(0.94); }

/* ---- belt marquee ---------------------------------------------------------
   <div class="sa-belt" data-belt><div class="sa-belt-track"> …items… </div></div>
   ambient.js wraps items into a group, clones it, sets --sa-belt-dur. */
.sa-belt{ position:relative; overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.sa-belt-track{ display:flex; width:max-content; will-change:transform;
  animation:saBelt var(--sa-belt-dur,30s) linear infinite; }
.sa-belt:hover .sa-belt-track{ animation-play-state:paused; }
.sa-belt-group{ display:flex; align-items:center; flex:0 0 auto; }
@keyframes saBelt{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }

/* ---- pinned horizontal track ----------------------------------------------
   <section data-pin-x>
     <div class="sa-pin-sticky"> …heading…
       <div class="sa-pin-viewport"><div class="sa-pin-track"> …cards… </div></div>
     </div>
   </section>
   Without JS (or on narrow/reduced-motion) the viewport is a natural
   horizontal scroller; with JS the section pins and scroll drives the track. */
.sa-pin-viewport{ overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.sa-pin-viewport::-webkit-scrollbar{ display:none; }
.sa-pin-track{ display:flex; gap:24px; width:max-content; }
[data-pin-x].sa-pinned .sa-pin-sticky{
  position:sticky; top:0; min-height:100vh; overflow:hidden;
  display:flex; flex-direction:column; justify-content:center; }
[data-pin-x].sa-pinned .sa-pin-viewport{ overflow:visible; }
[data-pin-x].sa-pinned .sa-pin-track{ transform:translate3d(0,0,0); will-change:transform; }
