/* ==========================================================================
   BULLETPROOF PERFORMANCE — newsletter pop-up

   The <dialog id="newsletter"> in index.html, opened by newsletter.js. Built
   on the site's own tokens and its .eyebrow, .btn, .field, .form__trap and
   .form__status rules, which both copies of style.css already carry, so only
   the dialog itself is styled here.

   This file is identical in academy/: the subdomain cannot reach this folder
   by URL. Change one, copy it to the other.
   ========================================================================== */

/* A closed <dialog> is hidden by the browser's own `display: none`. Any
   display set on .signup itself would override that and show it on load, so
   the layout only applies while it is [open]. */
.signup {
  width: min(900px, calc(100% - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.signup[open] {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  animation: signup-in .4s var(--ease);
}
/* Opening it focuses the dialog itself, so a screen reader starts at its
   title. The site's focus ring drawn round the whole pop-up only reads as a
   glitch; the controls inside keep theirs. */
.signup:focus-visible { outline: none; }
.signup::backdrop {
  background: rgba(4, 7, 11, .74);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.signup[open]::backdrop { animation: signup-fade .4s var(--ease); }

@keyframes signup-in {
  from { opacity: 0; transform: translateY(18px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes signup-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Photo column. The ground colour holds the space while the image, which is
   lazy and so only fetched once the pop-up opens, comes in. */
.signup__media {
  position: relative;
  background: var(--surface-2);
}
.signup__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 30%;
}
/* Settles the bright changing room into the dark panel beside it */
.signup__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(14, 21, 30, 0) 55%, var(--surface) 100%),
    linear-gradient(180deg, rgba(7, 11, 16, .05) 40%, rgba(7, 11, 16, .55) 100%);
}

/* Once they have joined, the photo column becomes the circuit video. The
   column takes the video's own shape, so nothing is cropped or letterboxed,
   and the overlay goes: it would sit on top of the player's controls. The
   ground is the video's own charcoal. */
.signup.is-done .signup__media { aspect-ratio: 720 / 922; background: #171717; }
.signup.is-done .signup__media img,
.signup.is-done .signup__media::after { display: none; }
.signup__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #171717;
}

/* The body scrolls inside the dialog when a short screen cannot fit it, and
   `contain` stops that scroll running on into the page behind. It is not
   positioned, so the close button sits on the dialog's corner rather than
   scrolling away with the body. */
.signup__body {
  max-height: calc(100dvh - 34px);
  padding: 44px 44px 36px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.signup h2 {
  font-size: clamp(1.45rem, 2.3vw, 1.9rem);
  line-height: 1.14;
  margin-bottom: var(--space-sm);
  padding-right: 28px; /* clear of the close button */
}
.signup .eyebrow { margin-bottom: var(--space-sm); }
/* "gas-tank" is one word to a reader: never "gas-" at a line end */
.signup__keep { white-space: nowrap; }
.signup__intro { margin-bottom: var(--space-lg); color: var(--text); font-size: .98rem; }

.signup__close {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255, 255, 255, .05);
  color: var(--heading);
  cursor: pointer;
  transition: background-color .2s var(--ease), border-color .2s var(--ease);
}
.signup__close svg { width: 18px; height: 18px; }
.signup__close:hover { background: rgba(255, 255, 255, .1); border-color: var(--line-strong); }
/* On a phone it ends up over the video's corner artwork: solid, so it still
   reads as a button there */
.signup.is-done .signup__close { background: rgba(7, 11, 16, .82); }
.signup.is-done .signup__close:hover { background: var(--surface-2); }

.signup__form .btn { margin-top: var(--space-xs); }

/* style.css carries .form__legal on the main site only, so the pop-up has its own */
.signup__legal { margin: var(--space-md) 0 0; font-size: .74rem; line-height: 1.5; color: var(--muted); }
.signup__legal a { color: inherit; text-decoration: underline; }
.signup__legal a:hover { color: var(--heading); }

/* Done state */
.signup__done { display: grid; align-content: center; min-height: 100%; }
.signup__done h2 { outline: none; }
.signup__done p { margin-bottom: var(--space-lg); }
.signup__tick {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  margin-bottom: var(--space-lg);
  border-radius: 50%;
  background: var(--accent-chip);
  box-shadow: var(--glow);
  color: var(--accent);
}
.signup__tick svg { width: 26px; height: 26px; }
.signup__later {
  justify-self: center;
  margin-top: var(--space-md);
  padding: 8px 12px;
  border: 0;
  background: none;
  color: var(--muted);
  font: 500 .9rem/1.4 var(--font-body);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.signup__later:hover { color: var(--heading); }

/* Phones: one column, no photo. The image is never fetched here, since a
   lazy image that is not displayed is not loaded. */
@media (max-width: 767px) {
  .signup { width: calc(100% - 24px); max-height: calc(100dvh - 24px); }
  .signup[open] { grid-template-columns: minmax(0, 1fr); }
  .signup__media { display: none; }
  .signup__body { max-height: calc(100dvh - 26px); padding: 28px 20px 24px; }
  .signup__close { top: 10px; right: 10px; }
  .signup h2 { font-size: 1.4rem; padding-right: 36px; }
  .signup__intro { margin-bottom: var(--space-md); }

  /* Joined: the video comes back, above the message, at a height that leaves
     the download button in view. The whole dialog scrolls rather than the
     body alone, since the video is not inside the body. The tick goes: the
     video already says it worked. */
  .signup.is-done { overflow-y: auto; overscroll-behavior: contain; }
  .signup.is-done .signup__media { display: block; aspect-ratio: auto; height: min(52dvh, 460px); }
  .signup.is-done .signup__body { max-height: none; overflow: visible; padding-top: 20px; }
  .signup.is-done .signup__tick { display: none; }
  .signup.is-done .signup__done h2 { padding-right: 0; }
}

/* Short landscape screens: keep the fields reachable without the photo. Once
   joined the video is the point, so it stays, beside the message. */
@media (max-height: 560px) and (min-width: 768px) {
  .signup[open]:not(.is-done) { grid-template-columns: minmax(0, 1fr); width: min(560px, calc(100% - 32px)); }
  .signup:not(.is-done) .signup__media { display: none; }
  /* Too short for the video's full height: fill the row and letterbox */
  .signup.is-done .signup__media { aspect-ratio: auto; }
}

/* style.css's reduced motion rule already cuts animations to nothing; this
   states the intent for the pop-up in its own file. */
@media (prefers-reduced-motion: reduce) {
  .signup[open], .signup[open]::backdrop { animation: none; }
}

@media (forced-colors: active) {
  .signup { border-color: CanvasText; }
  .signup__close { border-color: ButtonText; }
}

@media print {
  .signup { display: none !important; }
}
