/* ── First-visit intro + ambient motion ───────────────────────────────────────
   The overlay lives in the HTML but is display:none until an inline script in
   <head> sets data-intro="on" (first visit, motion not reduced). Two rules the
   implementation follows:

   1. The dismissal is a CSS animation with `forwards`, NOT a JS timeout. If the
      JS ever fails, a JS-driven overlay would leave a permanent black screen
      over the site. CSS finishes on its own.
   2. Nothing here hides content from crawlers — the page renders normally and
      the overlay is purely additive.                                          */

.intro { display: none; }

html[data-intro="on"] .intro {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #07100b;
  overflow: hidden;
  /* Hold, then hand the page over. The exit is STAGED: the wordmark leaves
     first, then the black panel lifts. Fading both at once showed the intro
     line and the hero <h1> — the same sentence — ghosting over each other. */
  animation: intro-out .75s cubic-bezier(.7, 0, .3, 1) 2.75s forwards;
}

/* Contents clear out before the curtain does. Only elements with no entrance
   animation of their own go here — .intro-glow and .intro-skip chain the exit
   onto their own declarations below, so neither one loses its entrance. */
html[data-intro="on"] .intro-inner,
html[data-intro="on"] .intro-lines {
  animation: content-out .4s cubic-bezier(.6, 0, .4, 1) 2.4s forwards;
}
@keyframes content-out {
  to { opacity: 0; transform: translateY(-10px); }
}
/* While the intro plays, don't let the page scroll underneath it. */
html[data-intro="on"] { overflow: hidden; }
html[data-intro="done"] { overflow: auto; }

@keyframes intro-out {
  to { opacity: 0; visibility: hidden; transform: scale(1.06); }
}

/* Expanding rule lines — the "something is being built" cue */
.intro-lines { position: absolute; inset: 0; pointer-events: none; }
.intro-lines i {
  position: absolute;
  left: 50%;
  width: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 55%, transparent), transparent);
  transform: translateX(-50%);
  animation: line-grow 1.5s cubic-bezier(.2, .8, .2, 1) forwards;
}
.intro-lines i:nth-child(1) { top: 32%; animation-delay: .25s; }
.intro-lines i:nth-child(2) { top: 50%; animation-delay: .10s; opacity: .5; }
.intro-lines i:nth-child(3) { top: 68%; animation-delay: .40s; }
@keyframes line-grow { to { width: min(680px, 84vw); } }

/* Soft brand glow that swells behind the wordmark */
.intro-glow {
  position: absolute;
  width: 760px; height: 420px;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--primary) 26%, transparent), transparent);
  opacity: 0;
  animation: glow-in 1.6s ease-out .2s forwards,
             content-out .4s cubic-bezier(.6, 0, .4, 1) 2.4s forwards;
  pointer-events: none;
}
@keyframes glow-in { 60% { opacity: 1; } to { opacity: .55; } }

.intro-inner { position: relative; text-align: center; padding: 0 24px; }

.intro-mark {
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: 800; font-size: .95rem; letter-spacing: .02em;
  color: var(--text-2);
  opacity: 0;
  animation: rise .7s cubic-bezier(.2, .8, .2, 1) .15s forwards;
}
.intro-mark span {
  width: 26px; height: 26px; border-radius: 8px; color: #fff; font-size: .72rem;
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  display: grid; place-items: center; font-weight: 800;
}

/* The line itself — words rise and sharpen out of a blur, one after another */
.intro-line {
  position: relative; /* the sheen ::after measures against this line, not an ancestor */
  margin-top: 22px;
  font-size: clamp(1.9rem, 6vw, 3.6rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.12;
  color: #f0f4ee;
}
.intro-line b { font-weight: 800; color: var(--primary); }
.intro-line i {
  display: inline-block;
  font-style: normal;
  opacity: 0;
  filter: blur(9px);
  transform: translateY(26px);
  animation: word-in .78s cubic-bezier(.2, .8, .2, 1) forwards;
}
@keyframes word-in {
  to { opacity: 1; filter: blur(0); transform: translateY(0); }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Sheen sweeping across the finished line */
.intro-line::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 42%, rgba(255,255,255,.72) 50%, transparent 58%);
  background-size: 280% 100%;
  background-position: 180% 0;
  mix-blend-mode: overlay;
  pointer-events: none;
  animation: sheen 1.15s cubic-bezier(.5, 0, .3, 1) 1.35s forwards;
}
@keyframes sheen { to { background-position: -80% 0; } }

.intro-sub {
  margin-top: 16px; color: var(--text-3); font-size: .95rem; letter-spacing: .02em;
  opacity: 0;
  animation: rise .8s ease-out 1.6s forwards;
}

.intro-skip {
  position: absolute; bottom: 26px; left: 50%; transform: translateX(-50%);
  background: none; border: 0; color: var(--text-3);
  font-family: inherit; font-size: .8rem; font-weight: 600; letter-spacing: .04em;
  padding: 8px 14px; border-radius: 999px; opacity: 0;
  animation: rise .6s ease-out 1.1s forwards,
             content-out .4s cubic-bezier(.6, 0, .4, 1) 2.4s forwards;
}
.intro-skip:hover { color: var(--text-1); background: rgba(255,255,255,.06); }

/* ── Hero entrance ────────────────────────────────────────────────────────────
   Runs on every load; just waits for the intro when there is one. */
.hero-eyebrow, .hero h1, .hero .sub, .hero-ctas, .hero-badges, .hero-note, .hero-visual {
  animation: rise .8s cubic-bezier(.2, .8, .2, 1) backwards;
}
.hero-eyebrow  { animation-delay: .05s; }
.hero h1       { animation-delay: .13s; }
.hero .sub     { animation-delay: .21s; }
.hero-ctas     { animation-delay: .29s; }
.hero-badges   { animation-delay: .35s; }
.hero-note     { animation-delay: .41s; }
.hero-visual   { animation-delay: .47s; }

/* Timed to land as the curtain lifts (panel fades 2.75s → 3.5s), so the page
   is settling into place as it's revealed rather than popping in after. */
html[data-intro="on"] .hero-eyebrow { animation-delay: 2.90s; }
html[data-intro="on"] .hero h1      { animation-delay: 2.98s; }
html[data-intro="on"] .hero .sub    { animation-delay: 3.06s; }
html[data-intro="on"] .hero-ctas    { animation-delay: 3.14s; }
html[data-intro="on"] .hero-badges  { animation-delay: 3.20s; }
html[data-intro="on"] .hero-note    { animation-delay: 3.26s; }
html[data-intro="on"] .hero-visual  { animation-delay: 3.32s; }

/* ── Scroll reveal ───────────────────────────────────────────────────────────
   Elements start hidden ONLY when JS is present to reveal them (the .js-reveal
   flag is set by intro.js), so a script failure can't blank the page. */
html.js-reveal .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s cubic-bezier(.2, .8, .2, 1), transform .7s cubic-bezier(.2, .8, .2, 1);
}
html.js-reveal .reveal.in { opacity: 1; transform: none; }
/* Stagger children of a revealed grid */
html.js-reveal .reveal-stagger > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s cubic-bezier(.2, .8, .2, 1), transform .6s cubic-bezier(.2, .8, .2, 1);
}
html.js-reveal .reveal-stagger.in > * { opacity: 1; transform: none; }
html.js-reveal .reveal-stagger.in > *:nth-child(2) { transition-delay: .07s; }
html.js-reveal .reveal-stagger.in > *:nth-child(3) { transition-delay: .14s; }
html.js-reveal .reveal-stagger.in > *:nth-child(4) { transition-delay: .21s; }
html.js-reveal .reveal-stagger.in > *:nth-child(5) { transition-delay: .28s; }

/* ── Ambient interaction polish ──────────────────────────────────────────────- */
.feature-card, .price-card {
  transition: transform .28s cubic-bezier(.2, .8, .2, 1), border-color .28s ease, box-shadow .28s ease;
}
.feature-card:hover, .price-card:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  box-shadow: 0 18px 40px -24px rgba(0,0,0,.7);
}
.feature-card .feature-icon { transition: transform .28s cubic-bezier(.2, .8, .2, 1); }
.feature-card:hover .feature-icon { transform: translateY(-2px) scale(1.06); }

/* Sheen sweep across the primary button on hover */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 40%, rgba(255,255,255,.45) 50%, transparent 60%);
  background-size: 250% 100%;
  background-position: 160% 0;
  transition: background-position .65s cubic-bezier(.4, 0, .2, 1);
  pointer-events: none;
}
.btn-primary:hover::after { background-position: -60% 0; }

/* The hero mock breathes, very slightly, so the fold isn't static */
@media (prefers-reduced-motion: no-preference) {
  .mock-window { animation: float 7s ease-in-out 1s infinite; }
  @keyframes float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-7px); }
  }
  /* The "live" dot in the promo tag */
  .promo-tag { position: relative; }
}

/* ── Respect reduced motion ──────────────────────────────────────────────────
   Anyone who asked their OS for less motion gets none of this — including the
   intro, which is skipped outright by the inline script. */
@media (prefers-reduced-motion: reduce) {
  .intro,
  .intro *,
  .hero-eyebrow, .hero h1, .hero .sub, .hero-ctas, .hero-badges, .hero-note, .hero-visual,
  .mock-window {
    animation: none !important;
    transition: none !important;
  }
  html.js-reveal .reveal,
  html.js-reveal .reveal-stagger > * {
    opacity: 1 !important;
    transform: none !important;
  }
}
