// NoMind — landing page sections (evaluation + governance positioning)
const { useState, useEffect: useEffectSections, useRef: useRefSections } = React;

function Eyebrow({ num, children }) {
  return (
    <div className="eyebrow">
      {num && <span className="eyebrow-num">{num}</span>}
      <span className="eyebrow-line" />
      <span className="eyebrow-text">{children}</span>
    </div>
  );
}

function MathBlock({ children }) {
  return <div className="math-block">{children}</div>;
}

function DiagramPlate({ eyebrow, title, src, alt }) {
  return (
    <figure className="nm-diagram-plate">
      <figcaption>
        <span className="mono-label">{eyebrow}</span>
        <strong>{title}</strong>
      </figcaption>
      <img src={src} alt={alt || title} />
    </figure>
  );
}

function getAnalyticsContext() {
  const params = new URLSearchParams(window.location.search);
  const utm = {};
  ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'].forEach(key => {
    const value = params.get(key);
    if (value) utm[key] = value;
  });

  const posthog = window.posthog;
  let distinctId = '';
  let sessionId = '';
  let deviceId = '';
  try { distinctId = posthog?.get_distinct_id?.() || ''; } catch (_) {}
  try { sessionId = posthog?.get_session_id?.() || posthog?.get_property?.('$session_id') || ''; } catch (_) {}
  try { deviceId = posthog?.get_property?.('$device_id') || ''; } catch (_) {}

  return {
    provider: 'posthog',
    distinctId,
    sessionId,
    deviceId,
    currentUrl: window.location.href,
    pathname: window.location.pathname,
    referrer: document.referrer || '',
    title: document.title,
    utm,
    viewport: {
      width: window.innerWidth,
      height: window.innerHeight,
    },
  };
}

function ParticleDissolve({ active }) {
  const canvasRef = useRefSections(null);

  useEffectSections(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    let frame;

    const resize = () => {
      const rect = canvas.getBoundingClientRect();
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      canvas.width = Math.max(1, Math.floor(rect.width * dpr));
      canvas.height = Math.max(1, Math.floor(rect.height * dpr));
      return { rect, dpr };
    };

    const { rect, dpr } = resize();
    if (!active) return;

    const sampleFormulaPixels = () => {
      const card = canvas.closest('.math-card');
      const stage = canvas.closest('.math-card-stage');
      const svg = card?.querySelector('.math-face-formula svg');
      if (!stage || !svg) return null;
      try {
        const stageRect = stage.getBoundingClientRect();
        const svgRect = svg.getBoundingClientRect();
        const xml = new XMLSerializer().serializeToString(svg);
        const img = new Image();
        const url = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(xml);
        return new Promise((resolve) => {
          img.onload = () => {
            const off = document.createElement('canvas');
            off.width = Math.max(1, Math.ceil(svgRect.width * dpr));
            off.height = Math.max(1, Math.ceil(svgRect.height * dpr));
            const octx = off.getContext('2d');
            octx.drawImage(img, 0, 0, off.width, off.height);
            URL.revokeObjectURL(url);
            const image = octx.getImageData(0, 0, off.width, off.height).data;
            const points = [];
            const step = Math.max(2, Math.floor(3 * dpr));
            for (let y = 0; y < off.height; y += step) {
              for (let x = 0; x < off.width; x += step) {
                const a = image[(y * off.width + x) * 4 + 3];
                if (a > 24 && Math.random() > 0.08) {
                  points.push({
                    x: (svgRect.left - stageRect.left) + x / dpr,
                    y: (svgRect.top - stageRect.top) + y / dpr,
                    a: a / 255,
                  });
                }
              }
            }
            resolve(points.length ? points : null);
          };
          img.onerror = () => resolve(null);
          img.src = url;
        });
      } catch (_) {
        return null;
      }
    };

    const hexToRgb = (value, fallback) => {
      const hex = value.trim().match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
      if (!hex) return fallback;
      return [parseInt(hex[1], 16) / 255, parseInt(hex[2], 16) / 255, parseInt(hex[3], 16) / 255];
    };

    const styles = getComputedStyle(document.documentElement);
    const colors = [
      hexToRgb(styles.getPropertyValue('--accent') || '#8aa38f', [0.54, 0.64, 0.56]),
      hexToRgb(styles.getPropertyValue('--ink') || '#151515', [0.08, 0.08, 0.08]),
      hexToRgb(styles.getPropertyValue('--accent-ink') || '#005a3b', [0, 0.35, 0.23]),
    ];

    let cancelled = false;
    let cleanup = () => {};

    Promise.resolve(sampleFormulaPixels()).then((sourcePoints) => {
      if (cancelled) return;

      const makeSource = (i, count) => sourcePoints?.[i % sourcePoints.length] || {
        x: rect.width * (0.08 + Math.random() * 0.26),
        y: rect.height * (0.2 + Math.random() * 0.5),
        a: 1,
      };

      if (window.THREE) {
        const THREE = window.THREE;
        const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true, premultipliedAlpha: false });
        renderer.setPixelRatio(dpr);
        renderer.setSize(rect.width, rect.height, false);
        renderer.setClearColor(0x000000, 0);

        const scene = new THREE.Scene();
        const camera = new THREE.OrthographicCamera(0, rect.width, rect.height, 0, -1, 1);
        const count = sourcePoints ? Math.min(Math.max(sourcePoints.length, 420), 1600) : 640;
        const positions = new Float32Array(count * 3);
        const velocities = new Float32Array(count * 2);
        const life = new Float32Array(count);
        const size = new Float32Array(count);
        const colorIndex = new Float32Array(count);
        const seed = new Float32Array(count);
        for (let i = 0; i < count; i++) {
          const s = makeSource(i, count);
          positions[i * 3 + 0] = s.x;
          positions[i * 3 + 1] = s.y;
          positions[i * 3 + 2] = 0;
          velocities[i * 2 + 0] = rect.width * (0.08 + Math.random() * 0.24) * (Math.random() > 0.5 ? 1 : 0.65);
          velocities[i * 2 + 1] = (Math.random() - 0.5) * 128;
          life[i] = 0.82 + Math.random() * 0.28;
          size[i] = (1.1 + Math.random() * 3.2) * dpr * (0.8 + s.a * 0.5);
          colorIndex[i] = i % 3;
          seed[i] = Math.random();
        }

        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
        geometry.setAttribute('a_velocity', new THREE.BufferAttribute(velocities, 2));
        geometry.setAttribute('a_life', new THREE.BufferAttribute(life, 1));
        geometry.setAttribute('a_size', new THREE.BufferAttribute(size, 1));
        geometry.setAttribute('a_color', new THREE.BufferAttribute(colorIndex, 1));
        geometry.setAttribute('a_seed', new THREE.BufferAttribute(seed, 1));

        const material = new THREE.ShaderMaterial({
          transparent: true,
          depthTest: false,
          uniforms: {
            u_time: { value: 0 },
            u_color0: { value: new THREE.Color(colors[0][0], colors[0][1], colors[0][2]) },
            u_color1: { value: new THREE.Color(colors[1][0], colors[1][1], colors[1][2]) },
            u_color2: { value: new THREE.Color(colors[2][0], colors[2][1], colors[2][2]) },
          },
          vertexShader: `
            attribute vec2 a_velocity;
            attribute float a_life;
            attribute float a_size;
            attribute float a_color;
            attribute float a_seed;
            uniform float u_time;
            varying float v_alpha;
            varying float v_color;
            float easeOutCubic(float x) { return 1.0 - pow(1.0 - x, 3.0); }
            void main() {
              float u = clamp(u_time / a_life, 0.0, 1.0);
              float ease = easeOutCubic(u);
              vec2 swirl = vec2(sin(u * 18.0 + a_seed * 6.283), cos(u * 15.0 + a_seed * 4.1)) * 13.0 * ease;
              vec3 displaced = position + vec3(a_velocity * u_time * ease + swirl + vec2(0.0, -22.0 * ease), 0.0);
              gl_Position = projectionMatrix * modelViewMatrix * vec4(displaced, 1.0);
              gl_PointSize = a_size * (1.0 - 0.58 * u);
              v_alpha = pow(1.0 - u, 1.32);
              v_color = a_color;
            }
          `,
          fragmentShader: `
            precision mediump float;
            uniform vec3 u_color0;
            uniform vec3 u_color1;
            uniform vec3 u_color2;
            varying float v_alpha;
            varying float v_color;
            void main() {
              vec2 p = gl_PointCoord - vec2(0.5);
              float d = length(p);
              float soft = smoothstep(0.5, 0.18, d);
              vec3 color = mix(u_color0, u_color1, step(0.5, v_color));
              color = mix(color, u_color2, step(1.5, v_color));
              gl_FragColor = vec4(color, soft * v_alpha * 0.86);
            }
          `,
        });
        const points = new THREE.Points(geometry, material);
        scene.add(points);
        const start = performance.now();
        const drawThree = (now) => {
          const t = Math.min((now - start) / 1000, 1.15);
          material.uniforms.u_time.value = t;
          renderer.render(scene, camera);
          if (t < 1.15) frame = requestAnimationFrame(drawThree);
        };
        frame = requestAnimationFrame(drawThree);
        cleanup = () => {
          cancelAnimationFrame(frame);
          geometry.dispose();
          material.dispose();
          renderer.dispose();
        };
        return;
      }

      const gl = canvas.getContext('webgl', { alpha: true, antialias: true, premultipliedAlpha: false });

      // Fallback for older browsers: same true glyph-source dissolve when sampling works.
      if (!gl) {
        const ctx = canvas.getContext('2d');
        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
        const particles = Array.from({ length: sourcePoints ? Math.min(sourcePoints.length, 520) : 180 }, (_, i) => {
          const s = makeSource(i, sourcePoints ? sourcePoints.length : 180);
          return ({
        x: s.x,
        y: s.y,
        vx: rect.width * (0.004 + Math.random() * 0.011),
        vy: (Math.random() - 0.5) * 1.8,
        r: 0.8 + Math.random() * 2.2,
        delay: (i / (sourcePoints?.length || 180)) * 220 + Math.random() * 120,
        life: 520 + Math.random() * 360,
        color: ['#8aa38f', '#151515', '#005a3b'][i % 3],
          });
        });
      const start = performance.now();
      const draw2d = (now) => {
        const t = now - start;
        ctx.clearRect(0, 0, rect.width, rect.height);
        for (const p of particles) {
          const local = t - p.delay;
          if (local <= 0 || local >= p.life) continue;
          const u = local / p.life;
          ctx.globalAlpha = Math.sin(Math.PI * u) * 0.72;
          ctx.fillStyle = p.color;
          ctx.beginPath();
          ctx.arc(p.x + p.vx * local, p.y + p.vy * local - u * 18, p.r, 0, Math.PI * 2);
          ctx.fill();
        }
        ctx.globalAlpha = 1;
        if (t < 1050) frame = requestAnimationFrame(draw2d);
      };
      frame = requestAnimationFrame(draw2d);
        cleanup = () => { cancelAnimationFrame(frame); ctx.clearRect(0, 0, rect.width, rect.height); };
        return;
      }

    const vertex = `
      attribute vec2 a_origin;
      attribute vec2 a_velocity;
        attribute float a_life;
        attribute float a_size;
        attribute float a_color;
        attribute float a_seed;
        uniform float u_time;
        uniform vec2 u_resolution;
        varying float v_alpha;
        varying float v_color;
        float easeOutCubic(float x) { return 1.0 - pow(1.0 - x, 3.0); }
        void main() {
        float u = clamp(u_time / a_life, 0.0, 1.0);
        float ease = easeOutCubic(u);
        vec2 swirl = vec2(sin(u * 18.0 + a_seed * 6.283), cos(u * 15.0 + a_seed * 4.1)) * 12.0 * ease;
        vec2 pos = a_origin + a_velocity * u_time * ease + swirl + vec2(0.0, -22.0 * ease);
        vec2 clip = (pos / u_resolution) * 2.0 - 1.0;
        gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);
        gl_PointSize = a_size * (1.0 - 0.55 * u);
        v_alpha = pow(1.0 - u, 1.35);
        v_color = a_color;
      }
    `;
    const fragment = `
      precision mediump float;
      uniform vec3 u_color0;
      uniform vec3 u_color1;
      uniform vec3 u_color2;
      varying float v_alpha;
      varying float v_color;
      void main() {
        vec2 p = gl_PointCoord - vec2(0.5);
        float d = length(p);
        float soft = smoothstep(0.5, 0.18, d);
        vec3 color = mix(u_color0, u_color1, step(0.5, v_color));
        color = mix(color, u_color2, step(1.5, v_color));
        gl_FragColor = vec4(color, soft * v_alpha * 0.82);
      }
    `;

    const compile = (type, source) => {
      const shader = gl.createShader(type);
      gl.shaderSource(shader, source);
      gl.compileShader(shader);
      return shader;
    };
    const program = gl.createProgram();
    gl.attachShader(program, compile(gl.VERTEX_SHADER, vertex));
    gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fragment));
    gl.linkProgram(program);
    gl.useProgram(program);

    const count = sourcePoints ? Math.min(Math.max(sourcePoints.length, 360), 1400) : 520;
    const stride = 8;
    const data = new Float32Array(count * stride);
    for (let i = 0; i < count; i++) {
      const base = i * stride;
      const band = i / count;
      const source = makeSource(i, count);
      data[base + 0] = source.x;
      data[base + 1] = source.y;
      data[base + 2] = rect.width * (0.08 + Math.random() * 0.24) * (0.75 + band * 0.5);
      data[base + 3] = (Math.random() - 0.5) * 120;
      data[base + 4] = 820 + Math.random() * 260;
      data[base + 5] = (1.05 + Math.random() * 2.8) * dpr * (0.8 + source.a * 0.5);
      data[base + 6] = i % 3;
      data[base + 7] = Math.random();
    }

    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
    const attrs = [
      ['a_origin', 2, 0], ['a_velocity', 2, 2], ['a_life', 1, 4],
      ['a_size', 1, 5], ['a_color', 1, 6], ['a_seed', 1, 7],
    ];
    attrs.forEach(([name, size, offset]) => {
      const loc = gl.getAttribLocation(program, name);
      gl.enableVertexAttribArray(loc);
      gl.vertexAttribPointer(loc, size, gl.FLOAT, false, stride * 4, offset * 4);
    });

    gl.uniform2f(gl.getUniformLocation(program, 'u_resolution'), canvas.width, canvas.height);
    gl.uniform3fv(gl.getUniformLocation(program, 'u_color0'), colors[0]);
    gl.uniform3fv(gl.getUniformLocation(program, 'u_color1'), colors[1]);
    gl.uniform3fv(gl.getUniformLocation(program, 'u_color2'), colors[2]);
    const timeLoc = gl.getUniformLocation(program, 'u_time');
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(0, 0, 0, 0);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

    const start = performance.now();
    const draw = (now) => {
      const t = now - start;
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.uniform1f(timeLoc, t);
      gl.drawArrays(gl.POINTS, 0, count);
      if (t < 1050) frame = requestAnimationFrame(draw);
    };
    frame = requestAnimationFrame(draw);
      cleanup = () => {
      cancelAnimationFrame(frame);
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.deleteBuffer(buffer);
      gl.deleteProgram(program);
      };
    });

    return () => {
      cancelled = true;
      cleanup();
    };
  }, [active]);

  return <canvas className="particle-canvas" ref={canvasRef} aria-hidden="true" />;
}

function MathCard({ metric }) {
  const [active, setActive] = useState(false);
  return (
    <div
      className={`math-card ${active ? 'is-dissolving' : ''}`}
      onMouseEnter={() => setActive(true)}
      onMouseLeave={() => setActive(false)}
      onFocus={() => setActive(true)}
      onBlur={() => setActive(false)}
      tabIndex="0"
    >
      <div className="math-card-label">{metric.k}</div>
      <div className="math-card-stage">
        <div className="math-face math-face-formula"><MathBlock>{metric.v}</MathBlock></div>
        <div className="math-face math-face-solution">{metric.solution}</div>
        <ParticleDissolve active={active} />
      </div>
    </div>
  );
}

function Nav({ onContact }) {
  return (
    <nav className="nm-nav">
      <div className="nm-wordmark">
        <img className="nm-logo-img nm-logo-wordmark" src="assets/logo-wordmark.png?v=2" alt="NoMind" />
      </div>
      <div className="nm-navlinks">
        <a href="#thesis">Thesis</a>
        <a href="#pilot-theater">Why now</a>
        <a href="#systems">Decision economics</a>
        <a href="#offer">The map</a>
        <a href="#working-models">Ways to work</a>
      </div>
      <button className="nm-navcta" onClick={onContact}>
        <span>Start a conversation</span>
        <span className="nm-navcta-arrow">↗</span>
      </button>
    </nav>
  );
}

function Hero() {
  return (
    <header className="nm-hero" data-screen-label="01 Hero">
      <div className="nm-hero-meta">
        <Eyebrow num="00">Index</Eyebrow>
        <div className="nm-hero-coord">
          <span>Fractional CTO</span><span>·</span><span>AI strategy</span><span>·</span><span>Technical diligence</span><span>·</span><span>Rev. 08 — 2026</span>
        </div>
      </div>

      <h1 className="nm-display">
        <span className="nm-display-line">Complexity should be calm.</span>
      </h1>

      <div className="nm-hero-foot">
        <p className="nm-lead">
          NoMind brings CTO-grade judgment to AI and software decisions, helping founders see clearly, move deliberately, and build systems that hold up.
        </p>
        <div className="nm-hero-ctas">
          <a href="#contact" className="btn btn-primary">
            <span>Start a conversation</span>
            <span className="btn-arrow">→</span>
          </a>
        </div>
      </div>

      <div className="nm-hero-ledger">
        <div><span className="mono-label">Focus</span><span>Fractional CTO · AI strategy · technical diligence</span></div>
        <div><span className="mono-label">Best fit</span><span>Founders · growing teams · services · healthcare · operations-heavy firms</span></div>
        <div><span className="mono-label">Paths</span><span>Opportunity map · architecture review · implementation advisory</span></div>
      </div>
    </header>
  );
}

function What() {
  return (
    <section id="thesis" className="nm-section" data-screen-label="02 Thesis">
      <div className="nm-section-head">
        <Eyebrow num="01">The thesis</Eyebrow>
        <h2 className="nm-h2">
          The hard part is no longer believing AI matters.<br/>
          <span className="dim">It is making the decisions that determine whether AI becomes leverage, risk, or expensive theater.</span>
        </h2>
      </div>

      <div className="nm-thesis-grid">
        <div className="nm-thesis-col">
          <div className="nm-tc-label"><span className="mono-label">A.</span><span>The gap</span></div>
          <p className="nm-body">
            Leadership can see the urgency, but the decision space is noisy: vendors oversell, internal teams chase demos, and nobody has a durable way to decide where AI belongs.
          </p>
        </div>

        <div className="nm-thesis-col">
          <div className="nm-tc-label"><span className="mono-label">B.</span><span>The failure mode</span></div>
          <p className="nm-body">
            Companies either underinvest because ownership is fuzzy, or overcommit to tools, hires, and pilots before they understand workflow value, data readiness, governance needs, and operating cost.
          </p>
        </div>

        <div className="nm-thesis-col">
          <div className="nm-tc-label"><span className="mono-label">C.</span><span>Our role</span></div>
          <p className="nm-body">
            We help leaders make those decisions with the right level of engagement: a focused opportunity map, ongoing fractional advisory, or implementation oversight as AI moves toward production.
          </p>
        </div>
      </div>

      <DiagramPlate
        eyebrow="Failure journey"
        title="What breaks between pilot and production"
        src="assets/diagrams/pilot-production-failure-map.png"
        alt="Journey diagram showing Demo, Pilot, Workflow, and Production decision stages where technical and operating failure modes accumulate before launch, supervision, or block decisions."
      />
    </section>
  );
}

function Transformation() {
  const rows = [
    { k: 'Pressure without ownership', v: 'Boards, customers, and competitors are forcing AI conversations before most organizations know who should own the roadmap.' },
    { k: 'Vendor-first decisions', v: 'Tool selection happens too early, before leaders know which workflows are valuable, feasible, safe, and economically sensible.' },
    { k: 'Hidden readiness gaps', v: 'The blockers are usually operational: messy handoffs, undocumented judgment, fragmented data, unclear review boundaries, and weak accountability.' },
    { k: 'Expensive false starts', v: 'A few unfocused pilots can burn months, create political scar tissue, and still leave leadership without a deployable operating plan.' },
  ];
  return (
    <section id="pilot-theater" className="nm-section nm-section-inset" data-screen-label="03 Pilot Theater">
      <div className="nm-section-head">
        <Eyebrow num="02">Why now</Eyebrow>
        <h2 className="nm-h2">
          Most organizations do not need another AI brainstorm. They need a way to decide what should launch, what needs supervision, and what should be blocked.
        </h2>
      </div>
      <div className="nm-table">
        {rows.map((r, i) => (
          <div className="nm-row" key={r.k}>
            <div className="nm-row-num">0{i+1}</div>
            <div className="nm-row-k">{r.k}</div>
            <div className="nm-row-v">{r.v}</div>
          </div>
        ))}
      </div>

      <DiagramPlate
        eyebrow="Readiness gates"
        title="What must be true before automation acts"
        src="assets/diagrams/workflow-risk-gates.png"
        alt="Minimal diagram showing a use case passing through context budget, routing decision, latency tolerance, failure mode, and governance audit gates before launch, supervision, or block decisions."
      />
    </section>
  );
}

function Systems() {
  const metrics = [
    {
      k: 'Amortized context cost',
      v: '\\[C_{req} = (1-h_{cache})C_{prefill}(T_{ctx}) + C_{decode}(T_{out}) + C_{tools}\\]',
      solution: 'Design context like a cache hierarchy: keep stable policy and workflow memory reusable, retrieve only what changes, and avoid paying the prefill tax on every request.'
    },
    {
      k: 'Latency budget',
      v: '\\[L_{e2e} \\approx L_{queue}(B) + L_{prefill}(T_{ctx}) + T_{out}/r_{decode} + L_{tools} + L_{retry}\\]',
      solution: 'Set latency budgets before architecture decisions: batch where throughput matters, stream where users wait, and move validation off the critical path when safe.'
    },
    {
      k: 'API bill at scale',
      v: '\\[Bill = N_{workflows} \\sum_j n_j(p^{in}_jT^{in}_j + p^{out}_jT^{out}_j)(1+r_j)\\]',
      solution: 'Model the bill per completed workflow, not per prompt. Retries, validators, tool loops, and long outputs are where demo economics quietly explode.'
    },
  ];
  return (
    <section id="systems" className="nm-section" data-screen-label="04 Systems Economics">
      <div className="nm-section-head">
        <Eyebrow num="03">Decision economics</Eyebrow>
        <h2 className="nm-h2">
          Production AI is an operating and economic system, not a tool shopping list.
        </h2>
      </div>
      <div className="nm-thesis-grid nm-systems-grid">
        <div className="nm-thesis-col">
          <div className="nm-tc-label"><span className="mono-label">Memory</span><span>Context is not free</span></div>
          <p className="nm-body">
            Good AI operating judgment identifies where institutional knowledge lives, what context is reusable, what data is missing, and which workflows can tolerate automation versus assistance.
          </p>
        </div>
        <div className="nm-thesis-col">
          <div className="nm-tc-label"><span className="mono-label">Compute</span><span>Inference multiplies</span></div>
          <p className="nm-body">
            AI cost is not just token price. It is retries, review queues, vendor lock-in, workflow redesign, enablement, and the cost of putting automation in the wrong part of the business.
          </p>
        </div>
        <div className="nm-thesis-col">
          <div className="nm-tc-label"><span className="mono-label">Economics</span><span>The roadmap is a capital allocation decision</span></div>
          <DiagramPlate
            eyebrow="Cost fanout"
            title="Where agent workflows multiply cost"
            src="assets/diagrams/agent-cost-fanout.png"
            alt="Minimal diagram showing where agent workflows multiply cost through planning, retrieval load, tool-use risk, validation, failure handling, and review burden."
          />
          <div className="math-stack">
            {metrics.map((m) => <MathCard metric={m} key={m.k} />)}
          </div>
        </div>
      </div>
    </section>
  );
}

function Offer() {
  const models = [
    {
      k: 'AI Opportunity Map',
      tag: 'Start here',
      summary: 'A 2–3 week diagnostic for leaders who need clarity before serious spend.',
      bestFor: 'You know AI matters, but need to decide where it belongs before hiring, buying, or launching pilots.',
      outcome: 'A ranked opportunity map, build / buy / block recommendations, readiness gaps, and a 90-day roadmap.',
      includes: [
        'Workflow interviews and opportunity scan',
        'Value, feasibility, risk, and owner model by use case',
        'Vendor and internal idea pressure-test',
        'Executive decision memo and 90-day action plan',
      ]
    },
    {
      k: 'Fractional AI Advisor',
      tag: 'Ongoing judgment',
      summary: 'Senior AI and CTO judgment for teams with momentum but no durable AI owner.',
      bestFor: 'You have projects, vendors, or internal teams moving already, but need sharper technical and strategic oversight.',
      outcome: 'A practical operating cadence for AI decisions: roadmap pressure-testing, architecture review, governance design, and executive support.',
      includes: [
        'Recurring executive advisory and technical review',
        'Vendor diligence and roadmap pressure-testing',
        'Governance, ownership, and risk boundary design',
        'Hiring, team shape, and capability-building guidance',
      ]
    },
    {
      k: 'Implementation Oversight',
      tag: 'Make it real',
      summary: 'Guidance from opportunity map to shipped capability without turning the work into staff augmentation.',
      bestFor: 'You have a validated direction and need pilots scoped, evals defined, architecture reviewed, and collaborators coordinated.',
      outcome: 'A governed path from plan to production-ready capability, with readiness gates before automation touches consequential work.',
      includes: [
        'Pilot scoping and evaluation design',
        'Architecture, workflow, and data-readiness review',
        'Specialist collaborator coordination where needed',
        'Launch gates for cost, risk, review, and ownership',
      ]
    },
  ];
  const [selected, setSelected] = useState(0);
  const active = models[selected];

  return (
    <section id="offer" className="nm-section nm-section-inset" data-screen-label="05 Ways to Work">
      <div className="nm-section-head">
        <Eyebrow num="04">Ways to work together</Eyebrow>
        <h2 className="nm-h2">
          Pick the relationship that matches the decision in front of you.<br/>
          <span className="dim">Map the opportunity, add senior judgment, or guide implementation toward production.</span>
        </h2>
      </div>

      <div className="nm-work-options" role="tablist" aria-label="Ways to work with NoMind">
        {models.map((m, i) => (
          <button
            className={`nm-work-option ${selected === i ? 'is-selected' : ''}`}
            type="button"
            role="tab"
            aria-selected={selected === i}
            aria-controls="work-model-detail"
            key={m.k}
            onClick={() => setSelected(i)}
          >
            <span className="nm-work-num mono-label">{String(i+1).padStart(2,'0')} · {m.tag}</span>
            <span className="nm-work-title">{m.k}</span>
            <span className="nm-work-summary">{m.summary}</span>
          </button>
        ))}
      </div>

      <div className="nm-work-detail" id="work-model-detail" role="tabpanel">
        <div className="nm-work-detail-main">
          <div className="nm-tc-label"><span className="mono-label">Selected</span><span>{active.k}</span></div>
          <p className="nm-work-detail-lead">{active.summary}</p>
          <div className="nm-work-detail-grid">
            <div>
              <div className="nm-work-detail-label mono-label">Best for</div>
              <p className="nm-body">{active.bestFor}</p>
            </div>
            <div>
              <div className="nm-work-detail-label mono-label">Outcome</div>
              <p className="nm-body">{active.outcome}</p>
            </div>
          </div>
        </div>
        <div className="nm-work-detail-side">
          <div className="nm-work-detail-label mono-label">What it includes</div>
          <ul className="nm-list">
            {active.includes.map((item) => <li key={item}><span>{item}</span></li>)}
          </ul>
        </div>
      </div>
    </section>
  );
}

function Founder() {
  const founderUrl = 'https://www.linkedin.com/in/christopherbun/';
  return (
    <section id="founder" className="nm-section nm-founder" data-screen-label="06 Founder">
      <div className="nm-founder-grid">
        <div>
          <Eyebrow num="05">Who is behind it</Eyebrow>
          <h2 className="nm-h2">
            Senior AI judgment,<br/>
            <span className="dim">not another vendor pitch.</span>
          </h2>
        </div>
        <div className="nm-founder-copy">
          <p className="nm-founder-lead">
            NoMind is led by <a className="nm-founder-link" href={founderUrl} target="_blank" rel="noopener noreferrer">Chris Bun</a>, a PhD machine learning scientist and former CTO who has spent his career turning ambiguous technical possibility into working systems.
          </p>
          <p className="nm-body">
            He works with leaders who need judgment across AI strategy, architecture, workflow design, and production risk — the parts that decide whether a promising pilot becomes operational leverage or expensive theater.
          </p>
        </div>
      </div>
    </section>
  );
}

function Contact() {
  const CONTACT_EMAIL = 'hello@nomind.systems';
  const [status, setStatus] = useState('idle');
  const [error, setError] = useState('');
  const [form, setForm] = useState({
    projectType: [],
    stage: '',
    constraint: [],
    email: '',
    note: '',
  });

  const projectTypes = [
    'AI Opportunity Map',
    'Fractional AI Advisor',
    'Implementation Oversight',
    'Not sure yet',
  ];
  const stages = [
    'AI is on the agenda',
    'Evaluating vendors / tools',
    'Running pilots',
    'Scaling across org',
  ];
  const constraints = [
    'Where to start',
    'Workflow fit',
    'Data / systems readiness',
    'Risk / governance',
    'Economics / ROI',
    'Ownership / staffing',
  ];

  const update = (key, value) => {
    setStatus('idle');
    setError('');
    setForm(prev => ({ ...prev, [key]: value }));
  };

  const toggle = (field, option) => {
    setStatus('idle');
    setError('');
    setForm(prev => {
      const current = prev[field];
      const next = current.includes(option)
        ? current.filter(item => item !== option)
        : [...current, option];
      return { ...prev, [field]: next };
    });
  };

  const OptionGroup = ({ num, label, field, options, multiple = false }) => (
    <div className="field field-full option-field" role="group" aria-label={label}>
      <div className="option-heading">
        <span className="mono-label">{num} · {label}</span>
        {multiple && <span className="option-hint">Select all that apply</span>}
      </div>
      <div className="option-grid">
        {options.map(option => {
          const selected = multiple ? form[field].includes(option) : form[field] === option;
          return (
            <label key={option} className={`choice ${selected ? 'selected' : ''}`}>
              <input
                type={multiple ? 'checkbox' : 'radio'}
                name={field}
                value={option}
                checked={selected}
                onChange={() => multiple ? toggle(field, option) : update(field, option)}

              />
              <span>{option}</span>
            </label>
          );
        })}
      </div>
    </div>
  );

  const submit = async (e) => {
    e.preventDefault();
    setStatus('sending');
    setError('');

    const analytics = getAnalyticsContext();
    const payload = {
      ...form,
      source: 'nomind-site',
      submittedAt: new Date().toISOString(),
      analytics,
    };

    try {
      window.posthog?.capture?.('diagnostic_request_submitted', {
        source: 'nomind-site',
        work_model: form.projectType,
        stage: form.stage,
        constraint: form.constraint,
        has_note: Boolean(form.note.trim()),
        form_version: 'work-model-v1',
      });
    } catch (_) {}

    try {
      const response = await fetch('/api/contact', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (!response.ok) throw new Error('request failed');
      setStatus('sent');
      setForm({ projectType: [], stage: '', constraint: [], email: '', note: '' });
    } catch (_) {
      setStatus('idle');
      setError(`This local preview is not connected yet. Email ${CONTACT_EMAIL} and include what you’re working on.`);
    }
  };

  return (
    <section id="contact" className="nm-section nm-contact" data-screen-label="07 Contact">
      <div className="nm-contact-head">
        <Eyebrow num="06">Start here</Eyebrow>
        <h2 className="nm-h2">
          Tell us where AI pressure is showing up.
        </h2>
      </div>

      <form className="nm-form diagnostic-form" onSubmit={submit}>
        <OptionGroup num="01" label="How do you want to work together?" field="projectType" options={projectTypes} multiple />
        <OptionGroup num="02" label="Where are you now?" field="stage" options={stages} />
        <OptionGroup num="03" label="What is the main constraint?" field="constraint" options={constraints} multiple />

        <label className="field">
          <span className="mono-label">04 · Email</span>
          <input
            type="email"
            required
            placeholder="you@company.com"
            value={form.email}
            onChange={(e) => update('email', e.target.value)}
          />
        </label>
        <label className="field">
          <span className="mono-label">05 · Optional context</span>
          <textarea
            rows="3"
            placeholder=""
            value={form.note}
            onChange={(e) => update('note', e.target.value)}
          />
        </label>

        <div className="nm-form-foot">
          <div className="nm-form-note">
            {(status === 'sent' || error) && <span className="dot" />}
            <span>
              {status === 'sent'
                ? `Received. We’ll reply from ${CONTACT_EMAIL}.`
                : error || ''}
            </span>
          </div>
          <button className="btn btn-primary" type="submit" disabled={status === 'sending'}>
            <span>{status === 'sending' ? 'Sending' : status === 'sent' ? 'Message received' : 'Start a conversation'}</span>
            <span className="btn-arrow">{status === 'sent' ? '✓' : '→'}</span>
          </button>
        </div>
      </form>
    </section>
  );
}

function Footer() {
  const founderUrl = 'https://www.linkedin.com/in/christopherbun/';
  return (
    <footer className="nm-footer" data-screen-label="10 Footer">
      <div className="nm-footer-top">
        <div className="nm-footer-mark">
          <div>
            <img className="nm-logo-img nm-footer-wordmark" src="assets/logo-wordmark.png?v=2" alt="NoMind" />
            <div className="mono-label dim">AI strategy · Systems · Operating design</div>
          </div>
        </div>
        <div className="nm-footer-cols">
          <div>
            <div className="mono-label dim">Focus</div>
            <ul>
              <li>AI strategy</li>
              <li>Executive roadmap</li>
              <li>Workflow governance</li>
              <li>Vendor / build diligence</li>
              <li>Fractional AI advisor</li>
            </ul>
          </div>
          <div>
            <div className="mono-label dim">Themes</div>
            <ul>
              <li>Build / buy / block</li>
              <li>90-day roadmap</li>
              <li>Human review boundaries</li>
              <li>Cost and operating model</li>
            </ul>
          </div>
          <div>
            <div className="mono-label dim">Contact</div>
            <ul>
              <li><a href="mailto:hello@nomind.systems">hello@nomind.systems</a></li>
              <li>Founded by <a href={founderUrl} target="_blank" rel="noopener noreferrer">Chris Bun</a></li>
              <li><a href="/privacy">Privacy</a></li>
              <li>Chicago · Remote</li>
              <li>Start a conversation</li>
            </ul>
          </div>
        </div>
      </div>
      <div className="nm-footer-bar">
        <span>© 2026 NoMind</span>
        <span className="nm-footer-tag">Trust is a workflow property</span>
        <span>Rev. 08</span>
      </div>
    </footer>
  );
}

Object.assign(window, { Nav, Hero, What, Transformation, Systems, Offer, Founder, Contact, Footer, Eyebrow, MathBlock, MathCard, ParticleDissolve });
