// Sections for the full portfolio site — Om Kushwaha (nskr.dev)
// Premium cinematic feel, smooth transitions, dark-first with light toggle.

const S = SITE_DATA;

// ─────────────── NAV ───────────────
function NavBar({ dark, onToggleDark }) {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const on = () => setScrolled(window.scrollY > 60);
    window.addEventListener('scroll', on, { passive: true });
    return () => window.removeEventListener('scroll', on);
  }, []);
  return (
    <nav className={`nav ${scrolled ? 'nav-scrolled' : ''}`}>
      <a href="#top" className="logo">
        <span className="logo-mark">◆</span>
        <span className="logo-text">OK</span>
      </a>
      <div className="nav-links">
        {['about', 'skills', 'experience', 'work', 'writing', 'contact'].map(l => (
          <a key={l} href={`#${l}`}>{l}</a>
        ))}
      </div>
      <div className="nav-actions">
        <button className="theme-btn" onClick={onToggleDark} aria-label="toggle theme">
          {dark ? '☾' : '☀'}
        </button>
        <a href="https://drive.google.com/file/d/18uemv5TG945QEc-FXfhjyDj8onrBAICB/view?usp=sharing" target="_blank" className="nav-cta">Resume ↗</a>
      </div>
    </nav>
  );
}

// ─────────────── HERO ───────────────
function Hero({ dark }) {
  const y = useScrollY();
  const p = Math.min(1, y / 600);

  // mouse-reactive tilt on the content block (rAF-throttled to avoid re-render storm)
  const [tilt, setTilt] = React.useState({ x: 0, y: 0 });
  React.useEffect(() => {
    let raf = 0, tx = 0, ty = 0, pending = false;
    const on = (e) => {
      const w = window.innerWidth, h = window.innerHeight;
      tx = (e.clientX / w - 0.5) * 8;
      ty = (e.clientY / h - 0.5) * 8;
      if (!pending) {
        pending = true;
        raf = requestAnimationFrame(() => { pending = false; setTilt({ x: tx, y: ty }); });
      }
    };
    window.addEventListener('mousemove', on);
    return () => { window.removeEventListener('mousemove', on); cancelAnimationFrame(raf); };
  }, []);

  // live clock
  const [now, setNow] = React.useState(() => new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);

  // rotating "now running" phrases — matches the figurines on screen
  const RUNNING_PHRASES = [
    'fine-tuning a TFLite model',
    'debugging a WebRTC pipeline',
    'pushing to Vercel at midnight',
    'teaching the model to stop hallucinating',
    'refactoring yesterday’s API',
    'shipping a side project',
  ];
  const [phraseIdx, setPhraseIdx] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setPhraseIdx((i) => (i + 1) % RUNNING_PHRASES.length), 2800);
    return () => clearInterval(id);
  }, []);

  // word strip
  const WORDS = ['FULLSTACK', 'COMPUTER VISION', 'ML', 'NEXT.JS', 'AI', 'ENGINEERED', 'FULLSTACK', 'COMPUTER VISION', 'ML', 'NEXT.JS', 'AI', 'ENGINEERED'];

  return (
    <section className="hero hero-v5" id="top">
      {/* code rain backdrop */}
      <div
        className="hero-v5-bg"
        style={{
          transform: `translateY(${y * 0.12}px)`,
          opacity: 1 - p * 0.4,
        }}
      >
        <div className="v5-grid" />
        <div className="v5-rain"><CodeRain /></div>
        <div className="v5-vignette" />
        <div className="v5-noise" />
      </div>

      {/* META TOP */}
      <div className="v5-meta-tl">
        <span className="v5-dot" /> SYS · ONLINE
        <span className="v5-sep">/</span>
        {now.toLocaleTimeString('en-US', { hour12: false })} IST
      </div>

      <a href={S.resumeUrl || '#'} className="v5-meta-tr" target="_blank" rel="noreferrer">
        <span>RESUME</span><span className="v5-arrow">↗</span>
      </a>

      {/* TERMINAL PROMPT (oversized) */}
      <div
        className="v5-prompt"
        style={{
          transform: `translate(${tilt.x * 1.5}px, ${tilt.y * 1.5}px)`,
        }}
      >
        <span className="v5-prompt-pre">~ /om</span>
        <span className="v5-prompt-arrow">▸</span>
        <span className="v5-prompt-cmd">build fullstack_</span>
        <span className="v5-caret" />
      </div>

      {/* GIANT EDITORIAL HEADLINE */}
      <div
        className="v5-content"
        style={{
          transform: `translateY(${y * 0.08}px)`,
          opacity: 1 - p * 1.2,
        }}
      >
        <h1 className="v5-title">
          <span className="v5-line"><FadeWords text="AI Engineer" stagger={70} /></span>
          <span className="v5-line v5-line-italic"><FadeWords text="Fullstack Developer." delay={220} stagger={70} /></span>
          <span className="v5-line v5-line-outline"><FadeWords text="Ship fast, ship real." delay={460} stagger={70} /></span>
        </h1>

        <div className="v5-meta-row">
          <div className="v5-meta-col">
            <span className="v5-meta-key">NAME</span>
            <span className="v5-meta-val">Om Kushwaha</span>
          </div>
          <div className="v5-meta-col">
            <span className="v5-meta-key">ROLE</span>
            <span className="v5-meta-val">AI Engineer & Fullstack Developer.</span>
          </div>
          <div className="v5-meta-col">
            <span className="v5-meta-key">STACK</span>
            <span className="v5-meta-val">React · Next.js · Node.js · Python</span>
          </div>
          <div className="v5-meta-col">
            <span className="v5-meta-key">BASED</span>
            <span className="v5-meta-val">Gujarat, India</span>
          </div>
        </div>

        <div className="v5-ctas">
          <a href="mailto:omkushwaha2005@gmail.com" className="v5-cta v5-cta-primary">
            <span className="v5-cta-label">Start a project</span>
            <span className="v5-cta-arrow">→</span>
          </a>
          <a href="#work" className="v5-cta v5-cta-ghost">
            <span className="v5-cta-dot" /> See the work
          </a>
        </div>
      </div>

      {/* WORD STRIP — bottom marquee */}
      <div className="v5-strip">
        <div className="v5-strip-track">
          {[...WORDS, ...WORDS].map((w, i) => (
            <span key={i} className="v5-strip-item">
              <span className="v5-strip-mark">✦</span>{w}
            </span>
          ))}
        </div>
      </div>

      {/* BOTTOM-RIGHT HUD */}
      <div className="v5-hud">
        <div className="v5-hud-row">
          <span className="v5-hud-key">NOW</span>
          <span className="v5-hud-val" key={phraseIdx}>{RUNNING_PHRASES[phraseIdx]}</span>
        </div>
        <div className="v5-hud-row v5-hud-scroll">
          <span className="v5-hud-key">SCROLL</span>
          <span className="v5-hud-bar"><span className="v5-hud-bar-fill" style={{ height: `${p * 100}%` }} /></span>
        </div>
      </div>
    </section>
  );
}

// CodeRain — falling glyph columns (canvas-free, pure CSS)
function CodeRain() {
  const columns = 28;
  const glyphs = '01∆◆◇○●▢▣▲▼←→↑↓§¶≈≠≡∞∇∂'.split('');
  return (
    <div className="rain-cols">
      {Array.from({ length: columns }).map((_, i) => {
        const col = [];
        const len = 14 + (i % 4) * 4;
        for (let j = 0; j < len; j++) {
          col.push(glyphs[(i * 13 + j * 7) % glyphs.length]);
        }
        return (
          <div
            key={i}
            className="rain-col"
            style={{
              left: `${(i * 100) / columns}%`,
              animationDelay: `${-(i * 0.5) % 8}s`,
              animationDuration: `${10 + (i % 5) * 2}s`,
            }}
          >
            {col.map((g, j) => (
              <span key={j} style={{ opacity: 1 - j / col.length }}>{g}</span>
            ))}
          </div>
        );
      })}
    </div>
  );
}

// ─────────────── MARQUEE ───────────────
function Marquee() {
  //const items = ['n8n', 'LangChain', 'Python', 'RAG', 'MCP', 'FastAPI', 'React', 'PyTorch', 'AWS', 'Docker', 'PostgreSQL', 'Redis', 'TypeScript'];
  const items = ['NEXT.JS', 'REACT', 'TYPESCRIPT' , 'POSTGRESQL', 'DOCKER', 'PYTORCH', 'LANGCHAIN', 'RAG', 'MCP', 'N8N', 'PYTHON', 'FASTAPI'];
  const row = [...items, ...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {row.map((t, i) => (
          <span key={i} className="marquee-item"><span className="marquee-dot">●</span> {t}</span>
        ))}
      </div>
    </div>
  );
}

// ─────────────── ABOUT ───────────────
function About() {
  return (
    <section className="section about" id="about">
      <Stamp style={{ top: '180px', right: '6%', transform: 'rotate(-8deg)' }}>// shipped 2026</Stamp>
      <Stamp style={{ bottom: '120px', left: '4%', transform: 'rotate(5deg)' }}>// Remote OK</Stamp>
      <SectionHeader num="01" label="About" bleed="§ ABOUT — ABOUT" bleedStyle="solid" />
      <div className="about-grid">
        <div>
          <h2 className="h-display">
            <FadeWords text="I engineer AI systems that" stagger={60} />
            <br/>
            <FadeWords text="ship, run on autopilot" delay={200} stagger={60} style={{ color: 'var(--accent)', fontStyle: 'italic' }} />
            <br/>
            <FadeWords text="and generate revenue." delay={400} stagger={60} />
          </h2>
        </div>
        <div className="about-right">
          <Reveal delay={200}>
            <p className="lead">
              My work lives at the core of AI engineering, LLM systems, and multi-modal vision models. I ship production-ready AI applications and full-stack platforms — engineered for high performance, zero downtime, and real monetization.
            </p>
          </Reveal>
          <Reveal delay={350}>
            <p>
              Currently engineering agentic AI workflows, hybrid RAG pipelines, and multi-modal models backed by fast, high-performance products.
            </p>
          </Reveal>
          <div className="stats-row">
            {[
              { n: 15, suf: '+', l: 'months freelance' },
              { n: 40, suf: '%', l: 'Workflow reduction' },
              { n: 97, suf: '%', l: 'Workflow Success' },
              { n: 10, suf: '+', l: 'Projects shipped' },
            ].map((s, i) => (
              <Reveal key={s.l} delay={500 + i * 80} className="stat">
                <div className="stat-n"><CountUp to={s.n} suffix={s.suf} /></div>
                <div className="stat-l">{s.l}</div>
              </Reveal>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function SectionHeader({ num, label, right, bleed, bleedStyle }) {
  // bleed: text to render as a huge type-bleed label above the section header
  // bleedStyle: 'solid' | 'outline'
  return (
    <>
      {bleed ? (
        <div className={`section-bleed ${bleedStyle === 'outline' ? 'is-outline' : 'is-solid'}`}>
          <div className="section-bleed-text">{bleed}</div>
        </div>
      ) : null}
      <div className="section-header">
        <div className="section-label">
          <span className="section-num">{num}</span>
          <span className="section-bar" />
          <span className="section-name"><Scramble text={label} duration={900} /></span>
        </div>
        {right}
      </div>
    </>
  );
}

function Stamp({ children, style }) {
  return <div className="rk-stamp" style={style}>{children}</div>;
}

// ─────────────── FEATURED WORK ───────────────
function Featured() {
  const [active, setActive] = React.useState(0);
  const p = S.featuredProjects;
  return (
    <section className="section featured" id="work">
      <SectionHeader num="03" label="Featured Work" bleed="FEATURED · WORK" bleedStyle="outline" right={<a className="section-link" href="#grid">all projects →</a>} />
      <div className="featured-list">
        {p.map((proj, i) => (
          <ProjectRow key={proj.id} p={proj} i={i} onHover={() => setActive(i)} active={active === i} />
        ))}
      </div>
    </section>
  );
}

function ProjectRow({ p, i, onHover, active }) {
  const [ref, shown] = useReveal({ threshold: 0.2 });
  return (
    <a href={p.url} target="_blank" rel="noopener noreferrer"
      ref={ref}
      onMouseEnter={onHover}
      className="proj-row"
      style={{
        opacity: shown ? 1 : 0,
        transform: shown ? 'translateY(0)' : 'translateY(60px)',
        transition: 'all 1000ms cubic-bezier(.2,.7,.2,1)',
      }}>
      <div className="proj-row-index">0{i + 1}</div>
      <div className="proj-row-title">
        <div className="proj-period mono-sm">{p.period}</div>
        <h3 className="proj-name">{p.title}</h3>
        <div className="proj-tagline">{p.tagline}</div>
      </div>
      <div className="proj-row-preview">
        <div className="proj-preview-inner">
          <ProjectArtwork id={p.id} />
          <div className="proj-preview-overlay">
            <div className="mono-sm">{p.tags.slice(0, 4).join(' · ')}</div>
          </div>
        </div>
      </div>
      <div className="proj-row-arrow">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M7 17L17 7M17 7H9M17 7V15" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </div>
    </a>
  );
}

// Abstract animated artwork per project id
function ProjectArtwork({ id }) {
  // OmniVision Pro — webcam + landmark dots
  if (id === 'omnivision') {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#060d18"/>
        <rect x="60" y="20" width="80" height="60" rx="4" fill="none" stroke="#22d3ee" strokeWidth="1" opacity=".7"/>
        {Array.from({ length: 33 }).map((_, i) => {
          const x = 100 + Math.cos(i / 33 * Math.PI * 2) * 28 + (i % 5 - 2) * 3;
          const y = 50 + Math.sin(i / 33 * Math.PI * 2) * 18 + (i % 3 - 1) * 3;
          return <circle key={i} cx={x} cy={y} r="1.4" fill={i % 7 === 0 ? '#f97316' : '#22d3ee'} opacity=".9">
            <animate attributeName="opacity" values=".4;1;.4" dur={`${1 + (i % 4) * .3}s`} repeatCount="indefinite"/>
          </circle>;
        })}
        <text x="100" y="100" fill="#22d3ee" fontSize="8" fontFamily="monospace" textAnchor="middle" opacity=".7">LIVE · MEDIAPIPE · WEBRTC</text>
        <circle cx="174" cy="24" r="6" fill="#f97316" opacity=".85">
          <animate attributeName="opacity" values=".4;1;.4" dur="1.2s" repeatCount="indefinite"/>
        </circle>
      </svg>
    );
  }
  // MyHRTools — dashboard / metrics
  if (id === 'myhrtools') {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0f1a0f"/>
        {[
          [20, 40, 60, '#22c55e'], [45, 25, 75, '#16a34a'],
          [70, 50, 50, '#22c55e'], [95, 30, 70, '#4ade80'],
          [120, 45, 55, '#22c55e'], [145, 20, 80, '#16a34a'],
          [170, 35, 65, '#22c55e'],
        ].map(([x, y, h, c], i) => (
          <rect key={i} x={x} y={y} width="18" height={h} rx="2" fill={c} opacity=".75">
            <animate attributeName="height" values={`${h};${h+14};${h}`} dur={`${2+i*.3}s`} repeatCount="indefinite"/>
            <animate attributeName="y" values={`${y};${y-14};${y}`} dur={`${2+i*.3}s`} repeatCount="indefinite"/>
          </rect>
        ))}
        <text x="100" y="112" fill="#4ade80" fontSize="8" fontFamily="monospace" textAnchor="middle" opacity=".8">LIGHTHOUSE 100 · ADSENSE ✓</text>
      </svg>
    );
  }
  // TwoFold — realtime social graph
  if (id === 'twofold') {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0e0820"/>
        {[[40,35],[100,25],[160,38],[60,80],[140,75],[100,65]].map(([x,y],i)=>(
          <g key={i}>
            <circle cx={x} cy={y} r="10" fill="#8b5cf6" opacity=".8">
              <animate attributeName="r" values="8;12;8" dur={`${2+i*.2}s`} repeatCount="indefinite"/>
            </circle>
            <circle cx={x} cy={y} r="16" fill="none" stroke="#8b5cf6" strokeWidth=".8" opacity=".4">
              <animate attributeName="r" values="14;22;14" dur={`${2.5+i*.2}s`} repeatCount="indefinite"/>
              <animate attributeName="opacity" values=".4;0;.4" dur={`${2.5+i*.2}s`} repeatCount="indefinite"/>
            </circle>
          </g>
        ))}
        {['M40,35 L100,25','M100,25 L160,38','M40,35 L60,80','M160,38 L140,75','M60,80 L100,65','M140,75 L100,65'].map((d,i)=>(
          <path key={i} d={d} fill="none" stroke="#a855f7" strokeWidth=".7" strokeDasharray="3 2" opacity=".6">
            <animate attributeName="stroke-dashoffset" from="0" to="-10" dur="1.4s" repeatCount="indefinite"/>
          </path>
        ))}
        <text x="100" y="110" fill="#a855f7" fontSize="8" fontFamily="monospace" textAnchor="middle" opacity=".7">SOCKET.IO · REAL-TIME</text>
      </svg>
    );
  }
  return <div className="artwork artwork-default" />;
}

// Abstract animated artwork for "More Projects" cards — keyed by title
function MoreProjectArt({ title, idx }) {
  // ChatBot-AI — message bubbles
  if (title.includes('ChatBot')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0d1218"/>
        {[{x:20,y:20,w:120,c:'#3b82f6'},{x:60,y:48,w:100,c:'#22d3ee'},{x:20,y:76,w:110,c:'#3b82f6'}].map((b,i)=>(
          <g key={i}>
            <rect x={b.x} y={b.y} width={b.w} height={20} rx="10" fill={b.c} opacity=".25"/>
            <rect x={b.x+8} y={b.y+7} width={b.w*.5} height={6} rx="3" fill={b.c} opacity=".6">
              <animate attributeName="width" values={`${b.w*.3};${b.w*.6};${b.w*.3}`} dur={`${2+i*.4}s`} repeatCount="indefinite"/>
            </rect>
          </g>
        ))}
        <text x="100" y="110" fill="#3b82f6" fontSize="8" fontFamily="monospace" textAnchor="middle" opacity=".7">~180ms · NLP · REST API</text>
      </svg>
    );
  }
  // Deep Facial Verification — siamese face match grid
  if (title.includes('Facial')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0d1218"/>
        {/* two face boxes with feature points */}
        {[40, 130].map((cx, k) => (
          <g key={k}>
            <rect x={cx} y="30" width="40" height="50" rx="3" fill="none" stroke="#f97316" strokeWidth="1" opacity=".7"/>
            {Array.from({ length: 8 }).map((_, i) => {
              const px = cx + 6 + (i % 4) * 9;
              const py = 38 + Math.floor(i / 4) * 18 + (i % 3) * 4;
              return <circle key={i} cx={px} cy={py} r="1.4" fill="#22d3ee">
                <animate attributeName="opacity" values=".4;1;.4" dur={`${1.5 + i * .1}s`} repeatCount="indefinite"/>
              </circle>;
            })}
          </g>
        ))}
        {/* connecting lines (siamese) */}
        {Array.from({ length: 5 }).map((_, i) => (
          <line key={i} x1={70 + (i % 3) * 4} y1={42 + i * 8} x2={130 + (i % 3) * 4} y2={42 + i * 8}
                stroke="#f97316" strokeWidth=".5" strokeDasharray="2 2" opacity=".6">
            <animate attributeName="stroke-dashoffset" from="0" to="-8" dur="1.2s" repeatCount="indefinite"/>
          </line>
        ))}
        <text x="100" y="105" fill="#fff" fontSize="8" fontFamily="monospace" textAnchor="middle" opacity=".55">SIM 0.97</text>
      </svg>
    );
  }
  if (title.includes('Suryapura Gram Vikas Portal')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0b1410"/>
        {[[20,22,45,28],[70,22,60,28],[135,22,45,28],[20,56,75,28],[100,56,80,28]].map(([x,y,w,h],i)=>(
          <g key={i}>
            <rect x={x} y={y} width={w} height={h} rx="3" fill="#22c55e" fillOpacity=".2"/>
            <rect x={x+6} y={y+6} width={w*0.5} height="4" rx="2" fill="#4ade80" fillOpacity=".8"/>
            <rect x={x+6} y={y+14} width={w*0.7} height="3" rx="1.5" fill="#22c55e" fillOpacity=".5"/>
          </g>
        ))}
        <path d="M 20 92 Q 70 82 100 85 T 180 78" fill="none" stroke="#4ade80" strokeWidth="1.2" strokeOpacity=".8"/>
        <text x="100" y="108" fill="#4ade80" fontSize="8" fontFamily="monospace" textAnchor="middle" fillOpacity=".8">CIVIC PORTAL · COMMUNITY SERVICES</text>
      </svg>
    );
  }

  // 6. RokanMitra — AI Civic Assistant & Agentic Workflow
  if (title.includes('RokanMitra')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#120d1c"/>
        {[[30,50],[90,30],[90,70],[150,50]].map(([x,y],i)=>(
          <g key={i}>
            <rect x={x-14} y={y-10} width="28" height="20" rx="4" fill="#a855f7" fillOpacity=".25"/>
            <rect x={x-12} y={y-8} width="24" height="16" rx="3" fill="#8b5cf6" fillOpacity=".8">
              <animate attributeName="opacity" values=".5;1;.5" dur={`${1.4+i*.2}s`} repeatCount="indefinite"/>
            </rect>
          </g>
        ))}
        {['M 42 50 L 78 30','M 42 50 L 78 70','M 102 30 L 138 50','M 102 70 L 138 50'].map((d,i)=>(
          <path key={i} d={d} fill="none" stroke="#e9d5ff" strokeWidth="1" strokeDasharray="3 2" strokeOpacity=".7">
            <animate attributeName="stroke-dashoffset" from="0" to="-10" dur="1s" repeatCount="indefinite"/>
          </path>
        ))}
        <text x="100" y="106" fill="#e9d5ff" fontSize="8" fontFamily="monospace" textAnchor="middle" fillOpacity=".8">AI CIVIC ASSISTANT · LANGCHAIN</text>
      </svg>
    );
  }
  // 2. MyHRTools — SaaS Metrics & AdSense Dashboard
  if (title.includes('MyHRTools')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0f1a0f"/>
        {[
          [20, 40, 60, '#22c55e'], [45, 25, 75, '#16a34a'],
          [70, 50, 50, '#22c55e'], [95, 30, 70, '#4ade80'],
          [120, 45, 55, '#22c55e'], [145, 20, 80, '#16a34a'],
          [170, 35, 65, '#22c55e'],
        ].map(([x, y, h, c], i) => (
          <rect key={i} x={x} y={y} width="18" height={h} rx="2" fill={c} opacity=".75">
            <animate attributeName="height" values={`${h};${h+14};${h}`} dur={`${2+i*.3}s`} repeatCount="indefinite"/>
            <animate attributeName="y" values={`${y};${y-14};${y}`} dur={`${2+i*.3}s`} repeatCount="indefinite"/>
          </rect>
        ))}
        <text x="100" y="112" fill="#4ade80" fontSize="8" fontFamily="monospace" textAnchor="middle" opacity=".8">LIGHTHOUSE 100 · ADSENSE ✓</text>
      </svg>
    );
  }

  // 3. OmniVision Pro — MediaPipe Landmarks & Camera Stream
  if (title.includes('OmniVision Pro')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#060d18"/>
        <rect x="60" y="20" width="80" height="60" rx="4" fill="none" stroke="#22d3ee" strokeWidth="1" strokeOpacity=".7"/>
        {Array.from({ length: 33 }).map((_, i) => {
          const x = 100 + Math.cos(i / 33 * Math.PI * 2) * 28 + (i % 5 - 2) * 3;
          const y = 50 + Math.sin(i / 33 * Math.PI * 2) * 18 + (i % 3 - 1) * 3;
          return (
            <circle key={i} cx={x} cy={y} r="1.4" fill={i % 7 === 0 ? '#f97316' : '#22d3ee'} fillOpacity=".9">
              <animate attributeName="opacity" values=".4;1;.4" dur={`${1 + (i % 4) * .3}s`} repeatCount="indefinite"/>
            </circle>
          );
        })}
        <circle cx="174" cy="24" r="5" fill="#ef4444">
          <animate attributeName="opacity" values=".3;1;.3" dur="1.2s" repeatCount="indefinite"/>
        </circle>
        <text x="100" y="102" fill="#22d3ee" fontSize="8" fontFamily="monospace" textAnchor="middle" fillOpacity=".8">LIVE · MEDIAPIPE · WEBRTC</text>
      </svg>
    );
  }
  
  // Omarchy — terminal lines
  if (title.includes('Omarchy')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0a0f0a"/>
        {[
          '$ omarchy --launch',
          '> menu: [apps]',
          '> menu: [system]',
          '> menu: [power]',
          '$ _',
        ].map((txt, i) => (
          <text key={i} x="14" y={28 + i * 16} fill={i === 4 ? '#22c55e' : '#86efac'} fontSize="9" fontFamily="monospace" opacity={.5 + i * .1}>
            {txt}
            {i === 4 ? <animate attributeName="opacity" values=".3;1;.3" dur="1s" repeatCount="indefinite"/> : null}
          </text>
        ))}
        <rect x="14" y="100" width="170" height="1" fill="#22c55e" opacity=".5"/>
      </svg>
    );
  }
  // 4. TwoFold Platform — Real-Time Socket Graph Nodes
  if (title.includes('TwoFold Platform')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0e0820"/>
        {[[40,35],[100,25],[160,38],[60,80],[140,75],[100,65]].map(([x,y],i)=>(
          <g key={i}>
            <circle cx={x} cy={y} r="8" fill="#8b5cf6" fillOpacity=".8">
              <animate attributeName="r" values="7;11;7" dur={`${1.8+i*.2}s`} repeatCount="indefinite"/>
            </circle>
            <circle cx={x} cy={y} r="14" fill="none" stroke="#8b5cf6" strokeWidth=".8" strokeOpacity=".4">
              <animate attributeName="r" values="12;18;12" dur={`${2.2+i*.2}s`} repeatCount="indefinite"/>
            </circle>
          </g>
        ))}
        {['M40,35 L100,25','M100,25 L160,38','M40,35 L60,80','M160,38 L140,75','M60,80 L100,65','M140,75 L100,65'].map((d,i)=>(
          <path key={i} d={d} fill="none" stroke="#a855f7" strokeWidth=".8" strokeDasharray="3 2" strokeOpacity=".6">
            <animate attributeName="stroke-dashoffset" from="0" to="-10" dur="1.4s" repeatCount="indefinite"/>
          </path>
        ))}
        <text x="100" y="110" fill="#a855f7" fontSize="8" fontFamily="monospace" textAnchor="middle" fillOpacity=".8">SOCKET.IO · REAL-TIME AI</text>
      </svg>
    );
  }
  // nskr.me — abstract typography portfolio
  if (title.includes('nskr')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#fef7e6"/>
        <text x="100" y="78" fill="#0a0a0a" fontSize="62" fontFamily="'Archivo Black', sans-serif" fontWeight="900" textAnchor="middle" letterSpacing="-2">
          nskr
        </text>
        <text x="100" y="78" fill="none" stroke="#f97316" strokeWidth=".5" fontSize="62" fontFamily="'Archivo Black', sans-serif" fontWeight="900" textAnchor="middle" letterSpacing="-2" opacity=".7">
          <animate attributeName="opacity" values=".3;.9;.3" dur="2.5s" repeatCount="indefinite"/>
          nskr
        </text>
        <line x1="20" y1="92" x2="180" y2="92" stroke="#0a0a0a" strokeWidth=".5"/>
        <text x="20" y="105" fill="#0a0a0a" fontSize="7" fontFamily="monospace" opacity=".7">// PERSONAL · 2025</text>
      </svg>
    );
  }
  // n8n Workflow — node graph
  if (title.includes('n8n')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0f0a1a"/>
        {/* nodes */}
        {[[30, 60], [80, 35], [80, 85], [130, 60], [170, 60]].map(([x, y], i) => (
          <g key={i}>
            <rect x={x - 10} y={y - 8} width="20" height="16" rx="3" fill="#a855f7" opacity=".85">
              <animate attributeName="opacity" values=".5;1;.5" dur={`${1.5 + i * .2}s`} repeatCount="indefinite"/>
            </rect>
            <circle cx={x - 10} cy={y} r="2" fill="#22d3ee"/>
            <circle cx={x + 10} cy={y} r="2" fill="#22d3ee"/>
          </g>
        ))}
        {/* connecting wires */}
        {[
          ['M 40 60 Q 60 60 70 35', 0],
          ['M 40 60 Q 60 60 70 85', .3],
          ['M 90 35 Q 110 35 120 60', .6],
          ['M 90 85 Q 110 85 120 60', .9],
          ['M 140 60 L 160 60', 1.2],
        ].map(([d, delay], i) => (
          <path key={i} d={d} fill="none" stroke="#a855f7" strokeWidth="1" strokeDasharray="3 3" opacity=".7">
            <animate attributeName="stroke-dashoffset" from="0" to="-12" dur="1.2s" repeatCount="indefinite" begin={`${delay}s`}/>
          </path>
        ))}
      </svg>
    );
  }
  // RAG Playground — document chunks + retrieval
  if (title.includes('RAG')) {
    return (
      <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
        <rect width="200" height="120" fill="#0f1410"/>
        {/* document chunks */}
        {Array.from({ length: 12 }).map((_, i) => {
          const col = i % 4;
          const row = Math.floor(i / 4);
          const x = 20 + col * 22;
          const y = 22 + row * 24;
          const highlighted = i === 2 || i === 6 || i === 9;
          return (
            <g key={i}>
              <rect x={x} y={y} width="18" height="18" rx="2" fill={highlighted ? '#f97316' : '#22c55e'} opacity={highlighted ? .9 : .25}>
                {highlighted ? <animate attributeName="opacity" values=".4;1;.4" dur={`${1.5 + i * .1}s`} repeatCount="indefinite"/> : null}
              </rect>
              {/* lines inside chunk */}
              <line x1={x + 2} y1={y + 5} x2={x + 14} y2={y + 5} stroke="#fff" strokeWidth=".4" opacity=".5"/>
              <line x1={x + 2} y1={y + 9} x2={x + 12} y2={y + 9} stroke="#fff" strokeWidth=".4" opacity=".5"/>
              <line x1={x + 2} y1={y + 13} x2={x + 14} y2={y + 13} stroke="#fff" strokeWidth=".4" opacity=".5"/>
            </g>
          );
        })}
        {/* query node */}
        <circle cx="170" cy="60" r="8" fill="#22d3ee">
          <animate attributeName="r" values="6;9;6" dur="2s" repeatCount="indefinite"/>
        </circle>
        <text x="170" y="63" fill="#0f1410" fontSize="8" fontFamily="monospace" textAnchor="middle" fontWeight="700">Q</text>
        {/* retrieval lines */}
        {[[60, 30], [128, 54], [82, 78]].map(([x, y], i) => (
          <line key={i} x1="162" y1="60" x2={x} y2={y} stroke="#f97316" strokeWidth=".7" opacity=".7" strokeDasharray="2 2">
            <animate attributeName="stroke-dashoffset" from="0" to="-8" dur="1s" repeatCount="indefinite"/>
          </line>
        ))}
      </svg>
    );
  }
  // fallback — animated gradient with glyph (current behavior)
  return (
    <svg className="artwork" viewBox="0 0 200 120" preserveAspectRatio="xMidYMid slice">
      <defs>
        <linearGradient id={`fb-${idx}`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0" stopColor={`oklch(60% 0.18 ${(idx * 60) % 360})`}/>
          <stop offset="1" stopColor={`oklch(50% 0.2 ${(idx * 60 + 120) % 360})`}/>
        </linearGradient>
      </defs>
      <rect width="200" height="120" fill={`url(#fb-${idx})`}/>
      <text x="100" y="78" fill="#fff" fontSize="56" fontFamily="'Comic Neue', cursive" textAnchor="middle" opacity=".75">{title.charAt(0)}</text>
    </svg>
  );
}

// ─────────────── ALL PROJECTS GRID ───────────────
function AllProjects() {
  return (
    <section className="section grid-sec" id="grid">
      <SectionHeader num="03" label="More Projects" bleed="MORE · MORE · MORE" bleedStyle="solid" right={<span className="mono-sm muted">//{S.otherProjects.length + S.featuredProjects.length} total</span>} />
      <div className="proj-grid">
        {S.otherProjects.map((p, i) => (
          <Reveal key={p.title} delay={i * 60} className="proj-card-wrap">
            <a href={p.url} target="_blank" rel="noopener noreferrer" className="proj-card">
              <div className="proj-card-art proj-card-art-svg">
                <MoreProjectArt title={p.title} idx={i} />
              </div>
              <div className="proj-card-body">
                <div className="mono-sm muted">{p.period}</div>
                <div className="proj-card-title">{p.title}</div>
                <div className="proj-card-tag">{p.tagline}</div>
                <div className="proj-card-chips">
                  {p.tags.slice(0, 3).map(t => <span key={t} className="chip">{t}</span>)}
                </div>
              </div>
            </a>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ─────────────── EXPERIENCE ───────────────
function CompanyLogo({ src, name }) {
  const [ok, setOk] = React.useState(true);
  const initials = name.split(/\s+/).slice(0, 2).map(w => w[0]).join('').toUpperCase();
  if (!src || !ok) {
    return <div className="exp-logo exp-logo-fallback" aria-label={name}>{initials}</div>;
  }
  return <img className="exp-logo" src={src} alt={`${name} logo`} onError={() => setOk(false)} />;
}

function Experience() {
  return (
    <section className="section exp" id="experience">
      <SectionHeader num="03" label="Experience" bleed="EXPERIENCE" bleedStyle="outline" />
      <div className="exp-list">
        {S.experience.map((e, i) => {
          const hasRoles = Array.isArray(e.roles) && e.roles.length > 0;
          return (
            <Reveal key={e.company + i} delay={i * 120} className="exp-item">
              <div className="exp-period mono-sm">{e.period}</div>
              <div className="exp-line" />
              <div className="exp-body">
                <div className="exp-head">
                  <CompanyLogo src={e.logo} name={e.company} />
                  <div className="exp-head-text">
                    <h3 className="exp-co-name">{e.company}</h3>
                    <div className="exp-meta mono-sm">
                      {e.type}{e.location ? ` · ${e.location}` : ''}
                    </div>
                  </div>
                </div>
                {hasRoles ? (
                  <ul className="exp-roles">
                    {e.roles.map((r, j) => (
                      <li key={j} className="exp-role-item">
                        <span className="exp-role-dot" />
                        <div className="exp-role-body">
                          <h4 className="exp-role">{r.role}</h4>
                          <div className="exp-role-period mono-sm">{r.period}</div>
                          {r.highlights && r.highlights.length > 0 && (
                            <ul className="exp-hl">
                              {r.highlights.slice(0, 5).map((h, k) => <li key={k}>{h}</li>)}
                            </ul>
                          )}
                        </div>
                      </li>
                    ))}
                  </ul>
                ) : (
                  <>
                    <h4 className="exp-role">{e.role}</h4>
                    <ul className="exp-hl">
                      {(e.highlights || []).slice(0, 5).map((h, j) => <li key={j}>{h}</li>)}
                    </ul>
                  </>
                )}
                {e.tags && e.tags.length > 0 && (
                  <div className="exp-chips">
                    {e.tags.map(t => <span key={t} className="chip">{t}</span>)}
                  </div>
                )}
              </div>
            </Reveal>
          );
        })}
      </div>
    </section>
  );
}

// ─────────────── SKILLS ───────────────
function Skills() {
  const groups = Object.entries(S.skills);
  return (
    <section className="section skills" id="skills">
      <Stamp style={{ top: '160px', right: '5%', transform: 'rotate(7deg)' }}>// PRODUCTION-TESTED </Stamp>
      <SectionHeader num="02" label="Stack" bleed="STACK · STACK" bleedStyle="solid" />
      <div className="skills-grid">
        {groups.map(([group, items], i) => (
          <Reveal key={group} delay={i * 80} className="skill-group">
            <div className="skill-group-title">{group}</div>
            <div className="skill-items">
              {items.map(it => (
                <span key={it} className="skill-pill">{it}</span>
              ))}
            </div>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ─────────────── WRITING ───────────────
/*function Writing() {
  return (
    <section className="section writing" id="writing">
      <SectionHeader num="06" label="Writing" bleed="WRITING · NOTES" bleedStyle="outline" right={<a className="section-link" href="https://omkushwahaportfolio.vercel.app/" target="_blank">all posts →</a>} />
      <div className="writing-list">
        {S.posts.map((p, i) => (
          <Reveal key={p.title} delay={i * 120}>
            <a href="https://omnivisionpro.streamlit.app/" className="post">
              {p.isNew && <span className="new-badge">NEW</span>}
              <div className="post-date mono-sm">{p.date}</div>
              <div className="post-title">{p.title}</div>
              <div className="post-excerpt">{p.excerpt}</div>
              <div className="post-more mono-sm">read →</div>
            </a>
          </Reveal>
        ))}
      </div>
    </section>
  );
}*/

// ─────────────── WRITING ───────────────

function Writing() {
  return (
    <section className="section writing" id="writing">
      <SectionHeader num="06" label="Writing" bleed="WRITING · NOTES" bleedStyle="outline" right={<a className="section-link" href="https://omkushwahaportfolio.vercel.app/" target="_blank">all posts →</a>} />
      <div className="writing-list">
        {S.posts.map((p, i) => (
          <Reveal key={p.title} delay={i * 120}>
            <a href={p.url || p.link || "#"} target="_blank" rel="noopener noreferrer" className="post">
              {p.isNew && <span className="new-badge">NEW</span>}
              <div className="post-date mono-sm">{p.date}</div>
              <div className="post-title">{p.title}</div>
              <div className="post-excerpt">{p.excerpt}</div>
              <div className="post-more mono-sm">read →</div>
            </a>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ─────────────── EDUCATION + CERTS ───────────────
function EduCerts() {
  return (
    <section className="section edu">
      <SectionHeader num="07" label="Education & Certs" bleed="EDU · CERTS" bleedStyle="solid" />
      <div className="edu-grid">
        <div>
          <div className="subhead">Education</div>
          {S.education.map((e, i) => (
            <Reveal key={e.school} delay={i * 80} className="edu-item">
              <div className="mono-sm muted">{e.period}</div>
              <div className="edu-degree">{e.degree}</div>
              <div className="edu-school">{e.school}</div>
              <div className="edu-note">{e.note}</div>
            </Reveal>
          ))}
        </div>
        <div>
          <div className="subhead">Certifications</div>
          {S.certifications.map((c, i) => (
            <Reveal key={c.title} delay={i * 80} className="edu-item">
              <div className="mono-sm muted">{c.date}</div>
              <div className="edu-degree">{c.title}</div>
              <div className="edu-school">{c.issuer}</div>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ─────────────── CONTACT ───────────────
function Contact() {
  return (
    <section className="section contact" id="contact">
      <div className="contact-grid">
        <div>
          <div className="section-label">
            <span className="section-num">08</span>
            <span className="section-bar" />
            <span className="section-name">Contact</span>
          </div>
          <h2 className="h-huge">
            <FadeWords text="Got a hard" stagger={80}/>
            <br/>
            <FadeWords text="Problem?" delay={200} stagger={80} style={{ fontStyle: 'italic', color: 'var(--accent)' }} />
            <br/>
            <FadeWords text="Let's build it." delay={400} stagger={80} />
          </h2>
          <a href="mailto:omkushwaha2005@gmail.com" className="contact-email">
            <Scramble text="omkushwaha2005@gmail.com" duration={1400} /> <span className="arr">→</span>
          </a>
        </div>
        <div className="contact-right">
          <div className="subhead">Elsewhere</div>
          {S.socials.map((s, i) => (
            <Reveal key={s.label} delay={i * 80}>
              <a href={s.url} target="_blank" rel="noopener noreferrer" className="social-link">
                <span>{s.label}</span>
                <span className="social-url mono-sm">{s.url.replace('https://', '').replace('mailto:', '')}</span>
                <span className="arr">↗</span>
              </a>
            </Reveal>
          ))}
        </div>
      </div>
      <footer className="footer">
        <div className="mono-sm">© 2026 · Om Kushwaha</div>
        <div className="mono-sm muted">Built with care · coffee </div>
      </footer>
    </section>
  );
}

// ─────────────── HERO V6 — Vortex / Viktor Oddy style ───────────────
function HeroV6() {
  // marquee thumbs — pulled from your project tags / featured projects
  const PROJECTS = S.featuredProjects.concat(S.otherProjects.slice(0, 3));
  const THUMBS = PROJECTS.map((p, i) => ({
    title: p.title,
    tags: (p.tags || []).slice(0, 3).join(' · '),
    hue: [22, 260, 188, 12, 320, 80, 200, 40][i % 8],
    glyph: ['◆','◇','○','●','▲','▼','■','□'][i % 8],
  }));
  const row = [...THUMBS, ...THUMBS];

  // parallax for the social/avatar block
  const [scrollY, setScrollY] = React.useState(0);
  React.useEffect(() => {
    let raf = 0;
    const on = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => setScrollY(window.scrollY));
    };
    window.addEventListener('scroll', on, { passive: true });
    return () => { window.removeEventListener('scroll', on); cancelAnimationFrame(raf); };
  }, []);

  return (
    <section className="hero-v6" id="top">
      <div className="v6-inner">
        {/* Logo / wordmark */}
        <div className="v6-fade" style={{ animationDelay: '0.1s' }}>
          <div className="v6-logo">Om Kushwaha</div>
        </div>

        {/* tagline (mono) */}
        <div className="v6-fade" style={{ animationDelay: '0.2s' }}>
          <div className="v6-tagline">The studio practice of OK</div>
        </div>

        {/* main heading — sans + serif italic mix */}
        <h1 className="v6-heading v6-fade" style={{ animationDelay: '0.3s' }}>
          <span className="v6-line">Build the <span className="v6-serif">next product</span>,</span>
          <span className="v6-line">the <span className="v6-serif">fullstack way.</span></span>
        </h1>

        {/* Body copy — three short paragraphs */}
        <div className="v6-body v6-fade" style={{ animationDelay: '0.4s' }}>
          <p>I spent the last 15+ months inside production web development — from real‑time computer vision to HR SaaS tools that earned Google AdSense approval.</p>
          <p>I lead the engineering on every project, backed by the stack I trust: Next.js, React, Node.js, Python, and a growing ML toolkit.</p>
          <p>Projects start with a focused sprint. Fast delivery, production quality.</p>
        </div>

        {/* CTA pair */}
        <div className="v6-ctas v6-fade" style={{ animationDelay: '0.5s' }}>
          <a href="mailto:omkushwaha2005@gmail.com" className="v6-btn v6-btn-primary">Start a chat</a>
          <a href="#work" className="v6-btn v6-btn-secondary">View projects</a>
        </div>

        {/* tiny availability row */}
        <div className="v6-avail v6-fade" style={{ animationDelay: '0.6s' }}>
          <span className="v6-dot" />
          <span>Open for work · Gujarat, India</span>
        </div>
      </div>

      {/* infinite marquee strip */}
      <div className="v6-marquee">
        <div className="v6-marquee-track">
          {row.map((t, i) => (
            <div key={i} className="v6-thumb" style={{ '--hue': t.hue }}>
              <div className="v6-thumb-bg">
                <span className="v6-thumb-glyph">{t.glyph}</span>
                <span className="v6-thumb-grid" />
              </div>
              <div className="v6-thumb-meta">
                <span className="v6-thumb-title">{t.title}</span>
                <span className="v6-thumb-tags">{t.tags}</span>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* bottom-left mini stat block */}
      <div
        className="v6-stat"
        style={{ transform: `translateY(${Math.min(scrollY * 0.2, 60)}px)` }}
      >
        <div className="v6-stat-num">7+</div>
        <div className="v6-stat-label">years writing<br/>production code</div>
      </div>
    </section>
  );
}

Object.assign(window, { NavBar, Hero, HeroV6, HeroV7, Marquee, About, Featured, AllProjects, Experience, Skills, Writing, EduCerts, Contact });

// ─────────────── HERO V7 — Olivia/Vortex bold orange ───────────────
function HeroV7() {
  const SKILLS = [
    //'Next.js', 'React', 'Node.js', 'TypeScript', 'Python', 'MongoDB',
    'LangChain','TensorFlow', 'LLM API Integration', 'Prompt Engineering',
    'Scikit-Learn', 'OpenCV', 'MediaPipe', 'Pandas', 'NumPy', 'TFLite', 'Docker','Kubernetes',
    'Next.js', 'React', 'Node.js', 'TypeScript', 'Python', 'MongoDB','HTML5',
  ];
  const row = [...SKILLS, ...SKILLS];

  const [boost, setBoost] = React.useState(false);
  const [videoOk, setVideoOk] = React.useState(true);
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [menuOpen]);
  const closeMenu = () => setMenuOpen(false);

  // staged intro: 0=initial, 1=headline, 2=watermark, 3=portrait, 4=ambient (mono blocks)
  const [stage, setStage] = React.useState(0);
  React.useEffect(() => {
    const t1 = setTimeout(() => setStage(1), 250);   // headline rises
    const t2 = setTimeout(() => setStage(2), 1050);  // watermark blooms
    const t3 = setTimeout(() => setStage(3), 1850);  // portrait slides in
    const t4 = setTimeout(() => setStage(4), 2350);  // mono blocks + marquee
    return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); clearTimeout(t4); };
  }, []);

  // JS-driven marquee — integer-pixel positions per frame = no subpixel shimmer
  const trackRef = React.useRef(null);
  const boostRef = React.useRef(false);
  React.useEffect(() => { boostRef.current = boost; }, [boost]);
  React.useEffect(() => {
    const track = trackRef.current;
    if (!track) return;
    let raf = 0;
    let pos = 0;       // current translateX in px (negative)
    let halfWidth = 0; // width of one duplicated half
    let lastT = performance.now();
    const baseSpeed = 60;   // px/sec
    const boostSpeed = 160; // px/sec
    const measure = () => { halfWidth = track.scrollWidth / 2; };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(track);
    const tick = (now) => {
      const dt = Math.min(0.05, (now - lastT) / 1000);
      lastT = now;
      const speed = boostRef.current ? boostSpeed : baseSpeed;
      pos -= speed * dt;
      if (halfWidth > 0 && -pos >= halfWidth) pos += halfWidth;
      track.style.transform = `translate3d(${Math.round(pos)}px, 0, 0)`;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => { cancelAnimationFrame(raf); ro.disconnect(); };
  }, []);

  return (
    <section className="hero-v7" id="top" data-stage={stage}>
      <div className="v7-topbar">
        <div className="v7-brand">◆ OK</div>
        <nav className="v7-nav">
          <a href="#work">PROJECTS</a>
          <a href="#writing">BLOG</a>
          <a href="#about">ABOUT</a>
          <a href="https://drive.google.com/file/d/18uemv5TG945QEc-FXfhjyDj8onrBAICB/view?usp=sharing" target="_blank" rel="noreferrer">RESUME</a>
        </nav>
        <a href="mailto:omkushwaha2005@gmail.com" className="v7-hire">
          // HIRE ME <span className="v7-hire-circle">↗</span>
        </a>
        <button
          className={`v7-burger ${menuOpen ? 'is-open' : ''}`}
          aria-label={menuOpen ? 'Close menu' : 'Open menu'}
          aria-expanded={menuOpen}
          onClick={() => setMenuOpen(o => !o)}
        >
          <span /><span /><span />
        </button>
      </div>

      <div className={`v7-mobile-menu ${menuOpen ? 'is-open' : ''}`} aria-hidden={!menuOpen}>
        <a href="#work" onClick={closeMenu}>PROJECTS</a>
        <a href="#writing" onClick={closeMenu}>BLOG</a>
        <a href="#about" onClick={closeMenu}>ABOUT</a>
        <a href="https://drive.google.com/file/d/18uemv5TG945QEc-FXfhjyDj8onrBAICB/view?usp=sharing" target="_blank" rel="noreferrer" onClick={closeMenu}>RESUME ↗</a>
        <a href="#contact" className="v7-mobile-hire" onClick={closeMenu}>
          // HIRE ME <span className="v7-hire-circle">↗</span>
        </a>
      </div>

      <div className="v7-watermark" aria-hidden="true">
        <span className="v7-watermark-word">OM.K</span>
      </div>

      <div className="v7-portrait">
        <img className="v7-avatar" src="avatar2.svg" alt="Om Kushwaha" loading="eager" decoding="async" fetchpriority="high" />
      </div>


      <h1 className="v7-headline" aria-label="AI Engineer">
        <span className="v7-headline-line">AI ENGINEER</span>
      </h1>

      <div className="v7-tagline">
        <div>// ZERO BLOAT UIs</div>
        <div className="v7-tagline-indent">HIGH-PERFORMANCE LLMs</div>
      </div>

      <div className="v7-bio">
        <div>// I'M OM — AI ENGINEER & FULLSTACK DEV</div>
        <div className="v7-bio-indent">BUILDING AI AGENTS & RAG PIPELINES WITH</div>
        <div>FASTAPI & PYTHON · OPEN TO WORK.</div>
      </div>

      <div
        className={`v7-marquee ${boost ? 'boost' : ''}`}
        onMouseEnter={() => setBoost(true)}
        onMouseLeave={() => setBoost(false)}
      >
        <div className="v7-marquee-track" ref={trackRef}>
          {row.map((s, i) => (
            <span key={i} className="v7-marquee-item">{s}</span>
          ))}
        </div>
      </div>
    </section>
  );
}

function PortraitPlaceholder() {
  // Stylized silhouette — head, headphones/glasses, shoulders
  return (
    <svg className="v7-silhouette" viewBox="0 0 600 800" preserveAspectRatio="xMidYMax slice" aria-hidden="true">
      <defs>
        <radialGradient id="v7sg" cx="50%" cy="35%" r="60%">
          <stop offset="0%" stopColor="#fff" stopOpacity=".22" />
          <stop offset="100%" stopColor="#fff" stopOpacity="0" />
        </radialGradient>
      </defs>
      {/* shoulders + body */}
      <path
        d="M 60 800 L 60 660 Q 90 580 180 540 Q 230 520 240 480 Q 245 460 240 440 L 360 440 Q 355 460 360 480 Q 370 520 420 540 Q 510 580 540 660 L 540 800 Z"
        fill="rgba(0,0,0,.18)"
      />
      {/* neck */}
      <path d="M 250 470 L 250 410 L 350 410 L 350 470 Q 320 480 300 480 Q 280 480 250 470 Z" fill="rgba(0,0,0,.22)" />
      {/* head */}
      <ellipse cx="300" cy="290" rx="120" ry="150" fill="rgba(0,0,0,.25)" />
      {/* hair top */}
      <path d="M 180 240 Q 200 140 300 130 Q 400 140 420 240 Q 410 200 380 195 Q 340 185 300 195 Q 260 185 220 195 Q 190 200 180 240 Z" fill="rgba(0,0,0,.32)" />
      {/* glasses bar */}
      <rect x="195" y="280" width="210" height="42" rx="20" fill="rgba(255,255,255,.55)" />
      <rect x="200" y="285" width="92" height="32" rx="14" fill="rgba(255,255,255,.85)" />
      <rect x="308" y="285" width="92" height="32" rx="14" fill="rgba(255,255,255,.85)" />
      {/* highlight */}
      <ellipse cx="300" cy="280" rx="220" ry="280" fill="url(#v7sg)" />
    </svg>
  );
}
