/* visdi-shared.jsx - VISDI by Minerva - Shared UI components
   Exports: WheelMark · NavBar · Btn · Eyebrow · Arrow · CircuitSVG · PageHero · SiteFooter · STAGE */

const WORDMARK   = "assets/logo-minerva-km-dark.svg";
const KM_HORIZONTAL = "assets/logo-minerva-km-horizontal.svg";   /* color-on-white — master bar */
const KM_WHITECLEAR = "assets/logo-minerva-km-white-clear.svg";  /* white, transparent — pinned sub-bar */
const MARK_SRC   = "assets/logo-minerva-km.svg";
const VISDI_ICON = "assets/logo-visdi-wheels-white.svg";
const NAV_SPECTRUM = "linear-gradient(90deg,#D51C29,#E0542A,#E0A230,#F2D12E,#8FBF3F,#069848,#1AA89A,#3FB1E5,#1C4DA1,#4A3BA8,#8B2CA8,#D20F8C)";

/* Standalone-bundle resolver: maps an asset path to its inlined blob URL when
   the page has been bundled (window.__resources present), else returns the path
   unchanged. No-op on the normal multi-file site. */
if (!window.__asset) window.__asset = function (p) { return (window.__resources && window.__resources[p]) || p; };

/* Stage color system - Brief §2.1: Diagnose=gold · Connect=blue · Operate=green */
const STAGE = {
  diagnose: { color:"#E0A230", bg:"rgba(224,162,48,0.08)",  border:"rgba(224,162,48,0.22)",  label:"Diagnose" },
  connect:  { color:"#3FB1E5", bg:"rgba(63,177,229,0.08)",  border:"rgba(63,177,229,0.22)",  label:"Connect"  },
  operate:  { color:"#04975e", bg:"rgba(4,151,94,0.08)",    border:"rgba(4,151,94,0.22)",    label:"Operate"  },
};

/* 2026 spectrum wheel - CSS-crop of logo-minerva-km.svg (61% height = wheel only) */
function WheelMark({ width = 360, style = {} }) {
  const aspect = 180.5 / 160.9;
  const fullH  = Math.round(width / aspect);
  const cropH  = Math.round(fullH * 0.61);
  return (
    <div style={{ width, height: cropH, overflow:"hidden", position:"relative", flexShrink:0,
      filter:"drop-shadow(0 12px 40px rgba(0,0,0,0.55))", ...style }}>
      <img src={window.__asset(MARK_SRC)} alt="" style={{ position:"absolute", width, height:fullH, top:0, left:0 }} />
    </div>
  );
}

/* Global navigation */
const NAV_LINKS = [
  { id:"method",   label:"The Method",   href:"visdi-method.html"  },
  { id:"products", label:"Products",     href:"visdi-products.html"},
  { id:"mingi",    label:"Mingi",        href:"visdi-mingi.html"   },
];

/* Persistent two-tier brand bar — Tier 1 master (firm, scrolls away) +
   Tier 2 General Intelligence sub-bar (sticky, pins). See the handoff spec. */
function NavBar({ page = "home" }) {
  const [pinned, setPinned] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setPinned(window.scrollY > 60);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  /* close the mobile menu if the viewport grows back to desktop */
  React.useEffect(() => {
    const onResize = () => { if (window.innerWidth > 1024) setMenuOpen(false); };
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  /* lock body scroll while the overlay is open */
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  const dim = "rgba(231,239,250,0.62)";
  const SKY = "#3FB1E5";

  /* master-bar division box — previews the destination site's theme.
     block=true → full-width stacked variant for the mobile menu (equal lengths). */
  const divBox = ({ href, label, kind, active, block = false }) => {
    const box = kind === "gi"
      ? { background: active ? "#0A1426" : "#0E1A30", color: "#FFFFFF",
          border: `1px solid ${active ? SKY : "rgba(63,177,229,0.45)"}`,
          boxShadow: active ? "0 2px 14px rgba(63,177,229,0.30)" : "none", dot: SKY }
      : { background: "#FFFFFF", color: active ? "#067A3E" : "var(--ink-800)",
          border: `1px solid ${active ? "#069348" : "var(--ink-300)"}`,
          boxShadow: active ? "0 2px 14px rgba(6,147,72,0.20)" : "0 1px 2px rgba(15,26,46,0.06)", dot: "#069348" };
    return (
      <a href={href} onClick={block ? () => setMenuOpen(false) : undefined}
        style={{ display: block ? "flex" : "inline-flex", alignItems:"center",
        justifyContent: block ? "center" : "flex-start", gap:9, cursor:"pointer",
        fontFamily:"var(--wix-text)", fontSize:15, fontWeight: active ? 700 : 600, letterSpacing:"-0.01em",
        whiteSpace:"nowrap", padding: block ? "14px 18px" : "10px 18px", borderRadius:"var(--radius-md)",
        width: block ? "100%" : "auto", boxSizing:"border-box",
        background:box.background, color:box.color, border:box.border, boxShadow:box.boxShadow }}>
        {active && <span style={{ width:8, height:8, borderRadius:"50%", background:box.dot, flexShrink:0 }} />}
        {label}
      </a>
    );
  };

  /* hamburger / close toggle — hidden on desktop via .nav-burger CSS */
  const burger = (color) => (
    <button className="nav-burger" aria-label={menuOpen ? "Close menu" : "Open menu"} aria-expanded={menuOpen}
      onClick={() => setMenuOpen(o => !o)}
      style={{ background:"none", border:"none", cursor:"pointer", padding:8, marginRight:-8 }}>
      <svg width="26" height="26" viewBox="0 0 26 26" fill="none" stroke={color} strokeWidth="2" strokeLinecap="round">
        {menuOpen
          ? [<line key="x1" x1="6" y1="6" x2="20" y2="20" />, <line key="x2" x1="20" y1="6" x2="6" y2="20" />]
          : [<line key="m1" x1="4" y1="8" x2="22" y2="8" />, <line key="m2" x1="4" y1="13" x2="22" y2="13" />, <line key="m3" x1="4" y1="18" x2="22" y2="18" />]}
      </svg>
    </button>
  );

  return (
    <React.Fragment>
      <style>{`
        @keyframes navLogoSettle{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}
        @keyframes navCtaReveal{from{opacity:0;transform:translateX(10px)}to{opacity:1;transform:translateX(0)}}
      `}</style>

      {/* ── Tier 1 — Minerva master brand bar (white, frosted; scrolls away) ── */}
      <header style={{ position:"relative", zIndex:60,
        display:"flex", alignItems:"center", justifyContent:"space-between",
        padding:"0 72px", height:76,
        background:"rgba(255,255,255,0.93)", backdropFilter:"blur(12px) saturate(1.4)",
        borderBottom:"1px solid var(--ink-200)" }}>
        <a href="/home/" style={{ display:"flex", alignItems:"center" }}>
          <img src={KM_HORIZONTAL} alt="Minerva Knowledge Management" style={{ height:42, width:"auto", display:"block" }} />
        </a>
        <div className="nav-actions" style={{ display:"flex", alignItems:"center", gap:14 }}>
          {divBox({ href:"/knowledge-governance/", label:"Knowledge Governance", kind:"kg", active:false })}
          {divBox({ href:"/general-intelligence/", label:"General Intelligence", kind:"gi", active:true })}
          <span style={{ width:1, height:24, background:"var(--ink-300)" }} />
          <a href="visdi-diagnostic.html" style={{ fontSize:15, fontWeight:700, color:"#0A1426",
            background:"var(--minerva-gold)", fontFamily:"var(--wix-text)",
            padding:"10px 19px", borderRadius:"var(--radius-md)", display:"inline-block", whiteSpace:"nowrap",
            boxShadow:"0 2px 10px rgba(224,162,48,0.30)" }}>Start a Diagnostic</a>
          <a href="https://www.linkedin.com/company/minerva-knowledge-and-risk-management/about/"
            target="_blank" rel="noopener noreferrer" aria-label="Minerva on LinkedIn" title="Minerva on LinkedIn"
            style={{ display:"inline-flex", alignItems:"center", justifyContent:"center", width:38, height:38,
              borderRadius:"50%", flexShrink:0, background:"var(--ink-100)", color:"var(--ink-500)",
              border:"1px solid var(--ink-200)", textDecoration:"none" }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
              <path d="M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.35V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28zM5.34 7.43a2.06 2.06 0 1 1 0-4.13 2.06 2.06 0 0 1 0 4.13zM7.12 20.45H3.56V9h3.56v11.45zM22.22 0H1.77C.8 0 0 .78 0 1.74v20.52C0 23.22.8 24 1.77 24h20.45c.98 0 1.78-.78 1.78-1.74V1.74C24 .78 23.2 0 22.22 0z"></path>
            </svg>
          </a>
        </div>
        {burger("#0A1426")}
        <span style={{ position:"absolute", left:0, right:0, bottom:-2, height:2,
          background:NAV_SPECTRUM, opacity:0.9 }} />
      </header>

      {/* ── Tier 2 — General Intelligence sub-bar (dark, sticky; pins) ── */}
      <nav style={{ position:"sticky", top:0, zIndex:50,
        display:"flex", alignItems:"center", justifyContent:"space-between",
        padding:"0 72px", height:56,
        background:"rgba(6,10,22,0.94)", backdropFilter:"blur(16px) saturate(1.5)",
        borderBottom:"1px solid rgba(255,255,255,0.08)",
        boxShadow: pinned ? "0 10px 30px rgba(0,0,0,0.45)" : "none", transition:"box-shadow .25s" }}>
        <div style={{ display:"flex", alignItems:"center", gap:16 }}>
          {pinned && (
            <a href="/home/" style={{ display:"flex", alignItems:"center",
              animation:"navLogoSettle .28s cubic-bezier(0.2,0.8,0.2,1) both" }}>
              <img src={KM_WHITECLEAR} alt="Minerva Knowledge Management" style={{ height:30, width:"auto", display:"block" }} />
            </a>
          )}
          {pinned && <span style={{ width:1, height:24, background:"rgba(255,255,255,0.16)",
            animation:"navLogoSettle .28s cubic-bezier(0.2,0.8,0.2,1) both" }} />}
          <a href="/general-intelligence/" style={{ display:"flex", alignItems:"center", gap:13 }}>
            <span style={{ width:4, height:22, borderRadius:2, background:SKY }} />
            <span style={{ fontFamily:"var(--wix-display)", fontWeight:700, fontSize:16.5,
              letterSpacing:"-0.005em", color:"#fff" }}>General Intelligence</span>
          </a>
        </div>
        <div className="nav-links-desktop" style={{ display:"flex", alignItems:"center", gap:28 }}>
          {NAV_LINKS.map(({ id, label, href }) => {
            const on = page === id;
            return (
              <a key={id} href={href} style={{ position:"relative", fontSize:15, fontFamily:"var(--wix-text)",
                fontWeight: on ? 600 : 400, letterSpacing:"-0.01em",
                color: on ? "#fff" : dim, paddingBottom:2 }}>
                {label}
                {on && <span style={{ position:"absolute", left:0, right:0, bottom:-18, height:2, background:SKY }} />}
              </a>
            );
          })}
          {pinned && (
            <a href="visdi-diagnostic.html" style={{ fontSize:14.5, fontWeight:700, color:"#0A1426",
              background:"var(--minerva-gold)", fontFamily:"var(--wix-text)",
              padding:"8px 16px", borderRadius:"var(--radius-md)", display:"inline-block", whiteSpace:"nowrap",
              animation:"navCtaReveal .26s cubic-bezier(0.2,0.8,0.2,1) both" }}>Start a Diagnostic</a>
          )}
        </div>
        {pinned && burger("#fff")}
      </nav>

      {/* ── Mobile menu overlay (hamburger target; equal-width stacked actions) ── */}
      <div className={"nav-menu-overlay" + (menuOpen ? " open" : "")}
        style={{ position:"fixed", top:0, left:0, right:0, zIndex:120, flexDirection:"column",
          background:"rgba(8,14,26,0.985)", backdropFilter:"blur(20px) saturate(1.4)",
          borderBottom:"1px solid rgba(255,255,255,0.10)", boxShadow:"0 24px 60px rgba(0,0,0,0.5)",
          maxHeight:"100vh", overflowY:"auto" }}>
        <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between",
          height:64, padding:"0 20px", borderBottom:"1px solid rgba(255,255,255,0.07)" }}>
          <img src={KM_WHITECLEAR} alt="Minerva Knowledge Management" style={{ height:28, width:"auto", display:"block" }} />
          <button aria-label="Close menu" onClick={() => setMenuOpen(false)}
            style={{ background:"none", border:"none", cursor:"pointer", padding:8, marginRight:-8 }}>
            <svg width="26" height="26" viewBox="0 0 26 26" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round">
              <line x1="6" y1="6" x2="20" y2="20" /><line x1="20" y1="6" x2="6" y2="20" />
            </svg>
          </button>
        </div>
        <div style={{ display:"flex", flexDirection:"column", gap:10, padding:"18px 20px 4px" }}>
          <span style={{ fontFamily:"var(--wix-text)", fontSize:12, fontWeight:700, letterSpacing:"0.16em",
            textTransform:"uppercase", color:"rgba(231,239,250,0.45)", marginBottom:2 }}>Divisions</span>
          {divBox({ href:"/knowledge-governance/", label:"Knowledge Governance", kind:"kg", active:false, block:true })}
          {divBox({ href:"/general-intelligence/", label:"General Intelligence", kind:"gi", active:true, block:true })}
          <a href="visdi-diagnostic.html" onClick={() => setMenuOpen(false)}
            style={{ display:"flex", justifyContent:"center", width:"100%", boxSizing:"border-box",
              fontSize:16, fontWeight:700, color:"#0A1426", background:"var(--minerva-gold)",
              fontFamily:"var(--wix-text)", padding:"14px 18px", borderRadius:"var(--radius-md)",
              marginTop:4, boxShadow:"0 2px 10px rgba(224,162,48,0.30)" }}>Start a Diagnostic</a>
        </div>
        <div style={{ display:"flex", flexDirection:"column", padding:"16px 20px 22px" }}>
          <span style={{ fontFamily:"var(--wix-text)", fontSize:12, fontWeight:700, letterSpacing:"0.16em",
            textTransform:"uppercase", color:"rgba(231,239,250,0.45)", marginBottom:4 }}>General Intelligence</span>
          {NAV_LINKS.map(({ id, label, href }) => (
            <a key={id} href={href} onClick={() => setMenuOpen(false)}
              style={{ fontFamily:"var(--wix-text)", fontSize:17, fontWeight: page===id ? 700 : 500,
                color: page===id ? "#fff" : "rgba(231,239,250,0.72)", padding:"12px 0",
                borderBottom:"1px solid rgba(255,255,255,0.06)" }}>{label}</a>
          ))}
        </div>
        <span style={{ height:3, background:NAV_SPECTRUM, opacity:0.85 }} />
      </div>
    </React.Fragment>
  );
}

/* Button */
function Btn({ children, href="#", variant="primary", accent, textColor, shadow, xstyle={} }) {
  const base = { display:"inline-flex", alignItems:"center", gap:8, fontSize:17,
    fontFamily:"var(--wix-text)", fontWeight:700, padding:"12px 22px",
    borderRadius:"var(--radius-md)", letterSpacing:"-0.01em", cursor:"pointer", ...xstyle };
  return variant==="primary"
    ? <a href={href} style={{ ...base, background:accent||"var(--minerva-blue)", color:textColor||"#fff", boxShadow:shadow||"none" }}>{children}</a>
    : <a href={href} style={{ ...base, background:"transparent", color:"#CCDCEe", border:"1px solid rgba(231,239,250,0.72)" }}>{children}</a>;
}

/* Baroque ring-dot ornament - echoes Mingi's ring motifs (Arturo's approved A/B/C type system) */
function EyebrowMark({ color, flip=false }) {
  return (
    <svg width="44" height="16" viewBox="0 0 44 16" fill="none"
      style={{ display:"block", flexShrink:0, transform: flip ? "scaleX(-1)" : "none" }}>
      <circle cx="6" cy="8" r="4.5" stroke={color} strokeWidth="1.6" />
      <circle cx="6" cy="8" r="2" fill={color} />
      <line x1="13" y1="8" x2="44" y2="8" stroke={color} strokeWidth="1.3" />
    </svg>
  );
}

/* Art-nouveau wavy vine-scroll divider - sits beneath display headlines */
function HeadlineDivider({ color="var(--minerva-gold)", style={} }) {
  return (
    <svg width="148" height="18" viewBox="0 0 148 18" fill="none"
      style={{ display:"block", margin:"10px 0 20px", ...style }}>
      <line x1="0" y1="9" x2="48" y2="9" stroke={color} strokeWidth="0.8" opacity="0.36" />
      <path d="M 54 9 Q 58 4 62 9 Q 66 14 70 9 Q 74 4 78 9 Q 82 14 86 9 Q 90 4 94 9"
        stroke={color} strokeWidth="1.5" fill="none" opacity="0.82" />
      <line x1="100" y1="9" x2="148" y2="9" stroke={color} strokeWidth="0.8" opacity="0.36" />
    </svg>
  );
}

/* Eyebrow label */
function Eyebrow({ children, color="var(--minerva-gold)", center=false }) {
  return (
    <div style={{ display:center?"flex":"inline-flex", alignItems:"center", gap:10,
      fontSize:13, fontWeight:700, textTransform:"uppercase", letterSpacing:"0.18em",
      color, fontFamily:"var(--wix-text)",
      ...(center ? { justifyContent:"center" } : {}) }}>
      <EyebrowMark color={color} />
      {children}
      {center && <EyebrowMark color={color} flip={true} />}
    </div>
  );
}

/* Inline Lucide-style icon set */
const ICONS = {
  users:        [<path key="a" d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>,<circle key="b" cx="9" cy="7" r="4"/>,<path key="c" d="M22 21v-2a4 4 0 0 0-3-3.87"/>,<path key="d" d="M16 3.13a4 4 0 0 1 0 7.75"/>],
  scale:        [<path key="a" d="m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/>,<path key="b" d="m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/>,<path key="c" d="M7 21H17"/>,<path key="d" d="M12 3v18"/>,<path key="e" d="M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2"/>],
  'alert-circle':[<circle key="a" cx="12" cy="12" r="10"/>,<line key="b" x1="12" x2="12" y1="8" y2="12"/>,<line key="c" x1="12" x2="12.01" y1="16" y2="16"/>],
  eye:          [<path key="a" d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/>,<circle key="b" cx="12" cy="12" r="3"/>],
  'layout-grid':[<rect key="a" width="7" height="7" x="3" y="3" rx="1"/>,<rect key="b" width="7" height="7" x="14" y="3" rx="1"/>,<rect key="c" width="7" height="7" x="14" y="14" rx="1"/>,<rect key="d" width="7" height="7" x="3" y="14" rx="1"/>],
  database:     [<ellipse key="a" cx="12" cy="5" rx="9" ry="3"/>,<path key="b" d="M3 5V19A9 3 0 0 0 21 19V5"/>,<path key="c" d="M3 12A9 3 0 0 0 21 12"/>],
  'shield-check':[<path key="a" d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>,<path key="b" d="m9 12 2 2 4-4"/>],
  zap:          [<polygon key="a" points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>],
  package:      [<path key="a" d="m7.5 4.27 9 5.15"/>,<path key="b" d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/>,<path key="c" d="m3.3 7 8.7 5 8.7-5"/>,<path key="d" d="M12 22V12"/>],
  'message-circle':[<path key="a" d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>],
  layers:       [<path key="a" d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"/>,<path key="b" d="m6.08 9.5-3.5 1.6a1 1 0 0 0 0 1.81l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9a1 1 0 0 0 0-1.83l-3.5-1.59"/>,<path key="c" d="m6.08 14.5-3.5 1.6a1 1 0 0 0 0 1.81l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9a1 1 0 0 0 0-1.83l-3.5-1.59"/>],
  'git-merge':  [<circle key="a" cx="18" cy="18" r="3"/>,<circle key="b" cx="6" cy="6" r="3"/>,<path key="c" d="M6 21V9a9 9 0 0 0 9 9"/>],
  'book-open':  [<path key="a" d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>,<path key="b" d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>],
  'check-circle':[<circle key="a" cx="12" cy="12" r="10"/>,<path key="b" d="m9 12 2 2 4-4"/>],
  'badge':      [<path key="a" d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"/>,<path key="b" d="m9 12 2 2 4-4"/>],
  'clipboard-check':[<rect key="a" width="8" height="4" x="8" y="2" rx="1" ry="1"/>,<path key="b" d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>,<path key="c" d="m9 14 2 2 4-4"/>],
  activity:     [<path key="a" d="M22 12h-4l-3 9L9 3l-3 9H2"/>],
  network:      [<rect key="a" x="16" y="16" width="6" height="6" rx="1"/>,<rect key="b" x="2" y="16" width="6" height="6" rx="1"/>,<rect key="c" x="9" y="2" width="6" height="6" rx="1"/>,<path key="d" d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/>,<path key="e" d="M12 12V8"/>],
};

function Icon({ name, size=24, color="currentColor", strokeWidth=1.8 }) {
  const paths = ICONS[name];
  if (!paths) return null;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
      style={{ display:"block", flexShrink:0 }}>
      {paths}
    </svg>
  );
}

/* Arrow icon */
function Arrow() {
  return (
    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 12h14M13 6l6 6-6 6"/>
    </svg>
  );
}

/* Medical circuit motif - life sciences visual language.
   Gold rounded traces · IV drip bags · capsule pills · dot grid clusters. */
function CircuitSVG({ color="var(--minerva-gold)", opacity=0.40, style:ext={} }) {
  const c = color;
  const o = opacity;
  const sw = 1.3;
  return (
    <svg width="580" height="520" viewBox="0 0 580 520" style={{ pointerEvents:"none", ...ext }}>
      <g stroke={c} strokeWidth={sw} fill="none" opacity={o}>
        <path d="M560 68 H430 a14 14 0 0 0-14 14 V390 a14 14 0 0 1-14 14 H240"/>
        <path d="M430 82 V44 a14 14 0 0 1 14-14 H516"/>
        <path d="M416 170 H500 a14 14 0 0 0 14-14 V128"/>
        <path d="M416 290 H508 a14 14 0 0 0 14-14 V250"/>
      </g>
      <g fill={c} opacity={o + 0.35}>
        <circle cx="430" cy="82" r="4.5"/>
        <circle cx="416" cy="170" r="4.5"/>
        <circle cx="416" cy="290" r="4.5"/>
        <circle cx="240" cy="404" r="4.5"/>
        <circle cx="514" cy="128" r="4"/>
        <circle cx="514" cy="250" r="4"/>
      </g>
      <g stroke={c} fill="none" strokeWidth={sw} opacity={o + 0.14}>
        <line x1="240" y1="408" x2="240" y2="420"/>
        <rect x="234" y="420" width="12" height="7" rx="3"/>
        <rect x="225" y="427" width="30" height="32" rx="4"/>
        <line x1="229" y1="436" x2="251" y2="436" strokeWidth="0.9"/>
        <line x1="229" y1="444" x2="251" y2="444" strokeWidth="0.9"/>
        <line x1="229" y1="452" x2="251" y2="452" strokeWidth="0.9"/>
        <line x1="240" y1="459" x2="240" y2="470"/>
        <rect x="234" y="470" width="12" height="9" rx="2"/>
      </g>
      <g stroke={c} fill="none" strokeWidth={sw} opacity={o + 0.14}>
        <line x1="416" y1="174" x2="416" y2="186"/>
        <rect x="410" y="186" width="12" height="7" rx="3"/>
        <rect x="401" y="193" width="30" height="32" rx="4"/>
        <line x1="405" y1="202" x2="427" y2="202" strokeWidth="0.9"/>
        <line x1="405" y1="210" x2="427" y2="210" strokeWidth="0.9"/>
        <line x1="405" y1="218" x2="427" y2="218" strokeWidth="0.9"/>
        <line x1="416" y1="225" x2="416" y2="236"/>
        <rect x="410" y="236" width="12" height="9" rx="2"/>
      </g>
      <g stroke={c} fill="none" strokeWidth={sw} opacity={o + 0.14}>
        <rect x="500" y="14" width="32" height="16" rx="8"/>
        <line x1="516" y1="14" x2="516" y2="30" strokeWidth="0.9"/>
      </g>
      <g stroke={c} fill="none" strokeWidth={sw} opacity={o + 0.14}>
        <line x1="430" y1="44" x2="430" y2="32"/>
        <rect x="422" y="0" width="16" height="34" rx="8"/>
        <line x1="422" y1="17" x2="438" y2="17" strokeWidth="0.9"/>
      </g>
      <g stroke={c} fill="none" strokeWidth={sw} opacity={o + 0.14}>
        <rect x="498" y="120" width="32" height="16" rx="8"/>
        <line x1="514" y1="120" x2="514" y2="136" strokeWidth="0.9"/>
      </g>
      <g stroke={c} fill="none" strokeWidth={sw} opacity={o + 0.14}>
        <line x1="514" y1="250" x2="530" y2="250"/>
        <rect x="530" y="234" width="16" height="34" rx="8"/>
        <line x1="530" y1="251" x2="546" y2="251" strokeWidth="0.9"/>
      </g>
      <g fill={c} opacity={o * 0.58}>
        {[12,22,32,42].flatMap(x=>[28,38,48,58,68].map(y=>(<circle key={`tl${x}${y}`} cx={x} cy={y} r="2"/>)))}
      </g>
      <g fill={c} opacity={o * 0.52}>
        {[540,550,560].flatMap(x=>[220,230,240,250].map(y=>(<circle key={`rm${x}${y}`} cx={x} cy={y} r="2"/>)))}
      </g>
    </svg>
  );
}

/* Decorative side-border ornament - line-art in the Dark Minerva "blue version"
   vocabulary: crown rings, inward chevrons, rotated-square diamonds, tendril
   curls. Stroke-only in sky-blue (no gold), muted, tiles seamlessly down any
   height via an SVG pattern. Top/bottom mask-fade; sits behind content (z:0). */
function VineBorder({ side = "left", opacity = 0.5, color = "var(--minerva-sky)", mask }) {
  const m = mask || "linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%)";
  const pid = `vb-${side}`;
  return (
    <div aria-hidden="true" style={{
      position:"absolute", top:0, [side]:0, height:"100%", width:172, zIndex:0,
      pointerEvents:"none", opacity, color,
      transform: side === "right" ? "scaleX(-1)" : "none",
      WebkitMaskImage:m, maskImage:m,
    }}>
      <svg width="172" height="100%" fill="none" style={{ display:"block" }}>
        <defs>
          <pattern id={pid} x="0" y="0" width="172" height="324" patternUnits="userSpaceOnUse">
            {/* meandering stem - endpoints align at x=70 so tiles connect */}
            <path d="M70 0 C 98 54, 46 98, 70 162 C 94 226, 42 270, 70 324"
              stroke="currentColor" strokeWidth="1.4" opacity="0.62" />
            {/* crown ring */}
            <circle cx="70" cy="46" r="12" stroke="currentColor" strokeWidth="1.6" />
            <circle cx="70" cy="46" r="18.5" stroke="currentColor" strokeWidth="0.8" strokeDasharray="3 6" opacity="0.5" />
            <circle cx="70" cy="46" r="3.5" fill="currentColor" stroke="none" opacity="0.8" />
            {/* inward chevron */}
            <path d="M52 150 L 80 163 L 52 176" stroke="currentColor" strokeWidth="1.5" opacity="0.78" />
            {/* rotated-square diamonds */}
            <rect x="33" y="95" width="13" height="13" transform="rotate(45 39.5 101.5)" stroke="currentColor" strokeWidth="1.2" opacity="0.7" />
            <rect x="106" y="120" width="9" height="9" transform="rotate(45 110.5 124.5)" stroke="currentColor" strokeWidth="1.1" opacity="0.52" />
            <rect x="40" y="236" width="10" height="10" transform="rotate(45 45 241)" stroke="currentColor" strokeWidth="1.1" opacity="0.6" />
            <rect x="101" y="252" width="14" height="14" transform="rotate(45 108 259)" stroke="currentColor" strokeWidth="1.2" opacity="0.7" />
            {/* small floating ring */}
            <circle cx="114" cy="208" r="8" stroke="currentColor" strokeWidth="1.2" opacity="0.5" />
            <circle cx="114" cy="208" r="2.5" fill="currentColor" stroke="none" opacity="0.6" />
            {/* tendril curl */}
            <path d="M70 286 q 28 -6 31 17" stroke="currentColor" strokeWidth="1.2" opacity="0.48" />
          </pattern>
        </defs>
        <rect x="0" y="0" width="172" height="100%" fill={`url(#${pid})`} />
      </svg>
    </div>
  );
}

/* Inner-page hero splash - 55vh min, matches main hero energy */
function PageHero({ eyebrow, title, body, accent="var(--minerva-sky)", eyebrowColor, rightSlot, circuit=true, bgImage, ghost, minHeight="55vh", pad="96px 0 80px", align="center" }) {
  const ghostWord = ghost !== undefined ? ghost : (title ? title.split(' ').slice(0,3).join(' ') : '');
  return (
    <section style={{
      minHeight, display:"flex", alignItems:align,
      background:"linear-gradient(155deg,#0A1426 0%,#0D1C36 55%,#081420 100%)",
      padding:pad, position:"relative", overflow:"hidden",
    }}>
      {bgImage && <img src={bgImage} alt="" aria-hidden="true" style={{ position:"absolute", top:0, right:-20,
            height:"115%", width:"auto", maxWidth:"52%", objectFit:"contain", objectPosition:"top right",
            opacity:0.3, filter:"saturate(0.5) brightness(0.82)", pointerEvents:"none", userSelect:"none",
            WebkitMaskImage:"radial-gradient(137% 137% at 100% 0%, #000 62%, transparent 94%)",
            maskImage:"radial-gradient(137% 137% at 100% 0%, #000 62%, transparent 94%)" }} />}
      <div style={{
        position:"absolute", bottom:-30, left:72, pointerEvents:"none", userSelect:"none",
        fontSize:200, fontWeight:700, lineHeight:1, letterSpacing:"-0.03em",
        color:"rgba(255,255,255,0.022)", fontFamily:"var(--baroque-display)", whiteSpace:"nowrap",
      }}>{ghostWord}</div>
      <div style={{ maxWidth:1280, margin:"0 auto", padding:"0 80px", position:"relative",
        width:"100%", display:"flex", alignItems:"center", gap:72 }}>
        <div style={{ flex:1 }}>
          <Eyebrow color={eyebrowColor||accent}>{eyebrow}</Eyebrow>
          <h1 style={{
            fontSize:70, fontWeight:700, lineHeight:1.08, letterSpacing:"-0.02em",
            fontFamily:"var(--baroque-display)", margin:"22px 0 0", color:"#fff", maxWidth:860, whiteSpace:"pre-line",
          }}>{title}</h1>
          <HeadlineDivider color={eyebrowColor||accent} />
          {body && <p style={{ fontSize:20, lineHeight:1.65, color:"#C4D8EE", maxWidth:620, margin:0 }}>{body}</p>}
        </div>
        {rightSlot && <div style={{ flex:"0 0 auto" }}>{rightSlot}</div>}
      </div>
    </section>
  );
}

/* Compact footer glossary - reachable from every page */
const GLOSSARY = [
  ["VISDI",              "Visual-Digital Knowledge - the architecture everything else is built on"],
  ["Mingi",              "Minerva General Intelligence - the result of compliant integration between humans and AI"],
  ["The Ledger",         "Auditable, append-only governance & comms layer - nothing ever overwritten"],
  ["CLV",                "Context Language Validation - the context-layer counterpart to CSV"],
  ["Knowledge Execution","The category - the compliant AI-ready knowledge layer"],
  ["Trust gate",         "Human verification checkpoint - nothing becomes knowledge without it"],
  ["knowledge packet",   "The atomic unit - small, self-contained, machine-legible"],
  ["GxP",                "The regulated standard in life sciences"],
];

/* Site footer */
function SiteFooter() {
  const dim="rgba(231,239,250,0.55)";
  const cols = [
    { label:"VISDI",    links:[["The Method","visdi-method.html"],["Products","visdi-products.html"],["Mingi","visdi-mingi.html"],["Who It's For","visdi-products.html"],["Why General Intelligence","general-intelligence.html"]] },
    { label:"Products", links:[["VISDI Diagnose","visdi-know.html"],["VISDI Connect","visdi-connect.html"],["VISDI Operate","visdi-operate.html"],["Start a Diagnostic","visdi-diagnostic.html"]] },
    { label:"Minerva",  links:[["Services ↗","https://minervakrm.com"],["Quality Systems","https://minervakrm.com"],["Investigations","https://minervakrm.com"],["Visualizations","https://minervakrm.com"]] },
  ];
  return (
    <footer style={{ background:"#030508", borderTop:"1px solid rgba(255,255,255,0.07)", padding:"64px 72px 36px" }}>
      <div style={{ maxWidth:1280, margin:"0 auto" }}>
        {/* Glossary strip */}
        <div style={{ marginBottom:48, paddingBottom:40, borderBottom:"1px solid rgba(255,255,255,0.07)" }}>
          <p style={{ fontSize:14, fontWeight:700, letterSpacing:"0.14em", textTransform:"uppercase",
            color:"rgba(231,239,250,0.35)", margin:"0 0 18px", fontFamily:"var(--wix-text)" }}>Key terms</p>
          <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:"10px 44px" }}>
            {GLOSSARY.map(([term, def]) => (
              <div key={term} style={{ fontSize:15, lineHeight:1.5 }}>
                <span style={{ fontWeight:700, color:"rgba(231,239,250,0.72)",
                  fontFamily:"var(--wix-text)" }}>{term}</span>
                <span style={{ color:"rgba(231,239,250,0.42)", marginLeft:6 }}>- {def}</span>
              </div>
            ))}
          </div>
        </div>
        <div style={{ display:"flex", gap:72, marginBottom:52 }}>
          <div style={{ flex:"0 0 220px" }}>
            <img src={WORDMARK} alt="Minerva KM" style={{ height:26, marginBottom:14 }} />
            <p style={{ fontSize:15, color:"rgba(231,239,250,0.72)", lineHeight:1.65, margin:"0 0 22px" }}>
              The AI-Ready Knowledge Layer<br/>for Regulated Life Sciences.
            </p>
            <div style={{ display:"flex", alignItems:"center", gap:8 }}>
              <span style={{ width:18, height:2, background:"var(--minerva-gold)" }} />
              <span style={{ fontSize:14, fontWeight:700, letterSpacing:"0.22em",
                color:"rgba(224,162,48,0.90)", textTransform:"uppercase",
                fontFamily:"var(--wix-text)" }}>FASTER SMARTER BETTER</span>
            </div>
          </div>
          <div style={{ flex:1, display:"flex", gap:52 }}>
            {cols.map(({ label, links }) => (
              <div key={label}>
                <p style={{ fontSize:14, fontWeight:700, letterSpacing:"0.12em", textTransform:"uppercase",
                  color:"rgba(231,239,250,0.72)", margin:"0 0 16px", fontFamily:"var(--wix-text)" }}>{label}</p>
                {links.map(([l,h])=>(
                  <a key={l} href={h} style={{ display:"block", fontSize:15, color:dim, marginBottom:10,
                    fontFamily:"var(--wix-text)" }}>{l}</a>
                ))}
              </div>
            ))}
          </div>
        </div>
        <div style={{ borderTop:"1px solid rgba(255,255,255,0.06)", paddingTop:24,
          display:"flex", justifyContent:"space-between" }}>
          <span style={{ fontSize:14, color:"rgba(231,239,250,0.36)", fontFamily:"var(--wix-text)" }}>© 2026 Minerva Knowledge Management · Los Angeles, CA</span>
          <span style={{ fontSize:14, color:"rgba(231,239,250,0.36)", fontFamily:"var(--wix-text)" }}>Life Sciences Consulting · Knowledge Execution</span>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, { WheelMark, NavBar, Btn, Eyebrow, EyebrowMark, HeadlineDivider, Arrow, Icon, CircuitSVG, VineBorder, PageHero, SiteFooter, STAGE, WORDMARK, MARK_SRC, VISDI_ICON });

/* ── Scroll-triggered animations - injected once, active on all pages ──
   IMPORTANT: this preview engine has a bug where a dynamically-injected
   attribute-selector CSS rule (e.g. [data-animate]{opacity:0}) wrongly beats
   an element's own inline style on React-rendered nodes - so a CSS hidden
   base state can leave content stuck invisible. We therefore use NO opacity
   CSS at all: the hidden state and the reveal are BOTH set as inline styles
   (which behave correctly), and a MutationObserver hides nodes the instant
   React inserts them so there is no first-paint flash. */
(function initAnim() {
  if (window.__vaInit) return; window.__vaInit = true;

  const SEL = '[data-animate],[data-stagger]';
  const EASE = 'cubic-bezier(.2,.8,.2,1)';
  const reduce = matchMedia('(prefers-reduced-motion:reduce)').matches;
  const targets = el => el.hasAttribute('data-stagger') ? [...el.children] : [el];

  const prep = el => {
    if (el.__vaPrepped) return; el.__vaPrepped = true;
    if (reduce) return;                       // reduced motion → never hide
    const dur = el.hasAttribute('data-stagger') ? '.6s' : '.7s';
    targets(el).forEach((t, i) => {
      t.style.transition = `opacity ${dur} ${EASE}`;
      if (el.hasAttribute('data-stagger')) t.style.transitionDelay = (i * 0.1) + 's';
      t.style.opacity = '0';
    });
  };
  const show = el => targets(el).forEach(t => { if (t.style.opacity !== '1') t.style.opacity = '1'; });
  const inView = el => {
    const r = el.getBoundingClientRect();
    const h = window.innerHeight || document.documentElement.clientHeight;
    return r.top < h * 0.92 && r.bottom > 0;
  };
  const scan = () => document.querySelectorAll(SEL).forEach(el => { prep(el); if (reduce || inView(el)) show(el); });

  /* Hide tagged nodes the moment React inserts them (kills first-paint flash). */
  const mo = new MutationObserver(scan);
  const startMO = () => mo.observe(document.getElementById('root') || document.body, { childList: true, subtree: true });
  startMO();

  /* Poll ~5s to cover React's async render + reveal whatever is in view; the
     scroll/resize listeners then reveal everything below the fold, forever. */
  let tries = 0;
  (function tick() { scan(); if (++tries < 50) setTimeout(tick, 100); })();
  addEventListener('scroll', scan, { passive: true });
  addEventListener('resize', scan, { passive: true });

  /* Hard fallback - never leave content stuck invisible. */
  setTimeout(() => document.querySelectorAll(SEL).forEach(show), 6000);
})();
