/* Tech Matic 3D depth layer.
   Only perspective, flattening and decorative surfaces live here. Every
   animated offset is set by tm-3d.js through GSAP, so a page without
   JavaScript or without GSAP renders exactly as it did before. */

/* Shared vanishing point for a group of cards. The class is added by
   tm-3d.js, so markup without the script keeps its original stacking. */
.tm-3d-stage {
  perspective: 1500px;
  perspective-origin: 50% 42%;
}

@media (max-width: 900px) {
  .tm-3d-stage {
    perspective: 1100px;
  }
}

/* Cards keep their own children flat; only the card plane rotates.
   No will-change here on purpose: blog.html alone carries 141 of these, and
   permanently promoting that many elements costs more memory than the hint
   saves. GSAP already promotes each card while its tween is running. */
.tm-3d-card {
  transform-style: flat;
}

/* Rotating a card over a white page needs a shadow that follows the tilt,
   otherwise the depth reads as a flat skew. */
.tm-3d-card.tm-3d-lift {
  box-shadow: 0 18px 44px -26px rgba(13, 29, 74, .34);
}

.tm-3d-heading {
  transform-style: flat;
}

/* Hero depth ------------------------------------------------------------- */

.tm-3d-hero-stage {
  perspective: 1400px;
  perspective-origin: 50% 50%;
}

.tm-3d-hero-layer {
  will-change: transform;
  transform-style: flat;
}

/* Gallery tilt ----------------------------------------------------------- */

/* Gallery pages carry up to 59 tiles, so promotion is scoped to the one
   tile the pointer is actually over. */
.tm-3d-tilt {
  position: relative;
  transform-style: flat;
  backface-visibility: hidden;
}

.tm-3d-tilt.tm-3d-tilt-active {
  will-change: transform;
}

/* A moving highlight sells a tilt far more than the rotation alone.
   --tm-gx / --tm-gy follow the pointer; the default keeps it invisible. */
.tm-3d-tilt::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity .32s ease;
  background: radial-gradient(
    38% 38% at var(--tm-gx, 50%) var(--tm-gy, 50%),
    rgba(255, 255, 255, .42) 0%,
    rgba(255, 255, 255, 0) 72%
  );
  mix-blend-mode: soft-light;
  border-radius: inherit;
  z-index: 3;
}

.tm-3d-tilt.tm-3d-tilt-active::after {
  opacity: 1;
}

/* Pinned depth scene ----------------------------------------------------- */

.tm-3d-scene.tm-3d-scene-active {
  position: relative;
}

/* The scene heading stays legible while the cards travel through depth. */
.tm-3d-scene.tm-3d-scene-active .section-title,
.tm-3d-scene.tm-3d-scene-active .gallery-intro {
  position: relative;
  z-index: 4;
}

/* Case study page helpers ------------------------------------------------ */

.tm-gallery-single {
  grid-template-columns: minmax(0, 1fr);
  max-width: 980px;
  margin-inline: auto;
}

.tm-gallery-single .gallery-item img {
  width: 100%;
  height: auto;
  object-fit: contain;
}

.tm-live-link {
  margin-top: 34px;
  text-align: center;
}

/* Accessibility ---------------------------------------------------------- */

/* A visitor who asks for less motion gets a flat, still page. tm-3d.js also
   reverts its inline transforms, so this only removes the decoration. */
@media (prefers-reduced-motion: reduce) {
  .tm-3d-stage,
  .tm-3d-hero-stage {
    perspective: none;
  }

  .tm-3d-hero-layer,
  .tm-3d-tilt.tm-3d-tilt-active {
    will-change: auto;
  }

  .tm-3d-tilt::after {
    display: none;
  }

  .tm-3d-card.tm-3d-lift {
    box-shadow: none;
  }
}
