/* ────────────────────────────────────────────────────────────
   Shared atoms for all hero variants.
   Exported to window so each variant file can pick them up.
   ──────────────────────────────────────────────────────────── */

// Logo wordmark. Source: assets/axion-wordmark-bone.svg - paths
// already filled in #EDEAE2 (Bone), so no recolor filter needed.
// The `color` prop is kept on the API for callers that want a
// different fill, applied via CSS `filter` for backwards compat.
function AxionMark({ height = 22, color = "#EDEAE2" }) {
  return (
    <img
      src="assets/axion-wordmark-bone.svg"
      alt="Axion"
      style={{ height, width: "auto", display: "block" }}
    />
  );
}

// Standard nav row - slot prop lets each variant style chrome around it
function NavLinks({ links = ["Platform", "Field tests", "Engineering", "Patents"], style }) {
  return (
    <div style={{ display: "flex", gap: 28, alignItems: "center", ...style }}>
      {links.map((l) => (
        <a
          key={l}
          href="#"
          style={{
            fontFamily: "var(--font-body)",
            fontSize: 14,
            color: "#EDEAE2",
            textDecoration: "none",
            letterSpacing: "-0.005em",
            whiteSpace: "nowrap"
          }}
        >
          {l}
        </a>
      ))}
    </div>
  );
}

// Brass CTA button. Hover state per the motion brief §10:
// "subtle outer halo glow (box-shadow expand + opacity), 300ms,
// ease-out-quart. Optimus pattern - not a color change, just a
// soft warm glow indicating interactivity." Implemented as a CSS
// class so :hover can layer the box-shadow without React state.
function BrassCTA({ children = "Request brief", size = "md", style, href }) {
  // Inject the hover-halo CSS once.
  React.useEffect(() => {
    if (document.getElementById("__brass-cta-css")) return;
    const s = document.createElement("style");
    s.id = "__brass-cta-css";
    s.textContent = `
      /* Primary button - sourced from the Axion design system
         (preview/comp-buttons.html → .btn-primary). Brass fill,
         4px radius, GT America Medium, simple background lift on
         hover (#D4A24C → #DCB066) over 120ms. */
      .ax-brass-cta {
        font-family: var(--font-display);
        font-weight: 500;
        background: #D4A24C;
        color: #1A1612;
        border: 1px solid transparent;
        border-radius: 4px;
        cursor: pointer;
        letter-spacing: 0.01em;
        line-height: 1;
        white-space: nowrap;
        transition: background 120ms ease, border-color 120ms ease;
      }
      .ax-brass-cta:hover,
      .ax-brass-cta:focus-visible {
        background: #DCB066;
        /* Pin the text color here because the global a:hover rule in
           colors_and_type.css would otherwise shift it to brass — making
           the label invisible against the brass background when this
           CTA renders as an <a> (href variant). */
        color: #1A1612;
        outline: none;
      }
    `;
    document.head.appendChild(s);
  }, []);

  const sizes = {
    sm: { padding: "8px 14px", fontSize: 13 },
    md: { padding: "10px 18px", fontSize: 14 },
    lg: { padding: "13px 24px", fontSize: 15 }
  };
  // When `href` is provided, render an anchor so the CTA can
  // open a mailto / link target. Otherwise keep the original
  // <button> for non-link usage. Inline-block + textDecoration:none
  // keep the visual identical to the button form.
  const commonProps = {
    className: "ax-brass-cta",
    style: {
      ...sizes[size],
      ...(href ? { display: "inline-block", textDecoration: "none" } : null),
      ...style
    }
  };
  if (href) {
    return (
      <a href={href} {...commonProps}>
        {children}
      </a>
    );
  }
  return (
    <button {...commonProps}>
      {children}
    </button>
  );
}

// Plex-Mono spec line - "KEY  VALUE" pair w/ wide tracked uppercase key
function SpecLine({ k, v, accent }) {
  return (
    <div style={{ display: "flex", gap: 12, alignItems: "baseline", fontFamily: "var(--font-mono)", fontSize: 12, lineHeight: 1.4 }}>
      <span style={{ color: "#6F7178", letterSpacing: "0.16em", textTransform: "uppercase", minWidth: 90 }}>{k}</span>
      <span style={{ color: accent || "#EDEAE2", letterSpacing: "0.04em" }}>{v}</span>
    </div>
  );
}

/* ────────────────────────────────────────────────────────────
   NavBar - sticky top nav with compact-on-scroll behaviour per
   the motion brief §10.

   Resting:    transparent · padding 24/56 · wordmark 100% · no blur
   Compacted:  rgba(0,0,0,0.8) · padding 16/56 · wordmark 90% · blur 12px

   Trigger:    scrollY > 100px (compact)
               scrollY <= 0      (un-compact)
   Easing:     400ms / ease-out-quart, both ways
   Stickiness: once compacted, scrolling UP does NOT un-compact
               unless the user reaches the very top of the page.

   Nav links use `.ax-nav-link` styling defined in the same
   <style> block so the underline-from-left hover and 70%→100%
   opacity transition come "for free."
   ──────────────────────────────────────────────────────────── */
function NavBar({ children, dispatchHero = false }) {
  const navRef = React.useRef(null);

  // Inject the nav stylesheet once for the whole page.
  React.useEffect(() => {
    if (document.getElementById("__ax-nav-css")) return;
    const s = document.createElement("style");
    s.id = "__ax-nav-css";
    s.textContent = `
      .ax-nav {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 50;
        display: flex;
        align-items: center;
        gap: 32px;
        padding: 24px 56px;
        background: transparent;
        backdrop-filter: blur(0px);
        -webkit-backdrop-filter: blur(0px);
        /* Threshold-triggered hide: at rest the bar sits in place;
           when JS adds .is-hidden (past a small scroll threshold)
           it slides up and fades in one fluid motion. The CSS
           transition — not scroll position — drives the animation,
           so the move completes on its own without further input. */
        transform: translateY(0);
        opacity: 1;
        will-change: transform, opacity;
        transition:
          padding var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1),
          background var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1),
          backdrop-filter var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1),
          -webkit-backdrop-filter var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1),
          border-color var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1),
          transform 420ms cubic-bezier(0.5, 0, 0.75, 0),
          opacity   300ms cubic-bezier(0.4, 0, 1, 1);
        border-bottom: 1px solid transparent;
      }
      /* Hidden: -100% lift so the bar fully clears frame regardless
         of its actual height, plus opacity 0. pointer-events kill
         input so the (invisible) CTA can't intercept taps. */
      .ax-nav.is-hidden {
        transform: translateY(-100%);
        opacity: 0;
        pointer-events: none;
      }
      /* Wordmark transform-origin left so any future scale never
         drifts the right edge of the lockup. */
      .ax-nav .ax-nav-mark {
        transform-origin: left center;
        transition: transform var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1);
      }

      /* ── Nav link - Inter 12 / #EDEAE2 / 70% rest opacity.
         Brief §10: hover raises opacity to 100% AND animates a
         1px underline from left, width 0 → 100%, 300ms,
         ease-out-quart. The underline is a ::after pseudo so the
         entrance animation on the <a> can keep ownership of the
         element's transform. */
      .ax-nav-link {
        position: relative;
        font-family: "Inter", system-ui, sans-serif;
        font-size: 14px;
        font-weight: 400;
        color: #EDEAE2;
        opacity: 0.7;
        text-decoration: none;
        letter-spacing: -0.005em;
        white-space: nowrap;
        /* Smooth opacity transition both directions on hover -
           per the motion video reference. ease-out-quart matches
           the rest of the nav's motion language. */
        transition: opacity var(--motion-fast) cubic-bezier(0.25, 1, 0.5, 1);
        padding: 4px 0;
      }
      .ax-nav-link:hover,
      .ax-nav-link:focus-visible {
        /* Color is pinned here because the global a:hover rule in
           colors_and_type.css would otherwise shift it to brass.
           Brand calls for a flat opacity lift, no color change. */
        color: #EDEAE2;
        opacity: 1;
        outline: none;
        text-decoration: none;
      }
      /* Mobile: AxionMark wordmark scales to 1.5× (20px → 30px tall).
         Overrides the inline height set by the AxionMark component
         via !important. Img width is auto so it scales proportionally. */
      @media (max-width: 768px) {
        .ax-nav .ax-nav-mark img {
          height: 23px !important;
        }
      }
      /* When the user has reduced motion preference, skip the
         hover transition (the opacity change still applies
         instantly so the affordance is preserved). */
      @media (prefers-reduced-motion: reduce) {
        .ax-nav,
        .ax-nav .ax-nav-mark,
        .ax-nav-link {
          transition: none !important;
        }
      }
    `;
    document.head.appendChild(s);
  }, []);

  // Scroll listener - threshold trigger. Once the user scrolls
  // past HIDE_THRESHOLD, add .is-hidden and let CSS drive the
  // slide+fade as one fluid motion (independent of further
  // scroll position). Return to within the threshold and it
  // slides back in. classList toggle so the change fires without
  // a React re-render.
  React.useEffect(() => {
    const el = navRef.current;
    if (!el) return;

    const HIDE_THRESHOLD = 40; // px scroll before the nav lifts off
    let ticking = false;
    let hidden = false;

    const update = () => {
      ticking = false;
      const y = Math.max(0, window.scrollY || window.pageYOffset || 0);
      const shouldHide = y > HIDE_THRESHOLD;
      if (shouldHide === hidden) return;
      hidden = shouldHide;
      el.classList.toggle("is-hidden", hidden);
    };

    const onScroll = () => {
      if (ticking) return;
      ticking = true;
      requestAnimationFrame(update);
    };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  return (
    <nav ref={navRef} className="ax-nav" data-hero={dispatchHero ? "dispatch" : undefined}>
      {children}
    </nav>
  );
}

// Background image with darkening filter - used by all three variants.
function HeroBG({ darken = 0.45, position = "right center", scale = 1, style }) {
  return (
    <div
      aria-hidden="true"
      style={{
        position: "absolute",
        inset: 0,
        backgroundImage: 'url("assets/hero-bg.png")',
        backgroundSize: "cover",
        backgroundPosition: position,
        backgroundRepeat: "no-repeat",
        transform: scale !== 1 ? `scale(${scale})` : undefined,
        transformOrigin: "right center",
        zIndex: 0,
        ...style
      }}
    >
      <div
        style={{
          position: "absolute",
          inset: 0,
          background: `rgba(15, 16, 18, ${darken})`,
          mixBlendMode: "multiply"
        }}
      />
    </div>
  );
}

Object.assign(window, { AxionMark, NavLinks, BrassCTA, SpecLine, HeroBG, NavBar });
