/* ============================================================
   COMING SOON TEASER — full-bleed photo "drop" page.
   global.css (fonts, resets, --brand-* vars, --duration-*) is always
   loaded first via layout.mjs, so this file only adds what's unique here.
   ============================================================ */

.teaser-page {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  padding: 32px 20px;
  text-align: center;
  background: #05100a; /* shows briefly before the photo paints */
}

/* ---- Background photo: slow Ken Burns drift, contained so the zoom
   never reveals an edge or causes scroll.
   Deliberately position:absolute + z-index:0 (stacked below .teaser-content
   via DOM order + z-index, not negative z-index) — .teaser-page has
   position:relative but no z-index, so it doesn't form its own stacking
   context, meaning position:fixed negative-z-index children here would
   escape to the document root and render BEHIND <body>'s own opaque
   background (global.css sets one) instead of behind this page's content.
   absolute + non-negative z-index avoids that trap entirely. */
.teaser-bg-wrap {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
.teaser-bg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 35%;
  transform: scale(1.06);
  transform-origin: center;
  will-change: transform;
  /* Deliberately subliminal: a long duration and a small scale/pan range
     so the motion sits just above the threshold of "I can see this
     moving" — felt more than seen. Linear, not ease-in-out: any
     acceleration/deceleration curve creates a moment where the rate of
     change is more noticeable, which is exactly the obvious "Ken Burns"
     look this is trying to avoid. */
  animation: teaser-kenburns 100s linear infinite alternate;
}
@keyframes teaser-kenburns {
  0% { transform: scale(1.06) translate(0%, 0%); }
  100% { transform: scale(1.11) translate(-1%, -0.7%); }
}

/* Dramatic scrim: darker at the edges and bottom so the white type stays
   legible over a busy forest photo without flattening the image itself. */
.teaser-scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(to bottom, rgba(4, 12, 8, 0.75) 0%, rgba(4, 12, 8, 0.25) 30%, rgba(4, 12, 8, 0.55) 70%, rgba(3, 9, 6, 0.9) 100%),
    radial-gradient(120% 90% at 50% 45%, transparent 35%, rgba(2, 8, 5, 0.55) 100%);
}

/* Faint film grain for a bit of cinematic texture — subtle on purpose. */
.teaser-grain {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

.teaser-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 620px;
}

.teaser-logo {
  width: 168px;
  height: auto;
  margin-bottom: 28px;
  opacity: 0;
  filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.4));
  animation: teaser-fade-up var(--duration-slow) var(--ease-standard) forwards;
}
.teaser-eyebrow {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7);
  margin-bottom: 14px;
  opacity: 0;
  animation: teaser-fade-up var(--duration-slow) var(--ease-standard) 0.1s forwards;
}
.teaser-headline {
  font-family: var(--font-display);
  /* Was 60px, sized for the original short 3-word headline ("Coming Home
     Soon"). The current longer headline wrapped to 5 lines at that size
     and read as oversized/dominant on the page (Hayden's feedback, Aug
     2026) — brought down to a size that fits comfortably within
     .teaser-content's 620px width without overwhelming the countdown/CTA
     below it. */
  font-size: 38px;
  font-weight: 400;
  line-height: 1.1;
  /* Matches every other heading site-wide (.hero-title, .legal-title,
     .type-title, etc.) — see the comment on .hero-title in home.css. Was
     0.06em, which read tighter/off-brand next to the rest of the site. */
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);
  margin-bottom: 36px;
  /* The break between "First Pick:" and "Rove's Final Release" is a
     deliberate <br> in the markup (Hayden's feedback, Aug 2026) — always
     two lines, split in the same place, at any screen width. Earlier this
     relied on text-wrap:balance to pick a wrap point automatically, but
     the browser's choice varied with viewport width; the explicit <br> is
     more predictable now that the exact split is intentional. balance is
     kept here only as a fallback in case "Rove's Final Release" itself
     ever needs to wrap again on a very narrow screen — it has no effect
     on the two lines the <br> already forces. Support: Chrome/Edge 114+,
     Safari 17.4+, Firefox 121+ (all well predate this build); degrades
     harmlessly to default wrapping on anything older. */
  text-wrap: balance;
  opacity: 0;
  animation: teaser-fade-up var(--duration-slow) var(--ease-standard) 0.2s forwards;
}
@keyframes teaser-fade-up {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---- Countdown ---- */
.teaser-countdown {
  display: flex;
  gap: 14px;
  margin-bottom: 10px;
  opacity: 0;
  animation: teaser-fade-up var(--duration-slow) var(--ease-standard) 0.35s forwards;
}
.teaser-countdown-unit {
  width: 76px;
  padding: 14px 0 12px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 14px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.teaser-countdown-value {
  display: block;
  font-family: var(--font-display);
  font-size: 34px;
  color: #fff;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.teaser-countdown-label {
  display: block;
  margin-top: 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
}
.teaser-countdown-date {
  font-size: 13px;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.65);
  margin-bottom: 36px;
  opacity: 0;
  animation: teaser-fade-up var(--duration-slow) var(--ease-standard) 0.45s forwards;
}

.teaser-cta-wrap {
  opacity: 0;
  animation: teaser-fade-up var(--duration-slow) var(--ease-standard) 0.55s forwards;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.teaser-cta {
  background-color: #fff;
  color: #0f2019;
  border: none;
  padding: 17px 40px;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  transition: transform var(--duration-fast) var(--ease-standard),
    background-color var(--duration-fast) var(--ease-standard);
}
.teaser-cta:hover {
  transform: scale(1.03);
  background-color: var(--brand-sage-light);
}
.teaser-cta:active {
  transform: scale(0.98);
}

/* Form reveal: collapsed via max-height (not `display`) so it can
   transition smoothly instead of snapping open — see the JS handler for
   [data-teaser-cta] in script.js, which removes [hidden] then adds
   .is-open on the next frame. */
.teaser-form {
  width: 100%;
  max-width: 420px;
  text-align: left;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transform: translateY(-8px);
  transition: max-height var(--duration-slow) var(--ease-standard),
    opacity var(--duration-base) var(--ease-standard),
    transform var(--duration-base) var(--ease-standard);
}
.teaser-form.is-open {
  /* Was 600px, sized for the earlier 3-field version. Now six fields (three
     rows instead of two) plus consent/submit — stacks to a single column
     per row on mobile (see the 640px breakpoint below), which is the
     tallest case. Sized with headroom for that. */
  max-height: 1000px;
  opacity: 1;
  transform: translateY(0);
}
.teaser-form .form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 14px;
}
.teaser-form label {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  display: block;
  margin-bottom: 4px;
}
.teaser-form input,
.teaser-form select {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 15px;
  font-family: var(--font-body);
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
  color: #fff;
}
.teaser-form input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}
.teaser-form input:focus,
.teaser-form select:focus {
  outline: none;
  border-color: var(--brand-sage);
  background: rgba(255, 255, 255, 0.16);
}
/* Native <select> boxes need their own rule (the shared `input` rule above
   doesn't apply to select) plus a couple of select-only fixes: the closed
   box's selected-value text needs to be readable against the dark photo
   background, and the "unselected" first option (value="") should read
   like a placeholder the same way the text inputs do — browsers render a
   <select>'s displayed value in the select's own `color`, so this doubles
   as the placeholder-style rule for that empty first option. The dropdown
   list itself (when opened) is unavoidably native OS chrome, same as the
   register form's selects elsewhere on the site (unit.css). */
.teaser-form select {
  cursor: pointer;
  color-scheme: dark;
}
.teaser-form select:invalid {
  color: rgba(255, 255, 255, 0.4);
}
.teaser-form select option {
  color: #0f2019;
}

.teaser-form .register-consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  margin-bottom: 16px;
}
.teaser-form .register-consent input[type='checkbox'] {
  width: 16px;
  height: 16px;
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: var(--brand-sage);
}
.teaser-form .register-consent-body {
  font-size: 11px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.6);
}
.teaser-form .register-consent-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.teaser-form .register-consent-text.is-expanded {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}
.teaser-form .register-consent-text a {
  color: rgba(255, 255, 255, 0.8);
}
.teaser-form .register-consent-toggle {
  display: inline-block;
  margin-top: 2px;
  background: none;
  border: none;
  padding: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--brand-sage);
  cursor: pointer;
  text-decoration: underline;
}

.teaser-submit {
  background: #fff;
  color: #0f2019;
  border: none;
  border-radius: 4px;
  padding: 15px 28px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  width: 100%;
  transition: background var(--duration-fast) ease, transform var(--duration-fast) ease;
}
.teaser-submit:hover {
  background: var(--brand-sage-light);
  transform: scale(1.01);
}
.teaser-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.teaser-form .register-status {
  font-size: 13px;
  color: var(--brand-sage);
  font-weight: 600;
  margin-top: 10px;
}
.teaser-form .register-status[hidden] {
  display: none;
}

/* Submitted state — script.js adds .is-submitted to the form once a lead
   has gone through. Everything except the confirmation message is hidden,
   so the visitor is left with the message alone rather than a blanked-out
   form inviting a second submission. The rule targets the form's children
   rather than the form itself because .register-status is one of those
   children — hiding the <form> would hide the message too. The remaining
   message is restyled to read as a standalone panel (it was sized as a
   small footnote under the button, which looks stranded on its own). */
.teaser-form.is-submitted > *:not(.register-status) {
  display: none;
}
.teaser-form.is-submitted .register-status {
  margin-top: 0;
  padding: 20px 22px;
  font-size: 15px;
  line-height: 1.55;
  text-align: center;
  /* The small-footnote version of this message is sage, which reads fine at
     13px directly under the button but drops below comfortable contrast
     once it's the only thing on screen over the photo. White matches the
     rest of the teaser's body copy; the panel border carries the framing. */
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
}
/* The message panel is much shorter than the form it replaces, so the
   .is-open max-height (sized for the tallest single-column mobile case)
   would leave a tall gap of empty space beneath it. */
.teaser-form.is-submitted.is-open {
  max-height: 240px;
}
.teaser-form.is-submitted .register-status:focus {
  outline: none;
}
.teaser-form.is-submitted .register-status:focus-visible {
  outline: 2px solid var(--brand-sage);
  outline-offset: 3px;
}

.teaser-footer {
  position: relative;
  z-index: 1;
  margin-top: 40px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
}
.teaser-footer a {
  color: rgba(255, 255, 255, 0.7);
}

@media (prefers-reduced-motion: reduce) {
  .teaser-logo,
  .teaser-eyebrow,
  .teaser-headline,
  .teaser-countdown,
  .teaser-countdown-date,
  .teaser-cta-wrap,
  .teaser-bg {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

@media (max-width: 640px) {
  .teaser-headline {
    font-size: 26px;
  }
  .teaser-countdown {
    gap: 8px;
  }
  .teaser-countdown-unit {
    width: 64px;
    padding: 10px 0 8px;
  }
  .teaser-countdown-value {
    font-size: 26px;
  }
  .teaser-form .form-row {
    grid-template-columns: 1fr;
  }
}
