/* Titan3D — Ambient lighting layer.
 *
 * The signature of the design system: layered, animated atmospheric depth.
 * A fixed root container sits behind all content (z-index: 0) and renders:
 *   1. Base radial gradient (top-down vertical depth)
 *   2. Noise texture (tactile, prevents banding)
 *   3. Animated indigo blobs (cinematic light pools)
 *   4. Grid overlay (technical precision)
 *
 * Markup contract — header.php renders:
 *   <div class="t3d-ambient" aria-hidden="true">
 *     <div class="t3d-ambient__grid"></div>
 *     <div class="t3d-ambient__blob t3d-ambient__blob--primary"></div>
 *     <div class="t3d-ambient__blob t3d-ambient__blob--secondary"></div>
 *     <div class="t3d-ambient__blob t3d-ambient__blob--tertiary"></div>
 *     <div class="t3d-ambient__blob t3d-ambient__blob--bottom"></div>
 *     <div class="t3d-ambient__noise"></div>
 *   </div>
 */

.t3d-ambient {
  position: fixed;
  inset: 0;
  z-index: var(--z-ambient);
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(ellipse 80% 60% at 50% 0%, #0a0a0f 0%, #050506 50%, #020203 100%);
}

/* Layer: noise texture (SVG inlined as data URI) ------------------- */
.t3d-ambient__noise {
  position: absolute;
  inset: 0;
  opacity: 0.025;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 1 0'/></filter><rect width='200' height='200' filter='url(%23n)'/></svg>");
  background-size: 200px 200px;
}

/* Layer: subtle 64px grid -------------------------------------- */
.t3d-ambient__grid {
  position: absolute;
  inset: 0;
  opacity: 0.025;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.6) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.6) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 70% 50% at 50% 30%, #000 35%, transparent 80%);
  -webkit-mask-image: radial-gradient(ellipse 70% 50% at 50% 30%, #000 35%, transparent 80%);
}

/* Layer: animated indigo blobs --------------------------------- */
.t3d-ambient__blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(120px);
  will-change: transform, opacity;
  opacity: 0.7;
}

/* Primary — top center, large, pulses gently. (Centred via translateX, so it
 * uses its own pulse keyframe that preserves the X centering.) */
.t3d-ambient__blob--primary {
  top: -300px;
  left: 50%;
  width: 1100px;
  height: 900px;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(94, 106, 210, 0.45) 0%, rgba(94, 106, 210, 0.18) 40%, transparent 70%);
  filter: blur(150px);
  animation: t3d-blob-pulse-centred 12s ease-in-out infinite;
}

/* Secondary — left side, drifts */
.t3d-ambient__blob--secondary {
  top: 35%;
  left: -150px;
  width: 700px;
  height: 700px;
  background: radial-gradient(circle, rgba(154, 100, 220, 0.18) 0%, rgba(94, 106, 210, 0.08) 40%, transparent 70%);
  animation: t3d-blob-drift 14s ease-in-out infinite;
}

/* Tertiary — right side, drifts opposite */
.t3d-ambient__blob--tertiary {
  top: 20%;
  right: -200px;
  width: 600px;
  height: 600px;
  background: radial-gradient(circle, rgba(60, 90, 200, 0.16) 0%, rgba(94, 106, 210, 0.06) 40%, transparent 70%);
  animation: t3d-blob-drift 16s ease-in-out infinite reverse;
}

/* Bottom accent — drifts at offset to break up the rhythm */
.t3d-ambient__blob--bottom {
  bottom: -350px;
  left: 30%;
  width: 800px;
  height: 600px;
  background: radial-gradient(circle, rgba(94, 106, 210, 0.18) 0%, transparent 65%);
  animation: t3d-blob-drift 18s ease-in-out infinite -3s;
}

@keyframes t3d-blob-pulse-centred {
  0%, 100% { transform: translateX(-50%) translateY(0) scale(1); opacity: 0.7; }
  50% { transform: translateX(-50%) translateY(-30px) scale(1.05); opacity: 0.9; }
}
@keyframes t3d-blob-drift {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0.6; }
  33%      { transform: translate3d(20px, -40px, 0) rotate(2deg); opacity: 0.8; }
  66%      { transform: translate3d(-30px, 20px, 0) rotate(-1deg); opacity: 0.5; }
}

/* Pause animations when the page is hidden (saves CPU on background tabs). */
html.t3d-page-hidden .t3d-ambient__blob {
  animation-play-state: paused;
}

/* Reduced motion: freeze blobs but keep colour ---------------------- */
@media (prefers-reduced-motion: reduce) {
  .t3d-ambient__blob,
  .t3d-ambient__blob--primary,
  .t3d-ambient__blob--secondary,
  .t3d-ambient__blob--tertiary,
  .t3d-ambient__blob--bottom { animation: none; }
}

/* Mouse-tracking spotlight (data-spotlight attr on element) --------
 * The spotlight is a radial gradient on a ::before pseudo. It's at z-index
 * 0 (negative would put it under the parent's bg). Direct element children
 * are forced to z-index: 1 so they paint ABOVE the spotlight — otherwise
 * static-positioned children would render UNDER the positioned ::before
 * (per CSS stacking context rules) and the spotlight would obscure
 * content on small cards. */
[data-spotlight] {
  position: relative;
}
[data-spotlight] > * {
  position: relative;
  z-index: 1;
}
[data-spotlight]::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    280px circle at var(--x, 50%) var(--y, 50%),
    rgba(94, 106, 210, 0.10),
    transparent 60%
  );
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease);
  pointer-events: none;
  z-index: 0;
}
[data-spotlight]:hover::before,
[data-spotlight]:focus-within::before { opacity: 1; }

/* Disable spotlight on tier cards — they have their own indigo backdrop
 * (especially the featured variant) and a spotlight on top reads as a
 * giant blob obscuring the price/features/button. */
.t3d-tier-card[data-spotlight]::before,
.t3d-tier-card::before {
  display: none !important;
}

/* Reveal animation utility: opacity 0 → 1, y 24px → 0.
 * Only hides when JS has bootstrapped (html.js-ready) — without JS,
 * content stays visible (graceful degradation + screenshot/SEO friendly). */
html.js-ready .t3d-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 700ms var(--ease),
    transform 700ms var(--ease);
  will-change: opacity, transform;
}
html.js-ready .t3d-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}
html.js-ready .t3d-reveal[data-stagger="1"] { transition-delay: 80ms; }
html.js-ready .t3d-reveal[data-stagger="2"] { transition-delay: 160ms; }
html.js-ready .t3d-reveal[data-stagger="3"] { transition-delay: 240ms; }
html.js-ready .t3d-reveal[data-stagger="4"] { transition-delay: 320ms; }
@media (prefers-reduced-motion: reduce) {
  html.js-ready .t3d-reveal { opacity: 1; transform: none; transition: none; }
}

/* Hero parallax (CSS hooks — JS sets --hero-progress: 0..1) -------- */
.t3d-parallax-hero {
  --hero-progress: 0;
  opacity: calc(1 - var(--hero-progress));
  transform: translateY(calc(var(--hero-progress) * 80px)) scale(calc(1 - var(--hero-progress) * 0.05));
  transition: transform 60ms linear, opacity 60ms linear;
  will-change: transform, opacity;
}
@media (prefers-reduced-motion: reduce) {
  .t3d-parallax-hero { transform: none; opacity: 1; }
}

/* Ensure typical content containers sit above the ambient layer (z-index: 0).
 * Scoped to specific classes/elements — must NOT apply to .t3d-nav--mobile or
 * .t3d-modal which need their own positioning. */
body > .t3d-header,
body > main,
body > .t3d-main,
body > .t3d-footer,
body > .t3d-skip-link {
  position: relative;
  z-index: var(--z-content);
}

/* Selection */
::selection { background: var(--accent-soft); color: var(--text-primary); }
