/* NiemanLab exit popup.
 *
 * Mailmunch's directness — one hard claim, one field, one button — in
 * Roscoe's clothes: the ink navy from the hero palette, Literata pinned to
 * its small-text optical size, Schibsted for everything else.
 *
 * Every selector is namespaced .nlep*, and the card is a fixed-position
 * child of a fixed overlay, so nothing here can be reached by — or reach
 * into — either the Simple stylesheet it runs under today or the Roscoe
 * one it will run under later.
 */

.nlep,
.nlep *,
.nlep *::before,
.nlep *::after { box-sizing: border-box; }

.nlep[hidden] { display: none; }

.nlep {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;

  /* NO opacity transition on this element, deliberately.
     The backdrop below carries a backdrop-filter, and Chrome cannot
     resolve one while an ancestor is mid-way through compositing its own
     fade — so the card arrived with the opacity transition and the blur
     snapped in a beat later, as two visibly separate events. The backdrop
     and the card now each animate themselves instead, and the blur ramps
     from 0 as part of that same transition, so the ground softens WITH
     the card rather than after it. */

  /* Clicks pass through until it is genuinely open. open() sets
     hidden=false and adds .is-open on the next animation frame — and rAF
     does not run in a backgrounded tab, which would otherwise leave an
     invisible full-viewport layer eating every click. */
  pointer-events: none;
}
.nlep.is-open { pointer-events: auto; }

/* NEUTRAL, not branded. A full screen of house colour reads as a state
   the reader moved into — right for the subscribe overlay, which they
   opened on purpose. This one arrives uninvited, so it has to read as the
   page being briefly covered, not replaced. Lighter than it was, too: the
   card is now light, so the backdrop no longer has to do the work of
   making it stand out — though at .76 it is doing plenty, which is what
   makes a pale card read as lit rather than merely placed. */
.nlep-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 14, 20, 0);
  -webkit-backdrop-filter: blur(0px);
          backdrop-filter: blur(0px);
  transition: background .3s ease,
              -webkit-backdrop-filter .3s ease,
              backdrop-filter .3s ease;
}
.nlep.is-open .nlep-backdrop {
  background: rgba(10, 14, 20, .76);
  -webkit-backdrop-filter: blur(6px) saturate(.92);
          backdrop-filter: blur(6px) saturate(.92);
}

/* Where backdrop-filter is unsupported the tint alone does the obscuring,
   so it goes darker. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nlep.is-open .nlep-backdrop { background: rgba(10, 14, 20, .86); }
}

html.nlep-locked,
html.nlep-locked body { overflow: hidden; }

/* ---- the card's colour, in one place ----
   Swapping the palette is these six values and nothing else. Light and
   warm on purpose: a dark card on a dimmed page is two layers of gloom,
   and this thing interrupts someone — it should read as an offer, not a
   warning. Apricot is from the Roscoe hero palette, so it is a colour the
   design already owns, and it is the nearest thing in that set to the
   coral the Mailmunch popup converted on for years. */
.nlep-card {
  --nlep-bg:      #d6e5e0;   /* Pale sage */
  --nlep-ink:     #1a1a1a;
  --nlep-soft:    rgba(26, 26, 26, .74);
  --nlep-faint:   rgba(26, 26, 26, .55);
  --nlep-rule:    rgba(26, 26, 26, .34);
  --nlep-btn:     #12243a;   /* Ink navy, so the CTA still reads as Roscoe */
  --nlep-btn-ink: #fff;

  position: relative;
  width: 100%;
  max-width: 540px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding: 42px 42px 34px;
  background: var(--nlep-bg);
  color: var(--nlep-ink);
  border-radius: 8px;
  box-shadow: 0 26px 70px rgba(0, 0, 0, .35);
  font-family: 'Schibsted Grotesk', -apple-system, system-ui, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

  opacity: 0;
  transform: translateY(10px) scale(.99);
  /* 40ms behind the backdrop, so the ground has started settling before
     the card lands on it. One gesture, not two. */
  transition: opacity .26s ease .04s, transform .26s ease .04s;
}
.nlep.is-open .nlep-card { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .nlep-backdrop, .nlep-card { transition: none; }
}

.nlep-x {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  padding: 8px;
  background: none;
  border: 0;
  border-radius: 4px;
  color: var(--nlep-faint);
  cursor: pointer;
  line-height: 0;
  transition: color .15s;
}
.nlep-x:hover,
.nlep-x:focus-visible { color: var(--nlep-ink); }

/* Literata at opsz 7 — the cut drawn for footnote-sized text, blown up
   large. Sturdy and open rather than the delicate display cut the axis
   would otherwise pick, which is what makes the claim land. */
.nlep-hed {
  margin: 0 0 24px;
  font-family: Literata, Georgia, serif;
  font-variation-settings: 'opsz' 7;
  font-weight: 600;
  /* 3rem at the top end, matching the subscribe overlay. The clamp keeps
     it from overwhelming a narrow card; text-wrap:balance is what
     actually evens the two lines, rather than leaving greedy wrapping to
     drop "inbox." onto a line by itself. */
  font-size: clamp(1.8rem, 6vw, 3rem);
  line-height: 1.1;
  letter-spacing: -.02em;
  text-wrap: balance;
  color: var(--nlep-ink);
}

.nlep-body {
  margin: 0 0 26px;
  font-size: .95rem;
  line-height: 1.55;
  color: var(--nlep-soft);
}

.nlep-label span { font-weight: 400; text-transform: none; letter-spacing: 0; }

.nlep-label {
  display: block;
  margin: 0 0 6px;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--nlep-faint);
}

/* Underlined rather than boxed, matching the subscribe overlay in the
   theme so the two read as the same family once Roscoe is live. */
.nlep-input {
  display: block;
  width: 100%;
  margin: 0 0 22px;
  padding: 9px 0;
  background: none;
  border: 0;
  border-bottom: 2px solid var(--nlep-rule);
  border-radius: 0;
  color: var(--nlep-ink);
  font-family: inherit;
  font-size: 1.15rem;
  font-weight: 300;
  outline: none;
  -webkit-appearance: none;
          appearance: none;
  transition: border-color .15s;
}
.nlep-input::placeholder { color: rgba(26, 26, 26, .38); }
.nlep-input:focus { border-bottom-color: var(--nlep-ink); }
/* :user-invalid, not :invalid — an empty required field is invalid from
   the moment it renders, and would light up red before anyone typed. */
.nlep-input:user-invalid { border-bottom-color: #a01b2d; }

.nlep-submit {
  position: relative;
  width: 100%;
  min-height: 48px;
  padding: 14px 24px;
  background: var(--nlep-btn);
  color: var(--nlep-btn-ink);
  border: 0;
  border-radius: 4px;
  font-family: inherit;
  font-size: .8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  cursor: pointer;
  transition: opacity .15s;
}
.nlep-submit:hover { opacity: .88; }
.nlep-submit:disabled { cursor: default; }

/* The wait is the real Sendy round trip — see popup.js. The button holds
   its size so the card doesn't jump when the label swaps out. */
.nlep-spin { display: none; }
.nlep-submit.is-busy .nlep-submit-label { visibility: hidden; }
.nlep-submit.is-busy .nlep-spin {
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 17px;
  height: 17px;
  margin: -9px 0 0 -9px;
  border: 2px solid rgba(255, 255, 255, .3);
  border-top-color: var(--nlep-btn-ink);
  border-radius: 50%;
  animation: nlep-spin .6s linear infinite;
}
@keyframes nlep-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .nlep, .nlep-card { transition: none; }
  .nlep-submit.is-busy .nlep-spin {
    animation: nlep-pulse 1s ease-in-out infinite;
    border-top-color: rgba(255, 255, 255, .3);
    background: var(--nlep-btn-ink);
  }
  @keyframes nlep-pulse { 50% { opacity: .25; } }
}

.nlep-fine {
  margin: 16px 0 0;
  font-size: .75rem;
  line-height: 1.5;
  color: var(--nlep-faint);
}
.nlep-fine a { color: var(--nlep-ink); }

/* Off-screen, not display:none — a bot reading the DOM should still find
   a field that looks fillable. */
.nlep-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Spoken, not seen: the spinner is decorative, so this is what a screen
   reader gets. Must stay in the accessibility tree, which display:none
   would not. */
.nlep-status {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.nlep-done-hed {
  margin: 0 0 12px;
  font-family: Literata, Georgia, serif;
  font-variation-settings: 'opsz' 7;
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.15;
  color: var(--nlep-ink);
}
.nlep-done-body {
  margin: 0 0 22px;
  font-size: .95rem;
  line-height: 1.55;
  color: var(--nlep-soft);
}
.nlep-done-body strong { color: var(--nlep-ink); }
#nlep-done:focus { outline: none; }

.nlep-close-btn {
  padding: 11px 22px;
  background: none;
  border: 1px solid var(--nlep-rule);
  border-radius: 4px;
  color: var(--nlep-ink);
  font-family: inherit;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  cursor: pointer;
}
.nlep-close-btn:hover { border-color: var(--nlep-ink); }

@media (max-width: 560px) {
  /* Centred, like the desktop. It was a bottom sheet — the native idiom
     for something the user pulled up themselves — but this arrives
     uninvited, and anchoring it to the thumb made it look like a system
     prompt rather than an offer. Centred also keeps the close button
     where the eye already expects it. */
  .nlep { padding: 16px; }
  .nlep-card { padding: 32px 24px 26px; max-height: 86vh; }
  .nlep-input { font-size: 1.05rem; }
}
