/* ---------------------------------------------------------------------------
   Contact.

   The page is a strip of film held between two black bands: the lockup above
   it, the menu below. A film from the library runs inside the strip, graded to
   black and white but left bright enough to read as a frame rather than as a
   texture, and the invitation is set over it.

   Everything around the invitation is the language of a monitor on set: a
   record light and a running timecode at the top of the strip, what is playing
   beside it, where the work is made and the local hour along the bottom.

   The face and the palette are the site's own — this is the same room as the
   gallery, with the lights down.
--------------------------------------------------------------------------- */

.contact-page,
.contact-page body {
  height: auto;
  min-height: 100%;
  overflow-x: hidden;
}

.contact-body {
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --edge: clamp(20px, 3.4vw, 54px);
  --band-top: clamp(118px, 19vh, 200px);    /* black above: the lockup's room */
  --band-foot: clamp(112px, 18vh, 190px);   /* black below: the menu's room */

  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100dvh;
  padding: var(--band-top) 0 var(--band-foot);
  background: var(--black);
  color: var(--white);
}

/* style.css holds the header and the menu back until the gallery reveals
   itself. There is no reveal here — the page is the content. */
.contact-body .app-header,
.contact-body .app-menu { opacity: 1; }

.contact-body .app-menu .link.is-current { color: rgba(255, 255, 255, 0.95); }

/* --- back --------------------------------------------------------------- */

/* Contact is one level in from the gallery, so the way out sits where a back
   control is looked for. The centred lockup owns the middle of the same band,
   so this keeps to the left edge and drops its label on narrow screens rather
   than crowding the name. */
.ct__back {
  position: fixed;
  top: var(--pad-y);
  left: var(--pad-x);
  z-index: 70;
  display: inline-flex;
  align-items: center;
  gap: 0.75em;
  padding: 0.35em 0;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  mix-blend-mode: difference;
  transition: color 0.45s var(--ease);
}

.ct__back:hover,
.ct__back:focus-visible { color: var(--white); }

/* The arrow is the part that answers the gesture; it slides back the way the
   link goes. */
.ct__back-arrow {
  display: inline-block;
  font-size: 14px;
  transition: transform 0.45s var(--ease);
}

.ct__back:hover .ct__back-arrow,
.ct__back:focus-visible .ct__back-arrow { transform: translateX(-4px); }

@media (max-width: 700px) {
  .ct__back-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* --- the strip ---------------------------------------------------------- */

.ct {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  height: clamp(430px, 62vh, 880px);
  padding: clamp(54px, 8vh, 86px) var(--edge);
  overflow: hidden;
  isolation: isolate;
}

/* The film fills the strip, in black and white and a stop or so down — far
   enough to carry type, bright enough to still be a frame. */
.ct__film {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.04) brightness(0.74);
  opacity: 0;
  transition: opacity 1.6s var(--ease);
}

.ct__film.is-on { opacity: 1; }

/* A wash that keeps the type legible wherever the cut lands: strongest down
   the centre line, where the invitation sits. */
.ct__grade {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(76% 62% at 50% 52%, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.12) 72%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.42) 0%, rgba(0, 0, 0, 0) 26%, rgba(0, 0, 0, 0) 74%, rgba(0, 0, 0, 0.42) 100%);
}

/* --- the bars ----------------------------------------------------------- */

.ct__bar {
  position: absolute;
  left: var(--edge);
  right: var(--edge);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
  font-family: var(--mono);
  font-size: clamp(9px, 0.82vw, 11px);
  font-weight: 300;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.58);
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.85);
  pointer-events: none;
}

.ct__bar--top { top: clamp(20px, 3.4vh, 38px); }
.ct__bar--foot { bottom: clamp(20px, 3.4vh, 38px); }

.ct__rec,
.ct__showing {
  display: inline-flex;
  align-items: center;
  gap: 0.9em;
}

/* "Now showing" is the label and the client is the answer, so they are set
   apart rather than run together. */
.ct__showing { gap: clamp(1.4em, 4vw, 4em); }

/* The record light: on, steady, the way a camera reads when it is running. */
.ct__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.75);
  animation: ctPulse 2.4s var(--ease) infinite;
}

.ct__tc { color: rgba(255, 255, 255, 0.72); }

.ct__showing-name { color: rgba(255, 255, 255, 0.9); }

/* --- the invitation ----------------------------------------------------- */

.ct__body {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin: 0 auto;
  max-width: 1100px;
}

.ct__lines {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 0.8vh, 12px);
  font-weight: 400;
  font-size: clamp(27px, 5vw, 62px);
  line-height: 1.12;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  text-transform: uppercase;
  text-shadow: 0 2px 28px rgba(0, 0, 0, 0.6);
  text-wrap: balance;
}

/* The second line answers the first, so it sits back a shade. */
.ct__line--soft { color: var(--gray-6); }

.ct__rule {
  display: block;
  width: min(40vw, 400px);
  height: 1px;
  margin: clamp(22px, 4vh, 46px) 0 clamp(20px, 3.4vh, 40px);
  background: rgba(255, 255, 255, 0.3);
}

.ct__label {
  margin: 0 0 clamp(14px, 2.4vh, 26px);
  font-family: var(--mono);
  font-size: clamp(9px, 0.82vw, 11px);
  font-weight: 300;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.85);
}

.ct__mail {
  font-size: clamp(17px, 2.9vw, 36px);
  letter-spacing: 0.08em;
  text-indent: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--white);
  text-shadow: 0 2px 22px rgba(0, 0, 0, 0.7);
  word-break: break-word;
  transition: opacity 0.5s var(--ease);
}

.ct__mail:hover,
.ct__mail:focus-visible { opacity: 0.68; }

/* --- the three ways out -------------------------------------------------- */

.ct__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 3.4vw, 54px);
  margin-top: clamp(26px, 5vh, 58px);
}

.ct__link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6em;
  font-size: clamp(12px, 1.3vw, 17px);
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.9);
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.8);
  transition: color 0.5s var(--ease);
}

.ct__link:hover,
.ct__link:focus-visible { color: var(--white); }

/* The arrow is the part that answers the gesture; it leaves the way it points. */
.ct__arrow {
  font-style: normal;
  font-size: 0.85em;
  transition: transform 0.45s var(--ease);
}

.ct__link:hover .ct__arrow,
.ct__link:focus-visible .ct__arrow { transform: translate(3px, -3px); }

/* Copying is not a destination, so it is set in the monitor's own face rather
   than the serif of the two links beside it. */
.ct__copy {
  padding: 0 0 0.45em;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.4);
  background: none;
  cursor: pointer;
  font-family: var(--mono);
  font-size: clamp(9px, 0.86vw, 11px);
  font-weight: 300;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.85);
  transition: color 0.5s var(--ease), border-color 0.5s var(--ease);
}

.ct__copy:hover,
.ct__copy:focus-visible {
  color: var(--white);
  border-bottom-color: rgba(255, 255, 255, 0.85);
}

/* Said out loud once, then gone. */
.ct__said {
  height: 1.2em;
  margin: clamp(10px, 1.8vh, 18px) 0 0;
  font-family: var(--mono);
  font-size: clamp(9px, 0.82vw, 11px);
  font-weight: 300;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.85);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}

.ct__said.is-on { opacity: 1; }

@keyframes ctPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.28; }
}

/* On a phone the strip takes more of the screen, since there is less of it,
   and the two ends of each bar stack rather than meeting in the middle. */
@media (max-width: 560px) {
  .contact-body {
    --band-top: clamp(104px, 16vh, 150px);
    --band-foot: clamp(104px, 16vh, 150px);
  }

  .ct {
    height: auto;
    min-height: clamp(460px, 64vh, 700px);
    padding: clamp(62px, 11vh, 92px) var(--edge);
  }

  .ct__bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  .ct__showing { gap: 0.9em; }

  /* A phone gives the invitation most of the strip, so a title burned into the
     clip lands under the type rather than beside it. The wash is taken up to
     meet that. */
  .ct__grade {
    background:
      radial-gradient(92% 72% at 50% 52%, rgba(0, 0, 0, 0.74) 0%, rgba(0, 0, 0, 0.3) 72%, rgba(0, 0, 0, 0.08) 100%),
      linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 24%, rgba(0, 0, 0, 0) 76%, rgba(0, 0, 0, 0.5) 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ct__dot { animation: none; }
  .ct__film,
  .ct__link,
  .ct__arrow,
  .ct__said { transition: none; }
}
