/* site-effects.css — shared "modern web" polish layer (additive + conflict-free).
   Pairs with site-effects.js. Locked to the existing Zinc + Indigo system
   (uses --accent / --accent-glow tokens, which flip automatically inside
   .band-dark). Everything gates on a JS-added class or [data-*] attribute and
   fully respects prefers-reduced-motion, so a script failure can never leave
   content hidden or a layout broken.

   Layers, all opt-in via classes added by site-effects.js:
     • .fx-card        cursor-follow spotlight + accent edge on hover
     • .fx-grad        gradient-fill emphasis text + one-shot sheen sweep
     • .fx-rise        scroll-in rise for card grids the page doesn't already animate
     • .fx-aurora      richer, slowly-drifting glow inside existing .finalcta-glow
*/

/* ── Card cursor spotlight + accent edge ─────────────────────────── */
.fx-card { position: relative; transition: border-color .4s ease; }
.fx-card::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; opacity: 0; z-index: 2;
  transition: opacity .5s ease;
  background:
    radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%),
      color-mix(in srgb, var(--accent) 30%, transparent), transparent 60%);
}
@media (hover: hover) {
  .fx-card:hover::after { opacity: .9; }
  .fx-card:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--border-subtle)); }
}

/* ── Gradient emphasis text + on-view sheen sweep ────────────────── */
/* Applied to existing emphasis spans (.h1-em / [data-gradient-text]); the
   plain accent colour remains the fallback until JS adds .fx-grad. */
.fx-grad {
  padding: 0 0.22em;
  margin: 0 -0.18em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  background-image: linear-gradient(
    100deg,
    var(--accent) 0%,
    color-mix(in srgb, var(--accent) 42%, #ffffff) 50%,
    var(--accent) 100%);
  background-size: 230% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.fx-grad.fx-sheen { animation: fxSheen 1.5s cubic-bezier(.4,0,.2,1) .15s both; }
@keyframes fxSheen {
  from { background-position: 100% 0; }
  to   { background-position: 0 0; }
}

/* ── Scroll-in rise for un-animated card grids ───────────────────── */
.fx-rise { opacity: 0; transform: translateY(30px) scale(.985); will-change: transform, opacity;
  transition: opacity .7s ease, transform .8s cubic-bezier(.16,1,.3,1); }
.fx-rise.fx-in { opacity: 1; transform: none; }

/* ── Richer, drifting glow inside the existing final-CTA glow node ──
   Only the BACKGROUND is touched — never transform/scale/opacity, which
   site-gsap.js (and homepage-motion.js) already pulse on this same node.
   Drift rides background-position so the two effects never collide. */
.finalcta-glow.fx-aurora {
  background:
    radial-gradient(closest-side, color-mix(in srgb, var(--accent) 40%, transparent), transparent 78%),
    radial-gradient(closest-side, color-mix(in srgb, var(--accent) 26%, transparent), transparent 80%);
  background-repeat: no-repeat;
  background-size: 62% 62%, 50% 50%;
  background-position: 30% 38%, 72% 64%;
  animation: fxAurora 13s ease-in-out infinite alternate;
}
@keyframes fxAurora {
  to { background-position: 44% 54%, 58% 44%; }
}

/* ── Highlighter: accent marker that wipes in behind key terms ───── */
.fx-mark {
  background-image: linear-gradient(120deg,
    color-mix(in srgb, var(--accent) 22%, transparent),
    color-mix(in srgb, var(--accent) 22%, transparent));
  background-repeat: no-repeat;
  background-position: 0 86%;
  background-size: 0% 40%;
  border-radius: 2px; padding: 0 .08em; margin: 0 -.04em;
  transition: background-size .7s cubic-bezier(.16,1,.3,1);
}
.fx-mark.fx-marked { background-size: 100% 40%; }

/* ── Problem section: subgrid row alignment between columns ────────
   Row map: 1=pcol-num · 2=pcol-tag · 3=pcol-h · 4=qlist · 5=qkicker
   Ensures both headings (and takeaways) land on the same baseline even
   when one heading wraps to a different number of lines. ────────────── */
@supports (grid-template-rows: subgrid) {
  .split {
    grid-template-rows: repeat(5, auto);
    row-gap: 0;
    column-gap: 80px;
  }
  .pcol {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 5;
    align-items: start;
  }
}

 — only when motion is allowed, so
      reduced-motion users keep the page's instant fallback ──────────── */
/* NOTE: .js-reveal .reveal base styles live in homepage.css (single source of
   truth). site-effects.css used to redefine them with different values, which
   caused a cascade conflict (two competing transform + transition declarations).
   Removed here; homepage.css definition is canonical. The GSAP scripts own the
   actual motion via inline styles — CSS is the fallback only. */

/* staggered child cascade (auto on .qlist/grids, opt-in via [data-stagger-in]).
   Hidden by DEFAULT and restored under reduced-motion — robust even in
   environments that report neither motion preference. */
.fx-stagger > * {
  opacity: 0; transform: translateY(20px); filter: blur(5px);
  transition: opacity .6s ease, transform .7s cubic-bezier(.16,1,.3,1), filter .6s ease;
}
.fx-stagger.fx-in > * { opacity: 1; transform: none; filter: blur(0); }
.fx-stagger.fx-in > *:nth-child(1){transition-delay:.04s}
.fx-stagger.fx-in > *:nth-child(2){transition-delay:.11s}
.fx-stagger.fx-in > *:nth-child(3){transition-delay:.18s}
.fx-stagger.fx-in > *:nth-child(4){transition-delay:.25s}
.fx-stagger.fx-in > *:nth-child(5){transition-delay:.32s}
.fx-stagger.fx-in > *:nth-child(6){transition-delay:.39s}
.fx-stagger.fx-in > *:nth-child(n+7){transition-delay:.46s}
@media (prefers-reduced-motion: reduce) {
  .fx-stagger > * { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
}

/* ── Page transition curtain (site-transition.js drives the exit) ──
   Entrance is pure CSS so it can never trap content behind it: the curtain
   starts covering and sweeps away on every load. Exit slides it back over,
   then navigation happens while covered → seamless wipe between pages. */
@media (prefers-reduced-motion: no-preference) {
  body::before {
    content: ""; position: fixed; inset: 0; z-index: 100000; pointer-events: none;
    background:
      radial-gradient(80% 96% at 86% -10%, rgba(129,140,248,0.50), transparent 58%),
      radial-gradient(66% 82% at 4% 110%, rgba(139,92,246,0.46), transparent 60%),
      #121318;
    transform: translateY(-101%);
    animation: ptReveal .62s cubic-bezier(.76,0,.24,1) both;
  }
  @keyframes ptReveal { 0% { transform: translateY(0); } 100% { transform: translateY(-101%); } }
  body.pt-leaving::before { animation: ptCover .46s cubic-bezier(.76,0,.24,1) forwards; }
  @keyframes ptCover { 0% { transform: translateY(101%); } 100% { transform: translateY(0); } }
}
@media print { body::before { display: none !important; } }

/* ── In-section scroll-progress rail (auto on long sections) ──────── */
.sec-progress { position: absolute; left: 0; top: 0; bottom: 0; width: 3px; z-index: 4; pointer-events: none; background: color-mix(in srgb, var(--accent) 15%, transparent); }
.sec-progress > i { display: block; width: 100%; height: 100%; transform: scaleY(0); transform-origin: top center; background: var(--accent); box-shadow: 0 0 14px var(--accent); }
@media (prefers-reduced-motion: reduce) { .sec-progress { display: none; } }

/* ── Shared "signal field" backdrop (injected by site-field.js) ──── */
.finalcta { position: relative; }
.fx-field {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 0; opacity: .62;
}
.finalcta > .wrap { position: relative; z-index: 2; }
.finalcta-glow { z-index: 1; }
/* keep content above an injected field in any opted-in dark band */
[data-field] > *:not(canvas) { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .fx-card::after { display: none; }
  .fx-mark { transition: none; }
  .fx-grad { -webkit-text-fill-color: var(--accent); color: var(--accent);
    background: none; -webkit-background-clip: border-box; background-clip: border-box; }
  .fx-rise { opacity: 1 !important; transform: none !important; transition: none !important; }
  .finalcta-glow.fx-aurora { animation: none; }
}
