/* ============================================================
   IMMERSIVE LAYER — WebGL background + scroll-driven 3D depth
   Loaded after each page's own <style> block so it wins the cascade.
   ============================================================ */

#webgl-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  background: var(--ink);
}

/* Scroll-driven 3D reveal — progress (--p, 0 to 1) is written by immersive.js
   as the element crosses the viewport, giving continuous scroll-scrubbed motion
   instead of a one-shot fade. Falls back to the .visible binary state if JS
   for any reason doesn't run (progressive enhancement, not a hard dependency). */
.reveal, .reveal-left, .reveal-right {
  --p: 0;
  opacity: var(--p);
  will-change: transform, opacity;
}
.reveal {
  transform: perspective(1400px) translateY(calc((1 - var(--p)) * 90px)) rotateX(calc((1 - var(--p)) * 18deg)) translateZ(calc((1 - var(--p)) * -140px));
}
.reveal-left {
  transform: perspective(1400px) translateX(calc((1 - var(--p)) * -90px)) rotateY(calc((1 - var(--p)) * -24deg)) translateZ(calc((1 - var(--p)) * -140px));
}
.reveal-right {
  transform: perspective(1400px) translateX(calc((1 - var(--p)) * 90px)) rotateY(calc((1 - var(--p)) * 24deg)) translateZ(calc((1 - var(--p)) * -140px));
}
.reveal.visible, .reveal-left.visible, .reveal-right.visible { opacity: 1; }

@media (max-width: 640px) {
  .reveal, .reveal-left, .reveal-right {
    transform: translateY(calc((1 - var(--p)) * 38px)) !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  #webgl-bg { display: none; }
  .reveal, .reveal-left, .reveal-right {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* WebGL photo layer — canvas overlays the real <img> it mirrors */
.preview-img, .proof-image-main, .story-img-main, .story-img-accent, .service-img {
  position: relative;
}
.gl-photo-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.preview-img img, .proof-image-main img, .story-img-main img, .story-img-accent img, .service-img img {
  transition: opacity 0.1s linear;
}

/* Tilt cards — mouse-tracked 3D tilt + sheen for price/product cards.
   Transform is set inline by JS (tilt-cards.js) so it always wins over
   any of the card's own :hover transform rules (inline beats class specificity). */
.tilt-card { transition: transform 0.5s var(--ease); }
.tilt-card.tilting { transition: transform 0.05s linear; }
.tilt-sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at 50% 50%, rgba(232,204,128,0.16), transparent 55%);
  transition: opacity 0.4s var(--ease);
}
