
.project-page .project-hero__media--matrix {
  position: relative;
  width: min(100%, 690px);
  max-width: min(100%, calc(100svh - var(--header) - 40px));
  aspect-ratio: 1 / 1 !important;
  justify-self: end;
  overflow: hidden;
  isolation: isolate;
  background: #010202;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.045);
}

.project-page .project-hero__media--matrix .project-hero-reveal__complete,
.project-page .project-hero__media--matrix .project-hero-reveal__matrix {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  pointer-events: none;
}

.project-page .project-hero__media--matrix .project-hero-reveal__complete {
  z-index: 1;
  inset: 10%;
  width: 80%;
  height: 80%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1);
  background: #010202;
  transition: opacity .22s ease;
}

.project-page .project-hero__media--matrix .project-hero-reveal__matrix {
  z-index: 2;
  object-fit: contain;
  opacity: 1;
  background: transparent;
  transition: opacity .48s cubic-bezier(.2,.72,.2,1);
}

/*
  The official letter grid occupies the central 80% of the square.
  The fragment and hotspot grids use the same 10% inset, so every
  interactive-cell centre coincides with its corresponding letter centre.
*/
.project-hero-reveal__fragments,
.project-hero-reveal__hotspots {
  position: absolute;
  inset: 10%;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  grid-template-rows: repeat(6, minmax(0, 1fr));
}

.project-hero-reveal__fragments {
  z-index: 3;
  pointer-events: none;
  transition: opacity .42s ease;
}

.project-hero-reveal__fragment {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  background-image: none;
  background-repeat: no-repeat;
  background-size: 600% 600%;
  background-position: var(--fragment-x) var(--fragment-y);
  transform: scale(.92);
  transform-origin: center;
  transition:
    opacity .2s ease,
    transform .34s cubic-bezier(.2,.72,.2,1);
}

.project-hero-reveal__fragment::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--fragment-glyph-image, none);
  background-repeat: no-repeat;
  background-size: 600% 600%;
  background-position: var(--fragment-x) var(--fragment-y);
  opacity: .5;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.45));
  pointer-events: none;
}

.project-hero-reveal__fragment.is-revealed {
  opacity: 1;
  transform: scale(1);
}

/* No veil, tint or greying is applied to the project fragment. */
.project-hero-reveal__fragment.is-revealed {
  filter: none;
}

.project-hero-reveal__hotspots {
  z-index: 5;
  touch-action: pan-y;
}

.project-hero-reveal__cell {
  position: relative;
  min-width: 0;
  min-height: 0;
  border: 0;
  padding: 0;
  background: transparent;
  color: transparent;
  cursor: crosshair;
}

.project-hero-reveal__cell::before {
  content: "";
  position: absolute;
  inset: 8%;
  border: 1px solid transparent;
  background: transparent;
  transform: scale(1);
  transform-origin: center;
  transition:
    border-color .2s ease,
    background .2s ease,
    transform .28s cubic-bezier(.2,.72,.2,1);
}

.project-hero-reveal__cell:hover::before,
.project-hero-reveal__cell:focus-visible::before {
  border-color: rgba(255,255,255,.46);
  background: rgba(255,255,255,.035);
  transform: scale(.9);
}

.project-hero-reveal__cell.is-revealed::before {
  border-color: transparent;
  background: transparent;
}

.project-hero-reveal__cell > span {
  position: absolute;
  right: 7%;
  bottom: 6%;
  color: transparent;
  font-size: 7px;
  letter-spacing: .1em;
  transition: color .2s ease;
}

.project-hero-reveal__cell:hover > span,
.project-hero-reveal__cell:focus-visible > span {
  color: rgba(255,255,255,.5);
}

.project-hero-reveal__cell:focus-visible {
  outline: 1px solid rgba(255,255,255,.78);
  outline-offset: -3px;
}

.project-hero-reveal__interface {
  position: absolute;
  z-index: 6;
  right: 14px;
  bottom: 12px;
  left: 14px;
  display: flex;
  justify-content: space-between;
  gap: 18px;
  pointer-events: none;
  transition:
    opacity .3s ease,
    transform .3s ease;
}

.project-hero-reveal__hint,
.project-hero-reveal__progress {
  margin: 0;
  padding: 7px 9px;
  color: rgba(255,255,255,.72);
  background: rgba(5,5,5,.34);
  backdrop-filter: blur(10px);
  font-size: 8px;
  letter-spacing: .14em;
  text-transform: uppercase;
  transition:
    opacity .28s ease,
    transform .28s ease;
}

.project-hero__media--matrix.has-activity .project-hero-reveal__hint {
  opacity: 0;
  transform: translateY(4px);
}

.project-hero__media--matrix.is-complete .project-hero-reveal__matrix,
.project-hero__media--matrix.is-complete .project-hero-reveal__fragments,
.project-hero__media--matrix.is-complete .project-hero-reveal__hotspots {
  opacity: 0;
  pointer-events: none;
}

.project-hero__media--matrix.is-complete .project-hero-reveal__interface {
  opacity: 0;
  transform: translateY(4px);
}

@media (max-width: 980px) {
  .project-page .project-hero__media--matrix {
    width: min(100%, 720px);
    max-width: 100%;
    justify-self: stretch;
  }
}

@media (max-width: 620px) {
  .project-hero-reveal__cell {
    cursor: pointer;
  }

  .project-hero-reveal__hint {
    font-size: 0;
  }

  .project-hero-reveal__hint::after {
    content: "Tap cells to reveal nearby fragments";
    font-size: 8px;
  }

  .project-hero-reveal__interface {
    right: 10px;
    bottom: 9px;
    left: 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .project-hero-reveal__fragment,
  .project-hero-reveal__matrix,
  .project-hero-reveal__interface {
    transition-duration: .01ms !important;
  }
}


.project-page .project-hero__media--matrix {
  background: #010202;
}

/*
  The image never enters the 10% protection zone.
  The visible project field is exactly 6 × 6, not an implied 7 × 7 crop.
*/
.project-page .project-hero__media--matrix .project-hero-reveal__complete {
  inset: 10%;
  width: 80%;
  height: 80%;
}

.project-hero-reveal__fragment,
.project-hero-reveal__fragment::after {
  background-size: 600% 600%;
}

/* The black protection zone remains visible after all cells are completed. */
.project-hero__media--matrix.is-complete {
  background: #010202;
}






/*
  The project image uses one geometry throughout the interaction:
  central 80% image field with a permanent 10% black protection zone.
  Completion removes the logo system but does not resize the image.
*/
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__complete {
  inset: 10%;
  width: 80%;
  height: 80%;
  transition: none;
}

.project-page .project-hero__media--matrix.is-complete {
  background: #010202;
}

/* Only interaction layers disappear at 36 / 36. */
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__matrix,
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragments,
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__hotspots,
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__interface {
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .project-page .project-hero__media--matrix .project-hero-reveal__complete {
    transition: none !important;
  }
}


/*
  At completion, keep the 36 image fragments visible. Only the white
  glyph layer fades, one letter at a time, in the reverse order of the
  intro's top-left-to-outer expansion.
*/
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragments {
  opacity: 1;
  pointer-events: none;
}

.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragment {
  opacity: 1;
  transform: scale(1);
}

.project-page .project-hero__media--matrix .project-hero-reveal__fragment::after {
  transition:
    opacity .42s cubic-bezier(.2,.72,.2,1);
  transition-delay: 0s;
}

.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragment::after {
  opacity: 0;
  transition-delay:
    calc(var(--letter-fade-order, 0) * 34ms);
}

/*
  Once the final top-left letter has disappeared, the fragment grid
  quietly gives way to the identical complete image underneath. Because
  both use the same square crop and protection zone, this creates no jump.
*/
.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragments {
  opacity: 0;
  transition:
    opacity .28s ease;
}

/* The interaction chrome leaves immediately; the letters carry the ending. */
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__matrix,
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__hotspots,
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__interface {
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragment::after {
    transition-delay: 0s !important;
    transition-duration: .01ms !important;
  }

  .project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragments {
    transition-duration: .01ms !important;
  }
}


/*
  The ordinary full image is not part of the initial state. The 36 fragment
  backgrounds provide every visible project pixel during interaction.
*/
.project-page .project-hero__media--matrix .project-hero-reveal__complete {
  opacity: 0;
}

/*
  At completion, reveal the identical full image underneath the fragment
  mosaic. The fragments remain visible during the reverse letter fade, then
  settle away with no visual gap.
*/
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__complete {
  opacity: 1;
}

/* The matrix is the only visible first-frame asset over the black field. */
.project-page .project-hero__media--matrix:not(.is-complete) .project-hero-reveal__matrix {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .project-page .project-hero__media--matrix .project-hero-reveal__complete {
    transition-duration: .01ms !important;
  }
}


/*
  Completion is one continuous movement:
  - white letters contract in reverse intro order;
  - the project image expands from the central 80% field to the full square;
  - both finish at approximately the same moment.
*/
.project-page .project-hero__media--matrix .project-hero-reveal__complete {
  inset: 10%;
  width: 80%;
  height: 80%;
  transition:
    opacity .22s ease,
    inset 1.58s cubic-bezier(.2,.72,.2,1),
    width 1.58s cubic-bezier(.2,.72,.2,1),
    height 1.58s cubic-bezier(.2,.72,.2,1);
}

.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__complete {
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 1;
  transition-delay: 0s;
}

/*
  The fragment mosaic remains above the expanding image while the letters
  disappear. It settles away only after both movements have completed.
*/
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragments {
  opacity: 1;
}

.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragments {
  opacity: 0;
  transition: opacity .24s ease;
}

/* The black safety zone is absorbed gradually by the growing project image. */
.project-page .project-hero__media--matrix {
  background: #010202;
}

@media (prefers-reduced-motion: reduce) {
  .project-page .project-hero__media--matrix .project-hero-reveal__complete {
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }
}


/*
  The separate complete-image layer is retained only as a preloaded fallback.
  It never becomes visible during or after completion.
*/
.project-page .project-hero__media--matrix .project-hero-reveal__complete,
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__complete,
.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__complete {
  inset: 10%;
  width: 80%;
  height: 80%;
  opacity: 0 !important;
  transition: none !important;
}

/*
  The same grid that revealed the 36 image cells enlarges continuously from
  the official 80% logo field to the full square. No second image is added.
*/
.project-page .project-hero-reveal__fragments {
  inset: 10%;
  opacity: 1;
  transition:
    inset 1.58s cubic-bezier(.2,.72,.2,1),
    opacity .01ms linear;
}

.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragments,
.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragments {
  inset: 0;
  opacity: 1;
}

/*
  All 36 cells remain visible after completion and together become the final
  full-square project image. The fragment layer is no longer removed.
*/
.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragment {
  opacity: 1;
  transform: scale(1);
}

.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragments {
  transition:
    inset 1.58s cubic-bezier(.2,.72,.2,1);
}

/*
  White glyphs still fade individually in reverse intro order while their
  parent image cells grow into the former safety zone.
*/
.project-page .project-hero__media--matrix.is-complete .project-hero-reveal__fragment::after,
.project-page .project-hero__media--matrix.is-settled .project-hero-reveal__fragment::after {
  opacity: 0;
}

/* Keep the outer square stable while the mosaic expands inside it. */
.project-page .project-hero__media--matrix,
.project-page .project-hero__media--matrix.is-complete,
.project-page .project-hero__media--matrix.is-settled {
  background: #010202;
}

@media (prefers-reduced-motion: reduce) {
  .project-page .project-hero-reveal__fragments {
    transition-duration: .01ms !important;
  }
}


/* Shared exact geometry: desaturated image, tonal logo, fragments and hotspots. */
.project-page .project-hero__media.project-hero__media--matrix
  > img.project-hero-reveal__complete,
.project-page .project-hero__media.project-hero__media--matrix
  > img.project-hero-reveal__matrix,
.project-page .project-hero__media.project-hero__media--matrix
  > .project-hero-reveal__fragments,
.project-page .project-hero__media.project-hero__media--matrix
  > .project-hero-reveal__hotspots {
  position: absolute !important;
  inset: 10% !important;
  width: 80% !important;
  height: 80% !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  box-sizing: border-box !important;
  transform: translateZ(0) !important;
}

.project-page .project-hero__media.project-hero__media--matrix
  > img.project-hero-reveal__complete {
  z-index: 1 !important;
  display: block !important;
  object-fit: cover !important;
  object-position: 50% 50% !important;
  background: #010202 !important;
  opacity: 1 !important;
  filter:
    grayscale(.85)
    brightness(.88)
    contrast(1.04) !important;
  backface-visibility: hidden;
  will-change: inset, width, height, opacity, filter;
  transition:
    opacity .22s ease,
    inset 1.58s cubic-bezier(.2,.72,.2,1),
    width 1.58s cubic-bezier(.2,.72,.2,1),
    height 1.58s cubic-bezier(.2,.72,.2,1),
    filter .48s cubic-bezier(.2,.72,.2,1) !important;
}

/* Same cropped tonal SVG used by both the static and per-cell logo states. */
.project-page .project-hero__media.project-hero__media--matrix
  > img.project-hero-reveal__matrix {
  z-index: 2 !important;
  display: block !important;
  object-fit: contain !important;
  object-position: 50% 50% !important;
  background: transparent !important;
  opacity: 1 !important;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.42)) !important;
  transition: opacity .42s cubic-bezier(.2,.72,.2,1) !important;
}

.project-page .project-hero__media.project-hero__media--matrix
  > .project-hero-reveal__fragments,
.project-page .project-hero__media.project-hero__media--matrix
  > .project-hero-reveal__hotspots {
  display: grid !important;
  grid-template-columns: repeat(6,minmax(0,1fr)) !important;
  grid-template-rows: repeat(6,minmax(0,1fr)) !important;
  gap: 0 !important;
}

.project-page .project-hero__media.project-hero__media--matrix
  > .project-hero-reveal__fragments {
  z-index: 3 !important;
  opacity: 1 !important;
  pointer-events: none !important;
  will-change: inset, width, height, opacity;
  transition:
    inset 1.58s cubic-bezier(.2,.72,.2,1),
    width 1.58s cubic-bezier(.2,.72,.2,1),
    height 1.58s cubic-bezier(.2,.72,.2,1),
    opacity .24s ease !important;
}

.project-page .project-hero__media.project-hero__media--matrix
  > .project-hero-reveal__hotspots {
  z-index: 5 !important;
}

/* A visited cell restores its exact image fragment to full colour. */
.project-page .project-hero-reveal__fragment.is-revealed {
  opacity: 1 !important;
  transform: scale(1) !important;
  filter:
    grayscale(0)
    saturate(1)
    brightness(1)
    contrast(1) !important;
}

/* White and black letters are the identical SVG pixels and tonal opacities. */
.project-page .project-hero__media.project-hero__media--matrix
  .project-hero-reveal__fragment::after {
  opacity: 1 !important;
  background-size: 600% 600% !important;
  background-position: var(--fragment-x) var(--fragment-y) !important;
  transform: none !important;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.46)) !important;
  transition-property: opacity,filter !important;
  transition-duration: .42s,.32s !important;
  transition-timing-function:
    cubic-bezier(.2,.72,.2,1),
    cubic-bezier(.2,.72,.2,1) !important;
  transition-delay: 0s,0s !important;
}

.project-page .project-hero__media.project-hero__media--matrix
  .project-hero-reveal__fragment.is-revealed::after {
  opacity: 1 !important;
  filter: brightness(0) saturate(0) !important;
}

.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > img.project-hero-reveal__complete,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > img.project-hero-reveal__complete,
.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > .project-hero-reveal__fragments,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > .project-hero-reveal__fragments {
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
}

.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > img.project-hero-reveal__complete,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > img.project-hero-reveal__complete {
  object-fit: cover !important;
  object-position: 50% 50% !important;
  opacity: 1 !important;
  filter: none !important;
  transition-delay: 0s !important;
}

.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > .project-hero-reveal__fragments {
  opacity: 1 !important;
}

.project-page .project-hero__media.project-hero__media--matrix.is-complete
  .project-hero-reveal__fragment {
  opacity: 1 !important;
  transform: scale(1) !important;
  filter: none !important;
}

/* Exact verified bottom-right-to-top-left letter fade. */
.project-page .project-hero__media.project-hero__media--matrix.is-complete
  .project-hero-reveal__fragment::after,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  .project-hero-reveal__fragment::after {
  opacity: 0 !important;
  transform: none !important;
  filter: brightness(0) saturate(0) !important;
  transition-delay:
    calc(var(--letter-fade-order,0) * 34ms),
    0s !important;
}

/* Static overlay and controls leave; fragment letters carry the ending. */
.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > img.project-hero-reveal__matrix,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > img.project-hero-reveal__matrix,
.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > .project-hero-reveal__hotspots,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > .project-hero-reveal__hotspots,
.project-page .project-hero__media.project-hero__media--matrix.is-complete
  > .project-hero-reveal__interface,
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > .project-hero-reveal__interface {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Final state: one continuous image, no fragment seams. */
.project-page .project-hero__media.project-hero__media--matrix.is-settled
  > .project-hero-reveal__fragments {
  opacity: 0 !important;
  transition: opacity .28s ease !important;
}

@media (prefers-reduced-motion: reduce) {
  .project-page .project-hero__media.project-hero__media--matrix
    > img.project-hero-reveal__complete,
  .project-page .project-hero__media.project-hero__media--matrix
    > img.project-hero-reveal__matrix,
  .project-page .project-hero__media.project-hero__media--matrix
    > .project-hero-reveal__fragments,
  .project-page .project-hero__media.project-hero__media--matrix
    .project-hero-reveal__fragment::after {
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }
}

/* Case-study geometry and sequencing -------------------------------------- */
/* Every project reveal uses one square field regardless of legacy ratio classes. */
.project-page .project-hero {
  align-items:center !important;
  padding-top: calc(var(--header) + 34px) !important;
  padding-bottom: 34px !important;
}
.project-page .project-hero__media.project-hero__media--matrix {
  width:min(100%,690px) !important;
  max-width:min(690px, calc(100svh - var(--header) - 68px)) !important;
  aspect-ratio:1/1 !important;
  justify-self:center !important;
  align-self:center !important;
  margin-inline:auto !important;
}
.project-page .project-hero__media.project-hero__media--matrix > img.project-hero-reveal__complete { object-fit:cover !important; object-position:50% 50% !important; }

/* All adjacent-image compositions close on one baseline. */
.project-page .media-grid,
.project-page .compare,
.project-page .media-triptych,
.project-page .drawing-grid { align-items:stretch !important; }
.project-page .media-grid > figure,
.project-page .compare > figure,
.project-page .media-triptych > figure,
.project-page .drawing-grid > figure { align-self:stretch !important; height:100% !important; }
.project-page .media-grid > figure img,
.project-page .compare > figure img,
.project-page .media-triptych > figure img { width:100% !important; height:100% !important; object-fit:cover !important; }

/* A single image is a deliberate full line, never half of an apparently missing pair. */
.project-page .media-grid:has(> figure:only-child) { grid-template-columns:1fr !important; }
.project-page .media-grid:has(> figure:only-child) > figure { aspect-ratio:16/9 !important; }

/* Odd technical/image sets finish as one full-width line. */
.project-page .drawing-grid > figure:last-child:nth-child(odd) {
  grid-column:1/-1 !important;
  min-height:0 !important;
  aspect-ratio:2/1 !important;
}
.project-page .drawing-grid > figure:last-child:nth-child(odd) img { width:100% !important; height:100% !important; object-fit:contain !important; }

/* One media rhythm between text chapters. */
.project-page .media-full,
.project-page .media-grid,
.project-page .compare,
.project-page .media-triptych,
.project-page .drawing-grid { margin-bottom:clamp(38px,4.2vw,58px) !important; }

/* Closing chapter is a CTA, not another hero. */
.project-page .project-end,
.project-page .project-end__content { min-height:clamp(330px,38vh,420px) !important; }
.project-page .project-end__content { padding-top:clamp(46px,5vw,64px) !important; padding-bottom:clamp(46px,5vw,64px) !important; }
.project-page .project-end h2 { max-width:680px !important; font-size:clamp(30px,3vw,42px) !important; }
.project-page .project-nav-footer { padding-top:22px !important; padding-bottom:22px !important; }

@media(max-width:760px){
  .project-page .project-hero { padding-top:calc(var(--header) + 20px) !important; padding-bottom:28px !important; }
  .project-page .project-hero__media.project-hero__media--matrix { width:min(82vw,320px) !important; max-width:320px !important; }
  .project-page .drawing-grid > figure:last-child:nth-child(odd) { grid-column:auto !important; aspect-ratio:auto !important; }
  .project-page .project-end,.project-page .project-end__content { min-height:300px !important; }
}
