function Logo({ size = 22, showWord = true, color = 'currentColor', accent = 'var(--accent)' }) {
  const h = size;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 10, color }}>
      {/* Geometric mark: stylized X — two chevrons forming a diamond with a notched core */}
      <svg width={h} height={h} viewBox="0 0 32 32" fill="none" aria-hidden="true">
        <path d="M4 4 L16 16 L4 28" stroke={color} strokeWidth="2.4" strokeLinecap="square" strokeLinejoin="miter"/>
        <path d="M28 4 L16 16 L28 28" stroke={color} strokeWidth="2.4" strokeLinecap="square" strokeLinejoin="miter"/>
        <rect x="14" y="14" width="4" height="4" fill={accent}/>
      </svg>
      {showWord && (
        <span style={{
          fontFamily: 'var(--font-brand)', fontWeight: 600,
          fontSize: h * 0.72, letterSpacing: '0.18em',
          textTransform: 'uppercase', lineHeight: 1,
        }}>
          XAILOS
        </span>
      )}
    </span>
  );
}

function useScrolled(threshold = 8) {
  const [s, setS] = React.useState(false);
  React.useEffect(() => {
    const h = () => setS(window.scrollY > threshold);
    h();
    window.addEventListener('scroll', h, { passive: true });
    return () => window.removeEventListener('scroll', h);
  }, [threshold]);
  return s;
}

function Nav() {
  const scrolled = useScrolled();
  return (
    <nav className={`nav ${scrolled ? 'scrolled' : ''}`}>
      <div className="container inner">
        <a href="#top" className="brand">
          <Logo size={22}/>
          <span className="pulse" title="Online"></span>
        </a>
        <div className="links">
          <a href="#products">Products</a>
          <a href="#studio">Studio</a>
          <a href="#principles">Principles</a>
          <a href="#contact" className="cta">Start a brief →</a>
        </div>
      </div>
    </nav>
  );
}

function NetworkBG() {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const canvas = ref.current; if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let W = 0, H = 0, raf = 0;
    const DPR = Math.min(window.devicePixelRatio || 1, 2);
    const css = getComputedStyle(document.body);
    const accent = css.getPropertyValue('--accent').trim() || '#ff6a3d';
    const line = css.getPropertyValue('--line-2').trim() || '#272b32';
    const text3 = css.getPropertyValue('--text-3').trim() || '#545962';

    const N = 42;
    const nodes = Array.from({ length: N }, () => ({
      x: Math.random(), y: Math.random(),
      vx: (Math.random() - 0.5) * 0.00025,
      vy: (Math.random() - 0.5) * 0.00025,
      r: 0.8 + Math.random() * 1.6,
      pulse: Math.random() * Math.PI * 2,
    }));
    // travelling signals along edges
    const signals = [];

    const resize = () => {
      const rect = canvas.getBoundingClientRect();
      W = rect.width; H = rect.height;
      canvas.width = W * DPR; canvas.height = H * DPR;
      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
    };
    resize();
    window.addEventListener('resize', resize);

    const MAX_DIST = 170;
    let last = performance.now();
    const loop = (t) => {
      const dt = Math.min(64, t - last); last = t;
      ctx.clearRect(0, 0, W, H);

      // update nodes
      for (const n of nodes) {
        n.x += n.vx * dt; n.y += n.vy * dt;
        if (n.x < 0 || n.x > 1) n.vx *= -1;
        if (n.y < 0 || n.y > 1) n.vy *= -1;
        n.pulse += 0.0012 * dt;
      }

      // edges
      for (let i = 0; i < N; i++) {
        for (let j = i + 1; j < N; j++) {
          const a = nodes[i], b = nodes[j];
          const dx = (a.x - b.x) * W, dy = (a.y - b.y) * H;
          const d = Math.hypot(dx, dy);
          if (d < MAX_DIST) {
            const alpha = (1 - d / MAX_DIST) * 0.35;
            ctx.strokeStyle = line;
            ctx.globalAlpha = alpha;
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.moveTo(a.x * W, a.y * H);
            ctx.lineTo(b.x * W, b.y * H);
            ctx.stroke();
          }
        }
      }
      ctx.globalAlpha = 1;

      // occasionally emit a signal
      if (Math.random() < 0.04) {
        const from = nodes[Math.floor(Math.random() * N)];
        // pick nearest neighbor
        let best = null, bd = Infinity;
        for (const b of nodes) {
          if (b === from) continue;
          const dx = (from.x - b.x) * W, dy = (from.y - b.y) * H;
          const d = Math.hypot(dx, dy);
          if (d < MAX_DIST && d < bd) { bd = d; best = b; }
        }
        if (best) signals.push({ from, to: best, t: 0, dur: 700 + Math.random() * 700 });
      }

      // render signals
      for (let i = signals.length - 1; i >= 0; i--) {
        const s = signals[i]; s.t += dt;
        const p = s.t / s.dur;
        if (p >= 1) { signals.splice(i, 1); continue; }
        const x = (s.from.x + (s.to.x - s.from.x) * p) * W;
        const y = (s.from.y + (s.to.y - s.from.y) * p) * H;
        // accent dot with glow
        ctx.globalAlpha = 1 - Math.abs(p - 0.5) * 1.2;
        ctx.fillStyle = accent;
        ctx.beginPath();
        ctx.arc(x, y, 2.2, 0, Math.PI * 2);
        ctx.fill();
        ctx.globalAlpha = 0.28 * (1 - Math.abs(p - 0.5) * 1.2);
        ctx.beginPath();
        ctx.arc(x, y, 6, 0, Math.PI * 2);
        ctx.fill();
      }
      ctx.globalAlpha = 1;

      // nodes
      for (const n of nodes) {
        const pulse = (Math.sin(n.pulse) + 1) / 2;
        ctx.fillStyle = text3;
        ctx.globalAlpha = 0.55 + pulse * 0.35;
        ctx.beginPath();
        ctx.arc(n.x * W, n.y * H, n.r, 0, Math.PI * 2);
        ctx.fill();
      }
      ctx.globalAlpha = 1;

      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => { cancelAnimationFrame(raf); window.removeEventListener('resize', resize); };
  }, []);
  return <canvas ref={ref} className="hero-net" aria-hidden="true"/>;
}

function Hero() {
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => { const t = setTimeout(() => setShown(true), 80); return () => clearTimeout(t); }, []);
  const fade = (i) => ({
    opacity: shown ? 1 : 0,
    transform: shown ? 'translateY(0)' : 'translateY(14px)',
    transition: `opacity 600ms var(--ease) ${i*90}ms, transform 600ms var(--ease) ${i*90}ms`
  });
  return (
    <section className="hero" id="top">
      <div className="hero-grid"></div>
      <NetworkBG/>
      <div className="hero-bg"></div>
      <div className="container inner">
        <div className="tagrow" style={fade(0)}>
          <span className="d"></span>
          <span>Studio online</span>
          <span className="sep">/</span>
          <span>Est. 2025 · Chennai</span>
        </div>
        <h1>
          <span style={{ display: 'block', ...fade(1) }}>Small tools.</span>
          <span style={{ display: 'block', ...fade(2) }}><em>Sharp</em> ideas.</span>
          <span style={{ display: 'block', ...fade(3) }}>Shipped fast.</span>
        </h1>
        <p className="sub" style={fade(4)}>
          An independent software studio building focused tools — quiet products with careful AI,
          for the operators running communities, clubs, and teams.
        </p>
        <div className="actions" style={fade(4)}>
          <a className="btn btn-primary" href="#products">See the work →</a>
          <a className="btn btn-ghost" href="#contact">Start a conversation</a>
        </div>

        <div className="stats" style={fade(5)}>
          <div className="stat">
            <div className="k">Status</div>
            <div className="v"><em>Shipping</em></div>
          </div>
          <div className="stat">
            <div className="k">Products live</div>
            <div className="v">03 <span style={{ color: 'var(--text-3)' }}>/ 05</span></div>
          </div>
          <div className="stat">
            <div className="k">Cadence</div>
            <div className="v">Weekly</div>
          </div>
          <div className="stat">
            <div className="k">Based</div>
            <div className="v">Remote</div>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Logo, Nav, Hero, NetworkBG });
