// Hero with three variants: wing (animated logo wing tracing flow), terminal, pipeline
const { useEffect, useState, useRef } = React;

function HeroWingFlow() {
  // Wing traces an SVG path from CI → IaC → Cluster → Prod nodes
  const pathRef = useRef(null);
  const wingRef = useRef(null);

  useEffect(() => {
    const path = pathRef.current;
    const wing = wingRef.current;
    if (!path || !wing) return;
    const total = path.getTotalLength();
    let raf;
    let t0 = performance.now();
    const DUR = 6500;

    function tick(now) {
      const elapsed = (now - t0) % DUR;
      const p = elapsed / DUR;
      const pt = path.getPointAtLength(p * total);
      const ahead = path.getPointAtLength((elapsed + 30) % DUR / DUR * total);
      const angle = Math.atan2(ahead.y - pt.y, ahead.x - pt.x) * 180 / Math.PI;
      wing.setAttribute('transform', `translate(${pt.x}, ${pt.y}) rotate(${angle}) translate(-14, -14)`);
      raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const nodes = [
  { x: 60, y: 80, label: "git push", sub: "main" },
  { x: 200, y: 40, label: "ci · build", sub: "passing" },
  { x: 340, y: 120, label: "terraform", sub: "apply" },
  { x: 200, y: 200, label: "k8s", sub: "rollout" },
  { x: 460, y: 180, label: "prod", sub: "200 ok" }];


  return (
    <div className="hero-visual" aria-hidden="true">
      <div className="hero-visual-head">
        <span className="dot r"></span><span className="dot y"></span><span className="dot g"></span>
        <span className="label">flow.svg — pipeline trace</span>
        <span style={{ marginLeft: 'auto', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11, color: 'var(--text-mute)' }}>
          live
        </span>
      </div>
      <div className="hero-visual-body" style={{ padding: 0 }}>
        <svg viewBox="0 0 520 280" style={{ display: 'block', width: '100%', height: 'auto' }}>
          <defs>
            <linearGradient id="flowGrad" x1="0" y1="0" x2="1" y2="1">
              <stop offset="0%" stopColor="#0b1018" stopOpacity="0.8" />
              <stop offset="60%" stopColor="#1e3a5f" />
              <stop offset="100%" stopColor="#7dd3fc" />
            </linearGradient>
            <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
              <feGaussianBlur stdDeviation="3" result="b" />
              <feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge>
            </filter>
          </defs>

          {/* dotted grid */}
          <g opacity="0.18">
            {Array.from({ length: 9 }).map((_, i) =>
            Array.from({ length: 5 }).map((_, j) =>
            <circle key={i + '-' + j} cx={40 + i * 60} cy={30 + j * 55} r="1" fill="#94a3b8" />
            )
            )}
          </g>

          {/* main flow path */}
          <path
            ref={pathRef}
            d="M 60 80 C 120 60, 160 30, 200 40 S 300 100, 340 120 S 240 200, 200 200 S 420 180, 460 180"
            fill="none"
            stroke="rgba(125,211,252,0.25)"
            strokeWidth="2"
            strokeDasharray="4 6" />
          
          {/* glowing trail */}
          <path
            d="M 60 80 C 120 60, 160 30, 200 40 S 300 100, 340 120 S 240 200, 200 200 S 420 180, 460 180"
            fill="none"
            stroke="url(#flowGrad)"
            strokeWidth="2.5"
            strokeDasharray="120 600"
            strokeLinecap="round"
            filter="url(#glow)">
            
            <animate attributeName="stroke-dashoffset" from="0" to="-720" dur="6.5s" repeatCount="indefinite" />
          </path>

          {/* nodes */}
          {nodes.map((n, i) =>
          <g key={i}>
              <rect x={n.x - 38} y={n.y - 14} width="76" height="28" rx="6"
            fill="#0d131c" stroke="rgba(148,163,184,0.25)" />
              <text x={n.x} y={n.y - 2} textAnchor="middle" fontFamily="JetBrains Mono, monospace"
            fontSize="10" fill="#e6edf6" fontWeight="500">{n.label}</text>
              <text x={n.x} y={n.y + 9} textAnchor="middle" fontFamily="IBM Plex Mono, monospace"
            fontSize="8" fill="#7dd3fc">{n.sub}</text>
            </g>
          )}

          {/* the flying wing logo */}
          <g ref={wingRef} filter="url(#glow)">
            <path
              d="M 4 18 Q 10 4, 24 6 L 22 12 Q 14 10, 8 16 Z M 12 18 Q 18 14, 24 14 L 22 22 Q 16 22, 12 22 Z"
              fill="url(#flowGrad)"
              stroke="#7dd3fc"
              strokeWidth="0.5" />
            
          </g>
        </svg>

        {/* under-flow caption */}
        <div style={{
          padding: '14px 20px',
          borderTop: '1px solid var(--line)',
          display: 'flex',
          gap: 24,
          fontFamily: 'IBM Plex Mono, monospace',
          fontSize: 11,
          color: 'var(--text-dim)',
          flexWrap: 'wrap'
        }}>
          <span><span style={{ color: 'var(--text-mute)' }}>$</span> avg deploy <span style={{ color: 'var(--text)' }}>2m 14s</span></span>
          <span><span style={{ color: 'var(--text-mute)' }}>$</span> mttr <span style={{ color: 'var(--text)' }}>12m</span></span>
          <span><span style={{ color: 'var(--text-mute)' }}>$</span> uptime <span style={{ color: '#4ade80' }}>99.97%</span></span>
        </div>
      </div>
    </div>);

}

function HeroTerminal() {
  // Each entry: command lines (typed letter-by-letter) followed by output (revealed in full)
  const target = [
    { p: '~/infra', cmd: 'terraform plan -target=module.sandbox_gcp_auth0' },
    { o: 'Plan: 12 to add, 0 to change, 0 to destroy.', c: '#94a3b8' },
    { o: '# mirrors prod public APIs — isolated stack', c: '#64748b' },
    { p: '~/ci', cmd: 'glab ci lint .gitlab-ci.yml --include-components' },
    { o: '✓ ci-components/auth · deploy · health-check · rollback', c: '#4ade80' },
    { o: '✓ pipeline valid · 7 stages · reusable=true', c: '#4ade80' },
    { p: '~/k8s', cmd: 'kubectl -n streaming rollout status sts/kafka-broker' },
    { o: 'statefulset "kafka-broker" rolled out · KRaft quorum healthy', c: '#7dd3fc' },
    { o: '# bye, Confluent bill 👋', c: '#64748b' },
    { p: '~/obs', cmd: 'bq query "SELECT severity, count(*) FROM logs.gke_router..."' },
    { o: 'ERROR=3  WARN=41  INFO=12k  · log router → BigQuery', c: '#94a3b8' },
    { p: '~/ci', cmd: 'curl -X POST $SLACK_WEBHOOK -d @health-ok.json' },
    { o: '✓ posted #deploys · "View workload →" linked to GKE console', c: '#4ade80' },
    { p: '~/homelab', cmd: 'kubectl --context=pi5 get nodes' },
    { o: 'pi5-cp · pi5-w1 · pi5-w2  Ready  v1.30.4  (kubeadm)', c: '#7dd3fc' },
    { o: '# tested at home before it touches your prod', c: '#64748b' },
  ];

  // step: index into target. typedChars: how many chars of current cmd are typed (only for cmd entries).
  const [step, setStep] = useState(0);
  const [typedChars, setTypedChars] = useState(0);

  useEffect(() => {
    if (step >= target.length) return;
    const cur = target[step];
    let timer;

    if (cur.cmd) {
      if (typedChars < cur.cmd.length) {
        // Vary typing speed: most keys 60–110ms, occasional pause 180–260ms,
        // longer pause after space or punctuation.
        const ch = cur.cmd[typedChars];
        const r = Math.random();
        let delay;
        if (ch === ' ') delay = 90 + Math.random() * 80;
        else if ('-_/.='.includes(ch)) delay = 110 + Math.random() * 90;
        else if (r < 0.08) delay = 220 + Math.random() * 140; // think pause
        else delay = 55 + Math.random() * 70;
        timer = setTimeout(() => setTypedChars(c => c + 1), delay);
      } else {
        // Pause after command before showing output (like pressing enter, then tool runs)
        timer = setTimeout(() => {
          setStep(s => s + 1);
          setTypedChars(0);
        }, 700 + Math.random() * 600);
      }
    } else {
      // Output line: hold briefly then advance
      timer = setTimeout(() => {
        setStep(s => s + 1);
        setTypedChars(0);
      }, 1100 + Math.random() * 500);
    }
    return () => clearTimeout(timer);
  }, [step, typedChars]);

  // Build visible list: completed entries + currently-typing one
  const visible = target.slice(0, step).map((l, i) => ({ ...l, i, partial: false }));
  const cur = target[step];
  const isTyping = cur && cur.cmd && typedChars < cur.cmd.length;
  if (cur && cur.cmd) {
    visible.push({ ...cur, i: step, partial: true, typed: cur.cmd.slice(0, typedChars) });
  }

  return (
    <div className="hero-visual" aria-hidden="true">
      <div className="hero-visual-head">
        <span className="dot r"></span><span className="dot y"></span><span className="dot g"></span>
        <span className="label">flochai@prod — zsh</span>
      </div>
      <div className="hero-visual-body" style={{
        padding: '20px 22px',
        fontFamily: 'JetBrains Mono, monospace',
        fontSize: 12.5,
        lineHeight: 1.85,
        minHeight: 280
      }}>
        {visible.map((l) => l.cmd ?
          <div key={l.i}>
            <span style={{ color: '#7dd3fc' }}>{l.p}</span>{' '}
            <span style={{ color: '#94a3b8' }}>$</span>{' '}
            <span style={{ color: '#e6edf6' }}>{l.partial ? l.typed : l.cmd}</span>
            {l.partial && (
              <span style={{ display: 'inline-block', width: 7, height: 13, background: '#7dd3fc', verticalAlign: 'middle', marginLeft: 1, animation: 'blink 1s steps(1) infinite' }}></span>
            )}
          </div> :
          <div key={l.i} style={{ color: l.c, paddingLeft: 12 }}>{l.o}</div>
        )}
        {/* Idle prompt with cursor when between commands */}
        {!isTyping && step < target.length && cur && !cur.cmd && (
          <div><span style={{ color: '#7dd3fc' }}>~/k8s</span>{' '}
            <span style={{ color: '#94a3b8' }}>$</span>{' '}
            <span style={{ display: 'inline-block', width: 7, height: 13, background: '#7dd3fc', verticalAlign: 'middle', animation: 'blink 1s steps(1) infinite' }}></span>
          </div>
        )}
        {step >= target.length && (
          <div><span style={{ color: '#7dd3fc' }}>~/k8s</span>{' '}
            <span style={{ color: '#94a3b8' }}>$</span>{' '}
            <span style={{ display: 'inline-block', width: 7, height: 13, background: '#7dd3fc', verticalAlign: 'middle', animation: 'blink 1s steps(1) infinite' }}></span>
          </div>
        )}
      </div>
    </div>);
}

function HeroPipeline() {
  // Static pipeline diagram with stages
  const stages = [
  { name: 'commit', status: 'done', sub: 'git@main' },
  { name: 'build', status: 'done', sub: '14s' },
  { name: 'test', status: 'done', sub: '482 pass' },
  { name: 'plan', status: 'done', sub: '4 add' },
  { name: 'apply', status: 'running', sub: 'gcp' },
  { name: 'rollout', status: 'queued', sub: 'k8s' }];

  const colorFor = (s) => s === 'done' ? '#4ade80' : s === 'running' ? '#7dd3fc' : '#64748b';

  return (
    <div className="hero-visual" aria-hidden="true">
      <div className="hero-visual-head">
        <span className="dot r"></span><span className="dot y"></span><span className="dot g"></span>
        <span className="label">pipeline · run #2486</span>
      </div>
      <div className="hero-visual-body" style={{ padding: '24px 22px' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {stages.map((s, i) =>
          <div key={i} style={{
            display: 'grid',
            gridTemplateColumns: '90px 1fr 70px',
            alignItems: 'center',
            gap: 12,
            padding: '10px 14px',
            border: '1px solid var(--line)',
            borderRadius: 8,
            background: 'color-mix(in srgb, var(--bg) 60%, transparent)'
          }}>
              <div style={{
              fontFamily: 'JetBrains Mono, monospace',
              fontSize: 13,
              color: 'var(--text)',
              fontWeight: 500
            }}>{s.name}</div>
              <div style={{
              height: 6,
              borderRadius: 999,
              background: 'rgba(148,163,184,.12)',
              overflow: 'hidden',
              position: 'relative'
            }}>
                <div style={{
                height: '100%',
                width: s.status === 'done' ? '100%' : s.status === 'running' ? '60%' : '0%',
                background: colorFor(s.status),
                borderRadius: 999,
                transition: 'width 1s ease',
                ...(s.status === 'running' ? { animation: 'pulse 1.5s ease-in-out infinite' } : {})
              }}></div>
              </div>
              <div style={{
              fontFamily: 'IBM Plex Mono, monospace',
              fontSize: 11,
              color: colorFor(s.status),
              textAlign: 'right'
            }}>{s.sub}</div>
            </div>
          )}
        </div>
      </div>
    </div>);

}

function HeroGitlabPipeline() {
  // Real-world ci-components pipeline: pre → build_push → deploy → health-check → rollback → integration → backup
  const stages = [
  { name: '.pre', jobs: [['hadolint', 'ok'], ['lint', 'ok'], ['sast', 'ok'], ['secrets-scan', 'ok'], ['unit-test', 'ok']] },
  { name: 'build_push', jobs: [['1. build', 'ok'], ['2. security-scan', 'ok'], ['3. e2e-playwright', 'ok'], ['4. push', 'manual']] },
  { name: 'deploy', jobs: [['1. deploy-dev', 'ok'], ['2. deploy-staging', 'manual'], ['3. deploy-prod', 'manual'], ['4. test-k3s', 'manual']] },
  { name: 'health-check', jobs: [['1. health-dev', 'ok'], ['2. health-staging', 'ok'], ['3. health-prod', 'ok']] },
  { name: 'rollback', jobs: [['1. no_rollback_dev', 'ok'], ['2. no_rollback_staging', 'ok'], ['3. no_rollback_prod', 'ok']] },
  { name: 'integration', jobs: [['1. integration-staging', 'ok'], ['2. integration-prod', 'ok']] },
  { name: 'backup', jobs: [['backup-post-deploy', 'manual']] }];

  // Build a flat ordered list of (stageIdx, jobIdx, finalStatus) to drive animation
  const flat = [];
  stages.forEach((st, si) => st.jobs.forEach(([j, s], ji) => {
    if (s === 'ok') flat.push({ si, ji, finalStatus: s });
  }));

  // progress: how many ok-jobs have completed so far (cycles)
  const [progress, setProgress] = useState(0);
  const [tick, setTick] = useState(0); // for running-pulse animation

  useEffect(() => {
    const total = flat.length;
    const interval = setInterval(() => {
      setProgress(p => {
        if (p >= total + 4) return 0; // pause at end then restart
        return p + 1;
      });
    }, 700);
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    const id = setInterval(() => setTick(t => t + 1), 500);
    return () => clearInterval(id);
  }, []);

  // Compute current status per job
  const statusFor = (si, ji, finalStatus) => {
    if (finalStatus === 'manual') return 'manual';
    const idx = flat.findIndex(f => f.si === si && f.ji === ji);
    if (idx < progress - 1) return 'ok';
    if (idx === progress - 1) return 'running';
    return 'pending';
  };

  const dotColor = (s) => {
    if (s === 'ok') return '#4ade80';
    if (s === 'running') return '#38bdf8';
    if (s === 'manual') return '#94a3b8';
    if (s === 'pending') return '#475569';
    return '#f59e0b';
  };

  // Compute totals
  const totalOk = flat.length;
  const completed = Math.min(progress, totalOk);
  const elapsed = (completed * 11.4).toFixed(0); // fake duration
  const isDone = progress > totalOk;

  return (
    <div className="hero-visual" aria-hidden="true">
      <div className="hero-visual-head">
        <span className="dot r"></span><span className="dot y"></span><span className="dot g"></span>
        <span className="label">ci-components · pipeline #2486</span>
        <span style={{ marginLeft: 'auto', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11, color: isDone ? '#4ade80' : '#38bdf8', display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{
            width: 8, height: 8, borderRadius: '50%',
            background: isDone ? '#4ade80' : '#38bdf8',
            boxShadow: `0 0 8px ${isDone ? '#4ade80' : '#38bdf8'}`,
            animation: isDone ? 'none' : 'gitlab-pulse 1s ease-in-out infinite'
          }}></span>
          {isDone ? 'passed' : 'running'}
        </span>
      </div>
      <style>{`
        @keyframes gitlab-pulse {
          0%, 100% { opacity: 1; transform: scale(1); }
          50% { opacity: 0.5; transform: scale(0.8); }
        }
        @keyframes gitlab-running-bg {
          0%, 100% { background: color-mix(in srgb, #38bdf8 15%, var(--bg-2) 85%); }
          50% { background: color-mix(in srgb, #38bdf8 25%, var(--bg-2) 75%); }
        }
        @keyframes gitlab-progress-fill {
          from { transform: scaleX(0); }
        }
      `}</style>
      <div style={{ padding: '18px 14px', display: 'flex', gap: 8, overflowX: 'auto' }}>
        {stages.map((st, i) => {
          const stageJobs = st.jobs.map(([j, finalS], ji) => ({ name: j, finalS, current: statusFor(i, ji, finalS) }));
          const stageActive = stageJobs.some(j => j.current === 'running');
          const stageDone = stageJobs.every(j => j.current === 'ok' || j.current === 'manual');
          return (
            <React.Fragment key={st.name}>
              <div style={{
                minWidth: 140, flexShrink: 0,
                border: `1px solid ${stageActive ? 'rgba(56,189,248,.5)' : 'var(--line-2)'}`,
                borderRadius: 8,
                background: 'color-mix(in srgb, var(--bg) 70%, transparent)',
                display: 'flex', flexDirection: 'column',
                transition: 'border-color .3s',
                boxShadow: stageActive ? '0 0 0 2px rgba(56,189,248,.15)' : 'none'
              }}>
                <div style={{
                  padding: '8px 10px', borderBottom: '1px solid var(--line)',
                  fontFamily: 'JetBrains Mono, monospace', fontSize: 11, fontWeight: 600,
                  color: 'var(--text)', display: 'flex', justifyContent: 'space-between', alignItems: 'center'
                }}>
                  <span>{st.name}</span>
                  <span style={{ color: stageDone ? '#4ade80' : (stageActive ? '#38bdf8' : 'var(--text-mute)'), fontSize: 10 }}>
                    {stageDone ? '✓' : (stageActive ? '●' : '▶')}
                  </span>
                </div>
                <div style={{ padding: '8px 6px', display: 'flex', flexDirection: 'column', gap: 5 }}>
                  {stageJobs.map(({ name, current }) => {
                    const isRun = current === 'running';
                    return (
                      <div key={name} style={{
                        display: 'flex', alignItems: 'center', gap: 7,
                        padding: '5px 7px',
                        background: isRun ? 'color-mix(in srgb, #38bdf8 18%, var(--bg-2) 82%)' : 'color-mix(in srgb, var(--bg-2) 80%, transparent)',
                        border: `1px solid ${isRun ? 'rgba(56,189,248,.5)' : 'var(--line)'}`,
                        borderRadius: 6,
                        fontFamily: 'IBM Plex Mono, monospace', fontSize: 10.5,
                        color: current === 'pending' ? 'var(--text-mute)' : 'var(--text-dim)',
                        opacity: current === 'pending' ? 0.55 : 1,
                        transition: 'background .25s, border-color .25s, opacity .25s',
                        position: 'relative', overflow: 'hidden'
                      }}>
                        <span style={{
                          width: 10, height: 10, borderRadius: '50%',
                          background: dotColor(current), flexShrink: 0,
                          boxShadow: `0 0 6px ${dotColor(current)}66`,
                          animation: isRun ? 'gitlab-pulse .9s ease-in-out infinite' : 'none'
                        }}></span>
                        <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', position: 'relative', zIndex: 1 }}>{name}</span>
                        {isRun && (
                          <span style={{
                            position: 'absolute', left: 0, top: 0, bottom: 0,
                            width: '100%',
                            background: 'linear-gradient(90deg, transparent, rgba(56,189,248,.18), transparent)',
                            animation: 'gitlab-progress-fill 1.4s linear infinite',
                            transformOrigin: 'left'
                          }}></span>
                        )}
                      </div>
                    );
                  })}
                </div>
              </div>
              {i < stages.length - 1 &&
                <div style={{
                  alignSelf: 'center', width: 14, height: 1,
                  background: stageDone ? 'linear-gradient(90deg, #4ade80, var(--accent))' : 'linear-gradient(90deg, var(--line-2), var(--accent))',
                  flexShrink: 0,
                  transition: 'background .3s'
                }}></div>
              }
            </React.Fragment>
          );
        })}
      </div>
      <div style={{
        padding: '12px 18px', borderTop: '1px solid var(--line)',
        display: 'flex', gap: 20, fontFamily: 'IBM Plex Mono, monospace',
        fontSize: 11, color: 'var(--text-dim)', flexWrap: 'wrap'
      }}>
        <span><span style={{ color: 'var(--text-mute)' }}>$</span> stages <span style={{ color: 'var(--text)' }}>7</span></span>
        <span><span style={{ color: 'var(--text-mute)' }}>$</span> jobs <span style={{ color: 'var(--text)' }}>{completed}/{totalOk}</span></span>
        <span><span style={{ color: 'var(--text-mute)' }}>$</span> elapsed <span style={{ color: 'var(--text)' }}>{Math.floor(elapsed/60)}m {String(elapsed%60).padStart(2,'0')}s</span></span>
        <span><span style={{ color: 'var(--text-mute)' }}>$</span> reusable <span style={{ color: '#4ade80' }}>true</span></span>
      </div>
    </div>);

}

function HeroJobLog() {
  // Streams a GitLab CI job log line-by-line: line-number gutter + timestamp + content.
  // Mimics a Playwright e2e smoke test inside a pytest run.
  const lines = [
    { ts: '18:07:07', text: 'Playwright integration smoke: E2E_BASE_URL=https://anchor.flochai.com', cls: 'link' },
    { ts: '18:07:08', text: '============================ test session starts ============================' },
    { ts: '18:07:08', text: 'platform linux -- Python 3.10.12, pytest-8.4.2, pluggy-1.6.0 -- /usr/bin/python' },
    { ts: '18:07:08', text: 'cachedir: .pytest_cache' },
    { ts: '18:07:08', text: 'rootdir: /builds/flochai/anchor-e2e' },
    { ts: '18:07:08', text: 'configfile: pytest.ini' },
    { ts: '18:07:08', text: 'plugins: base-url-2.1.0, playwright-0.5.2' },
    { ts: '18:07:08', text: 'collecting ... collected 1 item' },
    { ts: '18:07:08', text: 'tests/e2e/test_anchor_e2e.py::test_anchor_app_home[chromium] [e2e] Starting: E2E_BASE_URL=\'https://anchor.flochai.com\'' },
    { ts: '18:07:08', text: '[e2e] Step 1/4: open home (wait until domcontentloaded)' },
    { ts: '18:07:09', text: '[e2e]   navigated: url=\'https://anchor.flochai.com/\' title=\'Anchor\'' },
    { ts: '18:07:10', text: '[e2e] Step 2/4: assert tab title matches Anchor Method Scheduler' },
    { ts: '18:07:10', text: '[e2e]   tab title OK' },
    { ts: '18:07:10', text: '[e2e] Step 3/4: assert main heading (Anchor Method Generator) is visible' },
    { ts: '18:07:11', text: '[e2e]   heading OK' },
    { ts: '18:07:11', text: '[e2e] Step 4/4: assert Generate dates button is visible' },
    { ts: '18:07:11', text: '[e2e]   form submit button OK — Anchor app home smoke complete' },
    { ts: '18:07:11', text: 'PASSED', cls: 'ok' },
    { ts: '18:07:11', text: '============================ 1 passed in 3.49s ============================', cls: 'ok' },
    { ts: '18:07:12', text: 'Cleaning up project directory and file based variables', cls: 'cyan' },
    { ts: '18:07:13', text: 'Job succeeded', cls: 'ok-bold' },
  ];
  const START_LINE = 96;

  const [count, setCount] = useState(0);
  useEffect(() => {
    if (count >= lines.length) {
      const t = setTimeout(() => setCount(0), 4500);
      return () => clearTimeout(t);
    }
    const cur = lines[count];
    // Slight pause between lines; longer when we hit headers / PASSED
    let d = 320 + Math.random() * 220;
    if (cur.text.startsWith('====')) d = 520;
    if (cur.cls === 'ok' || cur.cls === 'ok-bold') d = 700;
    const t = setTimeout(() => setCount(c => c + 1), d);
    return () => clearTimeout(t);
  }, [count]);

  const visible = lines.slice(0, count);
  const colorFor = (cls) => {
    if (cls === 'ok' || cls === 'ok-bold') return '#4ade80';
    if (cls === 'cyan') return '#7dd3fc';
    if (cls === 'link') return '#e6edf6';
    return '#cbd5e1';
  };

  return (
    <div className="hero-visual" aria-hidden="true">
      <div className="hero-visual-head">
        <span className="dot r"></span><span className="dot y"></span><span className="dot g"></span>
        <span className="label">job · e2e-playwright · #2486</span>
        <span style={{ marginLeft: 'auto', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11, color: count >= lines.length ? '#4ade80' : '#38bdf8', display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{
            width: 8, height: 8, borderRadius: '50%',
            background: count >= lines.length ? '#4ade80' : '#38bdf8',
            boxShadow: `0 0 8px ${count >= lines.length ? '#4ade80' : '#38bdf8'}`,
            animation: count >= lines.length ? 'none' : 'gitlab-pulse 1s ease-in-out infinite'
          }}></span>
          {count >= lines.length ? 'passed' : 'running'}
        </span>
      </div>
      <div style={{
        background: '#0a0e14',
        fontFamily: 'JetBrains Mono, monospace',
        fontSize: 11.5,
        lineHeight: 1.55,
        padding: '12px 0 14px',
        minHeight: 360,
        maxHeight: 420,
        overflow: 'hidden',
        position: 'relative'
      }}>
        {visible.map((l, i) => {
          const lineNo = START_LINE + i;
          return (
            <div key={i} style={{
              display: 'grid',
              gridTemplateColumns: '32px 64px 1fr',
              gap: 8,
              padding: '0 8px',
              color: colorFor(l.cls),
              fontWeight: l.cls === 'ok-bold' ? 700 : 400
            }}>
              <span style={{ color: '#475569', textAlign: 'right', userSelect: 'none' }}>{lineNo}</span>
              <span style={{ color: '#64748b' }}>{l.ts}</span>
              <span style={{
                whiteSpace: 'nowrap',
                overflow: 'hidden',
                textOverflow: 'ellipsis'
              }}>
                {l.cls === 'link' ? (
                  <>Playwright integration smoke: E2E_BASE_URL=<span style={{ color: '#7dd3fc', textDecoration: 'underline', textDecorationStyle: 'dotted' }}>https://anchor.flochai.com</span></>
                ) : l.text}
              </span>
            </div>
          );
        })}
        {count < lines.length && (
          <div style={{
            display: 'grid', gridTemplateColumns: '32px 64px 1fr', gap: 8, padding: '0 8px',
          }}>
            <span style={{ color: '#475569', textAlign: 'right' }}>{START_LINE + visible.length}</span>
            <span style={{ color: '#64748b' }}>—</span>
            <span style={{ display: 'inline-block', width: 7, height: 12, background: '#7dd3fc', verticalAlign: 'middle', animation: 'blink 1s steps(1) infinite' }}></span>
          </div>
        )}
      </div>
    </div>);
}

function HeroVisual({ variant }) {
  if (variant === 'terminal') return <HeroTerminal />;
  if (variant === 'pipeline') return <HeroPipeline />;
  if (variant === 'gitlab') return <HeroGitlabPipeline />;
  if (variant === 'joblog') return <HeroJobLog />;
  return <HeroWingFlow />;
}

function Hero({ heroVariant, engineerCount = 2 }) {
  return (
    <section className="hero">
      <div className="container">
        <div className="hero-row">
          <div>
            <div className="mono-label">devops engineering · independent</div>
            <h1>
              Pipelines that are<br />
              <span className="accent">boring</span> — the best kind.
            </h1>
            <p className="hero-sub">
              We help engineering teams ship with confidence: clean Infrastructure as Code,
              CI/CD that doesn't fight you, and observability that's actually useful at 3am.
            </p>
            <div className="hero-actions">
              <a className="btn btn-cta" href="#contact">
                book a discovery call <span className="arrow">→</span>
              </a>
              <a className="btn btn-ghost" href="#experience">
                see recent work
              </a>
            </div>
            <div className="hero-meta">
              <div>
                <strong>10+ yrs</strong>
                shipping infra
              </div>
              <div>
                <strong>{engineerCount} engineer{engineerCount === 1 ? '' : 's'}</strong>
                available now
              </div>
              <div>
                <strong>GCP · K8s</strong>
                primary stack
              </div>
              <div>
                <strong>EU · remote</strong>
                CET / overlap US
              </div>
            </div>
          </div>
          <HeroVisual variant={heroVariant} />
        </div>
      </div>
    </section>);

}

Object.assign(window, { Hero });