/* ============================================================================
   Soarcery marketing - interior polish layer (polish.css), lane/site-polish.
   Sitewide one-shot choreography for the interior pages, in the trailer's
   composition language: light traces, glow as information, staged ignition
   that plays once and rests static. ProtectWise lineage: motion serves
   comprehension, nothing decorative loops behind text someone is reading.

   Conventions:
     html.pg            JS is alive (set inline in base.njk before first paint)
     html.pg.pg-go      page ignition plays (polish.js, 2x rAF after DOM ready)
     .reveal.in         existing one-shot scroll trigger from site.js
     [data-ignite].ig   one-shot scroll trigger from polish.js (own surfaces)

   All choreography is transform/opacity (plus a few px-scale one-shot
   box-shadow glints on tiny elements). Every hidden initial state is gated
   behind html.pg AND prefers-reduced-motion:no-preference, so no-JS and
   reduced-motion both get the complete composed static finals immediately.
   ========================================================================== */

/* ============================================================
   1. PAGE-LOAD IGNITION - every interior page arrives on purpose.
   The eyebrow tick draws and ignites, the h1 settles up 8px while
   its gradient span brightens, the sub then the CTAs fade after,
   and the hero visual frame rises last. ~500ms, once, then still.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  /* the staged ignition owns the phero entrance; stand the generic reveal down */
  html.pg .phero .reveal { opacity: 1; transform: none; transition: none; }

  html.pg .phero .eyebrow { opacity: 0; transform: translateY(5px); }
  html.pg .phero .eyebrow .tick { transform: scaleX(0); transform-origin: left center; }
  html.pg .phero h1 { opacity: 0; transform: translateY(8px); }
  html.pg .phero h1 .grad { opacity: .4; }
  html.pg .phero .sub { opacity: 0; }
  html.pg .phero .cta-row { opacity: 0; }
  html.pg .phero .hero-split .frame,
  html.pg .phero .hero-split .deep-block { opacity: 0; transform: translateY(14px); }

  html.pg.pg-go .phero .eyebrow { opacity: 1; transform: none;
    transition: opacity .28s ease, transform .32s cubic-bezier(.2,.7,.2,1); }
  html.pg.pg-go .phero .eyebrow .tick { animation: pl-tick .45s cubic-bezier(.2,.7,.2,1) .05s both; }
  html.pg.pg-go .phero h1 { opacity: 1; transform: none;
    transition: opacity .4s ease .06s, transform .5s cubic-bezier(.2,.7,.2,1) .06s; }
  html.pg.pg-go .phero h1 .grad { opacity: 1; transition: opacity .42s ease .22s; }
  html.pg.pg-go .phero .sub { opacity: 1; transition: opacity .38s ease .28s; }
  html.pg.pg-go .phero .cta-row { opacity: 1; transition: opacity .38s ease .38s; }
  html.pg.pg-go .phero .hero-split .frame,
  html.pg.pg-go .phero .hero-split .deep-block { opacity: 1; transform: none;
    transition: opacity .45s ease .22s, transform .55s cubic-bezier(.2,.7,.2,1) .22s; }
}
/* the tick draws left-to-right, flares to full light, settles to its rest state */
@keyframes pl-tick {
  0%   { transform: scaleX(0); opacity: 1; }
  70%  { opacity: 1; }
  100% { transform: scaleX(1); opacity: .5; }
}

/* ============================================================
   2. SECTION EYEBROW IGNITION - the kicker tick draws once when
   its section scrolls into view (rides the existing .reveal.in).
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.pg section:not(.phero) .reveal .eyebrow .tick { transform: scaleX(0); transform-origin: left center; }
  html.pg section:not(.phero) .reveal.in .eyebrow .tick { animation: pl-tick .5s cubic-bezier(.2,.7,.2,1) .14s both; }
}

/* ============================================================
   3a. QUEUE IGNITION [data-ignite="q"] - rows slide in as a
   cascade, then their verdict runes land after the evidence:
   read the row first, then the call. One-shot, rests static.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite="q"] > * { opacity: 0; transform: translateX(-10px); }
  html.pg [data-ignite="q"] .rune { opacity: 0; }
}
html.pg [data-ignite="q"].ig > * { opacity: 1; transform: none;
  transition: opacity .45s ease, transform .5s cubic-bezier(.2,.7,.2,1); }
html.pg [data-ignite="q"].ig > *:nth-child(1) { transition-delay: .05s; }
html.pg [data-ignite="q"].ig > *:nth-child(2) { transition-delay: .15s; }
html.pg [data-ignite="q"].ig > *:nth-child(3) { transition-delay: .25s; }
html.pg [data-ignite="q"].ig > *:nth-child(4) { transition-delay: .35s; }
html.pg [data-ignite="q"].ig > *:nth-child(5) { transition-delay: .45s; }
html.pg [data-ignite="q"].ig > *:nth-child(6) { transition-delay: .55s; }
html.pg [data-ignite="q"].ig .rune { opacity: 1; transition: opacity .4s ease; }
html.pg [data-ignite="q"].ig > *:nth-child(1) .rune { transition-delay: .6s; }
html.pg [data-ignite="q"].ig > *:nth-child(2) .rune { transition-delay: .72s; }
html.pg [data-ignite="q"].ig > *:nth-child(3) .rune { transition-delay: .84s; }
html.pg [data-ignite="q"].ig > *:nth-child(4) .rune { transition-delay: .96s; }
html.pg [data-ignite="q"].ig > *:nth-child(5) .rune { transition-delay: 1.08s; }
html.pg [data-ignite="q"].ig > *:nth-child(6) .rune { transition-delay: 1.2s; }
/* a step held at the gate announces itself once (phishing hero), then rests */
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite="q"].ig .agent-step.gate .s { animation: pl-gate 1.1s ease 1s 1 both; }
}
@keyframes pl-gate {
  0%, 100% { box-shadow: 0 0 0 0 rgba(249,115,22,0); }
  45% { box-shadow: 0 0 0 2px rgba(249,115,22,.35), 0 0 16px rgba(249,115,22,.3); }
}

/* ============================================================
   3b. LIST IGNITION [data-ignite="list"] - blocks rise in order.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite="list"] > * { opacity: 0; transform: translateY(8px); }
}
html.pg [data-ignite="list"].ig > * { opacity: 1; transform: none;
  transition: opacity .45s ease, transform .5s cubic-bezier(.2,.7,.2,1); }
html.pg [data-ignite="list"].ig > *:nth-child(1) { transition-delay: .05s; }
html.pg [data-ignite="list"].ig > *:nth-child(2) { transition-delay: .17s; }
html.pg [data-ignite="list"].ig > *:nth-child(3) { transition-delay: .29s; }
html.pg [data-ignite="list"].ig > *:nth-child(4) { transition-delay: .41s; }
html.pg [data-ignite="list"].ig > *:nth-child(5) { transition-delay: .53s; }
html.pg [data-ignite="list"].ig > *:nth-child(6) { transition-delay: .65s; }

/* ============================================================
   3c. STAGE IGNITION [data-ignite="stages"] - the platform /
   tier flow lights in order; each stage's rune dot glints once
   as it comes online. Investigate, decide, respond: in sequence.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite="stages"] .stage { opacity: 0; transform: translateY(10px); }
}
html.pg [data-ignite="stages"].ig .stage { opacity: 1; transform: none;
  transition: opacity .5s ease, transform .55s cubic-bezier(.2,.7,.2,1); }
html.pg [data-ignite="stages"].ig .stage:nth-child(1) { transition-delay: .05s; }
html.pg [data-ignite="stages"].ig .stage:nth-child(2) { transition-delay: .25s; }
html.pg [data-ignite="stages"].ig .stage:nth-child(3) { transition-delay: .45s; }
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite="stages"].ig .stage .cap .dot { animation: pl-glint .9s ease 1 both; }
  html.pg [data-ignite="stages"].ig .stage:nth-child(1) .cap .dot { animation-delay: .45s; }
  html.pg [data-ignite="stages"].ig .stage:nth-child(2) .cap .dot { animation-delay: .65s; }
  html.pg [data-ignite="stages"].ig .stage:nth-child(3) .cap .dot { animation-delay: .85s; }
}
@keyframes pl-glint {
  0%, 100% { box-shadow: 0 0 6px currentColor; }
  40% { box-shadow: 0 0 14px currentColor, 0 0 26px currentColor; }
}

/* baseline fix (observed on visual-v3, not introduced by this lane): .fill is
   a <span>, display:inline, so its width/height never rendered and the verdict
   bars were invisible sitewide. Blockify so the data-fill animation actually
   draws the light trace the spread depends on. */
.eng .fill { display: block; }

/* ============================================================
   3d. SPREAD IGNITION [data-ignite-spread] - the verdict spread
   as evidence choreography: engine rows arrive, their verdicts
   land after the bars have spoken, and the confidence-spread
   call lands last with a single glint. Glance, then pivot.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite-spread] .eng { opacity: 0; transform: translateY(6px); }
  html.pg [data-ignite-spread] .eng .verd { opacity: 0; }
  html.pg [data-ignite-spread] .spread-foot .rune { opacity: 0; }
  html.pg [data-ignite-spread] .spread-head .rune { opacity: 0; }
}
html.pg [data-ignite-spread].ig .eng { opacity: 1; transform: none;
  transition: opacity .45s ease, transform .5s cubic-bezier(.2,.7,.2,1); }
html.pg [data-ignite-spread].ig .eng:nth-of-type(1) { transition-delay: .1s; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(2) { transition-delay: .22s; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(3) { transition-delay: .34s; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(4) { transition-delay: .46s; }
html.pg [data-ignite-spread].ig .eng .verd { opacity: 1; transition: opacity .4s ease; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(1) .verd { transition-delay: .7s; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(2) .verd { transition-delay: .8s; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(3) .verd { transition-delay: .9s; }
html.pg [data-ignite-spread].ig .eng:nth-of-type(4) .verd { transition-delay: 1s; }
html.pg [data-ignite-spread].ig .spread-head .rune { opacity: 1; transition: opacity .4s ease 1.1s; }
html.pg [data-ignite-spread].ig .spread-foot .rune { opacity: 1; transition: opacity .4s ease 1.25s; }
@media (prefers-reduced-motion: no-preference) {
  html.pg [data-ignite-spread].ig .spread-foot .rune .dot { animation: pl-glint 1s ease 1.3s 1 both; }
}

/* ============================================================
   4. CARD-FAMILY STAGGER - era / definition-test / comparison /
   steps / split2 / FAQ groups arrive in composed rhythm when
   their .reveal fires, instead of as one undifferentiated slab.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal > * {
    opacity: 0; transform: translateY(12px); }
}
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > * {
  opacity: 1; transform: none;
  transition: opacity .55s ease, transform .6s cubic-bezier(.2,.7,.2,1); }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(1) { transition-delay: .05s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(2) { transition-delay: .13s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(3) { transition-delay: .21s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(4) { transition-delay: .29s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(5) { transition-delay: .37s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(6) { transition-delay: .45s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(7) { transition-delay: .53s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(8) { transition-delay: .61s; }
html.pg :is(.era, .steps, .compare, .split2, .faq, .c3).reveal.in > *:nth-child(n+9) { transition-delay: .69s; }
/* numbered steps light their badge in order as they land */
@media (prefers-reduced-motion: no-preference) {
  html.pg .steps.reveal.in .step .sn { animation: pl-numlight 1s ease 1 both; }
  html.pg .steps.reveal.in .step:nth-child(1) .sn { animation-delay: .35s; }
  html.pg .steps.reveal.in .step:nth-child(2) .sn { animation-delay: .55s; }
  html.pg .steps.reveal.in .step:nth-child(3) .sn { animation-delay: .75s; }
  html.pg .steps.reveal.in .step:nth-child(4) .sn { animation-delay: .95s; }
  html.pg .steps.reveal.in .step:nth-child(5) .sn { animation-delay: 1.15s; }
}
@keyframes pl-numlight {
  0%, 100% { box-shadow: 0 0 0 0 rgba(124,58,237,0); }
  45% { box-shadow: 0 0 0 1px rgba(124,58,237,.45), 0 0 18px rgba(124,58,237,.4); }
}

/* ============================================================
   5. FAQ - smooth height transition on <details> (progressive:
   browsers without ::details-content interpolation get the
   instant toggle they have today). Answer copy fades in with it.
   ============================================================ */
:root { interpolate-size: allow-keywords; }
@media (prefers-reduced-motion: no-preference) {
  .faq details::details-content {
    block-size: 0; overflow-y: clip; opacity: 0;
    transition: content-visibility .4s allow-discrete, opacity .32s ease, block-size .4s cubic-bezier(.2,.7,.2,1);
  }
  .faq details[open]::details-content { block-size: auto; opacity: 1; }
  .faq summary .pl svg { transition: transform .3s cubic-bezier(.2,.7,.2,1); }
  .faq details[open] summary .pl svg { transform: rotate(45deg); }
}

/* ============================================================
   6. BUTTONS - cast gains a charge-glow on hover and a press
   ripple-of-light; ghost gets a border-light sweep. Opacity
   (and a background-position pass on a px-scale ring) only,
   no transforms added.
   ============================================================ */
.btn-cast { position: relative; overflow: hidden; }
.btn-cast::before { /* charge glow: light pools at the top edge while held */
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(120% 170% at 50% -20%, rgba(255,255,255,.32), rgba(196,181,253,.14) 48%, transparent 72%);
  opacity: 0; transition: opacity .25s ease;
}
.btn-cast:hover::before, .btn-cast:focus-visible::before { opacity: 1; }
.btn-cast::after { /* press: a ripple of light, opacity only */
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(closest-side at 50% 55%, rgba(255,255,255,.55), rgba(196,181,253,.28) 55%, transparent 78%);
  opacity: 0; transition: opacity .5s ease;
}
.btn-cast:active::after { opacity: 1; transition: none; }

.btn-ghost { position: relative; }
.btn-ghost::before { /* border-light sweep: a glint travels the border ring */
  content: ""; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none;
  padding: 1px;
  background: linear-gradient(115deg, transparent 25%, rgba(196,181,253,.75) 46%, rgba(94,234,212,.4) 55%, transparent 78%);
  background-size: 250% 100%; background-position: 120% 0;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0; transition: opacity .3s ease;
}
.btn-ghost:hover::before, .btn-ghost:focus-visible::before { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .btn-ghost:hover::before { animation: pl-bsweep .8s cubic-bezier(.3,.6,.3,1) both; }
}
@keyframes pl-bsweep { from { background-position: 130% 0; } to { background-position: -30% 0; } }

/* ============================================================
   7. MEGA MENU - a single light pass sweeps the cover imagery
   each time a panel opens (one-shot: the pseudo only exists
   while .open, so the pass replays per open and then rests),
   and link icons brighten under the pointer.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  .nav-item.open .mega .m-cover::after,
  .nav-item.open .mega .m-shot::after {
    content: ""; position: absolute; inset: -10%; z-index: 4; pointer-events: none;
    background: linear-gradient(112deg, transparent 32%, rgba(237,233,254,.14) 46%, rgba(196,181,253,.22) 51%, transparent 68%);
    transform: translateX(-75%); opacity: 0;
    animation: pl-sheen 1.15s cubic-bezier(.3,.55,.35,1) .18s 1 both;
  }
}
@keyframes pl-sheen {
  0%   { opacity: 0; transform: translateX(-75%); }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { opacity: 0; transform: translateX(75%); }
}
.mega .m-link .mi { transition: color .15s ease, background .18s ease, border-color .18s ease, box-shadow .22s ease; }
.mega .m-link:hover .mi {
  color: #EDE9FE; border-color: var(--border-primary);
  background: rgba(124,58,237,.16);
  box-shadow: 0 0 14px rgba(124,58,237,.28), inset 0 0 8px rgba(124,58,237,.22);
}
.mega .m-link.t:hover .mi { color: #CCFBF1; border-color: rgba(20,184,166,.5); background: rgba(20,184,166,.14);
  box-shadow: 0 0 14px rgba(20,184,166,.25), inset 0 0 8px rgba(20,184,166,.2); }
.mega .m-link.o:hover .mi { color: #FFEDD5; border-color: rgba(249,115,22,.5); background: rgba(249,115,22,.14);
  box-shadow: 0 0 14px rgba(249,115,22,.25), inset 0 0 8px rgba(249,115,22,.2); }

/* ============================================================
   reduced motion: belt and braces. Initial states above are all
   gated on no-preference, so these finals are the whole story.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  [data-ignite] > *, [data-ignite] .rune,
  [data-ignite-spread] .eng, [data-ignite-spread] .eng .verd,
  [data-ignite-spread] .rune { opacity: 1 !important; transform: none !important; transition: none !important; }
  .btn-ghost:hover::before, .nav-item.open .mega .m-cover::after,
  .nav-item.open .mega .m-shot::after { animation: none !important; }
}
