/* ==========================================================================
   Purple Door Security — Contact panel
   Emerges from the threshold light once the door swings open.
   With JS disabled it is ordinary, always-visible page content.
   ========================================================================== */

.contact {
  /* Fixed, not absolute: the panel is centred on the viewport, so even if the
     document does scroll it cannot slide off-centre. Safe here because no
     ancestor sets transform/filter/perspective — .scene owns the perspective,
     and this panel is its sibling, not its child. If that ever changes, this
     silently becomes absolute-to-that-ancestor and the centring breaks. */
  position: fixed;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  z-index: 12;
  /* Clears the header when the no-JS build jumps to this via #contact. */
  scroll-margin-block-start: var(--pd-space-7);
  width: min(560px, calc(100vw - 2 * var(--pd-gutter)));
  max-height: min(88svh, 780px);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translate(-50%, -46%) scale(0.86);
  opacity: 0;
  visibility: hidden;
  filter: blur(12px);
  transition:
    opacity var(--pd-dur-slow) var(--pd-ease-entrance),
    transform var(--pd-dur-slow) var(--pd-ease-entrance),
    filter var(--pd-dur-slow) var(--pd-ease-entrance),
    visibility 0s linear var(--pd-dur-slow);

  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--pd-radius-xl);
  border: 1px solid rgba(var(--pd-purple-300-rgb), 0.16);
  background:
    linear-gradient(180deg, rgba(var(--pd-light-500-rgb), 0.07), transparent 26%),
    linear-gradient(165deg, rgba(var(--pd-purple-800-rgb), 0.94), rgba(16, 12, 28, 0.97));
  box-shadow:
    var(--pd-shadow-lg),
    0 0 90px -20px rgba(var(--pd-light-500-rgb), 0.35),
    inset 0 1px 0 rgba(var(--pd-light-400-rgb), 0.16);
  backdrop-filter: blur(14px);
}

/* Emergence is staged to land as the camera arrives, so the form resolves out
   of the light at the moment you finish stepping through — not before the
   door has opened, and not after the movement has stopped. */
.portal.is-open .contact {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, -50%) scale(1);
  filter: blur(0);
  transition-delay: var(--pd-delay-reveal), var(--pd-delay-reveal),
    var(--pd-delay-reveal), 0s;
}

.contact__head {
  margin-bottom: var(--pd-space-5);
}

.contact__title {
  font-size: var(--pd-text-xl);
  margin-top: var(--pd-space-2);
}

.contact__close {
  position: absolute;
  inset-block-start: var(--pd-space-4);
  inset-inline-end: var(--pd-space-4);
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--pd-ash);
  border-radius: var(--pd-radius-pill);
  background: rgba(28, 22, 48, 0.7);
  color: var(--pd-mute);
  cursor: pointer;
  transition: color var(--pd-dur-fast) var(--pd-ease-standard),
    border-color var(--pd-dur-fast) var(--pd-ease-standard);
}

.contact__close:hover {
  color: var(--pd-text);
  border-color: var(--pd-purple-400);
}

/* --- Form ---------------------------------------------------------------- */
.form__grid {
  display: grid;
  gap: var(--pd-space-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-2);
}

.field--full {
  grid-column: 1 / -1;
}

.field__label {
  font-size: var(--pd-text-sm);
  font-weight: 500;
  color: var(--pd-text);
}

.field__control {
  width: 100%;
  padding: var(--pd-space-3) var(--pd-space-4);
  min-height: 48px;
  border: 1px solid var(--pd-ash);
  border-radius: var(--pd-radius-md);
  background: rgba(8, 6, 15, 0.55);
  color: var(--pd-text);
  font-size: var(--pd-text-sm);
  transition: border-color var(--pd-dur-fast) var(--pd-ease-standard),
    box-shadow var(--pd-dur-fast) var(--pd-ease-standard);
}

.field__control::placeholder {
  color: rgba(167, 155, 196, 0.6);
}

.field__control:hover {
  border-color: var(--pd-purple-700);
}

.field__control:focus {
  outline: none;
  border-color: var(--pd-purple-400);
  box-shadow: 0 0 0 3px rgba(var(--pd-purple-500-rgb), 0.28);
}

textarea.field__control {
  resize: vertical;
  min-height: 118px;
  line-height: var(--pd-leading-normal);
}

select.field__control {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--pd-mute) 50%),
    linear-gradient(135deg, var(--pd-mute) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-inline-end: var(--pd-space-8);
}

select.field__control option {
  background: var(--pd-ink);
  color: var(--pd-text);
}

/* Invalid state is only shown once the field has been interacted with —
   :user-invalid, not :invalid, so an empty untouched form isn't a wall of red.
   The .is-invalid class is the fallback for browsers without :user-invalid. */
.field__control:user-invalid,
.field__control.is-invalid {
  border-color: var(--pd-danger);
}

.field__control:user-invalid:focus,
.field__control.is-invalid:focus {
  box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.25);
}

/* Data-minimisation notice under the message box — deliberately placed where
   someone is about to type, not buried in a privacy page they won't open. */
.field__note {
  margin: 0;
  font-size: var(--pd-text-xs);
  line-height: var(--pd-leading-normal);
  color: var(--pd-mute);
}

.field__error {
  display: none;
  align-items: center;
  gap: var(--pd-space-2);
  font-size: var(--pd-text-xs);
  color: var(--pd-danger);
}

.field__error:not(:empty) {
  display: flex;
}

/* Turnstile widget: give it breathing room and stop it from stretching the
   form rhythm. The widget itself is an iframe we don't style; flexible size
   + dark theme are set via data-attributes in the markup. */
.form__challenge {
  margin-top: var(--pd-space-5);
  min-height: 65px; /* reserve the managed-widget height to avoid reflow */
}

/* --- Actions ------------------------------------------------------------- */
.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pd-space-4);
  margin-top: var(--pd-space-5);
}

.form__note {
  font-size: var(--pd-text-xs);
  color: var(--pd-mute);
  margin: 0;
}

.btn[aria-busy="true"] {
  opacity: 0.7;
  pointer-events: none;
}

/* --- Status region ------------------------------------------------------- */
.form__status {
  margin-top: var(--pd-space-4);
  padding: var(--pd-space-4);
  border-radius: var(--pd-radius-md);
  font-size: var(--pd-text-sm);
  display: none;
}

.form__status:not(:empty) {
  display: block;
}

.form__status[data-state="success"] {
  background: rgba(74, 222, 155, 0.1);
  border: 1px solid rgba(74, 222, 155, 0.35);
  color: var(--pd-success);
}

.form__status[data-state="error"] {
  background: rgba(255, 107, 107, 0.1);
  border: 1px solid rgba(255, 107, 107, 0.35);
  color: var(--pd-danger);
}

/* --- Responsive ---------------------------------------------------------- */
@media (max-width: 34rem) {
  .form__grid {
    grid-template-columns: 1fr;
  }

  .contact {
    max-height: 90svh;
  }
}

/* --- No JavaScript ------------------------------------------------------- */
/* Static, in-flow, always visible. */
.no-js .contact {
  position: static;
  transform: none;
  opacity: 1;
  visibility: visible;
  filter: none;
  max-height: none;
  margin-inline: auto;
  margin-block-start: var(--pd-space-8);
  backdrop-filter: none;
}

.no-js .contact__close {
  display: none;
}
