// Components for Federico Caccia's personal site
// All React primitives, shared through window at the bottom.

const { useState, useEffect, useRef, useCallback } = React;

// -------- Nav --------
function TopBar({ active }) {
  const items = [
    { id: 'about', label: '01 / About' },
    { id: 'ventures', label: '02 / Ventures' },
    { id: 'trajectory', label: '03 / Trajectory' },
    { id: 'beyond', label: '04 / Beyond' },
    { id: 'console', label: '05 / Console' },
  ];
  return (
    <header className="fc-topbar">
      <div className="fc-mark">
        <span className="dot" />
        <span>FC / Federico Caccia</span>
      </div>
      <nav className="fc-navlinks">
        {items.map(i => (
          <a key={i.id} href={`#${i.id}`} className={active === i.id ? 'active' : ''}>
            {i.label}
          </a>
        ))}
      </nav>
    </header>
  );
}

// -------- Status bar --------
function StatusBar() {
  const [time, setTime] = useState('');
  useEffect(() => {
    const u = () => {
      const d = new Date();
      setTime(d.toLocaleTimeString('en-US', { hour12: false, timeZone: 'America/Argentina/Buenos_Aires' }) + ' ART');
    };
    u();
    const id = setInterval(u, 1000);
    return () => clearInterval(id);
  }, []);
  return (
    <div className="fc-statusbar">
      <div>LAT 34.6°S / LON 58.4°W · BUENOS AIRES</div>
      <div className="live"><span className="pulse" /> LIVE · {time}</div>
      <div>v3.0 · SHIPPING_IN_PUBLIC</div>
    </div>
  );
}

// -------- Hero --------
function Hero() {
  return (
    <section className="hero" id="home" data-screen-label="01 Hero">
      <div className="hero-top">
        <div>
          <div className="hero-overline">Federico Caccia · Est. Bariloche · 1989</div>
          <h1 className="hero-title">
            Building<br />
            <em>resilient</em> systems<br />
            from <span className="stroke">atoms</span> to blocks.
          </h1>
        </div>
      </div>
      <div className="hero-bottom">
        <p className="hero-sub">
          <b>M.Sc. Nuclear Engineer</b> turned tech entrepreneur.
          Founder &amp; CEO of <b>Rather Labs</b>, <b>Rather Ventures</b>,
          <b> Omnilane</b> &amp; <b>Serviry</b>. 130+ people across 10+ countries,
          shipping blockchain, AI and healthtech infrastructure.
        </p>
        <div className="meta-block">
          <div><span className="key">STATUS</span> &nbsp;·&nbsp; <span className="val">SELECTIVE BUILDER</span></div>
          <div><span className="key">BASE</span> &nbsp;·&nbsp; <span className="val">BUENOS AIRES / AR</span></div>
          <div><span className="key">FORMATION</span> &nbsp;·&nbsp; <span className="val">INSTITUTO BALSEIRO</span></div>
          <div><span className="key">OPS</span> &nbsp;·&nbsp; <span className="val">BLOCKCHAIN · AI · INFRA</span></div>
        </div>
        <div className="hero-cta">
          <a href="#console" className="btn primary">
            Init contact <span className="arrow">↗</span>
          </a>
          <a href="#about" className="btn">
            Read more <span className="arrow">↓</span>
          </a>
        </div>
      </div>
      <div className="scene-label">
        <div><span className="accent">◉</span> SCENE_001 · NUCLEUS</div>
        <div>PROTON · NEUTRON · e⁻</div>
        <div>morph → 02 network</div>
      </div>
    </section>
  );
}

// -------- About --------
function About() {
  return (
    <section className="about" id="about" data-screen-label="02 About">
      <div className="section-head">
        <div className="section-num">01 / About</div>
        <h2 className="section-title">The <em>why</em>.</h2>
        <div className="section-desc">A brief operating<br />manual for my head.</div>
      </div>
      <div className="about-grid">
        <div className="about-key">BIO · LONG FORM</div>
        <div>
          <p className="about-lead">
            I spent my twenties deep in <em>physics, math</em> and the discipline of designing
            robust engineering systems. I spend my thirties designing <em>economic infrastructure</em> that runs on code.
          </p>
        </div>
        <div className="about-body">
          <p>
            I studied <b>Nuclear Engineering</b> at the Instituto Balseiro — one of the hardest
            admissions in Latin America, ~10 students per year. I worked on the <b>RA-10 reactor</b>
            safety system at CNEA using C/C++ with a focus on parallelization and performance.
          </p>
          <p>
            In 2018 I jumped into blockchain at CoinFabrik. In 2020 I co-founded <b>Rather Labs</b>
            with Franco Scucchiero — we've grown it into a 130+ person engineering studio shipping
            DeFi, cross-chain, AI and healthtech products for 30+ partners worldwide.
          </p>
          <p>
            I build because engineering is how ideas actually touch the world. And because
            there are still systems worth re-designing from scratch.
          </p>
        </div>
      </div>

      <div className="stats-row">
        <div className="stat">
          <div className="n">130<em>+</em></div>
          <div className="l">Team · Rather Labs</div>
        </div>
        <div className="stat">
          <div className="n">10<em>+</em></div>
          <div className="l">Countries · active</div>
        </div>
        <div className="stat">
          <div className="n">30<em>+</em></div>
          <div className="l">Partners · shipped</div>
        </div>
        <div className="stat">
          <div className="n">4</div>
          <div className="l">Ventures · founder/CEO</div>
        </div>
      </div>
    </section>
  );
}

// -------- Ventures --------
function Ventures() {
  const items = [
    {
      num: '001',
      name: 'Rather Labs',
      role: 'Blockchain & AI engineering studio. 130+ engineers building DeFi, L2s, smart contracts and AI-driven infra for founders worldwide.',
      tag: 'CEO · ACTIVE',
      url: 'https://ratherlabs.com'
    },
    {
      num: '002',
      name: 'Rather Ventures',
      role: 'Our own product bets. Transcribego and other tools we build in-house and ship to market.',
      tag: 'CEO · ACTIVE',
      url: 'https://transcribego.com'
    },
    {
      num: '003',
      name: 'Omnilane Labs',
      role: 'Cross-chain infrastructure. Making capital and information flow natively across ecosystems.',
      tag: 'CEO · 2025',
      url: 'https://omnilane.xyz'
    },
    {
      num: '004',
      name: 'Serviry',
      role: 'Healthtech — consult doctors across any specialty directly through WhatsApp. Latam-first.',
      tag: 'CEO · 2025',
      url: '#'
    },
    {
      num: '005',
      name: 'Hatom Labs',
      role: 'Tech advisor. Leading lending protocol on MultiversX.',
      tag: 'TECH ADVISOR',
      url: '#'
    },
  ];
  return (
    <section className="ventures" id="ventures" data-screen-label="03 Ventures">
      <div className="section-head">
        <div className="section-num">02 / Ventures</div>
        <h2 className="section-title">What I'm <em>building</em>.</h2>
        <div className="section-desc">Active positions.<br />Selective commitments.</div>
      </div>
      <div className="venture-list">
        {items.map(v => (
          <a key={v.num} href={v.url} target="_blank" rel="noopener" className="venture">
            <div className="venture-num">/ {v.num}</div>
            <div className="venture-name">{v.name}</div>
            <div className="venture-role">{v.role}</div>
            <div className="venture-tag">{v.tag}</div>
            <div className="venture-arrow">↗</div>
          </a>
        ))}
      </div>
    </section>
  );
}

// -------- Timeline --------
function Timeline() {
  const entries = [
    {
      year: '2024 — NOW',
      title: 'Founding Omnilane, Serviry & shipping AI products',
      place: 'Buenos Aires · global',
      desc: 'Expanding from services into product. Cross-chain infra at Omnilane, healthtech at Serviry, AI workflows everywhere.',
      current: true,
    },
    {
      year: '2020 — NOW',
      title: 'Co-founder & CEO · Rather Labs',
      place: 'Founded Jul 2020 · FI cohort Aug 2020',
      desc: 'Scaled to 130+ people, 30+ partners across 10+ countries. Blockchain, AI, healthtech, gaming, cross-chain infra.',
    },
    {
      year: '2018 — 2020',
      title: 'Blockchain developer · CoinFabrik',
      place: 'Buenos Aires',
      desc: 'First contact with Web3. Smart contracts, protocol research, auditing — this is where the itch started.',
    },
    {
      year: '2014 — 2018',
      title: 'Researcher · Nuclear safety',
      place: 'CNEA · Centro Atómico Bariloche',
      desc: 'Designed & analyzed the safety system for the RA-10 reactor. C/C++, parallelization, performance. Respect for systems that can\'t fail.',
    },
    {
      year: '2014 — 2017',
      title: 'M.Sc. in Engineering · Instituto Balseiro',
      place: 'Bariloche · Patagonia',
      desc: 'Postgraduate specialization after the engineering degree. Nuclear reactor physics and safety.',
    },
    {
      year: '2009 — 2014',
      title: 'Nuclear Engineer · Instituto Balseiro',
      place: 'Bariloche',
      desc: 'One of the hardest admissions in LatAm. ~10 students per year. 5-year undergrad inside the Balseiro mountain campus.',
    },
  ];
  return (
    <section className="ventures" id="trajectory" data-screen-label="04 Trajectory">
      <div className="section-head">
        <div className="section-num">03 / Trajectory</div>
        <h2 className="section-title">Path, <em>non-linear</em>.</h2>
        <div className="section-desc">From reactor<br />physics to rollups.</div>
      </div>
      <div className="timeline-wrap">
        <div className="timeline">
          {entries.map((e, i) => (
            <div key={i} className={'tl-entry' + (e.current ? ' current' : '')}>
              <div className="tl-year">{e.year}</div>
              <div className="tl-content">
                <h3 className="tl-title">{e.title}</h3>
                <div className="tl-place">{e.place}</div>
                <p className="tl-desc">{e.desc}</p>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// -------- Beyond (personal) — gravity drop, settles cleanly, no rotation --------
function Beyond() {
  const facets = [
    { n: '/01', mid: <>Patagonia <em>native</em>.</>, bot: 'Bariloche · mountains', w: 260, h: 170 },
    { n: '/02', mid: <><em>Psychology</em> & neuroscience.</>, bot: 'Reading · passion', w: 280, h: 170 },
    { n: '/03', mid: <>Books of <em>all kinds</em>, always.</>, bot: 'Literature · essays', w: 320, h: 170 },
    { n: '/04', mid: <>Reading <em>physics</em> at 30k ft.</>, bot: 'Science · notes', w: 260, h: 170 },
    { n: '/05', mid: <>Travel, <em>around the world</em>.</>, bot: 'Travel', w: 250, h: 170 },
    { n: '/06', mid: <>Writing at <em>odd</em> hours.</>, bot: 'Notes · essays', w: 240, h: 170 },
    { n: '/07', mid: <>The <em>piano</em>, quietly.</>, bot: 'Music', w: 240, h: 170 },
    { n: '/08', mid: <><em>Yoga</em> & meditation.</>, bot: 'Practice · daily', w: 260, h: 170 },
    { n: '/09', mid: <><em>Coffee</em>, a lot of it.</>, bot: 'Ritual · morning', w: 240, h: 170 },
    { n: '/10', mid: <>Family first, <em>always</em>.</>, bot: 'Home', w: 240, h: 170 },
    { n: '/11', mid: <>Hans Zimmer, Nolan, <em>'90s cinema</em>.</>, bot: 'Cinema · scores', w: 320, h: 170 },
  ];
  const containerRef = useRef(null);
  const stageSize = useRef({ w: 1200, h: 640 });
  const bodies = useRef([]);
  const targets = useRef([]);         // resting positions
  const [, force] = useState(0);
  const rerender = () => force(v => v + 1);
  const dragRef = useRef(null);
  const startedRef = useRef(false);
  const fallenRef = useRef(new Set()); // which cards have started falling (staggered)
  const fallClockRef = useRef(0);
  const scaleRef = useRef(1);
  const sizedFacets = () => facets.map(f => ({ ...f, w: f.w * scaleRef.current, h: f.h * scaleRef.current }));

  // Compute a dense, brick-like target layout inside stage
  const computeTargets = useCallback(() => {
    const W = stageSize.current.w;
    const H = stageSize.current.h;
    // On narrow stages, shrink everything uniformly so rows can still fit 2–3 per row.
    let scale = 1;
    if (W < 700) scale = Math.max(0.55, W / 760);
    scaleRef.current = scale;
    const GAP_X = 14 * scale;
    const GAP_Y = 14 * scale;
    const ROW_H = 170 * scale;
    const fs = sizedFacets();
    // Greedy pack rows
    const rows = [];
    let row = { items: [], width: 0 };
    for (let i = 0; i < fs.length; i++) {
      const f = fs[i];
      const extra = row.items.length === 0 ? f.w : f.w + GAP_X;
      if (row.width + extra > W - 40) {
        rows.push(row);
        row = { items: [], width: 0 };
      }
      const extra2 = row.items.length === 0 ? f.w : f.w + GAP_X;
      row.items.push(i);
      row.width += extra2;
    }
    if (row.items.length) rows.push(row);

    const totalRowsHeight = rows.length * ROW_H + (rows.length - 1) * GAP_Y;
    // Bottom-align rows so they fill the lower part of the stage — first row closest to bottom, last row on top.
    // That way collisions can't wedge a later-falling row on top of a still-mid-fall earlier one.
    const BOTTOM_PADDING = 20;
    let y = H - BOTTOM_PADDING - totalRowsHeight;
    if (y < 10) y = 10;
    const nextTargets = new Array(facets.length);
    rows.forEach(r => {
      // center this row horizontally
      let x = (W - r.width) / 2;
      r.items.forEach(i => {
        nextTargets[i] = { x, y };
        x += fs[i].w + GAP_X;
      });
      y += ROW_H + GAP_Y;
    });
    targets.current = nextTargets;
  }, []);

  // Initialize: cards parked above the viewport, ready to drop
  const initBodies = useCallback(() => {
    const W = stageSize.current.w;
    bodies.current = facets.map((f, i) => ({
      x: targets.current[i] ? targets.current[i].x : 40 + (i * 90) % Math.max(200, W - 140),
      y: -260 - (i * 40),
      vx: 0,
      vy: 0,
    }));
    fallenRef.current = new Set();
    fallClockRef.current = 0;
  }, []);

  // Size observer
  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const update = () => {
      const rect = el.getBoundingClientRect();
      stageSize.current = { w: rect.width, h: rect.height };
      computeTargets();
      if (!startedRef.current) { initBodies(); rerender(); }
    };
    update();
    const ro = new ResizeObserver(update);
    ro.observe(el);
    return () => ro.disconnect();
  }, [computeTargets, initBodies]);

  // Trigger fall when section scrolls into view
  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting && !startedRef.current) {
          startedRef.current = true;
        }
      });
    }, { threshold: 0.25 });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);

  // Physics loop — attract to target, gentle damping, AABB collisions, no rotation
  useEffect(() => {
    let raf;
    const GRAVITY = 0.5;
    const DAMP = 0.88;
    const STAGGER_MS = 90;

    const loop = () => {
      const { w: W, h: H } = stageSize.current;
      const bs = bodies.current;
      const ts = targets.current;
      if (!bs.length || !ts.length) { raf = requestAnimationFrame(loop); return; }
      const fs = sizedFacets();

      // Stagger-release
      if (startedRef.current) {
        fallClockRef.current += 16;
        const maxIdx = Math.floor(fallClockRef.current / STAGGER_MS);
        for (let i = 0; i <= maxIdx && i < bs.length; i++) fallenRef.current.add(i);
      }

      // Integrate
      for (let i = 0; i < bs.length; i++) {
        const b = bs[i];
        const f = fs[i];
        if (dragRef.current?.i === i) continue;
        if (!fallenRef.current.has(i)) continue;

        const t = ts[i];
        // Pull horizontally toward target x (spring-ish, weak)
        const dx = t.x - b.x;
        b.vx += dx * 0.04;
        b.vx *= DAMP;
        // Gravity
        b.vy += GRAVITY;
        b.vy *= 0.995;

        b.x += b.vx;
        b.y += b.vy;

        // Floor clamp at target.y (so they land where intended, not at bottom)
        if (b.y >= t.y) {
          b.y = t.y;
          // Small bounce with heavy damping
          if (b.vy > 1.2) {
            b.vy = -b.vy * 0.18;
          } else {
            b.vy = 0;
          }
          // Settle horizontal
          if (Math.abs(b.vx) < 0.05 && Math.abs(dx) < 0.5) {
            b.vx = 0;
            b.x = t.x;
          }
        }
        // Walls
        if (b.x < 0) { b.x = 0; b.vx = Math.abs(b.vx) * 0.3; }
        if (b.x + f.w > W) { b.x = W - f.w; b.vx = -Math.abs(b.vx) * 0.3; }
      }

      // Mark landed cards for collision purposes — only landed cards are solid.
      const landed = new Set();
      for (let i = 0; i < bs.length; i++) {
        if (!fallenRef.current.has(i)) continue;
        const b = bs[i], t = ts[i];
        if (b.y >= t.y - 0.5 && Math.abs(b.vy) < 0.5 && Math.abs(b.vx) < 0.5) landed.add(i);
      }

      // AABB collisions — only resolve against LANDED cards and the dragged card.
      // This prevents mid-fall cards from wedging on each other.
      for (let i = 0; i < bs.length; i++) {
        if (!fallenRef.current.has(i) && dragRef.current?.i !== i) continue;
        if (landed.has(i) && dragRef.current?.i !== i) continue; // landed doesn't move
        for (let j = 0; j < bs.length; j++) {
          if (i === j) continue;
          const bothSolid = landed.has(j) || dragRef.current?.i === j;
          if (!bothSolid) continue;
          const a = bs[i], b = bs[j];
          const fa = fs[i], fb = fs[j];
          const ax2 = a.x + fa.w, ay2 = a.y + fa.h;
          const bx2 = b.x + fb.w, by2 = b.y + fb.h;
          if (a.x < bx2 && ax2 > b.x && a.y < by2 && ay2 > b.y) {
            const overlapX = Math.min(ax2 - b.x, bx2 - a.x);
            const overlapY = Math.min(ay2 - b.y, by2 - a.y);
            const draggedJ = dragRef.current?.i === j;
            if (overlapY < overlapX) {
              // Push A off of B vertically
              if (a.y < b.y) { a.y -= overlapY; if (a.vy > 0) a.vy = 0; }
              else           { a.y += overlapY; if (a.vy < 0) a.vy = 0; }
            } else {
              if (a.x < b.x) { a.x -= overlapX; a.vx = Math.min(a.vx, 0); }
              else           { a.x += overlapX; a.vx = Math.max(a.vx, 0); }
            }
          }
        }
      }

      rerender();
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);

  const onPointerDown = (i) => (e) => {
    e.preventDefault();
    e.currentTarget.setPointerCapture(e.pointerId);
    const rect = containerRef.current.getBoundingClientRect();
    const b = bodies.current[i];
    dragRef.current = {
      i,
      offX: (e.clientX - rect.left) - b.x,
      offY: (e.clientY - rect.top) - b.y,
      lastX: e.clientX,
      lastY: e.clientY,
    };
  };
  const onPointerMove = (i) => (e) => {
    const d = dragRef.current;
    if (!d || d.i !== i) return;
    const rect = containerRef.current.getBoundingClientRect();
    const b = bodies.current[i];
    const newX = e.clientX - rect.left - d.offX;
    const newY = e.clientY - rect.top - d.offY;
    b.vx = (e.clientX - d.lastX) * 0.3;
    b.vy = (e.clientY - d.lastY) * 0.3;
    b.x = newX;
    b.y = newY;
    d.lastX = e.clientX;
    d.lastY = e.clientY;
  };
  const onPointerUp = (i) => (e) => {
    if (dragRef.current?.i === i) dragRef.current = null;
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch {}
  };

  const reset = () => {
    startedRef.current = false;
    computeTargets();
    initBodies();
    rerender();
    // Release them again after a beat so the user sees the drop
    setTimeout(() => { startedRef.current = true; }, 200);
  };

  return (
    <section className="beyond" id="beyond" data-screen-label="05 Beyond">
      <div className="section-head">
        <div className="section-num">04 / Beyond Code</div>
        <h2 className="section-title">Off the <em>clock</em>.</h2>
        <div className="section-desc">Cards land when you<br />scroll. Drag to rearrange.</div>
      </div>
      <div className="beyond-hint">
        <span>◉ Drag any card — they settle back when released.</span>
        <button className="beyond-reset" onClick={reset}>↻ Drop again</button>
      </div>
      <div className="beyond-stage" ref={containerRef}>
        {(() => { const fs = sizedFacets(); return facets.map((f, i) => {
          const scaled = fs[i];
          const b = bodies.current[i] || { x: 0, y: -500 };
          const dragging = dragRef.current?.i === i;
          return (
            <div
              key={i}
              className={'facet-float' + (dragging ? ' dragging' : '')}
              style={{
                width: scaled.w,
                height: scaled.h,
                transform: `translate3d(${b.x}px, ${b.y}px, 0)`,
                zIndex: dragging ? 100 : i + 1,
              }}
              onPointerDown={onPointerDown(i)}
              onPointerMove={onPointerMove(i)}
              onPointerUp={onPointerUp(i)}
              onPointerCancel={onPointerUp(i)}
            >
              <div className="facet-placeholder" />
              <div className="facet-num">{f.n}</div>
              <div className="facet-mid">{f.mid}</div>
              <div className="facet-bot">{f.bot}</div>
            </div>
          );
        }); })()}
      </div>
    </section>
  );
}

// -------- Terminal / Console --------
function Console() {
  const [history, setHistory] = useState([
    { kind: 'out', text: 'fedecaccia.sh v3.0 — interactive console' },
    { kind: 'out', text: 'Powered by Claude (Anthropic). Not GPT — no API key needed.' },
    { kind: 'out', text: '' },
    { kind: 'out', text: 'JUST TYPE A QUESTION. Any language. The AI answers as Fede.' },
    { kind: 'out', text: '  → What\'s your take on AI agents?' },
    { kind: 'out', text: '  → ¿Por qué pasaste de nuclear a blockchain?' },
    { kind: 'out', text: '  → What keeps you up at night?' },
    { kind: 'out', text: '  → Recommend a book.' },
    { kind: 'out', text: '' },
    { kind: 'out', text: 'Or use a command: help · whoami · manifest · ventures · stack · now · journey · values · book · scene <mode>' },
  ]);
  const [cmd, setCmd] = useState('');
  const [busy, setBusy] = useState(false);
  const endRef = useRef(null);
  const inputRef = useRef(null);

  useEffect(() => {
    endRef.current?.parentElement?.scrollTo({
      top: endRef.current.parentElement.scrollHeight, behavior: 'smooth'
    });
  }, [history]);

  const commands = {
    help: () => [
      'AVAILABLE COMMANDS:',
      '  whoami          — who is Fede',
      '  manifest        — all my links',
      '  ventures        — companies I lead',
      '  stack           — tech I ship with',
      '  journey         — my trajectory in one paragraph',
      '  now             — what I am working on right now',
      '  values          — what I care about',
      '  book            — a book recommendation from me',
      '  ask <question>  — (optional) explicit prefix; you can also just type the question',
      '  contact         — how to reach me',
      '  scene <mode>    — toggle 3D: nucleus | network | particles',
      '  theme <color>   — accent: phosphor | xenon | plasma | amber | white',
      '  clear           — clear the console',
      '',
      'TRY AI: ask What do you think about <topic>?  (works in any language)',
    ],
    whoami: () => [
      '> Federico Caccia',
      '  M.Sc. Nuclear Engineer · Instituto Balseiro',
      '  Co-founder & CEO · Rather Labs',
      '  Based in Buenos Aires · Argentina',
      '  Building resilient systems since always.',
    ],
    manifest: () => [
      '  linkedin   · linkedin.com/in/fedecaccia',
      '  github     · github.com/fedecaccia',
      '  x          · x.com/fedeecaccia',
      '  instagram  · instagram.com/fedeeagusc',
      '  email      · fede@ratherlabs.com',
      '  research   · researchgate.net/profile/Federico-Caccia',
    ],
    ventures: () => [
      '  rather labs      · blockchain + AI engineering studio',
      '  rather ventures  · internal products (transcribego, …)',
      '  omnilane labs    · cross-chain infra',
      '  serviry          · healthtech / whatsapp-native',
      '  hatom labs       · tech advisor',
    ],
    stack: () => [
      '  languages      · typescript · python · solidity · rust · c/c++',
      '  web            · nextjs · react · three.js',
      '  chains         · evm · multiversx · solana · l2s',
      '  ai             · llms · rag · agents · fine-tuning',
      '  infra          · aws · gcp · k8s · terraform',
    ],
    contact: () => [
      '  → fede@ratherlabs.com',
      '  → dms on x / linkedin',
      '  Selective. Prefer a short note about what you\'re building.',
    ],
    now: () => [
      'CURRENTLY SHIPPING:',
      '  · Scaling Rather Labs (130+ engineers)',
      '  · Building Omnilane Labs — cross-chain infra',
      '  · Launching Serviry — healthtech via WhatsApp',
      '  · Deep into AI agents and LLM workflows',
      '  · Reading more psychology & neuroscience than ever',
    ],
    journey: () => [
      'Bariloche → Instituto Balseiro (Nuclear Eng.) → CNEA (C/C++, parallel systems)',
      ' → CoinFabrik (first blockchain) → co-founded Rather Labs (2020)',
      ' → 130+ people, 30+ partners, 10+ countries.',
      'Non-linear. Physics-first. Engineering-driven.',
    ],
    values: () => [
      '  · Build what you would trust your own money with',
      '  · Resilience over novelty',
      '  · Hire for autonomy, not compliance',
      '  · Keep shipping in public',
      '  · Take care of the body and mind that ships it',
    ],
    book: () => [
      'A rotating recommendation:',
      '  · Thinking, Fast and Slow — Daniel Kahneman',
      '  · The Beginning of Infinity — David Deutsch',
      '  · Man\'s Search for Meaning — Viktor Frankl',
      '  · Poor Charlie\'s Almanack — Charlie Munger',
      'Try `ask book about <topic>` for a tailored pick.',
    ],
    clear: () => { setHistory([]); return null; },
  };

  const handle = useCallback(async (raw) => {
    const input = raw.trim();
    if (!input) return;
    const lower = input.toLowerCase();
    const log = (lines) => setHistory(h => [...h, { kind: 'cmd', text: input }, ...(lines||[]).map(l => ({ kind: 'out', text: l }))]);

    if (lower === 'clear') { setHistory([]); return; }
    if (lower.startsWith('scene ')) {
      const mode = lower.slice(6).trim();
      if (['nucleus','network','particles'].includes(mode)) {
        window.__scene?.setMode(mode);
        log([`✓ 3D scene → ${mode}`]);
      } else {
        log([`✗ unknown scene. try: nucleus | network | particles`]);
      }
      return;
    }
    if (lower.startsWith('theme ')) {
      const map = { phosphor: '#00ff88', xenon: '#7cc3ff', plasma: '#ff3d8a', amber: '#ffb13d', white: '#ffffff' };
      const c = map[lower.slice(6).trim()];
      if (c) {
        document.documentElement.style.setProperty('--accent', c);
        window.__scene?.setAccent(c);
        log([`✓ accent → ${c}`]);
      } else {
        log(['✗ unknown theme. try: phosphor | xenon | plasma | amber | white']);
      }
      return;
    }
    if (lower.startsWith('ask ')) {
      const q = input.slice(4).trim();
      if (!q) { log(['✗ usage: ask <your question>']); return; }
      setHistory(h => [...h, { kind: 'cmd', text: input }, { kind: 'out', text: '⧗ thinking…' }]);
      setBusy(true);
      try {
        const res = await fetch('/api/chat', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ question: q }),
        });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = await res.json();
        const reply = data.reply || '✗ Empty response from AI.';
        setHistory(h => {
          const cleaned = h.slice(0, -1);
          return [...cleaned, { kind: 'out', text: reply.trim() }];
        });
      } catch (e) {
        setHistory(h => {
          const cleaned = h.slice(0, -1);
          return [...cleaned, { kind: 'out', text: '✗ AI channel unreachable. Try again or email fede@ratherlabs.com' }];
        });
      }
      setBusy(false);
      return;
    }
    const fn = commands[lower];
    if (fn) {
      const lines = fn();
      if (lines) log(lines);
      return;
    }
    // Anything else — treat as a free-form question for the AI
    setHistory(h => [...h, { kind: 'cmd', text: input }, { kind: 'out', text: '⧗ thinking…' }]);
    setBusy(true);
    try {
      const res = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ question: input }),
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      const reply = data.reply || '✗ Empty response from AI.';
      setHistory(h => {
        const cleaned = h.slice(0, -1);
        return [...cleaned, { kind: 'out', text: reply.trim() }];
      });
    } catch (e) {
      setHistory(h => {
        const cleaned = h.slice(0, -1);
        return [...cleaned, { kind: 'out', text: '✗ AI channel unreachable. Try again or email fede@ratherlabs.com' }];
      });
    }
    setBusy(false);
  }, []);

  return (
    <section className="terminal-section" id="console" data-screen-label="06 Console">
      <div className="section-head">
        <div className="section-num">05 / Console</div>
        <h2 className="section-title">Ask me <em>anything</em>.</h2>
        <div className="section-desc">AI-powered.<br />Try `ask …`</div>
      </div>
      <div className="terminal" onClick={() => inputRef.current?.focus()}>
        <div className="terminal-bar">
          <div className="dots"><span /><span /><span /></div>
          <div>FEDECACCIA.SH · AI_ENABLED</div>
          <div>{busy ? 'PROCESSING' : 'READY'}</div>
        </div>
        <div className="terminal-body">
          {history.map((h, i) => (
            <div key={i} className={'terminal-line ' + h.kind}>{h.text}</div>
          ))}
          <div ref={endRef} />
        </div>
        <form className="terminal-prompt" onSubmit={e => {
          e.preventDefault();
          if (busy) return;
          handle(cmd);
          setCmd('');
        }}>
          <span style={{ color: 'var(--accent)' }}>❯</span>
          <input
            ref={inputRef}
            value={cmd}
            onChange={e => setCmd(e.target.value)}
            placeholder={busy ? 'thinking…' : 'type a question in any language… (or a command)'}
            spellCheck={false}
            autoComplete="off"
            disabled={busy}
          />
          <span className="blink">▍</span>
        </form>
      </div>
    </section>
  );
}

// -------- Contact / Footer --------
function Contact() {
  return (
    <>
      <section className="contact" id="contact" data-screen-label="07 Contact">
        <div className="contact-eyebrow">/ get in touch</div>
        <h2 className="contact-title">
          Let's <em>build</em><br />something.
        </h2>
        <a className="contact-cta" href="mailto:fede@ratherlabs.com">
          fede@ratherlabs.com <span>↗</span>
        </a>
        <div className="social-strip">
          <a href="https://linkedin.com/in/fedecaccia" target="_blank" rel="noopener">→ linkedin</a>
          <a href="https://github.com/fedecaccia" target="_blank" rel="noopener">→ github</a>
          <a href="https://x.com/fedeecaccia" target="_blank" rel="noopener">→ x</a>
          <a href="https://www.instagram.com/fedeeagusc" target="_blank" rel="noopener">→ instagram</a>
          <a href="https://www.researchgate.net/profile/Federico-Caccia" target="_blank" rel="noopener">→ researchgate</a>
        </div>
      </section>
      <footer className="footer-mark">
        <div>© 2026 · Federico Caccia</div>
        <div>FC·v3.0 · made in Buenos Aires</div>
      </footer>
    </>
  );
}

// -------- Tweaks panel --------
function TweaksPanel({ open, tweaks, set }) {
  const accents = [
    { name: 'Phosphor', val: '#00ff88' },
    { name: 'Xenon', val: '#7cc3ff' },
    { name: 'Plasma', val: '#ff3d8a' },
    { name: 'Amber', val: '#ffb13d' },
    { name: 'White', val: '#ffffff' },
  ];
  return (
    <div className={'tweaks-panel' + (open ? ' open' : '')}>
      <h4>
        <span>TWEAKS</span>
        <span style={{ color: 'var(--ink-mute)' }}>v3.0</span>
      </h4>

      <label>Accent color</label>
      <div className="color-row">
        {accents.map(a => (
          <div key={a.val}
               className={'swatch' + (tweaks.accent === a.val ? ' active' : '')}
               style={{ background: a.val }}
               onClick={() => set({ accent: a.val })}
               title={a.name} />
        ))}
      </div>

      <label>3D scene</label>
      <select value={tweaks.sceneMode} onChange={e => set({ sceneMode: e.target.value })}>
        <option value="nucleus">Nucleus — atomic core</option>
        <option value="network">Network — blockchain nodes</option>
        <option value="particles">Particles — free cloud</option>
      </select>

      <label>Serif family</label>
      <select value={tweaks.serif} onChange={e => set({ serif: e.target.value })}>
        <option value="Instrument Serif">Instrument Serif</option>
        <option value="Geist">Geist Sans (no serif)</option>
      </select>

      <div className="row">
        <label style={{ margin: 0 }}>Grid overlay</label>
        <div className={'toggle' + (tweaks.showGrid ? ' on' : '')}
             onClick={() => set({ showGrid: !tweaks.showGrid })} />
      </div>
      <div className="row">
        <label style={{ margin: 0 }}>Status bar</label>
        <div className={'toggle' + (tweaks.showTerminal ? ' on' : '')}
             onClick={() => set({ showTerminal: !tweaks.showTerminal })} />
      </div>
    </div>
  );
}

Object.assign(window, {
  TopBar, StatusBar, Hero, About, Ventures, Timeline, Beyond, Console, Contact, TweaksPanel
});
