// surgx-landing-v3.jsx — SurgX Landing page, design v3.
// Mounts #root; IIFE pattern (same as browse-v3, Babel-race safe).
// Blank-over-wrong throughout: every fetch failure omits the section, never fakes.
// Reuses .sxv3 / .sx token root from surgx-pdp-v3.css; layout classes prefixed lx-.
(() => {
const { useState, useEffect, useRef, useCallback, useMemo } = React;

/* ---- shared search core (surgx-search-core.js, loaded before this script) ---- */
const { str, normalizeVendor, matchesQuery } = window.SurgxSearchCore;

/* ---- hero mode param (dark gate) ---- */
const _heroParam = new URLSearchParams(window.location.search).get('hero');

/* ================================================================
   HeroConstellation — 3D point-cloud canvas of the real taxonomy.
   Hub nodes = specialties (Fibonacci sphere), system nodes clustered
   around each hub. Perspective projection + depth-fade. Auto-rotates
   ~1 rev/40s with pointer parallax on desktop.
   Renders ONLY when taxonomy is truthy AND ?hero=3d.
   prefers-reduced-motion: reduce → single static frame, no rAF.
   ================================================================ */
function HeroConstellation({ taxonomy }) {
  const canvasRef = useRef(null);
  const stateRef = useRef(null);

  useEffect(() => {
    if (!taxonomy || !taxonomy.specialties || !taxonomy.specialties.length) return;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    /* ---- build 3D point cloud from taxonomy ---- */
    const specs = taxonomy.specialties;
    const N = specs.length;
    const TAU = Math.PI * 2;
    const GOLDEN = (1 + Math.sqrt(5)) / 2;
    const HUB_R = 1.0; /* sphere radius for hub distribution */

    /* Fibonacci sphere placement for hubs */
    const hubs = [];
    const systems = [];
    for (let i = 0; i < N; i++) {
      const theta = Math.acos(1 - 2 * (i + 0.5) / N);
      const phi = TAU * i / GOLDEN;
      const hx = HUB_R * Math.sin(theta) * Math.cos(phi);
      const hy = HUB_R * Math.sin(theta) * Math.sin(phi);
      const hz = HUB_R * Math.cos(theta);
      const cnt = specs[i].count || 1;
      const r = Math.max(3, Math.min(8, Math.sqrt(cnt) * 1.4));
      hubs.push({ x: hx, y: hy, z: hz, r: r, idx: i });

      /* system nodes — jittered sphere around hub, capped at 14 */
      const sysCount = Math.min(cnt, 14);
      for (let j = 0; j < sysCount; j++) {
        const st = Math.acos(1 - 2 * (j + 0.5) / Math.max(sysCount, 1));
        const sp = TAU * j / GOLDEN;
        const spread = 0.12 + Math.random() * 0.06;
        const sx = hx + spread * Math.sin(st) * Math.cos(sp);
        const sy = hy + spread * Math.sin(st) * Math.sin(sp);
        const sz = hz + spread * Math.cos(st);
        systems.push({ x: sx, y: sy, z: sz, hub: i });
      }
    }

    /* ---- rotation state ---- */
    const rot = { ay: 0, targetAy: 0, ax: 0.25 }; /* fixed X tilt ~14deg */
    const SPEED = TAU / 40; /* 1 rev per 40s */
    let mouseInfluence = { dx: 0, dy: 0 };
    let rafId = 0;
    let lastT = 0;
    let paused = false;

    /* ---- sizing (DPR-aware) ---- */
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    function resize() {
      const rect = canvas.getBoundingClientRect();
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    resize();

    /* ---- projection helpers ---- */
    function project(px, py, pz, w, h) {
      const cosAy = Math.cos(rot.ay);
      const sinAy = Math.sin(rot.ay);
      const cosAx = Math.cos(rot.ax);
      const sinAx = Math.sin(rot.ax);
      /* rotate Y then X */
      const x1 = px * cosAy - pz * sinAy;
      const z1 = px * sinAy + pz * cosAy;
      const y1 = py * cosAx - z1 * sinAx;
      const z2 = py * sinAx + z1 * cosAx;
      const f = 2.8;
      const scale = f / (f + z2);
      return { sx: w * 0.5 + x1 * scale * w * 0.38, sy: h * 0.5 + y1 * scale * h * 0.38, scale: scale, z: z2 };
    }

    /* ---- palette ---- */
    const HUB_COLOR = '#0B4A72';
    const SYS_COLOR = '#6FA6C6';
    const EDGE_BASE = 'rgba(11,74,114,';

    /* ---- frame ---- */
    function frame(t) {
      if (paused) { rafId = requestAnimationFrame(frame); return; }
      const dt = lastT ? (t - lastT) / 1000 : 0.016;
      lastT = t;

      /* auto-rotate + mouse parallax with easing */
      rot.targetAy += SPEED * dt;
      rot.ay += (rot.targetAy + mouseInfluence.dx - rot.ay) * 0.06;

      const rect = canvas.getBoundingClientRect();
      const w = rect.width;
      const h = rect.height;
      if (canvas.width !== w * dpr || canvas.height !== h * dpr) resize();

      ctx.clearRect(0, 0, w, h);

      /* project all points once */
      const pH = hubs.map(p => project(p.x, p.y, p.z, w, h));
      const pS = systems.map(p => project(p.x, p.y, p.z, w, h));

      /* edges (hub → system), low alpha with depth — darkened for visibility
         on the white landing background (Drew walk 2026-06-10: lines too faint) */
      for (let i = 0; i < pS.length; i++) {
        const s = pS[i];
        const hProj = pH[systems[i].hub];
        const depthAlpha = Math.max(0.10, Math.min(0.24, 0.24 * s.scale));
        ctx.beginPath();
        ctx.moveTo(hProj.sx, hProj.sy);
        ctx.lineTo(s.sx, s.sy);
        ctx.strokeStyle = EDGE_BASE + depthAlpha + ')';
        ctx.lineWidth = 0.6;
        ctx.stroke();
      }

      /* system nodes */
      for (let i = 0; i < pS.length; i++) {
        const s = pS[i];
        const alpha = Math.max(0.2, Math.min(0.85, 0.85 * s.scale));
        const r = Math.max(0.8, 1.5 * s.scale);
        ctx.beginPath();
        ctx.arc(s.sx, s.sy, r, 0, TAU);
        ctx.fillStyle = SYS_COLOR;
        ctx.globalAlpha = alpha;
        ctx.fill();
      }

      /* hub nodes (on top) */
      for (let i = 0; i < pH.length; i++) {
        const h2 = pH[i];
        const alpha = Math.max(0.35, Math.min(1, 1.0 * h2.scale));
        const r = Math.max(2, hubs[i].r * h2.scale);
        ctx.beginPath();
        ctx.arc(h2.sx, h2.sy, r, 0, TAU);
        ctx.fillStyle = HUB_COLOR;
        ctx.globalAlpha = alpha;
        ctx.fill();
      }

      ctx.globalAlpha = 1;
      rafId = requestAnimationFrame(frame);
    }

    /* ---- reduced motion: single static frame ---- */
    const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (prefersReduced) {
      rot.ay = 0.4; /* slight rotation so it's not head-on */
      frame(0);
      /* no rAF loop */
      stateRef.current = { cleanup: () => {} };
      return;
    }

    rafId = requestAnimationFrame(frame);

    /* ---- pointer parallax (desktop only, no touch) ---- */
    function onMouseMove(e) {
      const rect = canvas.getBoundingClientRect();
      const nx = ((e.clientX - rect.left) / rect.width - 0.5) * 2;
      const ny = ((e.clientY - rect.top) / rect.height - 0.5) * 2;
      mouseInfluence.dx = nx * 0.3;
    }
    canvas.addEventListener('mousemove', onMouseMove);

    /* ---- visibility / intersection pause ---- */
    function onVisChange() { paused = document.hidden; }
    document.addEventListener('visibilitychange', onVisChange);

    let observer = null;
    if (typeof IntersectionObserver !== 'undefined') {
      observer = new IntersectionObserver(([entry]) => {
        if (!entry.isIntersecting) paused = true;
        else if (!document.hidden) paused = false;
      }, { threshold: 0 });
      observer.observe(canvas);
    }

    /* ---- cleanup ---- */
    stateRef.current = {
      cleanup: () => {
        cancelAnimationFrame(rafId);
        canvas.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('visibilitychange', onVisChange);
        if (observer) observer.disconnect();
      }
    };

    return () => {
      if (stateRef.current && stateRef.current.cleanup) stateRef.current.cleanup();
    };
  }, [taxonomy]);

  if (!taxonomy || !taxonomy.specialties || !taxonomy.specialties.length) return null;

  return (
    <canvas
      ref={canvasRef}
      className="lx-hero3d-canvas"
      aria-hidden="true"
    />
  );
}

/* ---- tiny helpers ---- */
const initials = n => { const w = String(n || '?').split(/\s+/).filter(Boolean); return ((w[0]?.[0] || '?') + (w[1]?.[0] || '')).toUpperCase(); };

/* ================================================================
   SPECIALTY_GLYPHS — viewBox 0 0 24 24, monoline stroke, fill="none"
   Each value is an array of path-d strings (1-4 paths per glyph).
   ================================================================ */
const SPECIALTY_GLYPHS = {
  'orthopedics': [
    'M12 3 L12 21',
    'M9 3 Q12 5 15 3',
    'M9 21 Q12 19 15 21'
  ],
  'spine': [
    'M12 3 L12 21',
    'M8 6 L16 6',
    'M9 12 L15 12',
    'M8 18 L16 18'
  ],
  'neurosurgery': [
    'M12 4 Q5 4 5 12 Q5 20 12 20 Q19 20 19 12 Q19 4 12 4Z',
    'M9 8 Q12 10 9 13 Q12 15 9 18',
    'M15 8 Q12 10 15 14'
  ],
  'cardiovascular': [
    'M12 20 L4 12 Q4 6 8 6 Q12 6 12 10 Q12 6 16 6 Q20 6 20 12Z'
  ],
  'cardiothoracic': [
    'M12 18 L6 12 Q6 8 9 8 Q12 8 12 11 Q12 8 15 8 Q18 8 18 12Z',
    'M3 10 Q5 14 3 18'
  ],
  'vascular': [
    'M12 4 L12 12',
    'M12 12 Q8 16 6 20',
    'M12 12 Q16 16 18 20'
  ],
  'general-plastic-surgery': [
    'M9 4 L15 4',
    'M9 4 Q9 13 12 19',
    'M15 4 Q15 13 12 19'
  ],
  'ob-gyn': [
    'M12 7 Q7 7 7 13 L9 19',
    'M12 7 Q17 7 17 13 L15 19',
    'M9 19 L15 19'
  ],
  'gi-urology': [
    'M15 3 L17 3',
    'M15 3 Q15 8 11 10 Q6 12 6 16 Q6 20 10.5 20 Q15 20 16 15'
  ],
  'ophthalmology': [
    'M3 12 Q12 5 21 12 Q12 19 3 12Z',
    'M12 9.5 A2.5 2.5 0 0 1 12 14.5 A2.5 2.5 0 0 1 12 9.5Z'
  ],
  'ent': [
    'M16 5 Q20 5 20 10 Q20 16 15 19',
    'M16 10 Q14 10 14 13'
  ],
  'dental': [
    'M8 4 Q6 4 6 8 Q6 11 8 12 Q9 14 9 18 L9 20',
    'M16 4 Q18 4 18 8 Q18 11 16 12 Q15 14 15 18 L15 20',
    'M8 4 Q12 6 16 4'
  ],
  'anesthesiology': [
    'M7 8 Q7 4 12 4 Q17 4 17 8 L17 12 L7 12Z',
    'M12 12 L12 20'
  ],
  'critical-care': [
    'M4 12 L8 12 L10 7 L14 17 L16 12 L20 12'
  ],
  'wound-care': [
    'M4 12 L20 12',
    'M7 9 L9 15',
    'M13 15 L11 9',
    'M15 9 L17 15'
  ],
  'radiology-imaging': [
    'M12 12 L12 12.01',
    'M12 8 A4 4 0 0 1 16 12',
    'M12 5 A7 7 0 0 1 19 12',
    'M12 2 A10 10 0 0 1 22 12'
  ],
  'oncology': [
    'M12 3 Q9 5 9 8 Q9 11 12 13 Q15 11 15 8 Q15 5 12 3Z',
    'M10.5 12 Q13 15.5 16 20',
    'M13.5 12 Q11 15.5 8 20'
  ],
  'perioperative-or-support': [
    'M4 10 L20 10',
    'M4 10 L4 8',
    'M20 10 L20 8',
    'M12 10 L12 18'
  ],
  'blood-management': [
    'M12 4 Q7 11 7 14 Q7 20 12 20 Q17 20 17 14 Q17 11 12 4Z'
  ],
  'diagnostics-lab': [
    'M9 4 L9 10 Q6 16 8 19 L16 19 Q18 16 15 10 L15 4',
    'M9 4 L15 4'
  ],
  'physical-medicine': [
    'M5 19 L12 12 L19 16',
    'M9 15 A4.5 4.5 0 0 1 14.8 13.7'
  ],
  'endocrinology': [
    'M12 4 Q8 9 8 13 Q8 18 12 18 Q16 18 16 13 Q16 9 12 4Z',
    'M12 10 A1.5 1.5 0 0 1 12 13 A1.5 1.5 0 0 1 12 10Z'
  ],
  'pediatrics-neonatology': [
    'M12 8 A3 3 0 0 1 12 2 A3 3 0 0 1 12 8Z',
    'M12 8 Q8 12 9 18',
    'M12 8 Q16 12 15 18'
  ],
  'pulmonology': [
    'M12 3 L12 8',
    'M11 9 Q6 11 6 15.5 Q6 20 9 20 Q11 20 11 16.5 L11 9',
    'M13 9 Q18 11 18 15.5 Q18 20 15 20 Q13 20 13 16.5 L13 9'
  ],
  'multispecialty': [
    'M12 4 L12 20',
    'M4 12 L20 12',
    'M6.3 6.3 L17.7 17.7',
    'M17.7 6.3 L6.3 17.7'
  ],
  '__default': [
    'M7 7 L10 7 L10 10 L7 10Z',
    'M14 7 L17 7 L17 10 L14 10Z',
    'M7 14 L10 14 L10 17 L7 17Z',
    'M14 14 L17 14 L17 17 L14 17Z'
  ]
};
window.SurgxSpecialtyGlyphs = SPECIALTY_GLYPHS;

/* ---- SpecialtyGlyph component ---- */
function SpecialtyGlyph({ slug }) {
  const paths = SPECIALTY_GLYPHS[slug] || SPECIALTY_GLYPHS['__default'];
  return (
    <svg className="lx-st-glyph" width={20} height={20} viewBox="0 0 24 24" fill="none" aria-hidden="true">
      {paths.map((d, i) => (
        <path key={i} d={d} stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" />
      ))}
    </svg>
  );
}

const Glyph = ({ name, size = 40 }) => (
  <div className="sx-glyph" style={{ width: size, height: size, borderRadius: 10, fontSize: size * 0.34, flex: 'none' }}>
    {initials(name)}
  </div>
);

/* ---- clearance chip (same 3-state vocabulary as pdp-v3 / browse-v3) ---- */
/* NOTE: duplicated from browse-v3.jsx — both files share this component.
   If you change ClearanceChip behavior, update BOTH files. */
function ClearanceChip({ fda_510k_primary }) {
  const k = (str(fda_510k_primary).match(/^(K\d{6})$/) || [])[1];
  if (k) return <span className="sx-clearance cited">FDA 510(k) {k}</span>;
  return <span className="sx-clearance none">no K-number on record</span>;
}

/* ================================================================
   Typeahead — dual-tier search: curated first, then generic, top 8
   ================================================================ */
function Typeahead({ curated, generic }) {
  const [q, setQ] = useState('');
  const [focused, setFocused] = useState(false);
  const inputRef = useRef(null);
  const wrapRef = useRef(null);

  /* close on outside click */
  useEffect(() => {
    const handler = e => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setFocused(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  const results = useMemo(() => {
    const term = q.trim().toLowerCase();
    if (!term) return [];
    const curatedHits = (curated || []).filter(s => matchesQuery(s, term)).map(s => ({ ...s, _tier: 'curated' }));
    const genericHits = (generic || []).filter(s => matchesQuery(s, term)).map(s => ({ ...s, _tier: 'generic' }));
    /* curated first, then generic, capped at 8 total */
    const combined = [];
    for (const s of curatedHits) { if (combined.length >= 8) break; combined.push(s); }
    for (const s of genericHits) { if (combined.length >= 8) break; combined.push(s); }
    return combined;
  }, [q, curated, generic]);

  const showDropdown = focused && q.trim().length > 0;

  const navigate = useCallback((slug) => {
    window.location.href = '/system/' + encodeURIComponent(slug);
  }, []);

  const goToBrowse = useCallback(() => {
    const term = q.trim();
    if (term) {
      window.location.href = '/browse?q=' + encodeURIComponent(term);
    } else {
      window.location.href = '/browse';
    }
  }, [q]);

  const onKeyDown = useCallback((e) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      goToBrowse();
    }
  }, [goToBrowse]);

  return (
    <div className="lx-typeahead" ref={wrapRef}>
      <input
        ref={inputRef}
        className="lx-typeahead-input"
        type="search"
        value={q}
        onChange={e => setQ(e.target.value)}
        onFocus={() => setFocused(true)}
        onKeyDown={onKeyDown}
        placeholder="Search systems, vendors, K-numbers..."
        aria-label="Search the dictionary"
      />
      {showDropdown ? (
        <div className="lx-typeahead-dropdown">
          {results.length > 0 ? (
            <>
              {results.map(s => (
                <button
                  key={s.slug}
                  className="lx-typeahead-row"
                  onClick={() => navigate(s.slug)}
                >
                  <span className="lx-ta-name">{s.display_name || s.slug}</span>
                  <span className="lx-ta-vendor">{normalizeVendor(s.vendor)}</span>
                  <span className={'sx-tier ' + (s._tier === 'curated' ? 'curated' : 'generic')}>
                    {s._tier === 'curated' ? 'curated · grounded' : 'FDA records only'}
                  </span>
                </button>
              ))}
              <button className="lx-typeahead-seeall" onClick={goToBrowse}>
                see all results for "{q.trim()}"
              </button>
            </>
          ) : (
            <div className="lx-typeahead-empty">
              no matches — <button className="lx-ta-link" onClick={goToBrowse}>browse the full dictionary</button>
            </div>
          )}
        </div>
      ) : null}
    </div>
  );
}

/* ================================================================
   Featured card (browse-card idiom, .sx-card + glyph + chips)
   ================================================================ */
/* NOTE: duplicated browse-card pattern from browse-v3.jsx.
   If you change the card layout, update BOTH files. */
function FeaturedCard({ slug, display_name, vendor, fda_510k_primary, has_audio }) {
  const name = display_name || slug;
  const vendorShort = normalizeVendor(vendor);
  return (
    <a href={'/system/' + encodeURIComponent(slug)} className="sx-card lx-featured-card">
      <Glyph name={name} size={38} />
      <div className="lx-fc-body">
        <div className="lx-fc-name">{name}</div>
        {vendorShort ? <div className="lx-fc-vendor">{vendorShort}</div> : null}
        <div className="lx-fc-chips">
          <span className="sx-tier curated">curated &middot; grounded</span>
          <ClearanceChip fda_510k_primary={fda_510k_primary} />
          {has_audio ? <span className="lx-fc-audio-badge mono">audio</span> : null}
        </div>
      </div>
    </a>
  );
}

/* ================================================================
   Root component
   ================================================================ */
function SurgxLandingV3Root() {
  /* fetch states — null = loading, false = failed */
  const [landing, setLanding] = useState(null);
  const [taxonomy, setTaxonomy] = useState(null);
  const [systems, setSystems] = useState(null);
  const [genericIndex, setGenericIndex] = useState(null);
  const [sampleErr, setSampleErr] = useState(false);

  /* independent fetches — each error-tolerant */
  useEffect(() => {
    fetch('/api/r2/landing')
      .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
      .then(setLanding)
      .catch(() => setLanding(false));

    fetch('/api/r2/taxonomy')
      .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
      .then(setTaxonomy)
      .catch(() => setTaxonomy(false));

    fetch('/api/r2/systems')
      .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
      .then(setSystems)
      .catch(() => setSystems(false));

    fetch('/api/r2/generic-index')
      .then(r => { if (!r.ok) return false; return r.json(); })
      .then(d => setGenericIndex(d || false))
      .catch(() => setGenericIndex(false));
  }, []);

  /* derived lists for typeahead */
  const curatedList = systems && systems.items ? systems.items : [];
  const genericList = genericIndex && genericIndex.items ? genericIndex.items : [];

  /* landing payload sub-objects */
  const stats = landing && landing.stats ? landing.stats : null;
  const featured = landing && landing.featured && landing.featured.length > 0 ? landing.featured : null;
  const sample = landing && landing.sample ? landing.sample : null;

  return (
    <div className="sxv3 sx sx-landing">
      <div className="lx-page">

        {/* ============================================================
            1. HERO
            ============================================================ */}
        <header className={'lx-hero' + (_heroParam === '3d' && taxonomy ? ' lx-hero3d-active' : '')}>
          <div className="lx-hero3d-text">
            <div className="lx-hero-brand">
              {/* official wordmark (Drew walk annotation 2026-06-10): content-bbox
                  crop + downscale of static/og/surgx-logo.png (alpha preserved) */}
              <img className="lx-hero-logo" src="/static/v2-mobile/surgx-logo-trim.png" alt="SurgX" />
            </div>
            <h1 className="lx-hero-tagline">Surgical supply, with receipts.</h1>
            <p className="lx-hero-subline">
              Look up any surgical system — components, trays, and role-specific audio briefings — with every claim tied to its source.
            </p>
            <Typeahead curated={curatedList} generic={genericList} />
            <div className="lx-hero-cta">
              <a href="/browse" className="sx-btn primary">Browse the dictionary</a>
            </div>
          </div>
          {_heroParam === '3d' ? <HeroConstellation taxonomy={taxonomy} /> : null}
        </header>

        {/* ============================================================
            2. SPECIALTY GRID
            ============================================================ */}
        {taxonomy && taxonomy.specialties && taxonomy.specialties.length > 0 ? (
          <section className="lx-section" id="specialties" aria-label="Specialties">
            <div className="lx-sec-head">
              <span className="sx-kicker">by specialty</span>
            </div>
            <div className="lx-specialty-grid">
              {taxonomy.specialties.map(s => (
                <a
                  key={s.slug}
                  href={'/browse?specialty=' + encodeURIComponent(s.slug)}
                  className="lx-specialty-tile sx-card"
                >
                  <SpecialtyGlyph slug={s.slug} />
                  <span className="lx-st-name">{s.display}</span>
                  <span className="lx-st-count">{s.count} {s.count === 1 ? 'system' : 'systems'}</span>
                </a>
              ))}
            </div>
          </section>
        ) : null}

        {/* ============================================================
            3. RECEIPTS BAND — numbers from /api/r2/landing stats only
            ============================================================ */}
        {stats ? (
          <section className="lx-section lx-receipts" aria-label="Coverage">
            <div className="lx-sec-head">
              <span className="sx-kicker">the receipts</span>
            </div>
            {/* every card links to a TRUE destination (Drew walk annotation).
                On-page anchors render as links only while their target section
                exists — degraded fetch states fall back to a plain card (no
                dead anchors; Bugbot catch on #1686). */}
            <div className="lx-receipts-grid">
              <a href="/browse?tier=curated" className="lx-receipt-card sx-card">
                <span className="lx-rc-num mono">{stats.curated_systems}</span>
                <span className="lx-rc-label">curated systems</span>
              </a>
              <a href="/browse" className="lx-receipt-card sx-card">
                <span className="lx-rc-num mono">{stats.total_systems}</span>
                <span className="lx-rc-label">systems indexed</span>
              </a>
              {(() => {
                const specialtiesExists = !!(taxonomy && taxonomy.specialties && taxonomy.specialties.length > 0);
                const Tag = specialtiesExists ? 'a' : 'div';
                return (
                  <Tag {...(specialtiesExists ? { href: '#specialties' } : {})} className="lx-receipt-card sx-card">
                    <span className="lx-rc-num mono">{stats.specialties}</span>
                    <span className="lx-rc-label">specialties</span>
                  </Tag>
                );
              })()}
              {stats.audio_tracks > 0 && stats.systems_with_audio > 0 ? (
                (() => {
                  const educationExists = !sampleErr;
                  const Tag = educationExists ? 'a' : 'div';
                  return (
                    <Tag {...(educationExists ? { href: '#education' } : {})} className="lx-receipt-card sx-card">
                      <span className="lx-rc-num mono">{stats.audio_tracks}</span>
                      <span className="lx-rc-label">role-targeted audio tracks across {stats.systems_with_audio} systems</span>
                    </Tag>
                  );
                })()
              ) : null}
              <a href="#grounding" className="lx-receipt-card sx-card lx-receipt-statement">
                <span className="lx-rc-label">every premarket citation verified against openFDA</span>
              </a>
            </div>
          </section>
        ) : null}

        {/* ============================================================
            4. FEATURED ROW
            ============================================================ */}
        {featured ? (
          <section className="lx-section" aria-label="Featured systems">
            <div className="lx-sec-head">
              <span className="sx-kicker">featured systems</span>
            </div>
            <div className="lx-featured-grid">
              {featured.map(s => (
                <FeaturedCard
                  key={s.slug}
                  slug={s.slug}
                  display_name={s.display_name}
                  vendor={s.vendor}
                  fda_510k_primary={s.fda_510k_primary}
                  has_audio={s.has_audio}
                />
              ))}
            </div>
          </section>
        ) : null}

        {/* ============================================================
            5. EDUCATION HOOK — role-targeted audio
            ============================================================ */}
        {(sample || (stats && stats.audio_tracks)) && !sampleErr ? (
          <section className="lx-section lx-education" id="education" aria-label="Audio">
            <div className="lx-sec-head">
              <span className="sx-kicker">role-targeted audio</span>
            </div>
            <p className="lx-edu-line">
              A system can carry separate audio briefings — one for the surgeon, another for the circulating nurse, the CST, the first assist. The version you hear is the one made for your role.
            </p>
            {sample ? (
              <div className="lx-sample-player sx-card">
                <div className="lx-sp-title mono">{sample.title}</div>
                <audio
                  controls
                  preload="metadata"
                  src={sample.url}
                  onError={() => setSampleErr(true)}
                >
                  Your browser does not support the audio element.
                </audio>
              </div>
            ) : null}
          </section>
        ) : null}

        {/* ============================================================
            6. GROUNDING STRIP
            ============================================================ */}
        <section className="lx-section lx-grounding" id="grounding" aria-label="Grounding principles">
          <div className="lx-sec-head">
            <span className="sx-kicker">how this is built</span>
          </div>
          <div className="lx-grounding-grid">
            <div className="lx-ground-card sx-card">
              <div className="lx-gc-title">FDA records first</div>
              <div className="lx-gc-body">
                Profiles anchor to FDA premarket records — 510(k), PMA, De Novo — wherever one exists, and every cited record is verified against openFDA. Marketing copy is not a source. Systems with no premarket record on file say so.
              </div>
            </div>
            <div className="lx-ground-card sx-card">
              <div className="lx-gc-title">Source documents linked on every page</div>
              <div className="lx-gc-body">
                Where a fact came from is shown alongside the fact. Cited K-numbers link to the FDA record; gaps are labeled as gaps.
              </div>
            </div>
            <div className="lx-ground-card sx-card">
              <div className="lx-gc-title">Missing is shown as missing</div>
              <div className="lx-gc-body">
                If a field has no verified source, it says so. Nothing is invented to fill a blank.
              </div>
            </div>
          </div>
        </section>

        {/* ============================================================
            7. FOOTER
            ============================================================ */}
        <footer className="lx-footer">
          <a href="/browse" className="sx-btn quiet sm">Browse the dictionary</a>
          <a href="/?design=v2" className="sx-btn quiet sm">previous design</a>
        </footer>

      </div>
    </div>
  );
}

window.SurgxLandingV3Root = SurgxLandingV3Root;
// Mount inside the transpiled script (Babel-race pattern: a separate
// DOMContentLoaded mount blanks the page — keep this inline mount).
ReactDOM.createRoot(document.getElementById('root')).render(<SurgxLandingV3Root />);
})();
