/* ===========================================================================
   Section 4 - the RSVP moment.

   Deep olive, the portrait, and the oversized script across the top.

   THE SCRIPT NEVER TOUCHES THEIR FACES. In the de-bordered portrait their faces
   sit at roughly y 0.30 to 0.38, so the script occupies its own row above the
   photograph and is permitted to overlap only the top of the frame, capped at
   a tenth of the image height, where the sky is (FR-039, SC-022).
   =========================================================================== */

.section--rsvp-moment {
  background-color: var(--ground-olive-deep);
  color: var(--ink-reversed);
}

.rsvp-moment__layout {
  display: grid;
  gap: 0;
  justify-items: center;
  /* Grid items default to align-items: stretch. Combined with the script's
     large negative margin-block-end (below), Chromium's auto-row track
     sizing stretches the script's own box by the full magnitude of that
     negative margin instead of leaving it at its content height - measured
     as a script element nearly 2x its real line-height tall, which made the
     one-line check (V4) see it as wrapped. align-items: start keeps every
     item at its natural content height regardless of the margins any one of
     them sets. */
  align-items: start;
  text-align: center;
  container-type: inline-size;
  /* The portrait's RENDERED height at this breakpoint, from its own max-width
     and the master's 1030 x 1391 aspect. The script's overlap (below) is a
     fraction of this, not of the layout's own box, because 001's single-frame
     portrait is what the overlap measures against (research R7). Recomputed
     at the >=48rem breakpoint, where .rsvp-moment__portrait's max-width grows. */
  --portrait-h: calc(20rem * 1391 / 1030);
}

@media (min-width: 48rem) {
  .rsvp-moment__layout {
    --portrait-h: calc(23rem * 1391 / 1030);
  }
}

.rsvp-moment__script {
  /* Research R7: reproduces 4.png's own scale and crossing, which 001 gave up
     to keep the script clear of the photograph (see the removed "sits above
     the photograph" note this replaces). Sized to the layout's own width with
     a container query unit, not vw, so the gutter and the capped content
     width are both respected; a clamp() keeps it within the 40-190px range
     measured against the original (research R7). */
  /* 6.9, not research R7's original 7.4: measured at 1280px the script filled
     only 80% of the content width (SC-005 needs >=85%), so the divisor was
     tuned down per the T059 fallback until it cleared (T059). */
  font-size: clamp(2.5rem, 100cqi / 6.9, 11.875rem);
  line-height: 1.22;
  white-space: nowrap;
  /* base.css sets text-wrap: balance on every h1/h2/h3 to keep multi-line
     headings even. That is a DIFFERENT property from white-space in current
     browsers, not a longhand it resets, so it survives white-space: nowrap
     above and was forcing this single line to lay out as two artificially
     narrow ones (balance still ran even though there was nothing to
     balance). text-wrap: nowrap is what actually turns it off. */
  text-wrap: nowrap;
  padding-block-end: 0.14em;
  margin: 0;
  color: var(--ink-reversed);
  max-width: none;
  /* The soft shadow keeps the strokes that cross the portrait visible: the
     cream frame and sky underneath them would otherwise wash the ink out
     (001's "cream on cream, 1.00:1" problem). The gate strips this before
     measuring contrast (visual-rules V1), so it can only help. */
  text-shadow: 0 2px 10px rgb(0 0 0 / 0.35);
  /* Crosses INTO the top of the photograph by a fixed fraction of the
     portrait's own rendered height (R7): far enough to reproduce the
     original's composition, capped at 0.22 so the lowest descender still
     clears the faces (measured at y 0.30 of the portrait) with margin to
     spare. The contrast gate measures this with the portrait's rectangle
     masked out (visual-rules V4's documented exception): the strokes that
     fall on sky and treetops cannot meet 3:1 by construction, exactly as in
     the original, and the heading's words stay fully available elsewhere. */
  margin-block-end: calc(-0.22 * var(--portrait-h));
  position: relative;
  z-index: 2;
}

.rsvp-moment__artwork {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  justify-content: center;
}

.rsvp-moment__portrait {
  width: 100%;
  max-width: 20rem;
  height: auto;
  object-fit: contain;
  /* The site's single frame treatment. The baked-in cream border was cropped
     off the master so this is the only frame on the photograph (FR-104). */
  border: 6px solid var(--ground-cream);
  box-shadow: 0 12px 30px color-mix(in srgb, #15160d 45%, transparent);
}

.rsvp-moment__action {
  margin-block-start: var(--space-md);
  max-width: none;
}

.rsvp-link--primary {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  min-height: var(--touch-target);
  padding: var(--space-2xs) var(--space-md);
  background: var(--ground-cream);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  text-decoration: none;
  /* The label is three words at most and never wraps at desktop. */
  white-space: nowrap;
  border: var(--rule-strong) solid var(--ground-cream);
}

.rsvp-link--primary:hover,
.rsvp-link--primary:focus-visible {
  background: var(--accent-butter);
  border-color: var(--accent-butter);
  color: var(--ink);
}

@media (max-width: 26rem) {
  .rsvp-link--primary {
    /* At 320 px the full label does not fit on one line, and a wrapped CTA is
       broken. The label shortens rather than the button growing. */
    white-space: normal;
    font-size: var(--fs-sm);
  }
}

@media (min-width: 48rem) {
  /* .rsvp-moment__script's max-width: none is already the base rule (research
     R7's clamp() sizes it, not a width cap), so only the portrait grows here.
     --portrait-h above has its own matching >=48rem rule, right next to it. */
  .rsvp-moment__portrait {
    max-width: 23rem;
  }
}
