/* ==========================================================================
   Contact  —  Figma "Contact Us - Book a Demo" (924:25446)
   1920 x 2643 on Mono/Dark.

   Left column is the heading and the form; right column is the dot sphere,
   one testimonial card with its own Prev/Next, and the logo marquee. The
   card, its brackets and its squeeze all come from testimonial.css and
   ui.js — only the placement is here.

   Default -> Animate:
     masthead   translateY +40 -> 0, staggered left to right
     heading    translateY +86 -> 0
     sphere     fades in
     form       fades in
     card       fades in, then its controls
   ========================================================================== */

/* The canvas height. base.css falls back to the front page's 11559 when no
   page sets it, which is what this page was doing: 2643 of content and then
   nearly nine thousand units of empty dark below the footer. That was most of
   what read as uneven spacing.

   2679, not Figma's 2643: the footer partial is 936 tall against the 900 the
   contact frame draws, and it is shared with every other page. Better to give
   it the 36 than to clip it or fork it. */
.o-page--contact { --page-h: 2659; }   /* 1723 footer + 936 */

.contact {
  top: 0;
  height: calc(1228 * var(--s));   /* 356 + 712 photo/form + 160 */
  background: var(--c-mono-dark);
  overflow: clip;
}

/* --- masthead ------------------------------------------------------------
   Nothing here. The section renders the landing page's masthead verbatim, and
   hero.css positions those classes without scoping them to .hero, so they
   land in this section unchanged.
   -------------------------------------------------------------------------- */

/* --- heading ------------------------------------------------------------- */

.contact__title {
  position: absolute;
  left: calc(182 * var(--s));
  top: calc(206 * var(--s));
  width: calc(600 * var(--s));
  margin: 0;
  font-family: var(--f-display);
  font-size: calc(72 * var(--s));
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: calc(-2.16 * var(--s));
  color: var(--c-mono-light);
}

/* --- form ---------------------------------------------------------------- */

/* --- the photograph ------------------------------------------------------
   The frame runs it down the left of the section with the form opposite,
   both starting on the same line and ending on it. */
.contact__photo {
  position: absolute;
  left: calc(182 * var(--s));
  top: calc(356 * var(--s));
  width: calc(720 * var(--s));
  height: calc(712 * var(--s));
  margin: 0;
  /* Clipped: the hover zoom scales the picture inside this box rather than
     growing it. The four corner marks sit on the box's own edges, so they
     survive the clip. */
  overflow: hidden;
  background: var(--c-light-dark);
}
.contact__photo img { width: 100%; height: 100%; object-fit: cover; }
/* `.zoom img` carries will-change: transform, which gives the picture a
   stacking context -- so it joined the positioned layer and, being last in
   the markup, painted straight over the four corner marks. */
.contact__photo .brk__c { z-index: 1; }

.contact__form {
  position: absolute;
  left: calc(1018 * var(--s));
  top: calc(356 * var(--s));
  width: calc(720 * var(--s));
}


/* The form arrives a block at a time, from the left.
   Driven from here rather than with .rv wrappers in the markup, for two
   reasons: the fields partial is shared with the modal, which should not
   inherit a scroll reveal, and .rv and .rv-fade both declare `transition`, so
   putting them on one element loses the transform. One rule does both. */
.contact__form .cfields > * {
  opacity: 0;
  transform: translateX(calc(-64 * var(--s)));
  transition:
    opacity var(--rv-dur) var(--rv-ease),
    transform var(--rv-dur) var(--rv-ease);
  transition-delay: calc(var(--d, 0) * var(--rv-step));
}
.contact__form .cfields > *:nth-child(1) { --d: 3; }
.contact__form .cfields > *:nth-child(2) { --d: 4; }
.contact__form .cfields > *:nth-child(3) { --d: 5; }
.contact__form .cfields > *:nth-child(4) { --d: 6; }
.contact__form .cfields > *:nth-child(5) { --d: 7; }
.contact__form .cfields > *:nth-child(6) { --d: 8; }

.contact.is-in .contact__form .cfields > * { opacity: 1; transform: none; }

/* --- dot sphere ---------------------------------------------------------- */

.contact__sphere {
  position: absolute;
  left: calc(887 * var(--s));
  top: calc(231 * var(--s));
  width: calc(950 * var(--s));
  height: calc(950 * var(--s));
  opacity: 0;
  /* Same tint as the CTA halo. The dot mask and the 60s turn come from
     .dotring in base.css. */
  --ring-fill: var(--c-mono-light);
  --ring-p: 60s;

  /* Figma lays a large soft dark ellipse over the lower two-thirds of the
     sphere (928:16272), so the top reads and the rest sinks into the page.
     Done here as a mask on the sphere rather than as that overlay: the
     ellipse covers the ground the testimonial card stands on, and an opaque
     shape there is one stacking mistake away from covering the card. Fading
     the dots themselves cannot. */
  -webkit-mask: radial-gradient(
    ellipse 82% 66% at 50% 24%,
    #000 0%, rgba(0, 0, 0, 0.9) 42%, rgba(0, 0, 0, 0.35) 70%, transparent 92%
  );
          mask: radial-gradient(
    ellipse 82% 66% at 50% 24%,
    #000 0%, rgba(0, 0, 0, 0.9) 42%, rgba(0, 0, 0, 0.35) 70%, transparent 92%
  );
}
.contact.is-in .contact__sphere { opacity: 0.34; }

/* --- testimonial card ---------------------------------------------------- */

/* The right-hand column rises: card, then its controls, then the strip.
   testimonial.css already gives the card an opacity-0 / translateY(48) rest
   state, so this only lengthens the travel and lands it on its own beat. */
.contact__card,
.contact__navs,
.contact__marquee {
  opacity: 0;
  transform: translateY(calc(80 * var(--s)));
  transition:
    opacity var(--rv-dur) var(--rv-ease),
    transform var(--rv-dur) var(--rv-ease);
  transition-delay: calc(var(--d, 0) * var(--rv-step));
}
.contact__card    { --d: 4; }
.contact__navs    { --d: 6; }
.contact__marquee { --d: 7; }

.contact.is-in .contact__card,
.contact.is-in .contact__navs,
.contact.is-in .contact__marquee { opacity: 1; transform: none; }

/* testimonial.css owns how the card looks and how it squeezes; these are the
   only two numbers that differ here. The !important on left matches the one
   in testimonial.css's own reflow, which it needs to beat the --collapse
   expression baked into the shorthand. */
.contact__card {
  left: calc(1104 * var(--s) + (622 * var(--collapse) * var(--anchor)) * var(--s)) !important;
  top: calc(399 * var(--s));
}

/* testimonial.css lands the card's reveal with `.testimonial.is-in`, which
   cannot match inside .contact. The rule above is what lands it here. */

.contact__navs {
  position: absolute;
  left: calc(1562 * var(--s));
  top: calc(703 * var(--s));
  display: flex;
  gap: calc(16 * var(--s));
}

/* 64px here against the testimonial section's 80. */
.contact__nav-btn {
  position: static;
  width: calc(64 * var(--s));
  height: calc(64 * var(--s));
  transform: none;
  opacity: 1;
}
.contact .testimonial__nav-label { font-size: max(11px, calc(16 * var(--s))); }

/* --- logo marquee -------------------------------------------------------- */

.contact__marquee {
  position: absolute;
  left: calc(1104 * var(--s));
  top: calc(859 * var(--s));
  width: calc(634 * var(--s));
  height: calc(96 * var(--s));
  display: flex;
  align-items: center;
  overflow: hidden;
  --brk-color: var(--c-accent-yellow);
  /* Figma fades both ends with an ellipse over the band; a mask does the same
     without another element to keep in place. */
  -webkit-mask: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
          mask: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
}

.contact__marquee-track {
  display: flex;
  align-items: center;
  /* The track is a flex item of the 634-wide band, so without this it was
     shrunk to fit -- 576px instead of its content's 1639 -- and translating
     by a third of the *box* moved it a third of the wrong number. */
  flex: none;
  width: max-content;
  /* No gap. `gap` sits *between* items, so across three copies of four logos
     the distance from copy 1 to copy 2 is four items and four gaps while a
     third of the track is four items and 3.67 gaps -- the loop jumped every
     time it came round. A margin on each logo makes every item advance by
     exactly the same amount, so a third is a third. */
  animation: ocularai-contact-marquee 26s linear infinite;
  will-change: transform;
}

.contact__marquee-logo {
  display: block;
  height: calc(32 * var(--s));
  width: auto;
  flex: none;
  margin-right: calc(64 * var(--s));
  opacity: 0.7;
}

@keyframes ocularai-contact-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-33.333%); }
}

.contact__marquee:hover .contact__marquee-track { animation-play-state: paused; }

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

/* --- reused dots band ----------------------------------------------------
   The front page's band, moved to this frame's y. Figma draws five rows here
   against the band's own arrangement, so the row count is not matched — worth
   revisiting if it should be exact.
   -------------------------------------------------------------------------- */

/* The band's five rows sit at 217-549 inside a 600-tall box on the front
   page; here Figma puts the same five at 8-336 inside 347. So the box comes
   down to fit and the grid slides up to meet it -- otherwise the band ran to
   1836 and straight through the footer at 1743. Height 355 rather than 347 so
   the fifth row's cell is not clipped by nine units. */
.o-page--contact .dots {
  top: calc(1288 * var(--s));      /* 60 under the fields */
  height: calc(355 * var(--s));
}
.o-page--contact .dots__grid { transform: translateY(calc(-213 * var(--s))); }

/* The footer partial was in the section list all along, but footer.css puts it
   at the front page's y (10623) and this canvas is 2643 tall with overflow
   clipped -- so it was rendered, positioned eight thousand pixels below the
   page, and thrown away. */
.o-page--contact .footer { top: calc(1723 * var(--s)); }

/* --- reflow -------------------------------------------------------------- */

@media (max-width: 1023px), (max-width: 1200px) and (orientation: portrait) {
  .contact {
    height: auto;
    padding: 24px 20px 56px;
    overflow: visible;
  }

  .contact__item { position: static; }
  .contact__masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }
  .contact__logo { width: 132px; height: 32px; flex: none; }
  .contact__login { display: none; }
  .contact__nav { width: auto; height: auto; }
  .contact__nav-inner { gap: 16px; padding: 0; }

  .contact__title {
    position: static;
    width: auto;
    margin-top: 40px;
    font-size: 40px;
    letter-spacing: -1px;
  }

  .contact__form { position: static; width: auto; margin-top: 32px; }

  /* The sphere is decoration and there is no column to hold it. */
  .contact__sphere { display: none; }

  .contact__card {
    position: relative;
    left: auto !important;
    top: auto;
    /* Not !important: the phone layout sizes this card to the front page's
       own, and an !important here would be unanswerable. */
    width: 100%;
    height: auto;
    margin-top: 48px;
    padding: 24px 20px 28px;
  }
  .contact__navs {
    position: static;
    justify-content: center;
    gap: 16px;
    margin-top: 24px;
  }
  .contact__nav-btn { width: 56px; height: 56px; font-size: 13px; }

  .contact__marquee {
    position: static;
    width: auto;
    height: 64px;
    margin-top: 32px;
  }
}

@media (max-width: 767px), (min-width: 768px) and (max-width: 1200px) and (orientation: portrait) {
  .contact__nav { display: none; }
}

/* Only the phone frame has room for this; see template-parts/sections/contact.php. */
.contact__eyebrow { display: none; }

/* --- switched off -------------------------------------------------------
   The testimonial card, the dot pattern under it and the logo strip are
   kept in the markup -- the carousel script and the source list still read
   them -- but nothing about them is drawn. */
.contact__eyebrow,
.contact__card,
.contact__navs,
.contact__marquee,
.contact__sphere { display: none; }

/* One band stays, as the separator between the fields and the footer; the
   second went with the testimonial it sat under. */
.o-page--contact > main > .dots + .dots { display: none; }
