/* ============================================================
   TCA WEBSITE — "GET IN TOUCH" ZOOM SCENE
   DIFFERENT ARCHITECTURE from programs-scene.css on purpose — this
   is not a copy-paste of that pattern, and the difference matters.

   programs-scene's content is a short label + heading + one line of
   text, which comfortably fits inside a 100vh sticky frame with
   overflow:hidden. This section's content is a full form (5 fields +
   submit) plus an info panel (4 items + a map placeholder) — content
   that easily exceeds 100vh on real viewports. Putting that inside a
   vertically-centered, overflow:hidden 100vh box means whatever
   doesn't fit is simply gone: not scrollable, not reachable, just
   clipped — which is exactly the overlap/clipping bug this replaces
   (message field colliding with achievements above it, footer
   colliding with the form and swallowing the map placeholder below
   it — both were content being cut by a box too short for it).

   Fix: split the background and the content into two independent
   layers instead of one shared frame. The background (media +
   vignette + fades) is the ONLY thing that's position:sticky and
   height:100vh. The content is a normal-flow block with NO fixed
   height and NO overflow:hidden — it can be as tall as it needs to
   be, and a negative top margin pulls it up to visually sit on top
   of the sticky background underneath. As the content scrolls
   normally (nothing about it is pinned), the background stays
   pinned behind it for as long as the combined section is taller
   than 100vh, then releases and scrolls away like any other section.
   This is the standard "sticky background, scrolling foreground"
   technique — different from the "everything pinned together"
   technique hero/about/programs/journey use, because this section's
   content genuinely doesn't fit the second pattern.
   ============================================================ */

.contact-scene {
  position: relative;
  background: var(--navy-dark);
}

.contact-scene-wrapper {
  position: relative;
  /* No explicit height here — it's the natural sum of .contact-scene-bg's
     reserved 100vh plus .contact-scene__inner's own height (see that
     rule's margin-top: -100vh for how the two combine). Content decides
     its own size instead of being told to fit a guessed number. */
}

.contact-scene-bg {
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 1;
  overflow: hidden;
  --progress: 0;
}

.contact-scene-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.contact-scene-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 58%;
  display: block;
  transform: scale(1);
  transform-origin: 50% 58%; /* estimated center of the walkway/students
                                 grouping in the new art — same focal
                                 point for all 3 layers so they zoom
                                 toward one point in space, same
                                 reasoning as programs-scene's building
                                 focal point. Nudge live if the true
                                 subject sits elsewhere once you see it
                                 rendered. */
  will-change: transform;
}

/* Stacking order back -> front, matching the art's own depth — same
   pattern as programs-scene-media--back/--mid/--front. The mid and
   front layers are transparent everywhere except their own students,
   so the back layer shows through around them at scale 1 and gets
   progressively covered as the front layers scale up faster (see
   initZoomScene's per-layer scaleTo values in parallax.js). */
.contact-scene-media--back  { z-index: 1; }
.contact-scene-media--mid   { z-index: 2; }
.contact-scene-media--front { z-index: 3; }

.contact-scene-vignette {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 58%,
    transparent 30%,
    rgba(0, 8, 20, 0.7) 100%);
  opacity: calc(0.4 + (var(--progress) * 0.45));
}

/* A broad, mostly-uniform darkening on top of the vignette — the
   form card needs a consistently dark backdrop across its full width
   (unlike hero's narrow text column, the card sits centered and wide),
   and a vignette alone leaves the corners near-full-brightness. */
.contact-scene-scrim {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(0, 10, 25, 0.45) 0%,
    rgba(0, 10, 25, 0.6) 40%,
    rgba(0, 10, 25, 0.72) 100%);
}

.contact-scene-top-fade {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 22%;
  z-index: 5;
  pointer-events: none;
  background: linear-gradient(to bottom, var(--navy-dark) 0%, transparent 100%);
}

.contact-scene-fade {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 24%;
  z-index: 5;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, var(--navy-dark) 95%);
}

/* ---- Content ---- */
/* margin-top: -100vh pulls this up to visually start at the same
   point as .contact-scene-bg (which reserves its own 100vh directly
   above this in normal flow) — the standard sticky-background overlap
   trick. min-height guarantees at least 40vh of extra scroll beyond
   the background's own 100vh, so the zoom always has *some* room to
   animate even if the form is short on a very tall screen — but it's
   a FLOOR, not a cap: if the actual content (form + info panel) needs
   more room than that, this box simply grows to fit it, in full,
   with no clipping. That's the actual fix — nothing here can hide
   content the way the old overflow:hidden frame did. */
.contact-scene__inner {
  position: relative;
  z-index: 4;
  margin-top: -100vh;
  min-height: calc(100vh + 40vh);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 6rem 3rem;
}

.contact-scene__content {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
}

.contact-scene__intro {
  max-width: 560px;
  margin-bottom: 2.5rem;
}
.contact-scene__intro .section-text {
  color: rgba(255, 255, 255, 0.82);
}

.contact-scene__grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 3rem;
  align-items: start;
}

/* ---- Frosted form card — same recipe as .about__point (about-scene.css):
   translucent white fill, soft border, backdrop-blur. Consistent
   "glass card on a scene" language across the site instead of a new
   treatment invented just for this form.
   Compound selector (.contact-form.contact-form--glass) is deliberate,
   not decorative — a bare .contact-form--glass would tie in
   specificity with sections.css's .contact-form (background,
   border-top, padding all overlap), and since sections.css loads
   after this file, that plain rule would silently win and the glass
   background would never actually render. Compounding both classes
   beats it regardless of link order, instead of depending on this
   file staying ahead of sections.css in header.php forever. */
.contact-form.contact-form--glass {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-top: 3px solid var(--gold);
  border-radius: var(--radius-md);
  padding: 2.25rem;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* ---- Mascot video card — same frosted-glass recipe as the form/info
   cards above (see the note there for why: one visual language for
   "card on a scene" across the site, not a one-off treatment). Centered
   and capped at a modest width since this is a small closing moment,
   not another full grid column. ---- */
.contact-scene__mascot {
  max-width: 480px;
  margin: 3rem auto 0;
  text-align: center;
}

.mascot-video-card {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-top: 3px solid var(--gold);
  border-radius: var(--radius-md);
  padding: 0.6rem;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* Frame holds ONLY the video + button, with its own overflow:hidden —
   the mute button is positioned relative to this, not the card (which
   has its own 0.6rem padding around the frame), so it sits flush
   against the actual video edges rather than floating over the card's
   decorative border like it was before. */
.mascot-video-card__frame {
  position: relative;
  border-radius: calc(var(--radius-md) - 4px);
  overflow: hidden;
  line-height: 0;
}

.mascot-video-card__video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: rgba(0, 0, 0, 0.25);
  cursor: pointer;
}

/* Semi-transparent by default like a native video player's controls,
   sharpening to fully opaque on hover/focus so it's easy to find
   without permanently competing with the video for attention. */
.mascot-video-card__mute-btn {
  position: absolute;
  right: 0.85rem;
  bottom: 0.85rem;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  background: rgba(15, 15, 20, 0.4);
  opacity: 0.8;
  color: var(--white);
  font-size: 1.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: opacity 0.18s, background 0.18s, transform 0.18s;
}

.mascot-video-card__mute-btn:hover,
.mascot-video-card__mute-btn:focus-visible {
  opacity: 1;
  background: rgba(15, 15, 20, 0.78);
  transform: scale(1.08);
}

.mascot-video-card__caption {
  margin-top: 0.9rem;
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.92rem;
}

.contact-form--glass .contact-form__title {
  color: var(--white);
}

.contact-form--glass .form-group label {
  color: rgba(255, 255, 255, 0.85);
}

.contact-form--glass .form-group input,
.contact-form--glass .form-group textarea,
.contact-form--glass .form-group select {
  background: rgba(255, 255, 255, 0.92);
  border: 1.5px solid rgba(255, 255, 255, 0.3);
  color: var(--text-dark);
}

.contact-form--glass .form-group input:focus,
.contact-form--glass .form-group textarea:focus,
.contact-form--glass .form-group select:focus {
  border-color: var(--gold);
}

/* ---- Contact info — same glass treatment on each item so it reads
   against the scene instead of sitting directly on the art */
.contact-info--glass .ci-item {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius-md);
  padding: 1rem 1.1rem;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.contact-info--glass .ci-icon {
  background: rgba(255, 255, 255, 0.14);
}

.contact-info--glass .ci-label {
  color: var(--gold-light);
}

.contact-info--glass .ci-value {
  color: rgba(255, 255, 255, 0.82);
}

.contact-info--glass .map-placeholder {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.85);
}

/* ---- Responsive ---- */
@media (max-width: 900px) {
  .contact-scene__grid {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
  .contact-scene__inner { padding: 4rem 1.5rem; }
  .contact-form--glass { padding: 1.5rem; }
  .contact-scene-scrim {
    background: linear-gradient(to bottom,
      rgba(0, 10, 25, 0.55) 0%,
      rgba(0, 10, 25, 0.72) 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .contact-scene-bg { position: relative; height: 60vh; }
  .contact-scene__inner { margin-top: 0; min-height: 0; }
  .contact-scene-media img { transform: scale(1) !important; }
  .contact-scene-vignette { opacity: 0.45 !important; }
}
