/* ==========================================================================
   dlfx.css - download finale polish (dlfx.js): rotating #end-sub blurbs,
   #end-head glitch pulse, periodic sheen + breathing glow on .dl-btn.
   OWNERSHIP MAP (do not blur these lines):
   - site.css owns #end-sub / #end-head THE ELEMENTS (er-line opacity and
     transform, sub clip-path wipe, head split-word entrance). All motion
     here lives on the injected .dlx-sub-inner / .dlx-head-inner spans.
   - endfx.css owns .dl-btn::before (hover sweep), the primary pill's
     dlfx-halo, and the --mx/--my/--ms magnet transform on the element.
     This sheet only adds ::after (time-driven sheen), a breathing glow on
     the ALT pill (the primary already breathes via dlfx-halo), and a
     :focus-visible ring. Everything composes; nothing is overridden.
   - .dlx-inview is toggled by dlfx.js (IntersectionObserver) so the
     infinite sheen keyframes only run while the finale is on screen.
   PERF LAW: no backdrop-filter / filter anywhere inside #app.
   ========================================================================== */

/* ------------------------------------------------ rotating sub: inner span */
.dlx-sub-inner{display:block;min-height:var(--dlx-minh,0px)}
/* glitch slice during the decode swap (element clip-path untouched: this
   clip-path is on OUR span, site.css's wipe lives on #end-sub itself) */
.dlx-sub-inner.dlx-swap{animation:dlx-slice .3s linear 1}
@keyframes dlx-slice{
  0%{clip-path:inset(0 0 0 0);transform:none;text-shadow:none}
  20%{clip-path:inset(8% 0 62% 0);transform:translateX(3px);
    text-shadow:1px 0 rgba(255,80,100,.45),-1px 0 rgba(90,200,255,.45)}
  40%{clip-path:inset(55% 0 12% 0);transform:translateX(-3px);
    text-shadow:-1px 0 rgba(255,80,100,.45),1px 0 rgba(90,200,255,.45)}
  60%{clip-path:inset(24% 0 38% 0);transform:translateX(2px);
    text-shadow:1px 0 rgba(255,80,100,.3),-1px 0 rgba(90,200,255,.3)}
  80%,100%{clip-path:inset(0 0 0 0);transform:none;text-shadow:none}
}

/* --------------------------------------------- headline pulse: inner span */
.dlx-head-inner{display:block}
/* <=280ms, two clip slices + 1px RGB shadow shift, discrete steps for the
   glitch feel; applied per rotation by dlfx.js, removed right after */
.dlx-head-inner.dlx-pulse{animation:dlx-headpulse .26s steps(1,end) 1}
@keyframes dlx-headpulse{
  0%{clip-path:inset(0 0 68% 0);transform:translateX(2px);
    text-shadow:1px 0 rgba(255,70,90,.55),-1px 0 rgba(80,190,255,.55)}
  38%{clip-path:inset(56% 0 10% 0);transform:translateX(-2px);
    text-shadow:-1px 0 rgba(255,70,90,.55),1px 0 rgba(80,190,255,.55)}
  70%,100%{clip-path:inset(0 0 0 0);transform:none;text-shadow:none}
}

/* ------------------------------------------------ pills: periodic sheen
   ::after only (endfx.css owns ::before). Time-driven, so no pointer gate;
   .er-settled keeps it out of the clip-path entrance, .dlx-inview keeps the
   infinite keyframes parked while the finale is off screen. Transform lives
   on the pseudo, so it composes with the magnet vars on the element. */
#end.end--video #end-reveal-buttons .dl-btn::after{content:"";position:absolute;
  top:-4px;bottom:-4px;left:0;width:34%;
  background:linear-gradient(105deg,transparent 8%,rgba(255,255,255,.28) 44%,
    rgba(255,255,255,.46) 50%,rgba(255,255,255,.28) 56%,transparent 92%);
  transform:translateX(-170%) skewX(-16deg);opacity:.55;pointer-events:none}
#end.end--video.er-settled.dlx-inview #end-reveal-buttons .dl-btn::after{
  animation:dlx-shine 4.2s linear infinite}
#end.end--video.er-settled.dlx-inview #end-reveal-buttons .dl-btn--alt::after{
  animation-delay:1.4s}
@keyframes dlx-shine{
  0%,8%{transform:translateX(-170%) skewX(-16deg)}
  22%{transform:translateX(460%) skewX(-16deg)}
  100%{transform:translateX(460%) skewX(-16deg)}
}
/* hover intensifies the sweep (stacks with endfx.css's one-shot ::before) */
@media (hover:hover) and (pointer:fine){
  #end.end--video #end-reveal-buttons .dl-btn:hover::after{opacity:1}
}

/* breathing accent glow on the ALT (Mac) pill only: the primary already
   breathes via endfx.css dlfx-halo, and animation on the same element
   would cancel it. Accent = the site blue family. */
#end.end--video.er-settled.dlx-inview #end-reveal-buttons .dl-btn--alt{
  animation:dlx-breathe 4.6s ease-in-out .6s infinite}
@keyframes dlx-breathe{
  0%,100%{box-shadow:0 8px 26px rgba(0,0,0,.32),0 0 0 0 rgba(122,138,255,0)}
  50%{box-shadow:0 10px 30px rgba(0,0,0,.36),0 0 24px 2px rgba(122,138,255,.2)}
}

/* crisp keyboard ring (outline never collides with the box-shadow anims) */
#end.end--video #end-reveal-buttons .dl-btn:focus-visible{
  outline:2px solid rgba(150,163,255,.95);outline-offset:3px}

/* ------------------------------------------------------------ reduced motion
   site.css clamps animation-duration to .001s globally, which would strobe
   the infinite loops here; kill them outright (same pattern as endfx.css).
   dlfx.js switches to a plain crossfade at an 8s cadence: give the inner
   span its opacity transition here. */
@media (prefers-reduced-motion:reduce){
  #end.end--video #end-reveal-buttons .dl-btn::after{animation:none!important;opacity:0}
  #end.end--video #end-reveal-buttons .dl-btn--alt{animation:none!important}
  .dlx-sub-inner.dlx-swap,.dlx-head-inner.dlx-pulse{animation:none!important}
  .dlx-sub-inner{transition:opacity .2s linear}
  .dlx-sub-inner.dlx-hide{opacity:0}
}
