/* ============================================================
   Offer promo — sitewide banner + desktop exit-intent modal
   Owner-approved 2026-08-19.

   ⚠️ THE BANNER HEIGHT IS LOAD-BEARING. The nav is position:fixed and
   the homepage scroll animation hard-codes nav clearance in two places
   (.hero-sticky, .stage-scrub-pin). Everything that has to move when the
   banner appears or is dismissed reads --banner-h, so there is ONE number
   to change rather than four that must agree. Do not reintroduce a
   literal pixel offset in any of them.

   js/scrub.js reads getComputedStyle(sticky).top at runtime, so the
   scroll maths follows the variable on its own — no JS change needed.
   ============================================================ */

:root { --banner-h: 0px; }

/* Set by the inline head script BEFORE first paint, so a visitor who
   dismissed the banner never sees it flash in and back out. */
html.promo-on { --banner-h: 40px; }

@media (max-width: 700px) {
  html.promo-on { --banner-h: 62px; }  /* message wraps to a second line */
}

html.promo-on body { padding-top: var(--banner-h); }
html.promo-on .nav { top: var(--banner-h); }

/* The two hard-coded scroll-pin offsets, now derived. 88px and 0 are the
   original values — the banner is simply added on top. */
html.promo-on .hero-sticky { top: calc(88px + var(--banner-h)); }
html.promo-on .stage-scrub-pin { top: var(--banner-h); }

/* ── the banner ─────────────────────────────────────────────── */
/* WHITE, not blue. The nav and hero are both --dark-navy, and royal blue
   sits within a few points of that in luminance — the original gradient
   read as a second nav bar rather than as an offer. Nothing in this
   palette except white and lime can separate from navy, and lime as a
   full surface reads discount-retail against a consultative brand. */
.promo-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--banner-h);
  z-index: 1100;            /* above .nav (1000) */
  background: var(--white);
  color: var(--dark-navy);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  padding: 0 2.75rem 0 1.1rem;
  font-size: 0.84rem;
  line-height: 1.35;
}
html:not(.promo-on) .promo-bar { display: none; }

.promo-tag {
  background: var(--accent-green);
  color: var(--dark-navy);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  white-space: nowrap;
}
.promo-msg strong { font-weight: 700; }
.promo-go {
  color: var(--royal-blue);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.promo-go:hover { color: var(--dark-navy); }

.promo-x {
  position: absolute;
  right: 0.7rem; top: 50%;
  transform: translateY(-50%);
  background: none; border: none;
  color: #8A94A3;
  font-size: 1.15rem; line-height: 1;
  cursor: pointer; padding: 0.25rem 0.4rem;
}
.promo-x:hover { color: var(--dark-navy); }
.promo-x:focus-visible { outline: 2px solid var(--royal-blue); outline-offset: 2px; }

@media (max-width: 700px) {
  .promo-bar {
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 0.5rem;
    padding: 0 2.2rem 0 0.85rem;
    font-size: 0.78rem;
  }
  .promo-msg { flex: 1 1 100%; order: 2; }
}

/* ── the modal ──────────────────────────────────────────────── */

/* 🔴 THIS RULE IS NOT OPTIONAL. `[hidden] { display: none }` comes from
   the browser's own stylesheet, and ANY author rule setting `display`
   beats it — so `.promo-modal-backdrop { display: grid }` silently
   cancelled the hidden attribute and the pop-up showed full-screen on
   every page load, every device, with the close button doing nothing
   (close() sets .hidden, which was already true).
   Shipped that way 2026-08-19 and the owner found it. Any element that
   both sets `display` and relies on `hidden` needs this pair. */
.promo-modal-backdrop[hidden] { display: none; }

.promo-modal-backdrop {
  position: fixed;
  inset: 0;
  /* 0.55 over an already-dark hero barely dimmed anything, so the page
     never receded and the card had nothing to sit against. */
  background: rgba(8, 14, 26, 0.74);
  z-index: 2000;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  opacity: 0;
  animation: promoFade 0.22s ease forwards;
}
@keyframes promoFade { to { opacity: 1; } }

/* A bright card on a dimmed dark page — the arrangement that makes a
   dialog read as a dialog. The previous navy card sat on a navy scrim
   over a navy hero: three layers of the same colour, so it had no edge. */
.promo-modal {
  background: var(--white);
  color: var(--text-dark);
  border-radius: 12px;
  max-width: 470px;
  width: 100%;
  padding: 2.1rem 2.1rem 1.75rem;
  position: relative;
  overflow: hidden;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.45);
}
/* No coloured left accent bar. It is a retired pattern on this brand
   (see the design notes — "the generic Claude look"), and it had no
   business being reintroduced here. The lime lives in the eyebrow only. */
.promo-modal-x {
  position: absolute;
  right: 0.85rem; top: 0.7rem;
  background: none; border: none;
  color: #9AA3B2;
  font-size: 1.25rem; cursor: pointer; padding: 0.25rem 0.4rem;
}
.promo-modal-x:hover { color: var(--dark-navy); }
.promo-modal-x:focus-visible { outline: 2px solid var(--royal-blue); outline-offset: 2px; }

/* Royal, not lime — lime on white is nowhere near AA. */
.promo-modal .promo-eyebrow {
  color: var(--royal-blue);
  font-size: 0.66rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  margin-bottom: 0.55rem;
}
.promo-modal h3 {
  margin: 0 0 0.5rem;
  font-size: 1.5rem; line-height: 1.25;
  font-weight: 700; letter-spacing: -0.02em;
  color: var(--dark-navy);
}
.promo-modal h3 em { font-style: normal; color: var(--royal-blue); }
.promo-modal .promo-lede {
  margin: 0 0 1.25rem;
  color: var(--text-mid);
  font-size: 0.92rem;
}

.promo-form { display: grid; grid-template-columns: 1fr auto; gap: 0.55rem; }
.promo-form input {
  width: 100%;
  background: var(--white);
  border: 1px solid #C7CDD8;
  border-radius: 7px;
  padding: 0.8rem 1rem;
  color: var(--text-dark);
  font-family: inherit; font-size: 0.9rem;
  outline: none; box-sizing: border-box;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.promo-form input::placeholder { color: #98A0AE; }
.promo-form input:focus {
  border-color: var(--royal-blue);
  box-shadow: 0 0 0 3px rgba(34, 62, 145, 0.12);
}
.promo-form button {
  background: var(--royal-blue);
  color: var(--white);
  border: none; border-radius: 7px;
  padding: 0.8rem 1.25rem;
  font-family: inherit; font-weight: 700; font-size: 0.88rem;
  cursor: pointer; white-space: nowrap;
  transition: background 0.25s;
}
.promo-form button:hover { background: var(--royal-hover, #1a3078); }
.promo-form button[disabled] { opacity: 0.6; cursor: default; }
.promo-form button:focus-visible { outline: 2px solid var(--royal-blue); outline-offset: 2px; }

/* Honeypot — off-screen, not display:none. */
.promo-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

.promo-foot { margin: 0.8rem 0 0; font-size: 0.76rem; color: #7A8494; }
.promo-foot a { color: var(--royal-blue); text-decoration: underline; }

.promo-status { margin: 0.6rem 0 0; font-size: 0.8rem; min-height: 1.1em; }
.promo-status--error { color: #B42318; }
.promo-status--pending { color: var(--text-mid); }

@media (prefers-reduced-motion: reduce) {
  .promo-modal-backdrop { animation: none; opacity: 1; }
}
