/* ============================================================
   Pitot Group — Neuralink hero system
   Presentation layer for the persistent WebGL creature.
   Loaded once per page; all behaviour lives in neuralink.js.
   ============================================================ */

/* The persistent canvas. Fixed to the viewport so it survives the
   hero's overflow:hidden and stays put as the page scrolls (the
   docked state needs this). Never eats pointer events — text and
   CTAs above it stay live. Sits ABOVE the page background (z0) and
   BELOW the hero text/scrim (z2/z3). */
#nl-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100dvh;
  z-index: 1;
  display: block;
  pointer-events: none;
  /* Hidden until the module has rendered its first frame, to avoid a
     flash of an empty (transparent) canvas over the bg. */
  opacity: 0;
  transition: opacity 1.2s cubic-bezier(0.22, 0.61, 0.36, 1);
}
#nl-canvas.nl-on { opacity: 1; }

/* Hide the command-deck photo from the very FIRST paint whenever WebGL
   will drive the hero. neuralink.css is render-blocking, so this applies
   before the photo can paint — no flash before the creature loads. The
   photo runs a keyframe animation with `both` fill (heroFadeIn →
   opacity:1), so we cancel the animation, not just set opacity. The
   image is restored only when we positively fall back (no WebGL). */
html:not(.nl-fallback) .hero-image {
  animation: none !important;
  opacity: 0 !important;
}

/* The vertical sensor sweep (.hero-scan) belonged to the photo hero —
   remove it when the creature is in charge. */
html:not(.nl-fallback) .hero-scan { display: none !important; }

/* Keep a soft legibility scrim BETWEEN creature and text. The hero
   already ships .hero-overlay at z1; raise it above the canvas and,
   since there's no bright photo to tame now, lighten it to a left-only
   scrim that protects the text column and fully clears the right half
   where the creature lives. */
html.nl-active .hero-overlay {
  z-index: 2;
  background: linear-gradient(90deg,
    rgba(var(--bg-rgb), 0.92) 0%,
    rgba(var(--bg-rgb), 0.74) 26%,
    rgba(var(--bg-rgb), 0.32) 48%,
    rgba(var(--bg-rgb), 0.06) 66%,
    rgba(var(--bg-rgb), 0) 78%);
}

/* The platinum "arrival flash" overlay — shown instantly on a dive
   landing to mask WebGL compile latency, then faded by the module.
   Also used as the expand-flash on the outgoing page. */
.nl-flash {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(120% 120% at var(--nl-fx, 50%) var(--nl-fy, 50%),
      rgba(255, 255, 255, 0.92) 0%,
      rgba(var(--hi-rgb), 0.55) 22%,
      rgba(141, 174, 240, 0.0) 60%);
  will-change: opacity;
}
.nl-flash.nl-flash-show { opacity: 1; }
.nl-flash.nl-flash-fade {
  opacity: 0;
  transition: opacity 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* No-WebGL fallback: the module never runs, the photo hero stays
   exactly as authored. Nothing to do — .nl-active is never added. */
html.nl-fallback #nl-canvas { display: none; }

/* Honour reduced motion: the canvas still shows one static luminous
   frame (handled in JS), but the CSS transitions are neutralised so
   nothing animates here. */
@media (prefers-reduced-motion: reduce) {
  #nl-canvas { transition: none; }
  .nl-flash, .nl-flash.nl-flash-fade { transition: none; }
  html.nl-active .hero-image { transition: none; }
}

/* ============================================================
   Global UI — action-button perimeter glow
   A single luminous filament travels around the perimeter of the
   primary actions (matching the founder's Stitch redesign). Cool
   and restrained at rest; brightens on hover. Loaded site-wide via
   this stylesheet so every page's main CTAs share the treatment.
   ============================================================ */
@property --nl-ba { syntax: '<angle>'; initial-value: 0deg; inherits: false; }

/* Promote the primary text-CTA into a real boxed button. */
.link-arrow.primary {
  padding: 13px 26px;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(22, 27, 40, 0.85), rgba(13, 17, 26, 0.9));
  border: 1px solid rgba(180, 205, 235, 0.12);
  isolation: isolate;
  overflow: visible;
  box-shadow: 0 0 18px rgba(141, 174, 240, 0.10);
  transition: gap 0.4s var(--ease), background 0.4s var(--ease), box-shadow 0.5s var(--ease);
}
.link-arrow.primary::after { display: none !important; } /* drop the text underline */
.link-arrow.primary:hover {
  background: linear-gradient(180deg, rgba(28, 34, 50, 0.92), rgba(16, 21, 32, 0.94));
  box-shadow: 0 0 30px rgba(var(--hi-rgb), 0.28);
  text-shadow: none;
}

/* The travelling glow ring — a masked conic gradient on a pseudo so
   only the 1.5px border is painted; the centre is transparent so the
   label shows through. */
.nav-enquire, .cf-submit, .contact-form .submit, .framework-cta { position: relative; isolation: isolate; overflow: visible; }
/* --nl-glow tints the filament; default is the platinum/instrument
   blue. Buttons can override it (e.g. a section CTA in its neuralink
   hue) by setting --nl-glow inline. */
.link-arrow.primary::before,
.nav-enquire::before,
.cf-submit::before,
.contact-form .submit::before,
.framework-cta::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(from var(--nl-ba),
    transparent 0deg, transparent 72deg,
    color-mix(in srgb, var(--nl-glow, var(--section)) 55%, transparent) 110deg,
    color-mix(in srgb, var(--nl-glow, var(--section)) 32%, #ffffff) 132deg,
    color-mix(in srgb, var(--nl-glow, var(--section)) 55%, transparent) 154deg,
    transparent 196deg, transparent 360deg);
  -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 0.35s ease;
  pointer-events: none;
  z-index: 2;
}
.link-arrow.primary:hover::before, .link-arrow.primary:focus-visible::before,
.nav-enquire:hover::before, .nav-enquire:focus-visible::before,
.cf-submit:hover::before, .cf-submit:focus-visible::before,
.framework-cta:hover::before, .framework-cta:focus-visible::before {
  opacity: 1;
  animation: nl-ring 2.4s linear infinite;
}
@keyframes nl-ring { to { --nl-ba: 360deg; } }

/* Section CTAs carry their section's neuralink hue through the whole
   accent (filament, the leading rule, the arrow, the hover border). */
.framework-cta .framework-cta-arr {
  color: var(--nl-glow, var(--section));
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--nl-glow, var(--section)) 70%, transparent));
}
.framework-cta .framework-cta-label::before {
  background: var(--nl-glow, var(--section));
  box-shadow: 0 0 6px color-mix(in srgb, var(--nl-glow, var(--section)) 70%, transparent);
}
.framework-cta:hover { border-color: var(--nl-glow, var(--section)); }

/* Static glow filament for browsers without @property animation, and
   for reduced-motion users — still a luminous edge, just not moving. */
@media (prefers-reduced-motion: reduce) {
  .link-arrow.primary::before,
  .nav-enquire::before,
  .cf-submit::before,
  .framework-cta::before { animation: none; }
}
