/* ════════════════════════════════════════════════════════════
   SECTION 3D — styling for the runtime flip wrapper (js/s3d.js)

   The flip wrapper, the watermark, and the one rule that keeps a
   second owner off an element while GSAP animates it. Everything
   else about the entrance is animated inline by GSAP.

   Nothing in here applies unless js/motion.js or js/s3d.js has run:
   they build the .s3d__in wrapper and the .s3d__wm word, and they
   add and remove .eh-gsap-owned. So a reduced-motion visitor (where
   both scripts bail before touching the DOM) sees exactly the page
   as it was.
   ════════════════════════════════════════════════════════════ */

/* ── ONE OWNER AT A TIME ──────────────────────────────────────
   Added by window.EH_own() (js/motion.js) to any element GSAP is
   about to animate, removed again when that entrance completes.

   The cards this lands on carry CSS transitions of their own for
   their hover lifts — .calc-card `transform .2s`, .cm-card
   `opacity/transform .8s`, .testimonial-card `.85s`, .faq-item
   `.7s`, .service-card `.12s`, .project-card `.3s`,
   .guarantee-card `.2s`. With one of those live, the browser
   re-eases every frame GSAP writes, and when GSAP reads the
   element back to decide where the tween should end it gets the
   from-state the transition is still holding — so the tween
   finishes exactly where it started and the card can only fade,
   then teleport. Measured on #past-cards .calc-card: rotateX
   pinned at 42.00deg for the entire 433ms entrance (per-frame
   delta 0.000), then 42deg gone in one frame.

   animation-name too, for the same reason in its keyframe form: a
   running CSS animation outranks inline styles outright, so GSAP's
   writes are discarded in silence (the lesson already learned on
   .hero__content — see js/motion.js).

   This is a suppression, not a replacement: nothing here decides
   how anything looks, and the moment GSAP lets go the element is
   back on its own stylesheet with its hover transitions intact. */
.eh-gsap-owned {
  transition-property: none !important;
  animation-name: none !important;
}

/* The inner wrapper carries the flip.

   position/z-index are NOT decoration. The wrapper now sits where
   > .container used to, between the section and its content, and the
   slanted sections paint their background in a ::before at z-index 0 —
   so without a positioned wrapper above it the background would cover
   the content, and would do so *only during the flip* (a transform makes
   the wrapper a stacking context, trapping the .container's own z-index
   inside it). Every target section was checked: none has an absolutely
   positioned child of its own, so becoming the containing block here is
   free. */
.s3d__in {
  position: relative;
  z-index: 1;
  will-change: transform;
}

/* will-change is a standing request for a compositor layer. Fourteen of
   them for the whole visit is real memory, and the flip is a one-shot —
   js/s3d.js adds this class when the tween completes. */
.s3d__in.is-s3d-done {
  will-change: auto;
}

/* The four slant variants each lift their .container above the ::before
   background with a direct-child selector. The wrapper broke that
   relationship, so restore the exact same rules one level deeper —
   otherwise a positioned element inside .container loses its anchor. */
.section--warm.slant-top > .s3d__in > .container,
.section--warm.slant-both > .s3d__in > .container,
.section--dark.slant-top > .s3d__in > .container,
.section--dark.slant-bottom > .s3d__in > .container,
.section--dark.slant-both > .s3d__in > .container,
.section.slant-bone > .s3d__in > .container {
  position: relative;
  z-index: 1;
}

/* ── WATERMARK ────────────────────────────────────────────────
   A single giant word drifting behind a section (yPercent 18 → -18,
   scrubbed). z-index 0 puts it above the section's ::before background
   layer and below .s3d__in, which holds z-index 1. */
.s3d__wm {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden; /* 26vw type is wider than the viewport by design */
  pointer-events: none; /* it spans the whole section — it must never eat a click */
  -webkit-user-select: none;
  user-select: none;
}

.s3d__wm span {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 26vw;
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  white-space: nowrap;
  /* 4% ink. Anything stronger stops being texture and starts competing
     with the copy. Hex fallback first for engines without color-mix. */
  color: rgba(28, 28, 25, 0.04);
  color: color-mix(in srgb, var(--near-black) 4%, transparent);
}

.s3d__wm--ondark span {
  color: rgba(255, 255, 255, 0.04);
  color: color-mix(in srgb, var(--white) 4%, transparent);
}
