/* ════════════════════════════════════════════════════════════
   DEPTH LAYER — styling for js/depth.js

   Three scroll speeds on screen at once is what reads as depth. This
   file styles the three layers; js/depth.js builds them and drives them:

     .ehd-bg     photographic backdrop   ~1x  (yPercent -8 → 8)
     .ehd-wm     giant watermark word    ~2x  (yPercent 18 → -18)
     .ehd-drift  blurred colour plane    ~4x  (yPercent -30 → 30)
     .ehd-marquee  running word band     (rAF, not scroll-scrubbed)

   Nothing in here applies unless js/depth.js has run — every element it
   styles is created at runtime. A reduced-motion visitor gets the page
   exactly as it was, because the script bails before its first DOM write.

   Revert = remove the two depth tags from the page.
   ════════════════════════════════════════════════════════════ */

/* ── SHARED ───────────────────────────────────────────────────
   Every layer here is decoration. z-index 0 puts them above the
   section's ::before background (the slanted sections paint their colour
   there) and below .s3d__in, which holds z-index 1 and carries the real
   content. pointer-events:none is not optional — these span whole
   sections and must never eat a click on the form or the CTA. */
.ehd-bg,
.ehd-drift,
.ehd-wm,
.ehd-marquee {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

/* ── 1. PHOTOGRAPHIC BACKDROP (the SLOW layer) ────────────────
   overflow:hidden lives on this wrapper, not on the section: the dark
   and bone slant variants are explicitly overflow:visible so their
   clipped ::before can bleed past the box, and changing that would break
   the diagonal dividers.

   The mask is why there is no geometry maths here. A slant-top section's
   visible top edge is a diagonal cut into the top ~112px (--slant); a
   straight-edged photo would poke out above it into the section before.
   Fading the top of the layer to nothing hides the seam whatever the
   slant is. The mask is static — only the <img> inside moves — so it
   costs one composite, not per-frame work.

   34%, not 22%: measured on this page, at 22% the photo reached the top
   of #why's section header and pushed its 12.8px eyebrow (bone at 50%
   alpha, which the site already ships at a marginal 4.73:1) down to
   4.40:1 — under the 4.5 AA floor. 34% clears the whole header block —
   eyebrow, h2 and lead — so the photo only ever appears behind the body
   copy and the cards, which is the better-looking version anyway. */
.ehd-bg {
  inset: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 34%, #000 86%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 34%, #000 86%, transparent 100%);
}

/* The source's exact geometry: 128% tall, hung 14% above the top, so a
   ±8–12% yPercent tween never exposes an edge. */
.ehd-bg__img {
  position: absolute;
  left: 0;
  top: -14%;
  width: 100%;
  height: 128%;
  object-fit: cover;
  pointer-events: none;
  /* 8% — the source's own figure for a full-bleed backdrop behind copy.
     Measured on this site: bone text on near-black keeps a 14:1 contrast
     ratio at this opacity, so it is texture, not a background image. */
  opacity: 0.08;
  will-change: transform;
}

/* ── 2. DRIFT PLANES (the FAST layer) ─────────────────────────
   NO filter: blur(). Measured on the sibling project: animating blur on
   large elements is the single most expensive thing on the page and was
   the cause of mobile jank there. A radial-gradient IS the blur — it is
   rasterised once, then only ever translated, which the compositor does
   for free.

   Hidden below 768px as well. At 390px wide a 46vw disc is 180px and
   sits directly under the text column, so it stops being atmosphere and
   starts being haze over the copy — and two extra composited layers on a
   phone GPU buy nothing you can see. */
.ehd-drift {
  width: 46vw;
  height: 46vw;
  border-radius: 9999px;
  will-change: transform;
}

.ehd-drift--a {
  left: -14vw;
  top: 0;
  background: radial-gradient(closest-side,
    rgba(92, 138, 46, 0.30),
    rgba(92, 138, 46, 0.13) 52%,
    rgba(92, 138, 46, 0) 78%);
}

.ehd-drift--b {
  right: -12vw;
  bottom: 0;
  width: 42vw;
  height: 42vw;
  background: radial-gradient(closest-side,
    rgba(245, 241, 234, 0.13),
    rgba(245, 241, 234, 0.05) 52%,
    rgba(245, 241, 234, 0) 78%);
}

@media (max-width: 767px) {
  .ehd-drift { display: none; }
}

/* ── 3. WATERMARK WORD (the MIDDLE layer) ─────────────────────
   Same values as the source and as the four words js/s3d.js already
   places, so the two sets read as one system. 26vw means about seven
   characters fill the viewport; overflow:hidden catches anything longer
   rather than letting it widen the page. */
.ehd-wm {
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.ehd-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. Stronger than this stops being texture and competes 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);
}

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

/* ── 4. MARQUEE BAND ──────────────────────────────────────────
   Absolutely positioned inside the host section's TOP PADDING rather than
   inserted as a new block between two sections. That is the whole trick:
   --section-pad is 120–188px of empty space (84px on phones), so a 72px
   band drops into it and the page height does not change by a single
   pixel — which means not one existing ScrollTrigger's cached start/end
   moves. Adding it to the flow would have pushed every trigger below it
   down by the band height and needed a re-measure to correct, and a
   ScrollTrigger.refresh() while Lenis owns the scroll position corrupts
   every range on the page.

   TOP padding, not bottom: measured on this page, #wall-of-work carries
   z-index 3 and an opaque near-black background and its stage is pulled
   up by -55vh, so the bottom 495px of the section above it is painted
   over. A band in that bottom padding was invisible on desktop (visible
   on a phone, where the overlap is smaller) — which is exactly the sort
   of thing only a screenshot catches. The host's top padding is clear:
   the section above it is flat-bottomed and nothing overlaps down. */
.ehd-marquee {
  left: 0;
  right: 0;
  top: calc((var(--section-pad) - 72px) / 2);
  height: 72px;
  display: flex;
  align-items: center;
  overflow: hidden;
  border-top: 1px solid rgba(28, 28, 25, 0.12);
  border-bottom: 1px solid rgba(28, 28, 25, 0.12);
}

.ehd-marquee__track {
  display: flex;
  width: max-content;
  align-items: center;
  white-space: nowrap;
  will-change: transform;
}

/* The spacing is margin, NOT flex gap. The track holds the word list
   twice and wraps at scrollWidth/2; a flex gap adds one extra gap
   between the two halves, so the halves are not the same width and the
   wrap lands half a gap out every lap. A right margin on each item makes
   the two halves byte-identical in width. */
.ehd-marquee__item {
  display: flex;
  align-items: center;
  margin-right: 3rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(0.95rem, 1.5vw, 1.5rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(28, 28, 25, 0.30);
}

.ehd-marquee__item::after {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 3rem;
  transform: rotate(45deg);
  background: var(--olive);
  opacity: 0.5;
}

@media (max-width: 767px) {
  .ehd-marquee {
    height: 52px;
    top: calc((var(--section-pad) - 52px) / 2);
  }
  .ehd-marquee__item { margin-right: 1.75rem; }
  .ehd-marquee__item::after { margin-left: 1.75rem; }
}

/* ── REDUCED MOTION ───────────────────────────────────────────
   js/depth.js returns before it writes anything, so there is normally
   nothing to hide. This is the belt-and-braces case where the preference
   is switched on after the layers already exist. */
@media (prefers-reduced-motion: reduce) {
  .ehd-bg,
  .ehd-drift,
  .ehd-wm { display: none; }
  .ehd-marquee__track { transform: none !important; }
}
