/* =========================================================================
   template-parts/sections/section-team.php
   Moved out of the partial's inline <style id="es-team-carousel-css"> on the owner's
   instruction, 10 Sep 2026. en_print_css() (inc/css-loader.php) prints this
   file's <link> where the <style> used to be, once per page, so every page
   that renders this section shares this one file.
   ========================================================================= */

/* ══════════════════════════════════════════════════════════
   ARCH CAROUSEL
   Card size, spacing and the depth of the curve are decided
   here and nowhere else. The script measures the laid-out
   result rather than recomputing it, so there is one source
   of truth for the geometry.
   ══════════════════════════════════════════════════════════ */
.es-team__carousel {
  /* 46vw so the card grows with a narrow screen instead of collapsing to the
     floor: a 15.5vw term bottomed out at its minimum on every phone, leaving
     roughly 100px of text column, which a role like "Business Development
     Executive" needed five lines for. The panel then grew upward until it
     covered the face. The floor is now wide enough for that role in two
     lines, and the ceiling still lands where the desktop arch wants it. */
  --es-tc-w:   clamp(196px, 46vw, 216px);
  --es-tc-gap: clamp(12px, 1.6vw, 24px);
  --es-tc-arc: clamp(12px, 1.5vw, 21px);   /* drop per step out */
  position: relative;
}

/* Bleeds past the container so the arch runs to the page edges
   the way the reference does, and clips there. */
.es-team__viewport {
  margin-inline: calc(50% - 50vw);
  padding-block: var(--space-5);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.es-team__viewport::-webkit-scrollbar { display: none; }

.es-team__track {
  display: flex;
  gap: var(--es-tc-gap);
  width: max-content;
  margin: 0;
  padding: 0 var(--container-pad);
  list-style: none;
}

/* ── Enhanced state ────────────────────────────────────────
   Until the script runs, the block above is a plain scrollable
   row and every card is upright and in colour. `is-ready`
   switches it to the arch. Nothing here is required for the
   content to be reachable. */
.es-team__carousel.is-ready .es-team__viewport {
  overflow: hidden;
  /* Top: room for the lifted centre card and its shadow.
     Bottom: the arch drop on the outer cards plus the extra height the
     active card takes. The viewport clips, so anything not reserved here
     would be cut off. */
  padding-block: calc(var(--es-tc-arc) * 2) calc(var(--es-tc-arc) * 3);
}

.es-team__carousel.is-ready .es-team__track {
  padding: 0;
  margin-left: 50%;
  /* Centre the active slide, plus whatever the drag is currently offset by.
     One transform, so it stays on the compositor.

     --es-offset is the measured distance from the start of the track to the
     middle of the active card, written by the script. Deriving it here from
     the clamp() above instead would look tidier but is wrong: a vw inside a
     transform's calc() is not reliably recomputed when the viewport resizes,
     so the arch drifts off centre after a rotate or a window drag while the
     flex layout, which does recompute, moves under it. Measuring keeps the
     two in step and leaves the clamp() as the single source of size. */
  transform: translate3d(calc(var(--es-drag, 0px) - var(--es-offset, 0px)), 0, 0);
  transition: transform .62s cubic-bezier(.22, .61, .36, 1);
  cursor: grab;
  touch-action: pan-y;
}

.es-team__carousel.is-dragging .es-team__track {
  transition: none;
  cursor: grabbing;
}

/* The rebase jump must not be animated or the loop seam shows. */
.es-team__carousel.is-jumping .es-team__track { transition: none; }

.es-team__slide {
  flex: 0 0 var(--es-tc-w);
  width: var(--es-tc-w);
}

.es-team__carousel.is-ready .es-team__slide {
  opacity: var(--op, 1);
  transition: opacity .45s var(--ease-out);
}

/* ── Figure ────────────────────────────────────────────────
   The box that rides the arch: dropped and shrunk in proportion
   to how far off centre it is. Both values are written by the
   script as plain numbers.

   The height is fixed at the ACTIVE card's height on every
   figure, active or not, so the row reserves the tallest state
   up front and the card below grows inside that box rather than
   resizing it. That is what keeps the layout height constant.

   Without it the section bobbed once per rotation. `aspect-ratio`
   on the card is a LAYOUT property, so animating it resizes the
   flex row: on each step the outgoing card shrank 4.4 -> 4 while
   the incoming one grew 4 -> 4.4 on the same easing, so the
   tallest card at the half way point was 4.2, shorter than either
   end state. The track contracted and re-expanded, and everything
   below the carousel, the join CTA included, moved with it. */
.es-tc-figure {
  position: relative;
  height: calc(var(--es-tc-w) * 4.4 / 3);
  transform: translateY(calc(var(--ao, 0) * var(--es-tc-arc))) scale(var(--sc, 1));
  transition: transform .62s cubic-bezier(.22, .61, .36, 1);
}

/* ── Card ──────────────────────────────────────────────────
   3/4 rather than 5/6: a taller card gives the glass panel more
   room under the face, and it narrows the slice of a square
   photo the card shows, which is what lets the circular
   portraits below be zoomed less to hide their cut edge. */
.es-tc-card {
  /* Sits at the top of the figure's reserved box and grows downward into the
     slack below, which is exactly where it grew before. Every card therefore
     renders in the same place it always did; the only thing that changed is
     that the box around it no longer resizes. Left/right pin the width,
     aspect-ratio gives the height. */
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--gray-200);
  box-shadow: var(--shadow-sm);
  transition: box-shadow .45s var(--ease-out),
              aspect-ratio .62s cubic-bezier(.22, .61, .36, 1);
}

/* The centre card stands about 10% taller than its neighbours, so the eye
   lands on it before the colour and the lift register.

   Height only, via the aspect ratio rather than a scaleY: the width stays
   put so the arch spacing over it, and stretching the box would stretch the
   portrait and the type with it.

   This resizes a layout box, so on its own it moves the row. The figure
   above reserves this height on every card to absorb that, which is the
   only reason the section below does not move as the arch rotates. Do not
   drop that reserve without replacing the growth with a transform. */
.es-team__slide.is-active .es-tc-card {
  aspect-ratio: 3 / 4.4;
  box-shadow: var(--shadow-lg);
}

/* ── Portrait ──────────────────────────────────────────────
   Black and white at rest. The active card is the only one in
   colour, and hovering any card brings its colour back so the
   row reads as interactive. */
/* Two independent zooms multiplied into one transform: --es-fit is the
   constant crop that hides a circular source, --es-hover is the momentary
   nudge on hover. Kept as separate factors because a single `transform` on
   hover would otherwise wipe out the fit and snap the circle back. */
.es-tc-photo {
  --es-fit: 1;
  --es-hover: 1;
  --es-lift: 0px;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transform: translateY(var(--es-lift)) scale(calc(var(--es-fit) * var(--es-hover)));
  filter: grayscale(1);
  transition: filter .5s var(--ease-out), transform .6s var(--ease-out);
}

/* ── Circular source ───────────────────────────────────────
   The bundled portraits are circles cut out of a square canvas
   with the corners left transparent, so dropped into a
   rectangular card they render as a disc on a grey panel.

   There is no way to recover pixels that were deleted, so the
   card zooms until the visible rectangle sits wholly inside the
   circle. For a 3/4 card that boundary is 1.25; 1.36 leaves
   margin, and the 4% nudge down buys back headroom so the crop
   does not clip hair. Costs some sharpness, since the 261px
   source is being upscaled. Applied per person, only where no
   square original was found, so a real square photo renders
   untouched at full quality the moment one is added. */
.es-tc-card--round .es-tc-photo {
  --es-fit: 1.36;
  --es-lift: 4%;
}

.es-team__slide.is-active .es-tc-photo,
.es-tc-figure:hover .es-tc-photo { filter: grayscale(0); }

.es-tc-figure:hover .es-tc-photo { --es-hover: 1.04; }

/* Scrim under the glass panel. Guarantees the name and role
   clear AA no matter how bright the photo behind them is,
   which a translucent panel on its own cannot promise. */
.es-tc-card::after {
  content: "";
  position: absolute;
  inset: 45% 0 0 0;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(12, 10, 8, 0.55));
}

/* ── Glass info panel ──────────────────────────────────────
   Frosted bar inset from the card edges, carrying the name and
   role. The backdrop filter darkens as well as blurs, so the
   composite behind the white text stays dark whatever the
   photo does. Browsers without backdrop-filter get a heavier
   flat fill instead, which lands at the same contrast. */
.es-tc-meta {
  position: absolute;
  z-index: 2;
  right: var(--space-2);
  bottom: var(--space-2);
  left: var(--space-2);
  padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius-md);
  background: rgba(18, 16, 14, 0.42);
  -webkit-backdrop-filter: blur(14px) saturate(130%) brightness(0.62);
  backdrop-filter: blur(14px) saturate(130%) brightness(0.62);
  box-shadow: 0 8px 24px -14px rgba(0, 0, 0, 0.9);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .es-tc-meta { background: rgba(18, 16, 14, 0.82); }
}

/* Type scales with the card rather than sitting at a fixed size, so a phone
   gets a panel in proportion to the photo instead of one that eats it.
   Line clamping is the backstop: however long a role is, the panel can only
   ever reach four lines, so it cannot climb over the face again. */
.es-tc-name,
.es-tc-role {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* The one h3 on either page deliberately below --fs-card-title, and the
   reason is the component rather than the type scale: this name sits in a
   glass panel inside a 196-216px portrait card on an arch. At the 18-20px
   every other card heading uses, a two-word name wraps to two lines and the
   panel grows up over the face it is labelling. Held between --fs-caption
   and --fs-body-sm so it is still on the scale, just at the bottom of it. */
.es-tc-name {
  margin: 0;
  color: var(--text-inverse);
  font-size: clamp(var(--fs-caption), 0.5vw + 11px, var(--fs-body-sm));
  font-weight: var(--font-bold);
  line-height: 1.3;
  letter-spacing: var(--tracking-normal);
}

/* 0.88 rather than a lighter wash: against the darkest the panel is allowed
   to get, that is the point where the role still clears AA at 13px. */
/* Floor raised from 11px to --fs-eyebrow (12px), which is the smallest size
   anything on the site is set at. 11px was below that floor and it landed on
   a phone, over a photograph, in a translucent white. The ceiling is
   unchanged, so the desktop arch is exactly as it was. */
.es-tc-role {
  margin: 3px 0 0;
  color: rgba(255, 255, 255, 0.88);
  font-size: clamp(var(--fs-eyebrow), 0.4vw + 10px, var(--fs-caption));
  line-height: 1.3;
}

/* No hover on touch, so the active card is the only one that
   carries colour there. */
@media (hover: none) {
  .es-tc-photo { filter: grayscale(1); }
  .es-team__slide.is-active .es-tc-photo { filter: grayscale(0); }
}

/* ── Join line ─────────────────────────────────────────────
   The grid puts this in the last cell. A text card inside a
   photo arch would break the rhythm, so here it closes the
   section instead. */
.es-team__join-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  margin-top: var(--gap-fluid-md);
  text-align: center;
}

.es-team__join-line p {
  margin: 0;
  color: var(--text-body);
  font-size: var(--fs-body);
}

.es-team__join-line b {
  color: var(--brand-500);
  font-weight: var(--font-extrabold);
  letter-spacing: var(--tracking-normal);
}

@media (prefers-reduced-motion: reduce) {
  .es-team__carousel.is-ready .es-team__track,
  .es-tc-figure,
  .es-tc-card,
  .es-team__slide.is-active .es-tc-card,
  .es-tc-photo,
  .es-team__slide { transition: none; }
  /* Drops the hover nudge but keeps --es-fit, which is a crop, not motion. */
  .es-tc-figure:hover .es-tc-photo { --es-hover: 1; }
}

/* ══════════════════════════════════════════════════════════
   CARD REDESIGN, owner's reference, 17 Sep 2026
   White card, photo on top in its own rounded frame, a plain info strip
   under it: name, role, and a round arrow mark on the right. Full colour
   on every card (no greyscale). The arch, its geometry, the active-card
   growth and the reserved figure height above are unchanged.
   ══════════════════════════════════════════════════════════ */
.es-team__carousel .es-tc-card {
  display: flex;
  flex-direction: column;
  padding: 6px;
  border: 1px solid var(--border-subtle);
  background: var(--bg-surface);
  box-shadow: 0 6px 18px -10px rgba(22, 20, 16, 0.22);
}

.es-team__carousel .es-team__slide.is-active .es-tc-card {
  box-shadow: 0 18px 40px -18px rgba(22, 20, 16, 0.35);
}

/* No dark scrim: the name sits on white now. */
.es-team__carousel .es-tc-card::after { content: none; }

.es-tc-photo-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  border-radius: calc(var(--radius-lg) - 5px);
  background: var(--gray-100);
}

.es-team__carousel .es-tc-photo {
  filter: none;
}

@media (hover: none) {
  .es-team__carousel .es-tc-photo,
  .es-team__carousel .es-team__slide.is-active .es-tc-photo { filter: none; }
}

.es-team__carousel .es-tc-meta {
  position: static;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  flex: 0 0 auto;
  padding: 10px 6px 4px 8px;
  border: 0;
  border-radius: 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
}

.es-tc-meta__text { min-width: 0; }

.es-team__carousel .es-tc-name {
  color: var(--text-heading);
  font-size: clamp(var(--fs-caption), 0.4vw + 11px, 14px);
  -webkit-line-clamp: 1;
  line-clamp: 1;
}

.es-team__carousel .es-tc-role {
  margin-top: 2px;
  color: var(--text-muted);
  font-size: var(--fs-eyebrow);
  -webkit-line-clamp: 1;
  line-clamp: 1;
}

.es-tc-go {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--bg-surface);
  color: var(--text-heading);
  transition: background-color var(--duration-normal) var(--ease-out),
              border-color var(--duration-normal) var(--ease-out),
              color var(--duration-normal) var(--ease-out);
}

.es-team__slide.is-active .es-tc-go {
  border-color: var(--brand-500);
  color: var(--brand-500);
}

/* One font family in the team card (owner, 17 Sep 2026): the card and
   everything inside it use the site font, whatever a global heading or
   paragraph rule elsewhere would otherwise apply to the h3 and p. */
.es-team__carousel .es-tc-card,
.es-team__carousel .es-tc-card :is(h3, p, span, .es-tc-name, .es-tc-role) {
  font-family: var(--font-body);
}

.es-team__carousel .es-tc-name {
  letter-spacing: var(--tracking-normal);
}

/* ══════════════════════════════════════════════════════════
   SMOOTH ARCH, 17 Sep 2026
   es-team-carousel.js now draws the track offset, the arch drop, the scale
   and the centre card's height every frame from one spring-driven position,
   so the CSS transitions on those moving parts are switched off here. They
   were the source of the jerk: each step restarted half-finished
   transitions on three nested layers at once.
   ══════════════════════════════════════════════════════════ */
.es-team__carousel.is-ready .es-team__track {
  transition: none;
  will-change: transform;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.es-team__carousel.is-ready .es-team__slide { transition: none; }

.es-team__carousel.is-ready .es-tc-figure {
  transition: none;
  will-change: transform;
  contain: layout;
}

.es-team__carousel.is-ready .es-tc-card,
.es-team__carousel.is-ready .es-team__slide.is-active .es-tc-card {
  aspect-ratio: auto;
  transition: box-shadow .45s var(--ease-out);
}

/* The loop rebase swaps the centre card for its clone: nothing may animate. */
.es-team__carousel.is-jumping .es-tc-card,
.es-team__carousel.is-jumping .es-tc-go { transition: none !important; }

.es-team__carousel.is-ready .es-tc-photo { pointer-events: none; }

/* ── LinkedIn button ───────────────────────────────────────
   When a person has a LinkedIn URL the round mark in the strip becomes the
   link and shows the LinkedIn glyph. */
a.es-tc-go {
  text-decoration: none;
  cursor: pointer;
}

a.es-tc-go:hover,
a.es-tc-go:focus-visible {
  border-color: var(--brand-500);
  background: var(--brand-500);
  color: var(--text-inverse);
}

a.es-tc-go:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════
   PINNED SCROLL, owner, 17 Sep 2026
   The section stays on screen while page scroll slides the arch through
   every person; once the last card is centred the page scrolls on. The
   sticky top (--es-pin-top) is set by es-team-carousel.js: centred under
   the fixed header when the section fits the screen, or bottom-aligned when
   it is taller, so the carousel itself is always in view while pinned.
   ══════════════════════════════════════════════════════════ */
.es-team-pin { position: relative; }

.es-team-pin.is-pinning > .es-team {
  position: sticky;
  top: var(--es-pin-top, 0px);
}

.es-team-pin__spacer { display: none; }

.es-team-pin.is-pinning > .es-team-pin__spacer {
  display: block;
  /* One step of scroll per card change, plus a short hold at each end. */
  height: calc((var(--es-pin-cards, 6) - 1 + 0.8) * var(--es-pin-step, 240px));
}
