/* =========================================================
   05 / Contact and the footer
   One continuous ink block. The light page ends on the contact
   section's top hairline, a hard edge. Every value comes from tokens.css.
   ========================================================= */

/* ---------- Shared dark scope ----------
   Inside the block, the light line and text tokens point at their
   on-ink versions, so marks, rules, labels and notes follow. */

.contact,
.footer {
  --color-guide: var(--color-guide-on-ink);
  --color-rule: var(--color-rule-on-ink);
  --color-text-secondary: var(--color-text-on-ink-secondary);
  --focus-ring: var(--color-canvas);
  position: relative;
  background: var(--color-ink);
  color: var(--color-text-on-ink);
  /* Clips the fixed line canvas (and the shapes) to this block. */
  clip-path: inset(0);
  overflow: clip;
}

/* The vertical lines on the dark: viewport-sized and fixed, so they match
   the page lines exactly; the clip-path above cuts them to the block. */
.contact-lines,
.footer-lines {
  position: fixed;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

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

.section.contact {
  display: flex;
  flex-direction: column;
  min-height: var(--contact-min-height);
  padding: 0;
}

/* The bottom edge belongs to the footer's top line. */
.contact > .marks .plus.bottom,
.contact.has-lines::after {
  display: none;
}

.contact-top,
.contact-shelf,
.contact-bottom {
  position: relative;
  z-index: 2;
}

.contact-top {
  padding-top: var(--section-pad);
}

.contact-index {
  color: var(--color-red-signal);
}

.contact-title {
  font-size: var(--text-contact-size);
  font-weight: var(--text-display-weight);
  line-height: var(--text-contact-lh);
  letter-spacing: var(--text-display-ls);
  will-change: transform;
}

/* Open space the shapes rest above. Its bottom hairline is the shelf. */
.contact-shelf {
  flex: 1 0 var(--contact-shelf-gap);
  border-bottom: var(--line-width) solid var(--color-rule);
  pointer-events: none;
}

.contact-shelf-marks {
  will-change: transform;
}

.contact-bottom {
  padding: var(--space-48) 0 var(--section-pad);
}

/* Button and note sit in the last four columns, wide enough for the label
   on one line: headline top left, action bottom right, the shapes in
   between. */
.contact-cta.col {
  grid-column: -5 / -1;
}

@media (max-width: 639px) {
  .contact-cta.col {
    grid-column: 1 / -1;
  }
}

/* ---------- Button ----------
   .btn .btn--hairline from components.css, the same as the hero button.
   Only its width is set here: it fills the columns it sits in. */

.contact-cta .btn {
  display: flex;
  width: 100%;
}

.contact-note {
  margin-top: var(--space-16);
}

/* ---------- Shapes ---------- */

.contact-shapes {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.contact-shape {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  max-width: none;
  height: auto;
  user-select: none;
  will-change: transform;
}

/* Reduced motion: no physics, the shelf is one plain transition. */
.contact.is-static .contact-shape {
  transition: transform var(--shape-shelf-duration) var(--ease);
}

/* "Go to the button": follows the cursor while it is over a shape. */
.contact-cursor {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  pointer-events: none;
  will-change: transform;
}

.contact-cursor-text {
  display: block;
  padding: var(--space-4) var(--space-8);
  background: var(--color-canvas);
  color: var(--color-ink);
  white-space: nowrap;
  opacity: 0;
  transform: translate(var(--space-16), var(--space-24));
  transition:
    opacity var(--shape-label-duration) var(--ease),
    transform var(--shape-label-duration) var(--ease);
}

.contact-cursor.is-visible .contact-cursor-text {
  opacity: 1;
  transform: translate(var(--space-16), var(--space-16));
}

@media (prefers-reduced-motion: reduce) {
  .contact-cursor-text {
    transition: none;
  }
}

/* ---------- Footer ---------- */

.footer {
  padding: var(--footer-pad-top) 0 var(--footer-pad-bottom);
}

/* Footer links are .link .link--on-dark (components.css). */

.footer-grid {
  row-gap: var(--space-96);
}

.footer-title {
  margin-bottom: var(--space-label-title);
}

.footer-links li + li {
  margin-top: var(--space-8);
}

/* Human block: one bay. The intro text, then the photo frame, which is
   media and runs line to line. The photo follows the text on every
   breakpoint, so on mobile it stays with the intro. On tablet the block
   spans two rows, so Contact and Index stack beside it. */
.footer-human {
  display: flex;
  flex-direction: column;
  gap: var(--footer-human-gap);
}

@media (min-width: 640px) and (max-width: 1023px) {
  .footer-human {
    grid-row: span 2;
  }

  /* The tall human block spans Contact and Index; the second row soaks up
     the extra height so Index stays right below Contact. */
  .footer-grid {
    grid-template-rows: auto 1fr;
  }
}

.footer-human-photo {
  --photo-frame-ratio: var(--footer-photo-ratio);
  --photo-frame-bg: var(--color-ink);
  /* Whole columns, so its edges sit on the grid: a bay is --cols / --bays
     columns wide. */
  width: calc(100% * var(--footer-photo-cols) * var(--bays) / var(--cols));
  /* One gutter in from the line: its left edge lands on the text edge, so
     the line is not covered. */
  margin-left: var(--cell-pad);
}

/* Left text in the first bay, right text in the last. On mobile there is
   one bay, so they stack. */
.footer-bottom {
  display: grid;
  grid-template-columns: repeat(var(--bays), minmax(0, 1fr));
  row-gap: var(--space-8);
  padding-top: var(--space-24);
  border-top: var(--line-width) solid var(--color-rule);
}

.footer-bottom > * {
  grid-column: 1;
}

.footer-bottom > .footer-bottom-end {
  grid-column: -2;
}

@media (min-width: 640px) {
  .footer-bottom-end {
    text-align: end;
  }
}

@media (max-width: 639px) {
  .footer-grid {
    row-gap: var(--space-64);
  }
}
