// Direction 1 — "PERSONAL COMPUTER"
// The site IS a desktop OS. A nanobot lives in the corner.
// Sections are windows. Phosphor green + deep ink + mono.

const D1 = {
  ink: '#0a0e0a',
  ink2: '#121712',
  panel: '#0f1410',
  panel2: '#161c17',
  line: '#1f2a20',
  line2: '#2a3a2c',
  fg: '#cfe6cd',
  dim: '#7a9477',
  amber: '#e6c07a',
  green: '#7ee27a',
  red: '#ff7a7a',
  font: '"JetBrains Mono", "IBM Plex Mono", ui-monospace, monospace',
};

function D1Frame({ children }) {
  return (
    <div style={{
      width: '100%', height: '100%', background: D1.ink, color: D1.fg,
      fontFamily: D1.font, fontSize: 13, lineHeight: 1.5, overflow: 'hidden',
      position: 'relative',
      backgroundImage: `radial-gradient(ellipse at 50% 0%, rgba(126,226,122,0.06), transparent 60%), repeating-linear-gradient(0deg, rgba(126,226,122,0.025) 0 1px, transparent 1px 3px)`,
    }}>
      {children}
    </div>
  );
}

function D1MenuBar({ active, onNav }) {
  const mobile = useIsMobile();
  const items = ['HOME', 'INTRO', 'HISTORY', 'PORTFOLIO', 'CONTACT'];
  return (
    <div style={{
      height: 28, borderBottom: `1px solid ${D1.line2}`, background: D1.panel,
      display: 'flex', alignItems: 'center',
      padding: mobile ? '0 8px' : '0 200px 0 12px',
      fontSize: mobile ? 9 : 11, letterSpacing: 1.5, color: D1.dim,
      overflow: 'hidden',
    }}>
      <div style={{ color: D1.green, marginRight: mobile ? 6 : 18, flexShrink: 0 }}>◆ NJF/OS</div>
      {items.map(it => (
        <div key={it} onClick={() => onNav(it)} style={{
          padding: mobile ? '0 6px' : '0 12px', cursor: 'pointer', flexShrink: 0,
          color: active === it ? D1.fg : D1.dim,
          background: active === it ? D1.line : 'transparent',
          height: '100%', display: 'flex', alignItems: 'center',
        }}>{mobile ? it.slice(0, 3) : it}</div>
      ))}
      {!mobile && <>
        <div style={{ flex: 1 }} />
        <div style={{ color: D1.dim }}>{D1Clock()}</div>
      </>}
    </div>
  );
}
function D1Clock() {
  const [t, setT] = React.useState('');
  React.useEffect(() => {
    const tick = () => {
      const d = new Date();
      setT(`GBG ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}:${String(d.getSeconds()).padStart(2,'0')}`);
    };
    tick(); const i = setInterval(tick, 1000); return () => clearInterval(i);
  }, []);
  return t;
}

function D1Window({ title, x, y, w, h, children, accent, footer }) {
  const flow = x === undefined && y === undefined;
  return (
    <div style={flow ? {
      position: 'relative', width: '100%', minHeight: h, marginBottom: 14,
      background: D1.panel, border: `1px solid ${D1.line2}`,
      display: 'flex', flexDirection: 'column',
    } : {
      position: 'absolute', left: x, top: y, width: w, height: h,
      background: D1.panel, border: `1px solid ${D1.line2}`,
      boxShadow: `0 0 0 1px ${D1.ink} inset, 0 20px 60px rgba(0,0,0,0.6)`,
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{
        height: 22, display: 'flex', alignItems: 'center', padding: '0 8px',
        borderBottom: `1px solid ${D1.line2}`, background: D1.ink2,
        fontSize: 10, letterSpacing: 1.5, color: D1.dim,
      }}>
        <span style={{ color: accent || D1.green, marginRight: 8 }}>●</span>
        <span style={{ color: D1.fg }}>{title}</span>
        <div style={{ flex: 1 }} />
        <span style={{ marginRight: 8 }}>—</span>
        <span style={{ marginRight: 8 }}>□</span>
        <span>×</span>
      </div>
      <div style={{ flex: 1, overflow: 'hidden', position: 'relative' }}>{children}</div>
      {footer && (
        <div style={{
          height: 18, borderTop: `1px solid ${D1.line2}`, background: D1.ink2,
          fontSize: 9, letterSpacing: 1.5, color: D1.dim, padding: '0 8px',
          display: 'flex', alignItems: 'center'
        }}>{footer}</div>
      )}
    </div>
  );
}

// ── HOME ──────────────────────────────────────────────
function D1HomeMobile({ data }) {
  return (
    <div style={{ position: 'absolute', inset: 0, overflow: 'auto', padding: '24px 16px' }}>
      <div style={{ color: D1.dim, fontSize: 9, letterSpacing: 3, marginBottom: 12 }}>
        ▸ /USERS/NICOLAS · SESSION 0xC0FFEE
      </div>
      <div style={{ color: D1.fg, fontSize: 40, lineHeight: 1, letterSpacing: -0.5,
        textShadow: '0 0 18px rgba(126,226,122,0.25)' }}>
        Nicolas<br/>
        <span style={{ color: D1.green, textShadow: '0 0 22px rgba(126,226,122,0.5)' }}>Finsterbusch.</span>
      </div>
      <div style={{ color: D1.dim, fontSize: 14, marginTop: 14, lineHeight: 1.4 }}>
        AI consultant. Delivery leader. Systems thinker.
      </div>
      <div style={{ color: D1.fg, opacity: 0.55, fontSize: 12, marginTop: 6, lineHeight: 1.5 }}>
        30 years shipping governance-aware systems for regulated industries.
      </div>

      <div style={{ marginTop: 20, fontSize: 11, color: D1.dim, lineHeight: 1.9 }}>
        <div><span style={{ color: D1.green }}>●</span> Available · Q2 2026 onwards</div>
        <div>Gothenburg · Remote across EU/UK</div>
        <div>No work permit required</div>
      </div>

      <div style={{ marginTop: 24 }}>
        <D1Window title="njf.bmp" h={260}>
          {data.portraitUrl ? (
            <img src={data.portraitUrl} alt="Nicolas Finsterbusch"
              onClick={() => window.NJF_LIGHTBOX.openSingle(data.portraitUrl, 'Nicolas Finsterbusch · Gothenburg')}
              style={{ width: '100%', height: '100%', objectFit: 'cover',
                filter: 'sepia(0.2) hue-rotate(70deg) saturate(0.7)',
                display: 'block', cursor: 'zoom-in' }} />
          ) : (
            <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: `repeating-linear-gradient(0deg, ${D1.panel} 0 1px, ${D1.ink2} 1px 2px)`,
              color: D1.dim, fontSize: 9, letterSpacing: 2 }}>[ NO PORTRAIT ]</div>
          )}
        </D1Window>

        <D1Window title="now.log" h={140} accent={D1.amber}>
          <div style={{ padding: 12, fontSize: 11, lineHeight: 1.7 }}>
            <div style={{ color: D1.dim }}>$ tail -f now.log</div>
            <div><span style={{ color: D1.amber }}>2026-05</span> Clinical AI screening · 84% acc.</div>
            <div><span style={{ color: D1.amber }}>2026-04</span> Digital twin · ~26.6k LOC Python</div>
            <div><span style={{ color: D1.amber }}>2026-03</span> Luna Fusion Bites · Q2 launch</div>
            <div><span style={{ color: D1.amber }}>2026-02</span> CareerAscend live</div>
          </div>
        </D1Window>

        <D1Window title="pillars.cfg" h={180}>
          <div style={{ padding: 12, fontSize: 11, lineHeight: 1.7 }}>
            {data.pillars.map(p => (
              <div key={p.tag} style={{ marginBottom: 6 }}>
                <span style={{ color: D1.dim }}>{p.tag} </span>
                <span style={{ color: D1.fg }}>{p.title.toUpperCase()}</span>
              </div>
            ))}
          </div>
        </D1Window>

        <D1Window title="languages" h={70}>
          <div style={{ padding: 12, fontSize: 11, lineHeight: 1.7, color: D1.dim }}>
            ES <span style={{ color: D1.fg }}>native</span> · DE <span style={{ color: D1.fg }}>native</span><br/>
            EN <span style={{ color: D1.fg }}>fluent</span> · SV <span style={{ color: D1.dim }}>beginner</span>
          </div>
        </D1Window>
      </div>
    </div>
  );
}

function D1Home({ data }) {
  if (useIsMobile()) return <D1HomeMobile data={data} />;
  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      {/* Big phosphor name */}
      <div style={{
        position: 'absolute', left: 60, top: 80, color: D1.fg,
        fontSize: 64, lineHeight: 1, letterSpacing: -1,
        textShadow: '0 0 24px rgba(126,226,122,0.25)',
      }}>
        <div style={{ color: D1.dim, fontSize: 11, letterSpacing: 4, marginBottom: 18 }}>
          ▸ /USERS/NICOLAS &nbsp;·&nbsp; SESSION 0xC0FFEE
        </div>
        <div>Nicolas</div>
        <div style={{ color: D1.green, textShadow: '0 0 30px rgba(126,226,122,0.5)' }}>Finsterbusch.</div>
        <div style={{ color: D1.dim, fontSize: 18, marginTop: 22, letterSpacing: 0, lineHeight: 1.4, maxWidth: 460 }}>
          AI consultant. Delivery leader. Systems thinker.
        </div>
        <div style={{ color: D1.fg, opacity: 0.55, fontSize: 13, marginTop: 6, lineHeight: 1.5, maxWidth: 460 }}>
          30 years shipping governance-aware systems for regulated industries.
        </div>
      </div>

      {/* Status block bottom-left */}
      <div style={{ position: 'absolute', left: 60, bottom: 70, fontSize: 11, color: D1.dim, lineHeight: 1.9 }}>
        <div><span style={{ color: D1.green }}>●</span> Available · Q2 2026 onwards</div>
        <div>Gothenburg · Remote across EU/UK</div>
        <div>No work permit required</div>
      </div>

      {/* Floating windows */}
      <D1Window title="now.log" x={640} y={70} w={300} h={150} accent={D1.amber}>
        <div style={{ padding: 12, fontSize: 11, lineHeight: 1.7 }}>
          <div style={{ color: D1.dim }}>$ tail -f now.log</div>
          <div><span style={{ color: D1.amber }}>2026-05</span> Clinical AI screening · 84% acc.</div>
          <div><span style={{ color: D1.amber }}>2026-04</span> Digital twin · ~26.6k LOC Python</div>
          <div><span style={{ color: D1.amber }}>2026-03</span> Luna Fusion Bites · Q2 launch</div>
          <div><span style={{ color: D1.amber }}>2026-02</span> CareerAscend live</div>
          <div style={{ color: D1.green, marginTop: 6 }}>▌</div>
        </div>
      </D1Window>

      <D1Window title="pillars.cfg" x={640} y={240} w={300} h={210}>
        <div style={{ padding: 12, fontSize: 11, lineHeight: 1.7 }}>
          {data.pillars.map(p => (
            <div key={p.tag} style={{ marginBottom: 8 }}>
              <span style={{ color: D1.dim }}>{p.tag} </span>
              <span style={{ color: D1.fg }}>{p.title.toUpperCase()}</span>
            </div>
          ))}
        </div>
      </D1Window>

      <D1Window title="languages" x={640} y={470} w={300} h={86}>
        <div style={{ padding: 12, fontSize: 11, lineHeight: 1.7, color: D1.dim }}>
          ES <span style={{ color: D1.fg }}>native</span> · DE <span style={{ color: D1.fg }}>native</span><br/>
          EN <span style={{ color: D1.fg }}>fluent</span> · SV <span style={{ color: D1.dim }}>beginner</span>
        </div>
      </D1Window>

      <D1Window title="njf.bmp" x={60} y={320} w={200} h={220}>
        {data.portraitUrl ? (
          <img src={data.portraitUrl} alt="Nicolas Finsterbusch"
            onClick={() => window.NJF_LIGHTBOX.openSingle(data.portraitUrl, 'Nicolas Finsterbusch · Gothenburg')}
            style={{
              width: '100%', height: '100%', objectFit: 'cover',
              filter: 'sepia(0.2) hue-rotate(70deg) saturate(0.7)',
              display: 'block', cursor: 'zoom-in',
            }} />
        ) : (
          <div style={{
            height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center',
            background: `repeating-linear-gradient(0deg, ${D1.panel} 0 1px, ${D1.ink2} 1px 2px)`,
            color: D1.dim, fontSize: 9, letterSpacing: 2,
          }}>[ NO PORTRAIT ]</div>
        )}
      </D1Window>
    </div>
  );
}

// ── INTRO ─────────────────────────────────────────────
function D1Intro({ data }) {
  const mobile = useIsMobile();
  return (
    <div style={{ position: 'absolute', inset: 0, padding: mobile ? '24px 16px' : '60px 60px 40px', overflow: 'auto' }}>
      <div style={{ color: D1.dim, fontSize: 11, letterSpacing: 4, marginBottom: mobile ? 12 : 18 }}>▸ CAT INTRO.MD</div>
      <div style={{ color: D1.fg, fontSize: mobile ? 24 : 36, lineHeight: 1.15, marginBottom: mobile ? 20 : 28, maxWidth: 760 }}>
        I'm <span style={{ color: D1.green }}>Nicolas</span>. I ship AI systems that pass audits, and lead the teams that maintain them.
      </div>
      <div style={{ display: mobile ? 'block' : 'flex', gap: 32, maxWidth: 1100, alignItems: 'flex-start' }}>
        {data.portraitUrl && (
          <div style={{ width: mobile ? '100%' : 220, flexShrink: 0, border: `1px solid ${D1.line2}`, background: D1.panel,
            marginBottom: mobile ? 20 : 0 }}>
            <div style={{ height: 22, padding: '0 10px', borderBottom: `1px solid ${D1.line2}`, background: D1.ink2,
              display: 'flex', alignItems: 'center', fontSize: 9, letterSpacing: 2, color: D1.green }}>
              ● njf.bmp
            </div>
            <img src={data.portraitUrl} alt="Nicolas Finsterbusch"
              onClick={() => window.NJF_LIGHTBOX.openSingle(data.portraitUrl, 'Nicolas Finsterbusch · Gothenburg')}
              style={{
                display: 'block', width: '100%', aspectRatio: '4 / 5', objectFit: 'cover',
                filter: 'sepia(0.2) hue-rotate(70deg) saturate(0.7) contrast(1.05)',
                cursor: 'zoom-in',
              }} />
            <div style={{ padding: '8px 10px', fontSize: 10, color: D1.dim, letterSpacing: 1.5 }}>
              ▸ NICOLAS · GOTHENBURG · 2026
            </div>
          </div>
        )}
        <div style={{ flex: 1, display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: mobile ? 16 : 32 }}>
          {data.intro.map((p, i) => (
            <div key={i} style={{ color: D1.fg, opacity: 0.85, fontSize: 13, lineHeight: 1.7 }}>
              <span style={{ color: D1.dim, marginRight: 8 }}>{String(i+1).padStart(2,'0')}</span>{p}
            </div>
          ))}
        </div>
      </div>

      <div style={{ marginTop: mobile ? 28 : 40, borderTop: `1px solid ${D1.line2}`, paddingTop: 24 }}>
        <div style={{ color: D1.dim, fontSize: 10, letterSpacing: 3, marginBottom: 16 }}>CAPABILITIES</div>
        <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : 'repeat(4,1fr)', gap: mobile ? 12 : 16 }}>
          {data.pillars.map(p => (
            <div key={p.tag} style={{ border: `1px solid ${D1.line2}`, padding: 16, background: D1.panel }}>
              <div style={{ color: D1.green, fontSize: 10, marginBottom: 8 }}>{p.tag}</div>
              <div style={{ color: D1.fg, fontSize: 14, marginBottom: 8 }}>{p.title}</div>
              <div style={{ color: D1.dim, fontSize: 11, lineHeight: 1.6 }}>{p.body}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── HISTORY ───────────────────────────────────────────
function D1History({ data }) {
  const mobile = useIsMobile();
  return (
    <div style={{ position: 'absolute', inset: 0, padding: mobile ? '24px 16px' : '60px 60px 40px', overflow: 'auto' }}>
      <div style={{ display: mobile ? 'block' : 'flex', alignItems: 'flex-start', gap: 24 }}>
        <div style={{ flex: 1 }}>
          <div style={{ color: D1.dim, fontSize: 11, letterSpacing: 4, marginBottom: mobile ? 12 : 18 }}>▸ LS -LA /CAREER</div>
          <div style={{ color: D1.fg, fontSize: mobile ? 22 : 28, marginBottom: 8 }}>30 years. 15 chapters.</div>
          <div style={{ color: D1.dim, fontSize: 13, marginBottom: mobile ? 18 : 32 }}>Buenos Aires → London → Gothenburg.</div>
        </div>
        <a href={'https://' + data.linkedin} target="_blank" rel="noopener noreferrer" style={{
          color: D1.green, fontSize: 11, letterSpacing: 2, textDecoration: 'none',
          border: `1px solid ${D1.line2}`, padding: '8px 14px', whiteSpace: 'nowrap',
          display: mobile ? 'inline-block' : undefined, marginBottom: mobile ? 20 : 0,
        }}>↗ FULL CAREER ON LINKEDIN</a>
      </div>

      <div style={{ borderTop: `1px solid ${D1.line2}` }}>
          {data.history.map((h, i) => (
            <div key={i} style={{
              display: 'grid',
              gridTemplateColumns: mobile ? '90px 1fr' : '120px 1fr 1fr 1.4fr',
              gap: mobile ? 12 : 24, padding: '14px 0', borderBottom: `1px solid ${D1.line}`,
              fontSize: 12, alignItems: 'baseline',
            }}>
              <div style={{ color: D1.amber, fontSize: mobile ? 11 : 12 }}>{h.year}</div>
              <div>
                <div style={{ color: D1.fg }}>{h.role}</div>
                <div style={{ color: D1.dim, fontSize: 11, marginTop: 2 }}>{h.org} · {h.place}</div>
                {mobile && <div style={{ color: D1.fg, opacity: 0.7, fontSize: 11, lineHeight: 1.55, marginTop: 6 }}>{h.note}</div>}
              </div>
              {!mobile && <div style={{ color: D1.dim }}>{h.org} · {h.place}</div>}
              {!mobile && <div style={{ color: D1.fg, opacity: 0.75, fontSize: 11, lineHeight: 1.6 }}>{h.note}</div>}
            </div>
          ))}
      </div>
    </div>
  );
}

// ── PORTFOLIO ─────────────────────────────────────────
function D1Portfolio({ data }) {
  const sectors = React.useMemo(
    () => ['All', ...Array.from(new Set(data.projects.map(p => p.sector).filter(Boolean)))],
    [data.projects]
  );
  const [filter, setFilter] = React.useState('All');
  const filtered = React.useMemo(
    () => filter === 'All' ? data.projects : data.projects.filter(p => p.sector === filter),
    [data.projects, filter]
  );
  const [selId, setSelId] = React.useState(filtered[0] && filtered[0].id);
  React.useEffect(() => {
    if (!filtered.find(p => p.id === selId)) setSelId(filtered[0] && filtered[0].id);
  }, [filtered, selId]);
  const p = filtered.find(x => x.id === selId) || filtered[0];

  const mobile = useIsMobile();

  if (!p) {
    return <div style={{ padding: 60, color: D1.dim }}>No projects in this filter.</div>;
  }

  return (
    <div style={{ position: 'absolute', inset: 0,
      display: mobile ? 'flex' : 'grid',
      flexDirection: mobile ? 'column' : undefined,
      gridTemplateColumns: mobile ? undefined : '300px 1fr' }}>
      {/* Project list */}
      <div style={{
        borderRight: mobile ? 'none' : `1px solid ${D1.line2}`,
        borderBottom: mobile ? `1px solid ${D1.line2}` : 'none',
        background: D1.panel, overflow: 'auto', display: 'flex',
        flexDirection: 'column',
        flexShrink: 0,
        maxHeight: mobile ? '50vh' : undefined,
      }}>
        <div style={{ padding: '14px 12px 8px', color: D1.dim, fontSize: 10, letterSpacing: 3 }}>
          ▸ PROJECTS / {filtered.length}{filter !== 'All' && <span style={{ color: D1.dim2 }}> of {data.projects.length}</span>}
        </div>
        <div style={{ padding: '0 12px 10px', display: 'flex', gap: 4, flexWrap: 'wrap', borderBottom: `1px solid ${D1.line}` }}>
          {sectors.map(s => (
            <div key={s} onClick={() => setFilter(s)} style={{
              fontSize: 9, letterSpacing: 1, padding: '4px 8px', cursor: 'pointer',
              border: `1px solid ${filter === s ? D1.green : D1.line2}`,
              color: filter === s ? D1.green : D1.dim,
              background: filter === s ? 'rgba(126,226,122,0.08)' : 'transparent',
              textTransform: 'uppercase',
            }}>{s}</div>
          ))}
        </div>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {filtered.map(pr => (
            <div key={pr.id} onClick={() => setSelId(pr.id)} style={{
              padding: '12px 14px', cursor: 'pointer',
              borderTop: `1px solid ${D1.line}`,
              background: pr.id === selId ? D1.line : 'transparent',
              borderLeft: `2px solid ${pr.id === selId ? D1.green : 'transparent'}`,
            }}>
              <div style={{ color: D1.dim, fontSize: 10 }}>{pr.n} · {pr.year}</div>
              <div style={{ color: D1.fg, fontSize: 13, marginTop: 4 }}>{pr.title}</div>
              <div style={{ color: D1.dim, fontSize: 10, marginTop: 2 }}>{pr.kicker}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Detail */}
      <div style={{ padding: mobile ? '24px 16px' : '40px 40px 30px', overflow: 'auto', flex: mobile ? 1 : undefined }}>
        <div style={{ color: D1.dim, fontSize: 10, letterSpacing: 3 }}>{p.sector.toUpperCase()} · {p.year}</div>
        <div style={{ color: D1.fg, fontSize: mobile ? 24 : 36, marginTop: 12, lineHeight: 1.1 }}>{p.title}</div>
        <div style={{ color: D1.green, fontSize: 13, marginTop: 6 }}>{p.kicker}</div>

        {(p.live_url || p.liveUrl) && (
          <a href={p.live_url || p.liveUrl} target="_blank" rel="noopener noreferrer" style={{
            display: 'inline-block', marginTop: 14, padding: '8px 14px',
            background: D1.green, color: D1.ink, textDecoration: 'none',
            fontSize: 11, letterSpacing: 2, fontFamily: D1.font,
            boxShadow: '0 0 12px rgba(126,226,122,0.35)',
          }}>▸ VIEW LIVE ↗ {(p.live_url || p.liveUrl).replace(/^https?:\/\//, '').replace(/\/$/, '').toUpperCase()}</a>
        )}

        <div style={{ marginTop: 18, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          {p.tags.map(t => (
            <span key={t} style={{
              fontSize: 10, color: D1.dim, padding: '3px 8px',
              border: `1px solid ${D1.line2}`,
            }}>{t}</span>
          ))}
        </div>

        <div style={{ marginTop: 24, color: D1.fg, opacity: 0.85, fontSize: 13, lineHeight: 1.7, maxWidth: 620 }}>
          {p.summary}
        </div>

        {/* Cover image */}
        {p.cover_url && (
          <div onClick={() => window.NJF_LIGHTBOX.openProject(p, 0)} style={{
            marginTop: 22, maxWidth: 820,
            border: `1px solid ${D1.line2}`, background: D1.panel,
            position: 'relative', overflow: 'hidden',
            aspectRatio: p.legacy ? '4 / 3' : '16 / 9',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            cursor: 'zoom-in',
          }}>
            <div style={{
              position: 'absolute', top: 6, left: 8, fontSize: 9, letterSpacing: 2,
              color: D1.green, opacity: 0.7, zIndex: 1,
            }}>▸ {p.title.toUpperCase()}.JPG</div>
            <img src={p.cover_url} alt={p.title} style={{
              maxWidth: '100%', maxHeight: '100%',
              width: p.legacy ? 'auto' : '100%', height: p.legacy ? 'auto' : '100%',
              objectFit: p.legacy ? 'contain' : 'cover',
              display: 'block',
            }} />
          </div>
        )}

        {/* Metrics */}
        <div style={{ marginTop: 30, display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10, maxWidth: 620 }}>
          {p.metrics.map((m, i) => (
            <div key={i} style={{ border: `1px solid ${D1.line2}`, padding: '14px 16px' }}>
              <div style={{ color: D1.green, fontSize: 22, lineHeight: 1.1, textShadow: '0 0 14px rgba(126,226,122,0.4)' }}>{m.v}</div>
              <div style={{ color: D1.dim, fontSize: 10, marginTop: 4, letterSpacing: 1 }}>{m.k.toUpperCase()}</div>
            </div>
          ))}
        </div>

        {/* Gallery */}
        {Array.isArray(p.gallery) && p.gallery.length > 0 && (
          <div style={{ marginTop: 28, maxWidth: 820 }}>
            <div style={{ color: D1.dim, fontSize: 10, letterSpacing: 3, marginBottom: 10 }}>▸ GALLERY ({p.gallery.length})</div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
              {p.gallery.map((g, i) => {
                const url = typeof g === 'string' ? g : g.url;
                const cap = typeof g === 'string' ? null : g.caption;
                const startIdx = (p.cover_url ? 1 : 0) + i;
                return (
                  <div key={i} onClick={() => window.NJF_LIGHTBOX.openProject(p, startIdx)}
                    style={{ border: `1px solid ${D1.line2}`, background: D1.panel, cursor: 'zoom-in' }}>
                    <div style={{ aspectRatio: p.legacy ? '4 / 3' : '4 / 3', overflow: 'hidden' }}>
                      <img src={url} alt={cap || ''} style={{ width: '100%', height: '100%', objectFit: p.legacy ? 'contain' : 'cover', display: 'block' }} />
                    </div>
                    {cap && <div style={{ padding: '6px 8px', fontSize: 9, color: D1.dim, letterSpacing: 1 }}>▸ {cap}</div>}
                  </div>
                );
              })}
            </div>
          </div>
        )}

        <div style={{ marginTop: 24, color: D1.fg, opacity: 0.7, fontSize: 12, lineHeight: 1.7, maxWidth: 620 }}>
          {p.body}
        </div>
      </div>
    </div>
  );
}

// ── CONTACT ───────────────────────────────────────────
function D1Contact({ data }) {
  const mobile = useIsMobile();
  const [name, setName] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [message, setMessage] = React.useState('');
  const [status, setStatus] = React.useState('idle'); // idle | sending | sent | error

  const submit = async () => {
    if (!name.trim() || !email.trim() || !message.trim() || status === 'sending') return;
    setStatus('sending');
    const ok = window.NJF_NANOBOT && await window.NJF_NANOBOT.submitContact({
      name: name.trim(), email: email.trim(), message: message.trim(),
      variant: window.NJF_AB && window.NJF_AB.getVariant(),
      referrer: document.referrer || null,
    });
    if (ok) {
      window.NJF_AB && window.NJF_AB.logEvent('contact', { source: 'form' });
      setStatus('sent'); setName(''); setEmail(''); setMessage('');
    } else {
      setStatus('error');
    }
  };

  const inp = {
    width: '100%', padding: '10px 0', background: 'transparent',
    border: 'none', borderBottom: `1px solid ${D1.line2}`, color: D1.fg,
    fontFamily: D1.font, fontSize: 12, outline: 'none', marginBottom: 12,
  };

  return (
    <div style={{ position: 'absolute', inset: 0,
      padding: mobile ? '24px 16px' : '80px 60px',
      display: 'grid',
      gridTemplateColumns: mobile ? '1fr' : '1fr 1fr',
      gap: mobile ? 24 : 40,
      overflow: 'auto' }}>
      <div>
        <div style={{ color: D1.dim, fontSize: 11, letterSpacing: 4, marginBottom: 18 }}>▸ ESTABLISH CONNECTION</div>
        <div style={{ color: D1.fg, fontSize: mobile ? 28 : 44, lineHeight: 1.05, marginBottom: 18 }}>
          Let's talk about <span style={{ color: D1.green }}>your</span><br/>AI delivery problem.
        </div>
        <div style={{ color: D1.fg, opacity: 0.65, fontSize: 13, lineHeight: 1.7, maxWidth: 460, marginBottom: 24 }}>
          Best fits: applied AI architecture, governance-aware deployments, fractional delivery leadership for regulated programmes, AI-product strategy.
        </div>
        {[
          ['EMAIL', data.email],
          ['PHONE', data.phone],
          ['LINKEDIN', '/in/nicolasfinsterbusch'],
          ['LOCATION', 'Gothenburg, Sweden'],
        ].map(([k, v]) => (
          <div key={k} style={{ padding: '10px 0', borderTop: `1px solid ${D1.line}`, display: 'flex' }}>
            <div style={{ color: D1.dim, fontSize: 10, width: 90 }}>{k}</div>
            <div style={{ color: D1.fg, fontSize: 12 }}>{v}</div>
          </div>
        ))}
      </div>

      <div style={{ border: `1px solid ${D1.line2}`, padding: 24, background: D1.panel, alignSelf: 'start' }}>
        <div style={{ color: D1.dim, fontSize: 10, letterSpacing: 3, marginBottom: 14 }}>HANDSHAKE</div>
        <input value={name} onChange={(e) => setName(e.target.value)} placeholder="YOUR NAME" style={inp} />
        <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="YOUR EMAIL" type="email" style={inp} />
        <textarea value={message} onChange={(e) => setMessage(e.target.value)} placeholder="WHAT ARE YOU TRYING TO SHIP?"
          style={{ ...inp, height: 110, resize: 'none', marginBottom: 6 }} />
        <button onClick={submit} disabled={status === 'sending'} style={{
          marginTop: 12, width: '100%', padding: '12px',
          background: status === 'sent' ? D1.line2 : D1.green, color: D1.ink, border: 'none',
          fontFamily: D1.font, fontSize: 11, letterSpacing: 3,
          cursor: status === 'sending' ? 'wait' : 'pointer', opacity: status === 'sending' ? 0.6 : 1,
        }}>{
          status === 'sending' ? 'TRANSMITTING…' :
          status === 'sent'    ? '◆ PACKET RECEIVED'  :
          status === 'error'   ? 'RETRY ▸ (FAILED)'   :
                                 'SEND PACKET ▸'
        }</button>
        {status === 'error' && (
          <div style={{ marginTop: 10, color: D1.dim, fontSize: 10, letterSpacing: 1 }}>
            Connection refused. Try email: {data.email}
          </div>
        )}
      </div>
    </div>
  );
}

// ── NANOBOT (chat) ────────────────────────────────────
function D1Thinking({ color }) {
  const [n, setN] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setN(x => (x + 1) % 4), 350);
    return () => clearInterval(id);
  }, []);
  return <span style={{ color, opacity: 0.7 }}>{'·'.repeat(n) + ' '.repeat(3 - n)}</span>;
}

function D1Nanobot({ data, onNav }) {
  const mobile = useIsMobile();
  const [open, setOpen] = React.useState(!mobile);
  const [messages, setMessages] = React.useState([
    { from: 'bot', text: 'NANOBOT v0.4 online. I speak as Nicolas. Ask me anything about my work, history, or projects.' },
    { from: 'bot', text: 'Try: "show me the XC40 numbers" or "what are you working on now?"' },
  ]);
  const [input, setInput] = React.useState('');
  const ref = React.useRef(null);
  React.useEffect(() => { if (ref.current) ref.current.scrollTop = ref.current.scrollHeight; }, [messages]);

  const localRespond = (q) => {
    const lower = q.toLowerCase();
    let reply = "Nanobot is offline. Try Telegram or email nfinsterbusch@gmail.com. (Keyword fallback: 'xc40', 'clinical', 'history', 'contact', 'now'.)";
    if (/xc40|volvo/.test(lower)) reply = "XC40 was the highest-performing digital launch in Volvo Cars history at the time. 4.77M sessions in 7 days, 1.52M model views, 189,958 configurations across 15 markets. Ran it at AKQA.";
    else if (/clinical|medical|diagnosis/.test(lower)) reply = "Clinical AI screener with a 5-stage hybrid pipeline. Got primary diagnostic accuracy from 47% to 84%, neurodevelopmental hit 92%/100%. Designed to abstain rather than fabricate.";
    else if (/twin|legacy|echo|metatron/.test(lower)) reply = "The digital twin is fully local. No cloud. 26.6k lines of Python, 27 endpoints, 8 ChromaDB collections. Six-level consent governs every memory.";
    else if (/now|current|working/.test(lower)) { reply = "Currently consulting on applied AI and co-running Luna Fusion Bites. Opening Portfolio for you."; setTimeout(() => onNav('PORTFOLIO'), 600); }
    else if (/history|career|where/.test(lower)) { reply = "30 years across Buenos Aires, London, and Gothenburg: AKQA, Critical Mass, Stendahls, Tribal, e-kubo, plus the Flash years before. Opening History."; setTimeout(() => onNav('HISTORY'), 600); }
    else if (/contact|email|hire|reach/.test(lower)) { reply = "Quickest path: nfinsterbusch@gmail.com. Opening Contact."; setTimeout(() => onNav('CONTACT'), 600); }
    else if (/intro|about|who/.test(lower)) { reply = "Systems thinker, delivery leader, AI application architect. Not a data scientist. Opening Intro."; setTimeout(() => onNav('INTRO'), 600); }
    return reply;
  };

  const send = async () => {
    if (!input.trim()) return;
    const q = input.trim();
    const historyAtSend = messages;
    const pendingId = 'p_' + Date.now();
    setMessages(m => [...m, { from: 'me', text: q }, { from: 'bot', text: '', pending: true, id: pendingId }]);
    setInput('');
    let reply = null;
    if (window.NJF_NANOBOT) {
      reply = await window.NJF_NANOBOT.ask({
        message: q, history: historyAtSend, onNav,
        onChunk: (_chunk, full) => {
          setMessages(m => m.map(x => x.id === pendingId ? { ...x, text: full, pending: false } : x));
        },
      });
    }
    if (!reply) {
      reply = localRespond(q);
      setMessages(m => m.map(x => x.id === pendingId ? { from: 'bot', text: reply } : x));
    } else {
      setMessages(m => m.map(x => x.id === pendingId ? { from: 'bot', text: reply } : x));
    }
  };

  if (!open) {
    return (
      <div onClick={() => setOpen(true)} style={{
        position: 'absolute', right: 20, bottom: 20, width: 44, height: 44,
        background: D1.panel, border: `1px solid ${D1.green}`, cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: D1.green, fontSize: 16, boxShadow: '0 0 18px rgba(126,226,122,0.35)',
      }}>◆</div>
    );
  }

  return (
    <div style={mobile ? {
      position: 'fixed', left: 0, right: 0, bottom: 0, height: '70vh',
      background: D1.panel, borderTop: `1px solid ${D1.green}`,
      display: 'flex', flexDirection: 'column', zIndex: 50,
      boxShadow: '0 -10px 40px rgba(0,0,0,0.6)',
    } : {
      position: 'absolute', right: 20, bottom: 20, width: 320, height: 380,
      background: D1.panel, border: `1px solid ${D1.green}`,
      display: 'flex', flexDirection: 'column',
      boxShadow: '0 0 30px rgba(126,226,122,0.2), 0 20px 50px rgba(0,0,0,0.5)',
    }}>
      <div style={{
        height: 26, padding: '0 10px', borderBottom: `1px solid ${D1.line2}`,
        background: D1.ink2, display: 'flex', alignItems: 'center',
        fontSize: 10, letterSpacing: 2, color: D1.green,
      }}>
        <span style={{ marginRight: 8 }}>◆</span>
        <span>NANOBOT.NJF · speaking as Nicolas</span>
        <div style={{ flex: 1 }} />
        <span onClick={() => setOpen(false)} style={{ cursor: 'pointer', color: D1.dim }}>×</span>
      </div>

      <div ref={ref} style={{ flex: 1, overflow: 'auto', padding: 12, fontSize: 11, lineHeight: 1.6 }}>
        {messages.map((m, i) => (
          <div key={m.id || i} style={{ marginBottom: 10 }}>
            <span style={{ color: m.from === 'bot' ? D1.green : D1.amber }}>
              {m.from === 'bot' ? '▸ NJF' : '▸ YOU'}
            </span>
            <div style={{ color: D1.fg, opacity: m.from === 'me' ? 0.85 : 1, whiteSpace: 'pre-wrap' }}>
              {m.pending ? <D1Thinking color={D1.green} /> : m.text}
            </div>
          </div>
        ))}
      </div>

      <div style={{ padding: 8, borderTop: `1px solid ${D1.line2}`, display: 'flex', gap: 6 }}>
        <span style={{ color: D1.green, fontSize: 11, paddingTop: 6 }}>$</span>
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && send()}
          placeholder="ask..."
          style={{
            flex: 1, background: 'transparent', border: 'none',
            color: D1.fg, fontFamily: D1.font, fontSize: 11, outline: 'none',
          }}
        />
      </div>
    </div>
  );
}

// ── ROOT ──────────────────────────────────────────────
function Direction1({ data }) {
  const [section, setSection] = React.useState('HOME');
  const sec = {
    HOME: <D1Home data={data} />,
    INTRO: <D1Intro data={data} />,
    HISTORY: <D1History data={data} />,
    PORTFOLIO: <D1Portfolio data={data} />,
    CONTACT: <D1Contact data={data} />,
  }[section];
  return (
    <D1Frame>
      <D1MenuBar active={section} onNav={setSection} />
      <div style={{ position: 'absolute', inset: '28px 0 0 0' }}>
        {sec}
      </div>
      <D1Nanobot data={data} onNav={setSection} />
    </D1Frame>
  );
}

window.Direction1 = Direction1;
