/* ==========================================================================
   SERVICES INTRO — the lead-in line and one work photo (Figma «Frame 121»)
   --------------------------------------------------------------------------
   The line makes the claim («six roles, one pair of hands»); the services
   block right after proves it. The photo belongs to the selected role and
   changes with it, as on the desktop. The photo sits in the RIGHT column only —
   the same off-axis placement as the dropped preview in the cases teaser,
   so the page keeps one compositional move instead of inventing a new one.

   Gaps — the Figma panel values, box to box:
     band   → line     56
     line   → photo    56
   ========================================================================== */

.services-intro {
  margin-top: var(--space-between);
}

.services-intro__photo {
  display: block;
  width: calc((100% - var(--gutter)) / 2);   /* one column of the 2-col grid */
  margin-top: var(--space-between);
  margin-left: auto;                          /* right column */
}

/* Six photos, one per role, stacked in one grid cell: switching roles
   cross-fades them in place, the block never changes height. */
.services-intro__photo {
  display: grid;
}

.services-intro__img {
  grid-area: 1 / 1;
  transition: opacity 300ms ease, visibility 0s linear 300ms;
}

.js .services-intro__img[hidden] {
  display: block;
  visibility: hidden;
  opacity: 0;
}

.js .services-intro__img:not([hidden]) {
  transition-delay: 0s;
}

.services-intro__img img {
  width: 100%;
  height: auto;
  aspect-ratio: 167 / 280.7;
  object-fit: cover;
}

/* Strip hover zones are desktop-only (see below).
   Clips: on phones too since 5 Nov (Alina: the desktop is «much better»
   because it moves) — the light 360-wide files (-m), only the selected
   role's, only while the photo is on screen (js/services-video.js);
   Save-Data and "reduce motion" keep the photos. Stacked over the photos
   in the same grid cell, invisible until the clip is really playing
   (.is-on), then faded in over its own first frame = the photo. */
.services-intro__zone {
  display: none;
}

.services-intro__video {
  grid-area: 1 / 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 250ms ease;
}

.services-intro__video.is-on {
  opacity: 1;
}

/* The two gaps of the desktop strip mask, as animatable lengths: a
   registered custom property can transition, a plain one would jump. */
@property --gap-1 {
  syntax: "<length>";
  inherits: false;
  initial-value: 10px;
}

@property --gap-2 {
  syntax: "<length>";
  inherits: false;
  initial-value: 10px;
}

/* --------------------------------------------------------------------------
   DESKTOP (Figma «Frame 50», 1920)
   Intro and roles become one block: text on the left (643 of 1762),
   the role's photo on the right (636 × 1069), cut into three vertical
   strips with 10-px gaps — the Figma mask, done with a CSS mask so the
   photo stays one image. The left column is centred against the photo.

   Height cap: drawn at 1069 tall, the photo is taller than a real
   1920 × 1080 window (~900 px of page once the browser's own bars are
   gone), so it could never be seen whole. It is now the Figma size OR
   the screen minus 56 above and 56 below — whichever is smaller — and its
   width follows the 636 : 1069 proportion, staying pinned to the right
   margin. The text column keeps its Figma width.
   -------------------------------------------------------------------------- */
@media (min-width: 64em) {
  .services-block {
    --photo-h: min(
      calc(var(--content) * 1069 / 1762),
      calc(100vh - 2 * var(--space-between))
    );
    --photo-h: min(
      calc(var(--content) * 1069 / 1762),
      calc(100svh - 2 * var(--space-between))
    );
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: var(--photo-h);
    margin-top: var(--space-between);           /* 56 under the band */
    padding-right: calc(var(--content) * 1119 / 1762);
  }

  .services-intro {
    margin-top: 0;
  }

  .services-intro .t-body {
    max-width: 31.2rem;                         /* 499 */
  }

  .services-intro__photo {
    position: absolute;
    top: 50%;                                   /* centred on the block: on */
    transform: translateY(-50%);                /* short laptops the text   */
    right: var(--page-margin);                  /* column can be the taller */
    width: calc(var(--photo-h) * 636 / 1069);
    margin: 0;
    /* Three strips of one picture. S = one strip's width; each gap is
       drawn around its own centre line (S + 5, 2S + 15), so as a gap
       closes (--gap-n → 0) the two strips meet in the middle and the
       picture underneath simply shows through — nothing moves. */
    --gap-1: 10px;
    --gap-2: 10px;
    --strip: calc((100% - 20px) / 3);
    -webkit-mask-image: linear-gradient(to right,
      #000 0 calc(var(--strip) + (10px - var(--gap-1)) / 2),
      transparent 0 calc(var(--strip) + (10px + var(--gap-1)) / 2),
      #000 0 calc(var(--strip) * 2 + 10px + (10px - var(--gap-2)) / 2),
      transparent 0 calc(var(--strip) * 2 + 10px + (10px + var(--gap-2)) / 2),
      #000 0);
    mask-image: linear-gradient(to right,
      #000 0 calc(var(--strip) + (10px - var(--gap-1)) / 2),
      transparent 0 calc(var(--strip) + (10px + var(--gap-1)) / 2),
      #000 0 calc(var(--strip) * 2 + 10px + (10px - var(--gap-2)) / 2),
      transparent 0 calc(var(--strip) * 2 + 10px + (10px + var(--gap-2)) / 2),
      #000 0);
    transition:
      --gap-1 500ms cubic-bezier(0.2, 0.7, 0.2, 1),
      --gap-2 500ms cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  /* --- Hover: a strip joins its neighbour — for good -----------------------
     Four invisible zones over the picture, split at the gaps' centre
     lines: strip 1 → closes gap 1; strip 3 → closes gap 2; strip 2 joins
     the neighbour on the side the pointer is on (its left half → gap 1,
     right half → gap 2). js/services.js latches each join into a class
     (.is-joined-1 / -2), so a closed gap never reopens; the :has() rules
     are the no-JS fallback (join while hovered). Mouse only. */
  .services-intro__zone {
    position: absolute;
    z-index: 1;
    top: 0;
    bottom: 0;
    display: block;
  }

  .services-intro__zone--1 {
    left: 0;
    width: calc((100% - 20px) / 3 + 5px);
  }

  .services-intro__zone--2a {
    left: calc((100% - 20px) / 3 + 5px);
    right: 50%;
  }

  .services-intro__zone--2b {
    left: 50%;
    right: calc(100% - (100% - 20px) * 2 / 3 - 15px);
  }

  .services-intro__zone--3 {
    left: calc((100% - 20px) * 2 / 3 + 15px);
    right: 0;
  }

  @media (hover: hover) and (pointer: fine) {
    .services-intro__photo:has(.services-intro__zone--1:hover, .services-intro__zone--2a:hover) {
      --gap-1: 0px;
    }

    .services-intro__photo:has(.services-intro__zone--2b:hover, .services-intro__zone--3:hover) {
      --gap-2: 0px;
    }

    .services-intro__photo.is-joined-1 {
      --gap-1: 0px;
    }

    .services-intro__photo.is-joined-2 {
      --gap-2: 0px;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .services-intro__photo {
      transition: none;
    }
  }
}
