/* eslint-disable */
/* ============================================================
   kevinz.ai — enhancements bundle
   ------------------------------------------------------------
   • AsciiRain          — sparse cursor-aware Matrix-y bg
   • StickyNewsletter   — bottom dock that appears past hero
   • CommanderDemo      — sandboxed terminal w/ canned prompts
   • CareerTimeline     — horizontal 20-yr timeline, dismissible
   ============================================================ */

const { useEffect: _useEffectE, useRef: _useRefE, useState: _useStateE, useMemo: _useMemoE } = React;

/* ============================================================
   1. ASCII RAIN — canvas-based, cursor-aware, very subtle
   ============================================================ */
function AsciiRain({ density = 0.35, fontSize = 13, repelRadius = 110 }) {
  const canvasRef = _useRefE(null);
  const rafRef = _useRefE(0);
  const mouseRef = _useRefE({ x: -9999, y: -9999 });

  _useEffectE(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d", { alpha: true });
    const dpr = Math.min(window.devicePixelRatio || 1, 2);

    const CHARS = "01░▒▓·:-+*=#@▌▐▀▄│─┼├┤┬┴";
    let cols = 0;
    let drops = []; // {x, y, speed, ch, age}

    const resize = () => {
      canvas.width = window.innerWidth * dpr;
      canvas.height = window.innerHeight * dpr;
      canvas.style.width = window.innerWidth + "px";
      canvas.style.height = window.innerHeight + "px";
      ctx.scale(dpr, dpr);
      cols = Math.floor(window.innerWidth / fontSize);
      drops = [];
      for (let i = 0; i < cols; i++) {
        // sparse — only ~density of cols actually have a drop
        if (Math.random() < density) {
          drops.push({
            col: i,
            y: Math.random() * window.innerHeight,
            speed: 0.4 + Math.random() * 0.9,
            ch: CHARS[(Math.random() * CHARS.length) | 0],
            chTimer: 0
          });
        }
      }
    };
    resize();

    const onMove = (e) => {
      mouseRef.current.x = e.clientX;
      mouseRef.current.y = e.clientY;
    };
    const onLeave = () => { mouseRef.current.x = -9999; mouseRef.current.y = -9999; };

    window.addEventListener("resize", resize);
    window.addEventListener("pointermove", onMove, { passive: true });
    window.addEventListener("pointerleave", onLeave);

    const tick = () => {
      // soft trail — clear with low alpha
      ctx.fillStyle = "rgba(8, 9, 10, 0.18)";
      ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);

      ctx.font = `${fontSize}px var(--mono, monospace)`;
      const mx = mouseRef.current.x;
      const my = mouseRef.current.y;
      const r2 = repelRadius * repelRadius;

      for (let i = 0; i < drops.length; i++) {
        const d = drops[i];
        const x = d.col * fontSize;
        // distance to cursor
        const dx = x - mx;
        const dy = d.y - my;
        const dist2 = dx * dx + dy * dy;
        const inField = dist2 < r2;

        // fade chars near cursor (the "parting" effect)
        let alpha;
        if (inField) {
          const t = Math.sqrt(dist2) / repelRadius; // 0..1
          alpha = 0.04 + t * 0.08;
        } else {
          alpha = 0.10 + Math.random() * 0.04;
        }

        // amber tint for the "head" of each drop
        const isHead = d.chTimer < 2;
        ctx.fillStyle = isHead
          ? `rgba(255, 176, 60, ${alpha + 0.18})`
          : `rgba(170, 170, 170, ${alpha})`;

        ctx.fillText(d.ch, x, d.y);

        d.y += d.speed * fontSize * 0.18;
        d.chTimer++;
        if (d.chTimer > 8) {
          d.ch = CHARS[(Math.random() * CHARS.length) | 0];
          d.chTimer = 0;
        }
        if (d.y > window.innerHeight + fontSize) {
          d.y = -fontSize * (Math.random() * 8);
          d.speed = 0.4 + Math.random() * 0.9;
        }
      }
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(rafRef.current);
      window.removeEventListener("resize", resize);
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerleave", onLeave);
    };
  }, [density, fontSize, repelRadius]);

  return (
    <canvas
      ref={canvasRef}
      aria-hidden="true"
      style={{
        position: "fixed", inset: 0, zIndex: 0,
        pointerEvents: "none",
        opacity: 0.55,
        mixBlendMode: "screen"
      }}
    />
  );
}
window.AsciiRain = AsciiRain;


/* ============================================================
   2. STICKY NEWSLETTER FOOTER
   appears after user scrolls past hero (~600px)
   ============================================================ */
function StickyNewsletter() {
  const [show, setShow] = _useStateE(false);
  const [closed, setClosed] = _useStateE(false);
  const [email, setEmail] = _useStateE("");
  const [done, setDone] = _useStateE(false);

  _useEffectE(() => {
    if (closed) return;
    const onScroll = () => {
      const y = window.scrollY;
      const h = window.innerHeight;
      const max = document.documentElement.scrollHeight;
      // show after hero (~80vh) and hide near footer
      const past = y > h * 0.8;
      const nearEnd = y + h > max - 220;
      setShow(past && !nearEnd);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [closed]);

  if (closed) return null;

  return (
    <div className={"sticky-news " + (show ? "is-on" : "")} role="region" aria-label="Subscribe">
      <div className="sn-inner">
        <div className="sn-glyph">▸</div>
        <div className="sn-copy">
          <div className="sn-line">The Agent Report · sundays</div>
          <div className="sn-sub">commit logs from 5 companies. real cost data. no predictions.</div>
          {window.ThinkingBadge && (
            <div style={{ fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase", marginTop: 6 }}>
              <window.ThinkingBadge />
            </div>
          )}
        </div>
        {!done ? (
          <form className="sn-form" onSubmit={(e) => { e.preventDefault(); if (email.includes("@")) setDone(true); }}>
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="you@operator.io"
              aria-label="Email"
            />
            <button type="submit">subscribe →</button>
          </form>
        ) : (
          <div className="sn-done">✓ confirmed · check your inbox</div>
        )}
        <button className="sn-x" aria-label="Dismiss" onClick={() => setClosed(true)}>×</button>
      </div>
    </div>
  );
}
window.StickyNewsletter = StickyNewsletter;


/* ============================================================
   3. INTERACTIVE COMMANDER DEMO — canned prompts, scripted output
   placeholder for a real sandbox; scripted but feels alive
   ============================================================ */
function CommanderDemo() {
  // Four tabs: Overview · Skills · Agents · Features.
  // Each streams LLM-printout style (fast line-by-line, ~70-130ms per line) on
  // the right pane. Click a tab to jump. Auto-runs Overview on first visibility.
  const PROMPTS = [
    {
      id: "overview",
      label: "Overview",
      cmd: "commander › overview",
      script: [
        { t: 80,  line: "↻ commander v4.0.0-beta.11" },
        { t: 90,  line: "   the AI command layer for operators" },
        { t: 110, line: "" },
        { t: 100, line: "▸ 19 vendor packages aggregated" },
        { t: 90,  line: "▸ 280+ skills across 11 domains" },
        { t: 90,  line: "▸ 17 specialist agent personas" },
        { t: 100, line: "▸ multi-agent runtime · OpenClaw + Hermes" },
        { t: 110, line: "▸ MCP-native · pairs with Claude Code, Codex, Cursor, Cline" },
        { t: 90,  line: "" },
        { t: 80,  line: "▸ install:  npx commander" },
        { t: 80,  line: "▸ docs:     cc-commander.com" },
        { t: 90,  line: "▸ source:   github.com/KevinZai/commander" },
        { t: 100, line: "" },
        { t: 80,  line: "✓ ready" }
      ]
    },
    {
      id: "skills",
      label: "Skills",
      cmd: "commander › skills",
      script: [
        { t: 80,  line: "↻ scanning 11 domains · 280+ skills" },
        { t: 90,  line: "" },
        { t: 70,  line: "design          (39) — frontend · animation · anti-slop" },
        { t: 70,  line: "marketing       (45) — CRO · ads · email · social" },
        { t: 70,  line: "saas            (20) — auth · billing · multi-tenant" },
        { t: 70,  line: "devops          (21) — CI/CD · deploys · monitoring" },
        { t: 70,  line: "testing         (15) — TDD · E2E · coverage" },
        { t: 70,  line: "seo             (20) — schema · SERP · AI search" },
        { t: 70,  line: "security         (8) — OWASP · secrets · hardening" },
        { t: 70,  line: "data             (8) — SQL · ETL · analytics" },
        { t: 70,  line: "research         (8) — competitive · audits" },
        { t: 70,  line: "mobile           (8) — React Native · Expo" },
        { t: 70,  line: "makeover         (3) — site-wide refresh" },
        { t: 100, line: "" },
        { t: 80,  line: "✓ 280 skills loaded" }
      ]
    },
    {
      id: "agents",
      label: "Agents",
      cmd: "commander › agents",
      script: [
        { t: 80,  line: "↻ activating 17 specialist personas" },
        { t: 90,  line: "" },
        { t: 60,  line: "[ARCH]  architect           — system design, tech selection" },
        { t: 60,  line: "[BLDR]  builder             — TDD implementation" },
        { t: 60,  line: "[DBUG]  debugger            — root-cause investigation" },
        { t: 60,  line: "[REVW]  reviewer            — PR review, severity-rated" },
        { t: 60,  line: "[QA]    qa-engineer         — test suites, coverage" },
        { t: 60,  line: "[SEC]   security-auditor    — OWASP, CVE mapping" },
        { t: 60,  line: "[PERF]  performance         — profiling, hot-path" },
        { t: 60,  line: "[UI]    designer            — anti-slop interfaces" },
        { t: 60,  line: "[OPS]   devops              — CI/CD, infra, monitoring" },
        { t: 60,  line: "[PM]    product-manager     — PRDs, user stories" },
        { t: 60,  line: "[DOCS]  technical-writer    — docs, READMEs, API ref" },
        { t: 60,  line: "[RSCH]  researcher          — competitive analysis" },
        { t: 60,  line: "[DATA]  data-analyst        — cohort, insights" },
        { t: 60,  line: "[COPY]  content-strategist  — editorial calendars" },
        { t: 60,  line: "[FLT]   fleet-worker        — parallel batch ops" },
        { t: 60,  line: "[TS]    typescript-reviewer — TS-specific review" },
        { t: 60,  line: "[PY]    python-reviewer     — Python idioms" },
        { t: 100, line: "" },
        { t: 80,  line: "✓ 17/17 personas online" }
      ]
    },
    {
      id: "features",
      label: "Features",
      cmd: "commander › features",
      script: [
        { t: 80,  line: "↻ loading capability matrix" },
        { t: 90,  line: "" },
        { t: 80,  line: "[01] plugin-aware" },
        { t: 70,  line: "     auto-detects gstack · superpowers · CE" },
        { t: 70,  line: "     orchestrates them in one session" },
        { t: 90,  line: "" },
        { t: 80,  line: "[02] knowledge compounding" },
        { t: 70,  line: "     learns your stack · remembers patterns" },
        { t: 70,  line: "     across sessions, not just the current one" },
        { t: 90,  line: "" },
        { t: 80,  line: "[03] YOLO mode" },
        { t: 70,  line: "     10-question spec → 8-hour autonomous build" },
        { t: 70,  line: "     wakes you only when stuck" },
        { t: 90,  line: "" },
        { t: 80,  line: "[04] multi-model routing" },
        { t: 70,  line: "     Claude · Codex · local · OpenRouter" },
        { t: 70,  line: "     auto-failover to free tiers" },
        { t: 90,  line: "" },
        { t: 80,  line: "[05] dialectic review" },
        { t: 70,  line: "     FOR-agent + AGAINST-agent + referee" },
        { t: 70,  line: "     for irreversible decisions" },
        { t: 90,  line: "" },
        { t: 80,  line: "[06] verification gates" },
        { t: 70,  line: "     no commit without tests passing" },
        { t: 70,  line: "     no merge without code review" },
        { t: 100, line: "" },
        { t: 80,  line: "✓ all features active" }
      ]
    }
  ];

  const [running, setRunning] = _useStateE(false);
  const [activeId, setActiveId] = _useStateE("overview");
  const [lines, setLines] = _useStateE([]);
  const timersRef = _useRefE([]);
  const sectionRef = _useRefE(null);
  const startedRef = _useRefE(false);

  const stop = () => { timersRef.current.forEach(clearTimeout); timersRef.current = []; setRunning(false); };

  const run = (id) => {
    stop();
    setActiveId(id);
    const p = PROMPTS.find((x) => x.id === id);
    if (!p) return;
    setLines([{ kind: "prompt", text: p.cmd }]);
    setRunning(true);
    let acc = 0;
    p.script.forEach((step, i) => {
      acc += step.t;
      const tid = setTimeout(() => {
        setLines((prev) => [...prev, { kind: "line", text: step.line }]);
        if (i === p.script.length - 1) {
          const done = setTimeout(() => setRunning(false), 250);
          timersRef.current.push(done);
        }
      }, acc);
      timersRef.current.push(tid);
    });
  };

  _useEffectE(() => () => stop(), []);

  // Auto-run Overview when the section first scrolls into view.
  _useEffectE(() => {
    if (!sectionRef.current || startedRef.current) return;
    const obs = new IntersectionObserver((entries) => {
      for (const entry of entries) {
        if (entry.isIntersecting && !startedRef.current) {
          startedRef.current = true;
          run("overview");
          obs.disconnect();
          break;
        }
      }
    }, { threshold: 0.25 });
    obs.observe(sectionRef.current);
    return () => obs.disconnect();
  }, []);

  return (
    <section ref={sectionRef} id="demo" data-section="commander" className="section-pad">
      <div className="container">
        <div className="box-head">
          <window.AsciiBadge glyph="block" count={3} />
          <span>// 03b — try commander · sandbox</span>
          <span className="rule" />
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1.4fr", gap: 28, alignItems: "start" }} className="demo-grid">
          <div>
            <h2 className="h-section">all the best skills. one install.</h2>
            <p className="lede mt-20" style={{ maxWidth: "44ch" }}>
              Pick a tab. Watch it stream. The right pane shows the live capability list — no marketing version.
            </p>
            <div className="demo-prompts mt-24">
              {PROMPTS.map((p, idx) => (
                <button
                  key={p.id}
                  className={"demo-pill " + (activeId === p.id ? "is-on" : "")}
                  onClick={() => run(p.id)}>
                  <span className="demo-pill-num">[{String(idx + 1).padStart(2, "0")}]</span>
                  <span>{p.label}</span>
                  <span className="demo-pill-arrow">↗</span>
                </button>
              ))}
            </div>
            <div className="dim mt-24" style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase" }}>
              ▸ install the real one · <a href="https://cc-commander.com" className="amber">cc-commander.com</a>
            </div>
          </div>

          <div className="terminal" style={{ minHeight: 380 }}>
            <div className="win-title">
              <div className="lights"><span className="r" /><span className="a" /><span className="g" /></div>
              <span>~/sandbox · commander · {running ? "running" : "ready"}</span>
              <span className="meta">{lines.length} lines</span>
            </div>
            <div className="body" style={{ minHeight: 320 }}>
              {lines.length === 0 && (
                <div className="dim" style={{ fontSize: 12.5 }}>
                  $ pick a tab — overview · skills · agents · features<span className="cursor" />
                </div>
              )}
              {lines.map((l, i) => l.kind === "prompt" ? (
                <div key={i}><span className="term-amber">commander</span> <span className="term-prompt">›</span> {l.text.replace(/^commander › /, "")}</div>
              ) : (
                <div key={i} style={{ paddingLeft: 4 }}>{l.text}</div>
              ))}
              {running && <div><span className="term-amber">▌</span> <span className="dim">working</span><span className="cursor" /></div>}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}
window.CommanderDemo = CommanderDemo;


/* ============================================================
   4. CAREER TIMELINE — horizontal 20-yr arc · dismissible

   STATUS (2026-04-25): ARCHIVED but preserved.
   Currently unmounted in app.jsx. Per Kevin: keep in source for a
   possible future remount or migration to a /career or /timeline
   route. Do NOT delete — it captures real career data that's hard
   to re-derive. To remount: add <window.CareerTimeline /> to app.jsx
   between <Credentials /> and <window.AsciiPicCTA />.
   ============================================================ */
function CareerTimeline() {
  const [closed, setClosed] = _useStateE(false);

  // Best-guess composite based on the rest of the site copy.
  // User can edit, dismiss, or keep.
  const events = [
    { y: "2005", t: "First exit", d: "Sold first venture in early-stage mobile.", tag: "founder" },
    { y: "2010", t: "MyWiFi Networks", d: "Hospitality WiFi marketing → 40+ countries.", tag: "founder" },
    { y: "2014", t: "Best-seller", d: "Amazon best-selling author · mobile marketing.", tag: "author" },
    { y: "2017", t: "Udemy · 5K+ students", d: "WiFi marketing curriculum.", tag: "teacher" },
    { y: "2019", t: "Collision Stage", d: "Keynote on captive-portal economics.", tag: "speaker" },
    { y: "2022", t: "Guest Networks", d: "Physical-space data plane spinout.", tag: "founder" },
    { y: "2023", t: "DMHub", d: "WhatsApp-first AI front desk · $49/mo.", tag: "founder" },
    { y: "2024", t: "ReadyIQ", d: "AI deployment for non-technical CEOs.", tag: "founder" },
    { y: "2025", t: "OpenClaw + Hermes", d: "Self-hosted agent workforce. $2.48/day.", tag: "operator" },
    { y: "2026", t: "Commander · 38 agents", d: "OSS AI command layer · 280+ skills.", tag: "operator" }
  ];

  if (closed) return null;

  return (
    <section data-section="timeline" className="section-pad" style={{ paddingTop: 40, paddingBottom: 40 }}>
      <div className="container">
        <div className="box-head">
          <window.AsciiBadge glyph="bracket" count={3} />
          <span>// 1.5 — twenty years · one continuous arc</span>
          <span className="rule" />
          <button
            onClick={() => setClosed(true)}
            style={{
              fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.18em",
              textTransform: "uppercase", color: "var(--fg-4)", background: "transparent",
              border: "1px solid var(--line)", padding: "4px 10px", cursor: "pointer"
            }}
            title="Dismiss timeline">
            × dismiss
          </button>
        </div>

        <div className="timeline-wrap">
          <div className="timeline-axis" />
          <div className="timeline-track">
            {events.map((e, i) => (
              <div key={i} className={"tl-item " + (i % 2 ? "tl-down" : "tl-up")}>
                <div className="tl-stem" />
                <div className="tl-card">
                  <div className="tl-year">{e.y}</div>
                  <div className="tl-title">{e.t}</div>
                  <div className="tl-desc">{e.d}</div>
                  <div className="tl-tag">[ {e.tag} ]</div>
                </div>
                <div className="tl-dot" />
              </div>
            ))}
          </div>
        </div>
        <div className="dim mt-12" style={{ fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", textAlign: "center" }}>
          scroll horizontally · ←→
        </div>
      </div>
    </section>
  );
}
window.CareerTimeline = CareerTimeline;
