/* ============================================================
   People — "The Hang"

   The directory is treated as a gallery hang rather than a card list:
   one unified tonal series of portraits, quiet wall labels, and a
   two-datum rhythm. Attention — pointer or keyboard — brings a single
   person into full colour while the rest of the wall recedes. That is
   the only interactive idea on the page, and it is deliberate.

   Content is fixed by source parity: 37 people, source order, source
   wording, source filters. Everything below is presentation only.
   ============================================================ */

.people-page {
  /* One gutter for the hero and the directory so every left edge on the
     page sits on the same line at every viewport. */
  --gutter: max(40px, calc((100vw - 1460px) / 2));
  --wall: #f7f5ef;
  --rule: rgba(24, 25, 23, 0.2);
  --rule-strong: rgba(24, 25, 23, 0.52);
  --accent: #7d4634;
  --label: #8a6d3f;
  background: var(--wall);
}

.people-page .primary-menu > li:first-child > a {
  color: var(--accent);
}

/* ------------------------------------------------------------
   Hero — field of thirty-seven
   ------------------------------------------------------------ */

.people-hero {
  /* Tracks viewport width rather than height: the headline is set in vw, so a
     vh-driven hero leaves a dead band under the title on tall narrow screens. */
  min-height: clamp(420px, 33vw, 500px);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: calc(var(--header-height) + clamp(78px, 8.4vw, 118px)) 0 clamp(56px, 5.6vw, 84px);
  color: var(--ink);
  background: #ece7dd;
}

.people-hero__art {
  position: absolute;
  z-index: -1;
  inset: 0;
  overflow: hidden;
  will-change: transform, opacity;
}

.people-hero__canvas {
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
  filter: blur(8px) saturate(1.1);
  transform: scale(1.16);
  transform-origin: 58% 46%;
  transition: opacity 1500ms ease;
  animation: people-field-drift 52s ease-in-out infinite alternate;
}

.people-hero__canvas.is-composed {
  opacity: 1;
}

.people-hero__veil,
.people-hero__grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* The headline lives on the left, so the left stays paper-pale and colour
   is only allowed to gather towards the right edge. The foot of the hero
   dissolves into the directory ground, so the abstract field resolves into
   the real people rather than stopping at a hard seam. */
.people-hero__veil {
  z-index: 1;
  background:
    linear-gradient(97deg,
      rgba(247, 244, 236, 0.82) 0%,
      rgba(247, 244, 236, 0.62) 38%,
      rgba(247, 244, 236, 0.3) 70%,
      rgba(247, 244, 236, 0.12) 100%),
    linear-gradient(180deg,
      rgba(247, 244, 236, 0.4) 0%,
      rgba(247, 244, 236, 0) 22%,
      rgba(247, 245, 239, 0) 58%,
      rgba(247, 245, 239, 1) 100%);
}

.people-hero__grain {
  z-index: 2;
  opacity: 0.15;
  background-image: radial-gradient(rgba(61, 51, 58, 0.32) 0.6px, transparent 0.7px);
  background-size: 5px 5px;
  mix-blend-mode: soft-light;
}

.people-hero__content {
  position: relative;
  z-index: 3;
  margin: 0 var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(320px, 1.2fr);
  align-items: end;
  gap: clamp(48px, 8vw, 168px);
}

.people-hero__content::before {
  content: "";
  height: 1px;
  position: absolute;
  top: -30px;
  right: 0;
  left: 0;
  background: rgba(57, 49, 47, 0.34);
}

/* Negative left margin is optical, not layout: it pulls the serif P's side
   bearing back so the stem — not the glyph box — meets the rule above. */
.people-hero h1 {
  margin: 0 0 0 -0.045em;
  font-family: var(--serif);
  font-size: clamp(84px, 10.5vw, 164px);
  font-weight: 400;
  letter-spacing: -0.075em;
  line-height: 0.76;
}

.people-hero p {
  max-width: 700px;
  margin: 0 0 4px;
  color: #34312e;
  font-family: var(--serif);
  font-size: clamp(25px, 2.25vw, 37px);
  letter-spacing: -0.032em;
  line-height: 1.12;
  text-wrap: balance;
}

@keyframes people-field-drift {
  from { transform: scale(1.16) translate3d(-1.1%, -0.5%, 0); }
  to { transform: scale(1.22) translate3d(1.2%, 0.9%, 0); }
}

/* ------------------------------------------------------------
   Directory
   ------------------------------------------------------------ */

.people-directory {
  padding: clamp(50px, 5.4vw, 76px) var(--gutter) clamp(96px, 10vw, 148px);
  background: var(--wall);
}

.people-filters {
  min-height: 66px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid rgba(24, 25, 23, 0.12);
}

.people-filters__intro {
  min-width: 96px;
  color: var(--label);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.people-filters__controls {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0 clamp(16px, 1.8vw, 30px);
}

.people-filter-label {
  margin-right: clamp(4px, 0.8vw, 14px);
  color: #6d6a63;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Filters read as an editorial rail, not as buttons in boxes: the state is
   carried by weight, colour and a single hairline. */
.people-filter {
  min-height: 40px;
  padding: 0 1px;
  position: relative;
  border: 0;
  border-bottom: 1px solid transparent;
  color: #57544d;
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  letter-spacing: 0.012em;
  transition: color 320ms ease, border-color 320ms ease;
}

.people-filter:hover {
  color: var(--ink);
  border-bottom-color: rgba(24, 25, 23, 0.32);
}

.people-filter.is-selected {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.people-clear {
  min-height: 40px;
  margin-left: clamp(6px, 1vw, 16px);
  padding: 0 1px;
  border: 0;
  color: var(--label);
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.03em;
  text-decoration: underline;
  text-decoration-color: rgba(138, 109, 63, 0.4);
  text-underline-offset: 5px;
  transition: color 300ms ease, transform 300ms ease;
}

.people-clear:hover {
  color: #5c3328;
  transform: translateX(-2px);
}

.people-clear[hidden] {
  display: none;
}

.people-filter:focus-visible,
.people-clear:focus-visible,
.person-card a:focus-visible {
  outline: 2px solid #a9844f;
  outline-offset: 5px;
}

/* ------------------------------------------------------------
   The hang
   ------------------------------------------------------------ */

.people-grid {
  --hang-offset: clamp(36px, 4.2vw, 74px);
  margin-top: clamp(38px, 4vw, 58px);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(22px, 2.6vw, 44px);
  row-gap: clamp(54px, 5.4vw, 92px);
  align-items: start;
}

/* --hang and --reveal-delay are set from the *visible* index in people.js, so
   the rhythm and the cascade stay correct after a filter is applied rather
   than following DOM order. */
.person-card {
  min-width: 0;
  margin-top: calc(var(--hang, 0) * var(--hang-offset));
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 900ms cubic-bezier(0.22, 1, 0.36, 1) calc(var(--reveal-delay, 0) * 1ms),
    transform 900ms cubic-bezier(0.22, 1, 0.36, 1) calc(var(--reveal-delay, 0) * 1ms);
}

.person-card.is-visible {
  opacity: 1;
  transform: none;
}

.person-card[hidden] {
  display: none;
}

.person-card > a {
  height: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  color: var(--ink);
  text-decoration: none;
  transition: opacity 520ms ease;
}

.person-card__portrait {
  aspect-ratio: 0.9;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  outline: 1px solid rgba(35, 30, 28, 0.1);
  outline-offset: -1px;
  background: #ded8d0;
}

.person-card__portrait img {
  width: 100%;
  height: 100%;
  position: relative;
  z-index: 0;
  display: block;
  object-fit: cover;
  object-position: center 14%;
  filter: contrast(1.045) brightness(1.02);
  transform: scale(1.006);
  transition: transform 1100ms cubic-bezier(0.22, 1, 0.36, 1), filter 700ms ease;
}

/* The unifying layer. Blending in "color" keeps each photograph's own
   luminosity and replaces its hue with a single warm-to-violet ramp, so
   two different photo sources — the Sydney studio set and the China
   portraits — read as one commissioned series instead of a mixed wall. */
.person-card__portrait::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0;
  background: linear-gradient(158deg, #93764f 0%, #7a5a52 44%, #5c5570 100%);
  mix-blend-mode: color;
  opacity: 0.62;
  transition: opacity 760ms ease;
  pointer-events: none;
}

.person-card__portrait::after {
  content: "";
  position: absolute;
  z-index: 2;
  inset: 0;
  background: linear-gradient(180deg, transparent 62%, rgba(30, 26, 28, 0.15));
  transition: opacity 620ms ease;
  pointer-events: none;
}

/* Wall label. The rule sits directly under the frame so the text reads as
   mounted beneath the work rather than floating over it. */
.person-card__meta {
  position: relative;
  margin: 0;
  padding: 15px 26px 0 0;
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--rule);
  transition: border-color 520ms ease;
}

.person-card__meta h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(23px, 1.72vw, 30px);
  font-weight: 400;
  letter-spacing: -0.028em;
  line-height: 1.04;
  transition: color 460ms ease;
}

.person-card__role {
  margin: 9px 0 0;
  color: #5d5a53;
  font-size: 12px;
  letter-spacing: 0.004em;
  line-height: 1.46;
}

.person-card__location {
  margin: 13px 0 0;
  color: var(--label);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.13em;
  line-height: 1.4;
  text-transform: uppercase;
}

/* A printer's mark rather than a UI button — present enough to signal the
   link on touch, quiet enough to stay out of the composition. */
.person-card__arrow {
  width: 13px;
  height: 13px;
  position: absolute;
  top: 19px;
  right: 0;
  fill: none;
  stroke: rgba(24, 25, 23, 0.34);
  stroke-linecap: square;
  stroke-linejoin: miter;
  stroke-width: 1.4;
  transition: transform 520ms cubic-bezier(0.22, 1, 0.36, 1), stroke 460ms ease;
}

/* ------------------------------------------------------------
   Attention — the single interaction
   ------------------------------------------------------------ */

@media (hover: hover) {
  .people-grid:has(.person-card:hover) .person-card:not(:hover) > a {
    opacity: 0.56;
  }
}

.people-grid:has(a:focus-visible) .person-card:not(:has(a:focus-visible)) > a {
  opacity: 0.5;
}

.person-card:hover .person-card__portrait::before,
.person-card:focus-within .person-card__portrait::before {
  opacity: 0;
}

.person-card:hover .person-card__portrait::after,
.person-card:focus-within .person-card__portrait::after {
  opacity: 0.4;
}

.person-card:hover .person-card__portrait img,
.person-card:focus-within .person-card__portrait img {
  filter: contrast(1) brightness(1) saturate(1.02);
  transform: scale(1.035);
}

.person-card:hover .person-card__meta,
.person-card:focus-within .person-card__meta {
  border-top-color: var(--accent);
}

.person-card:hover .person-card__meta h2,
.person-card:focus-within .person-card__meta h2 {
  color: var(--accent);
}

.person-card:hover .person-card__arrow,
.person-card:focus-within .person-card__arrow {
  stroke: var(--accent);
  transform: translate(3px, -3px);
}

.people-empty {
  margin: 54px 0 0;
  color: #625d55;
  font-family: var(--serif);
  font-size: clamp(24px, 2vw, 30px);
}

.people-empty[hidden] {
  display: none;
}

/* ------------------------------------------------------------
   Responsive
   ------------------------------------------------------------ */

@media (max-width: 1180px) {
  .people-page {
    --gutter: 28px;
  }

  .people-hero__content {
    grid-template-columns: minmax(0, 0.74fr) minmax(320px, 1.26fr);
  }
}

@media (max-width: 960px) {
  .people-hero {
    min-height: 430px;
    padding-top: calc(var(--header-height) + 78px);
  }

  /* A pair of columns cannot carry an alternating datum without simply
     looking lopsided, so the hang flattens here. */
  .people-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    --hang-offset: 0px;
  }

  .people-hero__content {
    grid-template-columns: 1fr;
    gap: 36px;
  }

  .people-hero h1 {
    font-size: clamp(82px, 14vw, 124px);
  }

  .people-hero p {
    max-width: 680px;
    font-size: clamp(25px, 3.5vw, 33px);
  }
}

@media (max-width: 680px) {
  .people-page {
    --gutter: 20px;
  }

  .people-hero {
    min-height: 436px;
    padding-top: calc(var(--header-height) + 70px);
    padding-bottom: 50px;
  }

  .people-hero__content::before {
    top: -22px;
  }

  .people-hero h1 {
    margin-left: -0.025em;
    font-size: clamp(72px, 22vw, 96px);
  }

  .people-hero p {
    max-width: 96%;
    font-size: clamp(24px, 7.2vw, 30px);
  }

  .people-filters {
    min-height: 0;
    display: block;
    padding: 18px 0 19px;
  }

  .people-filters__controls {
    justify-content: flex-start;
    margin-top: 12px;
    gap: 0 clamp(14px, 4.4vw, 22px);
  }

  .people-filter-label {
    width: 100%;
    margin: 0 0 2px;
  }

  .people-filter,
  .people-clear {
    min-height: 42px;
    font-size: 12px;
  }

  .people-clear {
    margin-left: 0;
  }

  /* The wall stays a wall on a phone: two columns keep the series legible
     and keep the directory to a scroll length a visitor will actually
     finish, rather than 37 full-width plates. */
  .people-grid {
    margin-top: 26px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 14px;
    row-gap: 34px;
  }

  .person-card__portrait {
    aspect-ratio: 0.82;
  }

  .person-card__meta {
    padding: 11px 17px 0 0;
  }

  .person-card__meta h2 {
    font-size: 19px;
    letter-spacing: -0.022em;
  }

  .person-card__role {
    margin-top: 6px;
    font-size: 11px;
    line-height: 1.4;
  }

  .person-card__location {
    margin-top: 9px;
    font-size: 8.5px;
    letter-spacing: 0.1em;
  }

  /* Touch has no hover state, so the link mark stays — it is the only
     standing affordance on a phone. */
  .person-card__arrow {
    width: 10px;
    height: 10px;
    top: 14px;
    stroke-width: 1.5;
  }
}

@media (prefers-reduced-motion: reduce) {
  .people-hero__canvas {
    animation: none;
  }

  .person-card,
  .person-card > a,
  .person-card__portrait img,
  .person-card__portrait::before,
  .person-card__portrait::after,
  .person-card__meta,
  .person-card__meta h2,
  .person-card__arrow {
    transition: none;
  }

  .person-card {
    opacity: 1;
    transform: none;
  }
}
