/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

/* ─── Mobile breakpoint hook ─────────────────────────────────────── */
function useMobile(bp = 768) {
  const [is, setIs] = useState(() => typeof window !== 'undefined' && window.innerWidth <= bp);
  useEffect(() => {
    const fn = () => setIs(window.innerWidth <= bp);
    window.addEventListener('resize', fn, { passive: true });
    fn();
    return () => window.removeEventListener('resize', fn);
  }, [bp]);
  return is;
}

/* ─── Reveal hook ────────────────────────────────────────────────── */
function useReveal(threshold = 0.12) {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setVisible(true); io.disconnect(); } },
      { threshold }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [threshold]);
  return [ref, visible];
}

/* ─── Back to top ─────────────────────────────────────────────────── */
function BackToTop() {
  const [vis, setVis] = useState(false);
  const [hover, setHover] = useState(false);
  useEffect(() => {
    const fn = () => setVis(window.scrollY > 500);
    window.addEventListener('scroll', fn, { passive: true });
    return () => window.removeEventListener('scroll', fn);
  }, []);
  const r = 26;
  const circ = +(2 * Math.PI * r).toFixed(1);
  return (
    <button
      onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      title="Back to top"
      style={{
        position: 'fixed', bottom: 'calc(28px + env(safe-area-inset-bottom, 0px))', right: 20, zIndex: 120,
        width: 44, height: 44, borderRadius: 999,
        background: '#0A0A0A', color: '#fff', border: 'none',
        cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
        opacity: vis ? 1 : 0, pointerEvents: vis ? 'all' : 'none',
        transform: vis ? 'translateY(0)' : 'translateY(14px)',
        transition: 'opacity 300ms, transform 400ms cubic-bezier(.22,1,.36,1)',
      }}>
      <svg width="56" height="56" viewBox="0 0 56 56"
        style={{ position: 'absolute', top: -6, left: -6, overflow: 'visible', pointerEvents: 'none' }}>
        <circle cx="28" cy="28" r={r}
          fill="none" stroke="#0A0A0A" strokeWidth="1.5"
          strokeDasharray={circ}
          strokeDashoffset={hover ? 0 : circ}
          style={{
            transform: 'rotate(-90deg)', transformOrigin: '28px 28px',
            transition: 'stroke-dashoffset 600ms cubic-bezier(.22,1,.36,1)',
          }} />
      </svg>
      <span style={{
        fontSize: 16, display: 'inline-block', lineHeight: 1,
        transform: hover ? 'translateY(-3px)' : 'translateY(0)',
        transition: 'transform 440ms cubic-bezier(.34,1.56,.64,1)',
      }}>↑</span>
    </button>
  );
}

/* ─── Nav link — chip fill from bottom ───────────────────────────── */
function NavLink({ label, id, go }) {
  const [hover, setHover] = useState(false);
  return (
    <a
      onClick={() => go(id)}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative', display: 'inline-flex', alignItems: 'center',
        fontFamily: "'Inter', sans-serif", fontSize: 13, fontWeight: 600,
        letterSpacing: '0.02em',
        color: hover ? '#fff' : '#0A0A0A',
        cursor: 'pointer',
        padding: '6px 11px', borderRadius: 7,
        overflow: 'hidden',
        transition: 'color 240ms cubic-bezier(.22,1,.36,1)',
      }}>
      {/* Fill chip — spring overshoot from bottom for life */}
      <span style={{
        position: 'absolute', inset: 0,
        background: '#0A0A0A', borderRadius: 7,
        transform: hover ? 'scaleY(1)' : 'scaleY(0)',
        transformOrigin: 'bottom',
        transition: hover
          ? 'transform 340ms cubic-bezier(.34,1.56,.64,1)'
          : 'transform 220ms cubic-bezier(.22,1,.36,1)',
        pointerEvents: 'none',
      }} />
      <span style={{
        position: 'relative', display: 'inline-block',
        transform: hover ? 'translateY(-1px)' : 'translateY(0)',
        transition: 'transform 340ms cubic-bezier(.34,1.56,.64,1)',
      }}>{label}</span>
    </a>
  );
}

/* ─── Nav ─────────────────────────────────────────────────────────── */
function Nav() {
  const isMobile = useMobile(640);
  const [scrolled, setScrolled] = useState(false);
  const [ctaHover, setCtaHover] = useState(false);
  const [ctaOffset, setCtaOffset] = useState({ x: 0, y: 0 });
  const ctaBtnRef = useRef(null);
  const handleCtaMove = (e) => {
    if (!ctaBtnRef.current) return;
    const rect = ctaBtnRef.current.getBoundingClientRect();
    setCtaOffset({
      x: (e.clientX - rect.left - rect.width / 2) * 0.10,
      y: (e.clientY - rect.top - rect.height / 2) * 0.10,
    });
  };
  useEffect(() => {
    const fn = () => setScrolled(window.scrollY > 60);
    window.addEventListener('scroll', fn, { passive: true });
    return () => window.removeEventListener('scroll', fn);
  }, []);
  const go = (id) => document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });
  return (
    <div style={{
      position: 'fixed', top: 20, left: 0, right: 0,
      zIndex: 100, display: 'flex', justifyContent: 'center', pointerEvents: 'none',
    }}>
      <nav style={{
        pointerEvents: 'all', display: 'flex', alignItems: 'center', gap: isMobile ? 12 : 28,
        border: '1.5px solid rgba(0,0,0,0.82)', borderRadius: 999,
        padding: isMobile ? '8px 8px 8px 16px' : '8px 8px 8px 22px',
        background: scrolled ? 'rgba(255,255,255,0.97)' : 'rgba(255,255,255,0.72)',
        backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
        transition: 'background 400ms cubic-bezier(.22,1,.36,1), box-shadow 400ms',
        boxShadow: scrolled ? '0 6px 28px rgba(0,0,0,0.09)' : 'none',
      }}>
        <span onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
          style={{
            fontFamily: "'Anton', sans-serif", fontSize: 20, letterSpacing: '0.05em',
            color: '#000', cursor: 'pointer', lineHeight: 1,
          }}>NK</span>
        <div style={{ width: 1, height: 16, background: 'rgba(0,0,0,0.15)', flexShrink: 0 }} />
        {!isMobile && (
          <div style={{ display: 'flex', gap: 4 }}>
            {[['Work','works'],['About','about'],['Skills','skills'],['Contact','contact']].map(([l,id]) => (
              <NavLink key={id} label={l} id={id} go={go} />
            ))}
          </div>
        )}
        {/* CTA — liquid fill interaction system */}
        <a
          ref={ctaBtnRef}
          onClick={() => go('contact')}
          onMouseEnter={() => setCtaHover(true)}
          onMouseLeave={() => { setCtaHover(false); setCtaOffset({ x: 0, y: 0 }); }}
          onMouseMove={ctaHover ? handleCtaMove : undefined}
          style={{
            position: 'relative', overflow: 'hidden',
            fontFamily: "'Inter', sans-serif", fontSize: 12, fontWeight: 700,
            letterSpacing: ctaHover ? '0.09em' : '0.06em',
            textTransform: 'uppercase',
            background: '#0A0A0A',
            color: ctaHover ? '#0A0A0A' : '#fff',
            padding: '10px 12px 10px 20px',
            borderRadius: 999, cursor: 'pointer',
            border: '1.5px solid #0A0A0A',
            display: 'inline-flex', alignItems: 'center', gap: 10,
            transform: `translate(${ctaHover ? ctaOffset.x : 0}px, ${ctaHover ? ctaOffset.y : 0}px) scale(${ctaHover ? 1.025 : 1})`,
            boxShadow: ctaHover
              ? '0 10px 36px rgba(0,0,0,0.22), 0 2px 8px rgba(0,0,0,0.10)'
              : '0 2px 10px rgba(0,0,0,0.12)',
            transition: ctaHover
              ? 'transform 140ms cubic-bezier(.22,1,.36,1), letter-spacing 400ms cubic-bezier(.22,1,.36,1), color 120ms 160ms cubic-bezier(.22,1,.36,1), box-shadow 220ms'
              : 'transform 500ms cubic-bezier(.34,1.56,.64,1), letter-spacing 300ms cubic-bezier(.22,1,.36,1), color 160ms cubic-bezier(.22,1,.36,1), box-shadow 340ms',
          }}>
          {/* Liquid fill — directional scaleX, springs in from left, retracts right-to-left */}
          <span style={{
            position: 'absolute', inset: 0, zIndex: 0, pointerEvents: 'none',
            background: '#fff',
            transform: ctaHover ? 'scaleX(1)' : 'scaleX(0)',
            transformOrigin: ctaHover ? 'left center' : 'right center',
            transition: `transform ${ctaHover ? 440 : 380}ms cubic-bezier(.76,0,.24,1)`,
          }} />
          <span style={{ position: 'relative', zIndex: 1 }}>Get In Touch</span>
          {/* Arrow orbital — inverts with fill */}
          <span style={{
            position: 'relative', zIndex: 1,
            width: 24, height: 24, borderRadius: 999,
            background: ctaHover ? '#0A0A0A' : 'rgba(255,255,255,0.14)',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 11, flexShrink: 0, overflow: 'hidden',
            transition: ctaHover
              ? 'background 200ms cubic-bezier(.22,1,.36,1) 180ms'
              : 'background 160ms cubic-bezier(.22,1,.36,1)',
          }}>
            <span style={{
              position: 'absolute', fontSize: 11, color: '#fff',
              transform: ctaHover ? 'translate(12px, -12px)' : 'translate(0,0)',
              opacity: ctaHover ? 0 : 1,
              transition: 'transform 340ms cubic-bezier(.22,1,.36,1), opacity 220ms',
            }}>→</span>
            <span style={{
              position: 'absolute', fontSize: 11, color: '#fff',
              transform: ctaHover ? 'translate(0,0)' : 'translate(-12px,12px)',
              opacity: ctaHover ? 1 : 0,
              transition: 'transform 340ms cubic-bezier(.22,1,.36,1), opacity 220ms',
            }}>→</span>
          </span>
        </a>
      </nav>
    </div>
  );
}

/* ─── Hero nav item ───────────────────────────────────────────────── */
function HeroNavItem({ num, label, id, go }) {
  const [hover, setHover] = useState(false);
  return (
    <button onClick={() => go(id)}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'flex', alignItems: 'center', gap: 12,
        background: 'none', border: 'none', cursor: 'pointer', padding: '5px 0',
      }}>
      <span style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: 9, fontWeight: 500,
        letterSpacing: '0.06em', border: '1px solid rgba(0,0,0,0.22)', borderRadius: 999,
        width: 28, height: 18, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
        background: hover ? '#0A0A0A' : 'transparent',
        color: hover ? '#fff' : 'rgba(0,0,0,0.38)',
        transition: 'background 240ms cubic-bezier(.22,1,.36,1), color 240ms',
      }}>{num}</span>
      <span style={{
        fontFamily: "'Anton', sans-serif", fontWeight: 400,
        fontSize: 'clamp(20px, 2.5vw, 38px)',
        color: '#0A0A0A', letterSpacing: '-0.01em', lineHeight: 1,
        textTransform: 'uppercase',
        opacity: hover ? 1 : 0.72,
        transform: hover ? 'translateX(7px)' : 'translateX(0)',
        display: 'inline-block',
        transition: 'transform 380ms cubic-bezier(.34,1.56,.64,1), opacity 240ms',
      }}>{label}</span>
    </button>
  );
}

/* ─── Hero ─────────────────────────────────────────────────────────── */
function Hero() {
  const isMobile = useMobile(640);
  const [mounted, setMounted] = useState(false);
  const [parallax, setParallax] = useState({ x: 0, y: 0 });
  const heroRef = useRef(null);

  useEffect(() => { const t = setTimeout(() => setMounted(true), 80); return () => clearTimeout(t); }, []);

  useEffect(() => {
    const el = heroRef.current;
    if (!el) return;
    const onMove = (e) => {
      const rect = el.getBoundingClientRect();
      const nx = (e.clientX - rect.left - rect.width / 2) / (rect.width / 2);
      const ny = (e.clientY - rect.top - rect.height / 2) / (rect.height / 2);
      setParallax({ x: nx * 20, y: ny * 11 });
    };
    el.addEventListener('mousemove', onMove, { passive: true });
    return () => el.removeEventListener('mousemove', onMove);
  }, []);

  const go = (id) => document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });
  const navItems = [['01', 'About', 'about'], ['02', 'Works', 'works'], ['03', 'Skills', 'skills'], ['04', 'Contact', 'contact']];

  const fade = (delay = 0) => ({
    opacity: mounted ? 1 : 0,
    transform: mounted ? 'translateY(0)' : 'translateY(22px)',
    transition: `opacity 1000ms ${delay}ms cubic-bezier(.22,1,.36,1), transform 1000ms ${delay}ms cubic-bezier(.22,1,.36,1)`,
  });

  return (
    <section id="hero" ref={heroRef} style={{ position: 'relative', height: '100vh', minHeight: 760, overflow: 'hidden' }}>
      {/* Parallax bg */}
      <div style={{
        position: 'absolute', top: '-6%', left: '-4%', right: '-4%', bottom: '-6%',
        backgroundImage: "url(assets/hero-cloth-bg.png)",
        backgroundSize: 'cover', backgroundPosition: 'center',
        transform: `translate(${parallax.x}px, ${parallax.y}px)`,
        transition: 'transform 650ms cubic-bezier(.22,1,.36,1)',
        willChange: 'transform',
      }} />
      {/* Gradient veil */}
      <div style={{
        position: 'absolute', inset: 0, zIndex: 1, pointerEvents: 'none',
        background: 'linear-gradient(180deg, rgba(255,255,255,0.44) 0%, rgba(255,255,255,0) 26%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.96) 100%)',
      }} />

      {/* Top meta row — hidden on mobile */}
      <div style={{
        position: 'absolute', top: 92, left: 0, right: 0, zIndex: 3,
        display: isMobile ? 'none' : 'flex', justifyContent: 'center', alignItems: 'center', gap: 16,
        ...fade(0),
      }}>
        {['PORTFOLIO \'23 — \'26', 'BASED IN TEL AVIV', 'OPEN FOR WORK'].map((item, i) => (
          <React.Fragment key={item}>
            {i > 0 && <span style={{ width: 3, height: 3, borderRadius: 999, background: '#000', opacity: 0.24, flexShrink: 0 }} />}
            <span style={{
              fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500,
              letterSpacing: '0.2em', textTransform: 'uppercase', color: '#0A0A0A', opacity: 0.55,
            }}>{item}</span>
          </React.Fragment>
        ))}
      </div>

      {/* Center nav — left column, hidden on mobile */}
      <div style={{
        position: 'absolute', top: '36%', transform: 'translateY(-50%)',
        left: 32, zIndex: 2, display: isMobile ? 'none' : 'flex', flexDirection: 'column', gap: 4,
        ...fade(300),
      }}>
        {navItems.map(([num, label, id]) => (
          <HeroNavItem key={id} num={num} label={label} id={id} go={go} />
        ))}
      </div>

      {/* Scroll indicator — bottom-right, hidden on mobile */}
      <div style={{
        position: 'absolute', right: 36, bottom: 36, zIndex: 3,
        display: isMobile ? 'none' : 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
        opacity: mounted ? 0.85 : 0,
        transition: 'opacity 1400ms 1000ms',
        pointerEvents: 'none',
      }}>
        {/* Vertical animated line — taller for presence */}
        <div style={{
          width: 1, height: 64, background: 'rgba(0,0,0,0.12)',
          position: 'relative', overflow: 'hidden',
        }}>
          <div style={{
            position: 'absolute', inset: 0,
            background: '#000',
            animation: 'scrollLine 2.4s ease-in-out infinite',
          }} />
        </div>
        {/* SCROLL text rotated */}
        <span style={{
          fontFamily: "'JetBrains Mono', monospace",
          fontSize: 8, letterSpacing: '0.28em', textTransform: 'uppercase',
          color: '#000', writingMode: 'vertical-rl',
          transform: 'rotate(180deg)', opacity: 0.7,
        }}>SCROLL</span>
      </div>

      {/* Bottom anchor */}
      <div style={{ position: 'absolute', bottom: 0, left: isMobile ? 16 : 24, right: isMobile ? 16 : 24, zIndex: 3, paddingBottom: isMobile ? 24 : 30 }}>
        {/* Separator */}
        <div style={{
          height: 1, background: 'rgba(0,0,0,0.11)', marginBottom: 14,
          opacity: mounted ? 1 : 0, transition: 'opacity 1400ms 60ms',
        }} />

        {/* Name */}
        <h1 style={{
          fontFamily: "'Anton', sans-serif", fontWeight: 400,
          fontSize: isMobile ? 'clamp(36px, 12vw, 80px)' : 'clamp(32px, 10vw, 158px)',
          lineHeight: 0.92, letterSpacing: '-0.025em',
          textTransform: 'uppercase', color: '#000', margin: '0 0 14px',
          wordBreak: 'break-word',
          ...fade(80),
        }}>NATANEL KALINER</h1>

        {/* Tagline */}
        <p style={{
          fontFamily: "'Inter', sans-serif",
          fontSize: isMobile ? 14 : 'clamp(14px, 1.4vw, 20px)',
          fontWeight: 400, lineHeight: 1.62,
          color: '#0A0A0A', margin: '0 0 18px', maxWidth: isMobile ? '92%' : '46%', opacity: 0.80,
          ...fade(200),
        }}>
          Creating experiences that feel alive — game UI, product systems, and interactive moments that resonate.
        </p>

        {/* Discipline pills */}
        <div style={{ display: 'flex', gap: 7, flexWrap: 'wrap', ...fade(280) }}>
          {['UX / UI', 'GAME DESIGN', 'PRODUCT', 'MOTION'].map(t => (
            <span key={t} style={{
              fontFamily: "'JetBrains Mono', monospace", fontSize: 9, fontWeight: 500,
              letterSpacing: '0.14em', textTransform: 'uppercase',
              color: '#0A0A0A', opacity: 0.48,
              padding: '4px 10px', borderRadius: 999,
              border: '1px solid rgba(0,0,0,0.18)',
            }}>{t}</span>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ─── About ──────────────────────────────────────────────────────── */
function About() {
  const isMobile = useMobile(768);
  const [ref, visible] = useReveal(0.12);
  const stats = [
    { n: '4', label: 'Years of practice', plus: true },
    { n: '20', label: 'Projects shipped', plus: true },
    { n: 'TLV', label: 'Based in Israel', plus: false },
  ];
  return (
    <section id="about" style={{ background: '#fff', padding: isMobile ? '80px 20px 72px' : '160px 24px 140px' }} ref={ref}>
      <div style={{
        maxWidth: 1320, margin: '0 auto',
        display: 'grid',
        gridTemplateColumns: isMobile ? '1fr' : '0.85fr 1.5fr',
        gap: isMobile ? 40 : 100,
        alignItems: 'center',
      }}>
        {!isMobile && (
          <div style={{
            position: 'relative', aspectRatio: '4/5', overflow: 'hidden',
            opacity: visible ? 1 : 0, transform: visible ? 'translateY(0)' : 'translateY(36px)',
            transition: 'opacity 1000ms cubic-bezier(.22,1,.36,1), transform 1000ms cubic-bezier(.22,1,.36,1)',
          }}>
            <img src="assets/photo-headshot.png" alt="Natanel Kaliner"
              style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center top', display: 'block', mixBlendMode: 'multiply', transform: 'scale(0.84)', transformOrigin: 'center 82%' }} />
          </div>
        )}
        <div style={{
          display: 'flex', flexDirection: 'column', gap: isMobile ? 20 : 28,
          opacity: visible ? 1 : 0, transform: visible ? 'translateY(0)' : 'translateY(36px)',
          transitionDelay: '160ms',
          transition: 'opacity 1000ms cubic-bezier(.22,1,.36,1), transform 1000ms cubic-bezier(.22,1,.36,1)',
        }}>
          {isMobile ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
              <div style={{ width: 52, height: 52, borderRadius: 999, overflow: 'hidden', flexShrink: 0, border: '1.5px solid #E8E8E8', background: '#F5F5F5' }}>
                <img src="assets/photo-headshot.png" alt="Natanel Kaliner"
                  style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 15%', display: 'block' }} />
              </div>
              <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888' }}>(01) — About</span>
            </div>
          ) : (
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888' }}>(01) — About</span>
          )}
          <h2 style={{ fontFamily: "'Inter', sans-serif", fontSize: isMobile ? 'clamp(28px, 7vw, 42px)' : 'clamp(34px, 4.2vw, 60px)', fontWeight: 800, lineHeight: 1.05, letterSpacing: '-0.03em', color: '#0A0A0A', margin: 0 }}>
            Designing interactive experiences across{' '}
            <em style={{ fontStyle: 'italic', fontWeight: 300 }}>games</em>,{' '}
            <em style={{ fontStyle: 'italic', fontWeight: 300 }}>apps</em>,{' '}
            and the <em style={{ fontStyle: 'italic', fontWeight: 300 }}>web</em>.
          </h2>
          <p style={{ fontFamily: "'Inter', sans-serif", fontSize: isMobile ? 15 : 18, lineHeight: 1.7, color: '#555', margin: 0 }}>
            My approach is centered on real user experience — understanding real needs, translating them into clear interfaces, and shaping digital journeys that feel effortless. Whether it's an app, a responsive website, or an interactive product, my goal is to deliver designs that not only look good but also solve real problems.
          </p>
          <div style={{ display: 'flex', alignItems: isMobile ? 'flex-start' : 'center', gap: isMobile ? 28 : 40, paddingTop: isMobile ? 24 : 32, borderTop: '1px solid #E8E8E8', flexWrap: 'wrap' }}>
            {stats.map((item) => (
              <div key={item.label} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                <div style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: isMobile ? 48 : 64, lineHeight: 0.88, letterSpacing: '-0.02em', color: '#000' }}>
                  {item.n}{item.plus && <span style={{ fontSize: '0.45em', verticalAlign: 'super', marginLeft: 2, color: '#888' }}>+</span>}
                </div>
                <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 11, fontWeight: 600, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#888' }}>{item.label}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Marquee — depth layering: filled row + outline row ─────────── */
function Marquee() {
  const [paused1, setPaused1] = useState(false);
  const [paused2, setPaused2] = useState(false);

  const row1 = ['EXPERIENCE DESIGN', 'GAME INTERFACES', 'INTERACTION CRAFT', 'VISUAL SYSTEMS', 'NARRATIVE UX', 'DIGITAL PRODUCTS'];
  const row2 = ['FIGMA', 'UI ARCHITECTURE', 'MOTION DESIGN', 'PROTOTYPING', 'PRODUCT THINKING', 'FRAMER', 'CREATIVE DIRECTION'];

  /* filled=true  → solid white text (foreground, close)
     filled=false → outline-only text (recedes, creates depth) */
  const track = (items, reverse, speed, paused, setPaused, scale, starDelay, filled) => {
    const doubled = [...items, ...items];
    const fs = `clamp(${Math.round(28 * scale)}px, ${(4.2 * scale).toFixed(1)}vw, ${Math.round(66 * scale)}px)`;
    const starFs = `clamp(${Math.round(11 * scale)}px, ${(1.5 * scale).toFixed(1)}vw, ${Math.round(20 * scale)}px)`;
    return (
      <div
        onMouseEnter={() => setPaused(true)}
        onMouseLeave={() => setPaused(false)}
        style={{
          padding: filled ? '22px 0' : '8px 0 16px',
          overflow: 'hidden',
          position: 'relative', cursor: 'default',
        }}>
        {/* Wider edge fades for cinematic feel */}
        <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: '14%', background: 'linear-gradient(90deg, #0A0A0A 30%, transparent 100%)', zIndex: 2, pointerEvents: 'none' }} />
        <div style={{ position: 'absolute', right: 0, top: 0, bottom: 0, width: '14%', background: 'linear-gradient(-90deg, #0A0A0A 30%, transparent 100%)', zIndex: 2, pointerEvents: 'none' }} />
        <div style={{
          display: 'flex', alignItems: 'center', whiteSpace: 'nowrap',
          animation: `${reverse ? 'mqScrollRev' : 'mqScroll'} ${speed}s linear infinite`,
          animationPlayState: paused ? 'paused' : 'running',
          width: 'max-content',
        }}>
          {doubled.map((t, i) => (
            <span key={i} style={{ display: 'inline-flex', alignItems: 'center' }}>
              <span style={{
                fontFamily: "'Anton', sans-serif", fontWeight: 400,
                fontSize: fs, lineHeight: 1, letterSpacing: '-0.01em',
                textTransform: 'uppercase', padding: '0 22px',
                /* Filled: bright solid white. Outline: very receded stroke */
                color: filled ? `rgba(255,255,255,${paused ? 0.95 : 0.82})` : 'transparent',
                WebkitTextStroke: filled ? 'none' : `1.5px rgba(255,255,255,${paused ? 0.42 : 0.18})`,
                transition: 'color 280ms, -webkit-text-stroke-color 280ms',
              }}>{t}</span>
              {/* Star: rotation only — no vertical drift */}
              <span style={{
                fontSize: starFs, flexShrink: 0, display: 'inline-block',
                color: `rgba(255,255,255,${paused ? 0.85 : filled ? 0.38 : 0.16})`,
                animation: `mqSpin ${22 + starDelay * 8}s linear infinite`,
                animationDelay: `${starDelay * 2}s`,
                transition: 'color 280ms',
              }}>✦</span>
            </span>
          ))}
        </div>
      </div>
    );
  };

  return (
    <section style={{ background: '#0A0A0A', overflow: 'hidden', borderTop: '1px solid rgba(255,255,255,0.07)' }}>
      {track(row1, false, 44, paused1, setPaused1, 1.0,  0, true)}
      <div style={{ height: 1, background: 'rgba(255,255,255,0.045)', margin: '0 0' }} />
      {track(row2, true,  22, paused2, setPaused2, 0.72, 1, false)}
    </section>
  );
}

/* ─── Skills ─────────────────────────────────────────────────────── */
const SKILLS = [
  { num: '01', title: 'UI / UX DESIGN',     desc: 'Research-led interfaces, flows, and systems that survive contact with real users. From wireframe to shipped product.',  tags: ['Wireframing', 'Prototyping', 'Design Systems', 'User Research'] },
  { num: '02', title: 'PRODUCT THINKING',   desc: 'End-to-end product design from ambiguous brief to shipped surface — strategy, information architecture, scope.',          tags: ['Discovery', 'Strategy', 'IA', 'Roadmapping'] },
  { num: '03', title: 'DIGITAL & WEB',      desc: 'Marketing sites, brand systems, and motion-rich landing pages built to perform and convert with intention.',              tags: ['Landing Pages', 'Brand', 'Webflow', 'Framer'] },
  { num: '04', title: 'GAME & INTERACTIVE', desc: 'Game UX, in-game interfaces, LiveOps design, and playful micro-interactions that deepen narrative experiences.',          tags: ['Game UI', 'LiveOps', 'Motion', 'Narrative UX'] },
];

function SkillRow({ num, title, desc, tags, index, visible }) {
  const isMobile = useMobile(768);
  const [hover, setHover] = useState(false);
  return (
    <article
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'grid',
        gridTemplateColumns: isMobile ? '1fr' : '72px 1fr auto',
        gap: isMobile ? 12 : 36,
        alignItems: 'center', padding: isMobile ? '22px 16px' : '28px 24px',
        borderBottom: '1px solid #DCDCDC',
        background: hover ? '#0A0A0A' : '#fff',
        color: hover ? '#fff' : '#0A0A0A',
        transform: hover ? 'translateX(6px)' : 'translateX(0)',
        transition: 'background 320ms cubic-bezier(.22,1,.36,1), color 320ms, transform 380ms cubic-bezier(.22,1,.36,1)',
        cursor: 'default',
        opacity: visible ? 1 : 0,
        transitionDelay: `${150 + index * 80}ms`,
      }}>
      {!isMobile && <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.14em', opacity: 0.45 }}>{num}</span>}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {isMobile && <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, fontWeight: 500, letterSpacing: '0.14em', opacity: 0.45 }}>{num}</span>}
        <h3 style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: isMobile ? 'clamp(24px, 6vw, 40px)' : 'clamp(28px, 3.8vw, 52px)', lineHeight: 1, letterSpacing: '-0.01em', margin: 0 }}>{title}</h3>
        <p style={{ fontFamily: "'Inter', sans-serif", fontSize: 15, lineHeight: 1.6, margin: 0, maxWidth: 560, color: hover ? 'rgba(255,255,255,0.6)' : '#666', transition: 'color 280ms' }}>{desc}</p>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {tags.map(t => (
            <span key={t} style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase', padding: '4px 10px', borderRadius: 999, border: `1px solid ${hover ? 'rgba(255,255,255,0.18)' : '#CCC'}`, color: hover ? 'rgba(255,255,255,0.75)' : '#555', transition: 'all 240ms' }}>{t}</span>
          ))}
        </div>
      </div>
      {!isMobile && <div style={{ fontFamily: "'Anton', sans-serif", fontSize: 'clamp(44px, 5vw, 76px)', lineHeight: 1, letterSpacing: '-0.02em', opacity: hover ? 0.15 : 0.05, transition: 'opacity 320ms', userSelect: 'none' }}>{num}</div>}
    </article>
  );
}

function Skills() {
  const isMobile = useMobile(768);
  const [ref, visible] = useReveal(0.08);
  return (
    <section id="skills" style={{ background: '#fff', padding: isMobile ? '80px 20px 72px' : '160px 24px 120px' }} ref={ref}>
      <div style={{ maxWidth: 1320, margin: '0 auto' }}>
        <div style={{
          display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 24 : 48,
          alignItems: 'end', marginBottom: isMobile ? 40 : 64, paddingBottom: isMobile ? 28 : 40,
          borderBottom: '1px solid #DCDCDC',
          opacity: visible ? 1 : 0, transform: visible ? 'none' : 'translateY(24px)',
          transition: 'opacity 800ms cubic-bezier(.22,1,.36,1), transform 800ms cubic-bezier(.22,1,.36,1)',
        }}>
          <div>
            <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888', marginBottom: 20 }}>(02) — Disciplines</div>
            <h2 style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: isMobile ? 'clamp(48px, 14vw, 100px)' : 'clamp(64px, 9.5vw, 148px)', lineHeight: 0.88, letterSpacing: '-0.02em', textTransform: 'uppercase', color: '#000', margin: 0 }}>MY CRAFT</h2>
          </div>
          <p style={{ fontFamily: "'Inter', sans-serif", fontSize: isMobile ? 15 : 18, lineHeight: 1.65, color: '#666', margin: 0, maxWidth: 500, alignSelf: 'end' }}>
            Four disciplines that overlap constantly. The surface shifts from game interface to product to web — the obsession with clarity, rhythm, and craft does not.
          </p>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          {SKILLS.map((s, i) => <SkillRow key={s.num} {...s} index={i} visible={visible} />)}
        </div>
      </div>
    </section>
  );
}

/* ─── Works ──────────────────────────────────────────────────────── */
const PROJECTS = [
  { id: 'yallaeat',    img: 'project/yallaeat-assets/hero.png',    title: 'YALLAEAT',    subtitle: 'Rescuing food, sustainably.',              tag: 'UI/UX Design',    duration: '1.5 Months', year: '2025', link: 'project/yallaeat.html' },
  { id: 'twos',        img: 'project/soul-assets/01_hero_visual.png', title: 'THE WEIGHT OF THE SOUL', subtitle: 'Symbolic pixel-art RPG — Egyptian mythology, fragment collection & emotional world design.', tag: 'Game Design', duration: '3 Months', year: '2025', link: 'project/soul.html' },
  { id: 'best-fiends', img: 'project/bestfiends-assets/01_hero_visual.png', title: 'BEST FIENDS', subtitle: 'Halloween LiveOps for a mobile game.',      tag: 'Game UX',         duration: 'Concept',    year: '2025', link: 'project/best-fiends.html' },
  { id: 'airbnb',      img: 'project/airbnb-assets/01_hero_visual.png', title: 'AIRBNB', subtitle: 'Neighborhood Matters — case study.', tag: 'UX Case Study', duration: '4 Weeks', year: '2023', link: 'project/airbnb.html' },
  { id: 'appcharge',   img: 'project-appcharge.png',   title: 'LIVEOPS STUDIO', subtitle: 'AI-powered game store builder — from design system to interactive prototype.', tag: 'AI Design System', duration: '8 Weeks',  year: '2025', link: 'project/appcharge.html' },
  { id: 'fish-of-fortune', img: 'project/fish-of-fortune-assets/01_hero.png', title: 'FISH OF FORTUNE', subtitle: 'Playable underwater HTML game — AI-directed development, progression systems, and rapid iteration.', tag: 'Game Design', duration: '2 Weeks', year: '2025', link: 'project/fish-of-fortune.html' },
];

function ProjectCard({ project, index, visible, onOpen }) {
  const [hover, setHover] = useState(false);
  const handleClick = () => {
    if (project.link) window.location.href = project.link;
    else onOpen(project);
  };
  return (
    <article
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      onClick={handleClick}
      style={{
        display: 'flex', flexDirection: 'column', gap: 18, cursor: 'pointer',
        opacity: visible ? 1 : 0, transform: visible ? 'translateY(0)' : 'translateY(36px)',
        transitionDelay: `${150 + index * 80}ms`,
        transition: 'opacity 800ms cubic-bezier(.22,1,.36,1), transform 800ms cubic-bezier(.22,1,.36,1)',
      }}>
      <div style={{
        position: 'relative', aspectRatio: '4/3', borderRadius: 12, overflow: 'hidden',
        background: '#EBEBEB',
        boxShadow: hover ? '0 28px 70px rgba(0,0,0,0.18)' : '0 4px 20px rgba(0,0,0,0.06)',
        transform: hover ? 'translateY(-10px) scale(1.01)' : 'translateY(0) scale(1)',
        transition: 'box-shadow 480ms cubic-bezier(.22,1,.36,1), transform 480ms cubic-bezier(.22,1,.36,1)',
      }}>
        <img src={project.img.includes('/') ? project.img : `assets/${project.img}`} alt={project.title}
          style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', transform: hover ? 'scale(1.07)' : 'scale(1)', transition: 'transform 700ms cubic-bezier(.22,1,.36,1)' }} />
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.54)', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 12, opacity: hover ? 1 : 0, transition: 'opacity 300ms cubic-bezier(.22,1,.36,1)', color: '#fff' }}>
          <span style={{ fontFamily: "'Anton', sans-serif", fontSize: 28, letterSpacing: '0.03em', textTransform: 'uppercase', transform: hover ? 'translateY(0)' : 'translateY(8px)', transition: 'transform 380ms cubic-bezier(.22,1,.36,1)' }}>View Project</span>
          <span style={{ fontSize: 24, display: 'inline-block', transform: hover ? 'translate(4px, -2px)' : 'translate(0,0)', transition: 'transform 380ms cubic-bezier(.22,1,.36,1)' }}>→</span>
        </div>
        <div style={{ position: 'absolute', top: 12, right: 12, background: 'rgba(255,255,255,0.9)', backdropFilter: 'blur(10px)', padding: '3px 10px', borderRadius: 999, fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.1em', color: '#0A0A0A' }}>{project.year}</div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '0 2px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 10 }}>
          <h3 style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: 'clamp(32px, 3.8vw, 52px)', lineHeight: 1, letterSpacing: '-0.02em', textTransform: 'uppercase', color: '#000', margin: 0, transform: hover ? 'translateX(4px)' : 'translateX(0)', transition: 'transform 360ms cubic-bezier(.22,1,.36,1)', display: 'inline-block' }}>{project.title}</h3>
          <span style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, fontWeight: 700, letterSpacing: '0.10em', textTransform: 'uppercase', padding: '4px 10px', border: '1.5px solid #0A0A0A', borderRadius: 999, whiteSpace: 'nowrap', transition: 'background 260ms, color 260ms', background: hover ? '#0A0A0A' : 'transparent', color: hover ? '#fff' : '#0A0A0A' }}>{project.tag}</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 8, borderTop: '1px dashed #D5D5D5' }}>
          <span style={{ fontFamily: "'Inter', sans-serif", fontSize: 13, fontWeight: 400, color: '#777', fontStyle: 'italic' }}>{project.subtitle}</span>
          <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.10em', textTransform: 'uppercase', color: '#AAA' }}>{project.duration}</span>
        </div>
      </div>
    </article>
  );
}

/* ─── Works contact link — connected to interaction ecosystem ─────── */
function WorksLink({ href, children }) {
  const [hover, setHover] = useState(false);
  return (
    <a href={href}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative', display: 'inline-flex', alignItems: 'center', gap: 5,
        fontFamily: "'Inter', sans-serif", fontSize: 13, fontWeight: 700,
        color: '#0A0A0A', textDecoration: 'none',
        letterSpacing: hover ? '0.04em' : '0',
        transition: 'letter-spacing 360ms cubic-bezier(.22,1,.36,1)',
      }}>
      <span style={{ position: 'relative' }}>
        {children}
        {/* Underline — directional reveal matching fill system */}
        <span style={{
          position: 'absolute', bottom: -2, left: 0, right: 0, height: 1.5,
          background: '#0A0A0A',
          transform: hover ? 'scaleX(1)' : 'scaleX(0)',
          transformOrigin: hover ? 'left' : 'right',
          transition: `transform ${hover ? 380 : 320}ms cubic-bezier(.76,0,.24,1)`,
        }} />
      </span>
      {/* Arrow trajectory */}
      <span style={{
        position: 'relative', width: 15, height: 15, overflow: 'hidden',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <span style={{
          position: 'absolute', fontSize: 13,
          transform: hover ? 'translate(11px, -11px)' : 'translate(0, 0)',
          opacity: hover ? 0 : 1,
          transition: 'transform 340ms cubic-bezier(.22,1,.36,1), opacity 220ms',
        }}>↗</span>
        <span style={{
          position: 'absolute', fontSize: 13,
          transform: hover ? 'translate(0, 0)' : 'translate(-11px, 11px)',
          opacity: hover ? 1 : 0,
          transition: 'transform 340ms cubic-bezier(.22,1,.36,1), opacity 220ms',
        }}>↗</span>
      </span>
    </a>
  );
}

/* ─── Works ──────────────────────────────────────────────────────── */
function Works({ onOpenProject }) {
  const isMobile = useMobile(768);
  const [ref, visible] = useReveal(0.06);
  return (
    <section id="works" style={{ background: '#F7F7F7', padding: isMobile ? '80px 20px 72px' : '140px 24px 120px' }} ref={ref}>
      <div style={{ maxWidth: 1320, margin: '0 auto' }}>
        <div style={{ marginBottom: isMobile ? 40 : 80, opacity: visible ? 1 : 0, transform: visible ? 'none' : 'translateY(20px)', transition: 'opacity 800ms cubic-bezier(.22,1,.36,1), transform 800ms cubic-bezier(.22,1,.36,1)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingBottom: 16, marginBottom: 24, borderBottom: '1px solid #D8D8D8' }}>
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888' }}>(03) — Selected works</span>
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888' }}>{String(PROJECTS.length).padStart(2, '0')} projects</span>
          </div>

          {/* Year timeline — 2023 / 2026, ghost treatment */}
          <div>
            {[['SELECTED', '2023'], ['WORKS', '2026']].map(([word, year]) => (
              <div key={word} style={{ display: 'flex', alignItems: 'baseline', gap: isMobile ? 12 : 20 }}>
                <span style={{
                  fontFamily: "'Anton', sans-serif", fontWeight: 400,
                  fontSize: isMobile ? 'clamp(44px, 11vw, 100px)' : 'clamp(72px, 12vw, 196px)', lineHeight: 0.88,
                  letterSpacing: '-0.025em', textTransform: 'uppercase',
                  color: '#000', flexShrink: 0,
                }}>{word}</span>
                {/* Thin solid connector */}
                <div style={{ flex: 1, height: 1, background: '#0A0A0A', opacity: 0.10, marginBottom: '0.24em' }} />
                {/* Year — ghost: same black type at low opacity, much larger */}
                <span style={{
                  fontFamily: "'Anton', sans-serif", fontWeight: 400,
                  fontSize: isMobile ? 'clamp(22px, 5vw, 50px)' : 'clamp(36px, 5.5vw, 90px)', lineHeight: 0.88,
                  letterSpacing: '-0.02em',
                  color: '#0A0A0A', opacity: 0.18,
                  flexShrink: 0,
                }}>{year}</span>
              </div>
            ))}
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(2, 1fr)', gap: isMobile ? '48px 0' : '68px 32px' }}>
          {PROJECTS.map((p, i) => <ProjectCard key={p.id} project={p} index={i} visible={visible} onOpen={onOpenProject} />)}
        </div>

        <div style={{ marginTop: 40, paddingTop: 20, borderTop: '1px solid #E0E0E0', display: 'flex', justifyContent: 'space-between', alignItems: 'center', opacity: visible ? 1 : 0, transitionDelay: '500ms', transition: 'opacity 800ms' }}>
          <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#AAA' }}>More work available upon request</span>
          <WorksLink href="mailto:natanelkaliner@gmail.com">Get in touch</WorksLink>
        </div>
      </div>
    </section>
  );
}

/* ─── Project modal ───────────────────────────────────────────────── */
function ProjectModal({ project, onClose }) {
  useEffect(() => {
    document.body.style.overflow = project ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [project]);
  if (!project) return null;
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.72)', backdropFilter: 'blur(14px)', zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <div onClick={e => e.stopPropagation()} style={{ background: '#fff', borderRadius: 18, maxWidth: 1060, width: '100%', maxHeight: '90vh', overflow: 'auto', position: 'relative' }}>
        <button onClick={onClose} style={{ position: 'absolute', top: 14, right: 14, width: 42, height: 42, borderRadius: 999, border: '1.5px solid #000', background: '#fff', fontSize: 20, cursor: 'pointer', zIndex: 2, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>×</button>
        <div style={{ aspectRatio: '16/9', background: '#EEE', overflow: 'hidden', borderTopLeftRadius: 18, borderTopRightRadius: 18 }}>
          <img src={project.img.includes('/') ? project.img : `assets/${project.img}`} alt={project.title} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
        </div>
        <div style={{ padding: '32px 48px 48px', display: 'flex', flexDirection: 'column', gap: 14 }}>
          <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888' }}>{project.tag} · {project.year}</span>
          <h2 style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: 'clamp(44px, 7vw, 88px)', lineHeight: 1, letterSpacing: '-0.02em', textTransform: 'uppercase', margin: 0 }}>{project.title}</h2>
          <p style={{ fontFamily: "'Inter', sans-serif", fontSize: 17, lineHeight: 1.65, color: '#333', maxWidth: 680, margin: 0 }}>{project.subtitle}</p>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 24, marginTop: 12, paddingTop: 24, borderTop: '1px solid #EBEBEB' }}>
            {[{l:'Role',v:'Lead UX/UI Designer'},{l:'Timeline',v:project.duration},{l:'Tools',v:'Figma, Framer'},{l:'Year',v:project.year}].map(({l,v}) => (
              <div key={l} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 10, fontWeight: 700, letterSpacing: '0.14em', textTransform: 'uppercase', color: '#AAA' }}>{l}</div>
                <div style={{ fontFamily: "'Inter', sans-serif", fontSize: 15, fontWeight: 600, color: '#0A0A0A' }}>{v}</div>
              </div>
            ))}
          </div>
          {project.link && (
            <a href={project.link} style={{ alignSelf: 'flex-start', marginTop: 8, padding: '14px 28px', borderRadius: 999, background: '#0A0A0A', color: '#fff', fontFamily: "'Inter', sans-serif", fontSize: 13, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', textDecoration: 'none' }}>
              Full Case Study →
            </a>
          )}
        </div>
      </div>
    </div>
  );
}

/* ─── Contact ─────────────────────────────────────────────────────── */
function BoxField({ label, value, onChange, placeholder, multiline, error }) {
  const [focus, setFocus] = useState(false);
  const Tag = multiline ? 'textarea' : 'input';
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <span style={{ fontFamily: "'Inter', sans-serif", fontSize: 11, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: error ? '#C62828' : '#888', transition: 'color 200ms' }}>{label}</span>
      <Tag value={value} onChange={e => onChange(e.target.value)}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        placeholder={placeholder} rows={multiline ? 5 : undefined}
        style={{
          fontFamily: "'Inter', sans-serif", fontSize: 16, fontWeight: 400,
          color: '#0A0A0A', background: '#F7F7F7',
          border: `1.5px solid ${focus ? '#0A0A0A' : error ? '#C62828' : '#E0E0E0'}`,
          borderRadius: 10, padding: '14px 16px', outline: 'none',
          width: '100%', boxSizing: 'border-box',
          resize: multiline ? 'none' : undefined,
          transition: 'border-color 200ms',
        }} />
      {error && <span style={{ fontFamily: "'Inter', sans-serif", fontSize: 11, color: '#C62828', marginTop: -2 }}>{error}</span>}
    </div>
  );
}

/* ─── Send button — shimmer + arrow trajectory + magnetic ─────────── */
function SendButton({ status }) {
  const btnRef = useRef(null);
  const [hover, setHover] = useState(false);
  const [offset, setOffset] = useState({ x: 0, y: 0 });

  const isDisabled = status === 'sending' || status === 'success';

  const handleMove = (e) => {
    if (!btnRef.current || isDisabled) return;
    const rect = btnRef.current.getBoundingClientRect();
    const x = (e.clientX - rect.left - rect.width / 2) * 0.20;
    const y = (e.clientY - rect.top - rect.height / 2) * 0.20;
    setOffset({ x, y });
  };

  const bgColor = status === 'success' ? '#166534' : '#0A0A0A';
  const borderColor = status === 'success' ? '#166534' : '#0A0A0A';

  return (
    <button
      ref={btnRef} type="submit"
      disabled={isDisabled}
      onMouseEnter={() => !isDisabled && setHover(true)}
      onMouseLeave={() => { setHover(false); setOffset({ x: 0, y: 0 }); }}
      onMouseMove={hover && !isDisabled ? handleMove : undefined}
      style={{
        position: 'relative', overflow: 'hidden',
        padding: '13px 28px', borderRadius: 999,
        background: bgColor,
        color: hover && !isDisabled ? bgColor : '#fff',
        border: `1.5px solid ${borderColor}`,
        fontFamily: "'Inter', sans-serif", fontSize: 13, fontWeight: 700,
        letterSpacing: hover && !isDisabled ? '0.10em' : '0.08em',
        textTransform: 'uppercase',
        cursor: isDisabled ? 'default' : 'pointer',
        display: 'inline-flex', alignItems: 'center', gap: 12,
        opacity: status === 'sending' ? 0.7 : 1,
        transform: `translate(${hover && !isDisabled ? offset.x : 0}px, ${hover && !isDisabled ? offset.y : 0}px) scale(${hover && !isDisabled ? 1.02 : 1})`,
        transition: hover && !isDisabled
          ? 'transform 140ms cubic-bezier(.22,1,.36,1), box-shadow 200ms, color 120ms 180ms cubic-bezier(.22,1,.36,1), letter-spacing 420ms cubic-bezier(.22,1,.36,1), background 300ms, border-color 300ms'
          : 'transform 520ms cubic-bezier(.34,1.56,.64,1), box-shadow 340ms, color 180ms cubic-bezier(.22,1,.36,1), letter-spacing 300ms cubic-bezier(.22,1,.36,1), background 300ms, border-color 300ms',
        boxShadow: hover && !isDisabled
          ? '0 10px 32px rgba(0,0,0,0.18), 0 2px 8px rgba(0,0,0,0.10)'
          : '0 2px 8px rgba(0,0,0,0.10)',
      }}>
      {/* Liquid fill */}
      <span style={{
        position: 'absolute', inset: 0, zIndex: 0, pointerEvents: 'none',
        background: '#fff',
        transform: hover && !isDisabled ? 'scaleX(1)' : 'scaleX(0)',
        transformOrigin: hover && !isDisabled ? 'left center' : 'right center',
        transition: `transform ${hover && !isDisabled ? 520 : 440}ms cubic-bezier(.76,0,.24,1)`,
      }} />

      {status === 'sending' ? (
        <span style={{ position: 'relative', zIndex: 1 }}>Sending…</span>
      ) : status === 'success' ? (
        <span style={{ position: 'relative', zIndex: 1 }}>✓ Message Sent!</span>
      ) : (
        <>
          <span style={{ position: 'relative', zIndex: 1 }}>Send Message</span>
          {/* Arrow — naked trajectory */}
          <span style={{
            position: 'relative', zIndex: 1,
            width: 20, height: 20,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            overflow: 'hidden', flexShrink: 0,
          }}>
            <span style={{
              position: 'absolute', fontSize: 16,
              transform: hover ? 'translate(14px, -14px)' : 'translate(0, 0)',
              opacity: hover ? 0 : 1,
              transition: 'transform 360ms cubic-bezier(.22,1,.36,1), opacity 240ms',
            }}>→</span>
            <span style={{
              position: 'absolute', fontSize: 16,
              transform: hover ? 'translate(0, 0)' : 'translate(-14px, 14px)',
              opacity: hover ? 1 : 0,
              transition: 'transform 360ms cubic-bezier(.22,1,.36,1), opacity 240ms',
            }}>→</span>
          </span>
        </>
      )}
    </button>
  );
}

/* ─── Social link — arrow trajectory + row shift ─────────────────── */
function SocialLink({ n, label, href }) {
  const [hover, setHover] = useState(false);
  return (
    <a href={href}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        padding: '20px 0', borderBottom: '1px solid #E8E8E8', textDecoration: 'none',
      }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, overflow: 'hidden' }}>
        {/* Number badge — fills on hover */}
        <span style={{
          fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500,
          letterSpacing: '0.1em', borderRadius: 999, padding: '2px 8px',
          border: `1px solid ${hover ? '#0A0A0A' : '#E0E0E0'}`,
          background: hover ? '#0A0A0A' : 'transparent',
          color: hover ? '#fff' : '#BBB',
          transition: 'background 240ms cubic-bezier(.22,1,.36,1), color 240ms, border-color 240ms',
          flexShrink: 0,
        }}>{n}</span>
        {/* Label — slides right, same easing as arrow */}
        <span style={{
          fontFamily: "'Inter', sans-serif", fontSize: 18, fontWeight: 600, color: '#0A0A0A',
          transform: hover ? 'translateX(10px)' : 'translateX(0)',
          transition: 'transform 380ms cubic-bezier(.22,1,.36,1)',
          display: 'inline-block',
        }}>{label}</span>
      </div>
      {/* Arrow — diagonal exit/enter with subtle rotation */}
      <div style={{ position: 'relative', width: 22, height: 22, overflow: 'hidden', flexShrink: 0 }}>
        <span style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 17, color: '#0A0A0A',
          transform: hover ? 'translate(15px, -15px) rotate(8deg)' : 'translate(0, 0) rotate(0deg)',
          opacity: hover ? 0 : 1,
          transition: 'transform 380ms cubic-bezier(.22,1,.36,1), opacity 260ms',
        }}>↗</span>
        <span style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 17, color: '#0A0A0A',
          transform: hover ? 'translate(0, 0) rotate(0deg)' : 'translate(-15px, 15px) rotate(-8deg)',
          opacity: hover ? 1 : 0,
          transition: 'transform 380ms cubic-bezier(.22,1,.36,1), opacity 260ms',
        }}>↗</span>
      </div>
    </a>
  );
}

function Contact() {
  const isMobile = useMobile(768);
  const [form, setForm]     = useState({ name: '', email: '', message: '' });
  const [status, setStatus] = useState('idle'); // 'idle' | 'sending' | 'success' | 'error'
  const [errors, setErrors] = useState({});
  const set = (k) => (v) => {
    setForm(f => ({ ...f, [k]: v }));
    if (errors[k]) setErrors(e => ({ ...e, [k]: '' }));
  };

  const validate = () => {
    const e = {};
    if (!form.name.trim())    e.name    = 'Name is required';
    if (!form.email.trim())   e.email   = 'Email is required';
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim())) e.email = 'Please enter a valid email';
    if (!form.message.trim()) e.message = 'Message is required';
    return e;
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    const errs = validate();
    if (Object.keys(errs).length) { setErrors(errs); return; }
    setErrors({});
    setStatus('sending');

    try {
      const res = await fetch('/api/contact', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name:         form.name.trim(),
          email:        form.email.trim(),
          message:      form.message.trim(),
          page_url:     window.location.href,
          submitted_at: new Date().toLocaleString('en-IL', { timeZone: 'Asia/Jerusalem' }),
          botcheck:     '',   // honeypot — must stay empty
        }),
      });
      const data = await res.json();
      if (res.ok && data.success) {
        setStatus('success');
        setForm({ name: '', email: '', message: '' });
        setTimeout(() => setStatus('idle'), 7000);
      } else {
        console.error('Contact API error:', data);
        setStatus('error');
        setTimeout(() => setStatus('idle'), 6000);
      }
    } catch (err) {
      console.error('Network error:', err);
      setStatus('error');
      setTimeout(() => setStatus('idle'), 6000);
    }
  };

  const socials = [
    { n: '001', label: 'Email',    href: 'mailto:natanelkaliner@gmail.com' },
    { n: '002', label: 'LinkedIn', href: 'https://www.linkedin.com/in/natanel-kaliner-ab6966395' },
  ];
  return (
    <section id="contact" style={{ background: '#fff', padding: isMobile ? '80px 20px 72px' : '180px 24px 140px', borderTop: '1px solid #E8E8E8' }}>
      <div style={{ maxWidth: 1320, margin: '0 auto' }}>
        <div style={{ marginBottom: isMobile ? 48 : 96 }}>
          <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888', display: 'block', marginBottom: 28 }}>Get In Touch / 04</span>
          <h2 style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: isMobile ? 'clamp(40px, 11vw, 80px)' : 'clamp(56px, 8.5vw, 136px)', lineHeight: 1.0, letterSpacing: '-0.025em', textTransform: 'uppercase', color: '#000', margin: 0 }}>
            FROM IDEA<br/>TO EXPERIENCE.
          </h2>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1.4fr 1fr', gap: isMobile ? 56 : 100, alignItems: 'start' }}>
          <form onSubmit={onSubmit} noValidate style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            {/* Honeypot — hidden from real users, bots fill it in */}
            <input type="checkbox" name="botcheck" style={{ display: 'none' }} tabIndex={-1} autoComplete="off" />
            <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: 16 }}>
              <BoxField label="Your Name" value={form.name} onChange={set('name')} placeholder="Your name"       error={errors.name} />
              <BoxField label="Email"     value={form.email} onChange={set('email')} placeholder="your@email.com" error={errors.email} />
            </div>
            <BoxField label="What can I help with?" value={form.message} onChange={set('message')} placeholder="Tell me about the project, role, or collaboration…" multiline error={errors.message} />
            <div style={{ display: 'flex', alignItems: 'center', gap: 20, marginTop: 8, flexWrap: 'wrap' }}>
              <SendButton status={status} />
              {status === 'error' ? (
                <span style={{ fontFamily: "'Inter', sans-serif", fontSize: 12, color: '#C62828', lineHeight: 1.5 }}>
                  Something went wrong. Please try again or{' '}
                  <a href="mailto:natanelkaliner@gmail.com" style={{ color: '#C62828', fontWeight: 700 }}>email me directly</a>.
                </span>
              ) : (
                <span style={{ fontFamily: "'Inter', sans-serif", fontSize: 12, color: '#AAA' }}>
                  {status === 'success' ? "I’ll get back to you soon!" : 'All fields are required'}
                </span>
              )}
            </div>
          </form>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 0, paddingTop: 4 }}>
            <p style={{ fontFamily: "'Inter', sans-serif", fontSize: 17, lineHeight: 1.7, color: '#555', margin: '0 0 48px 0', maxWidth: 380 }}>
              Open for freelance projects, full-time roles, and creative collaborations. Based in Tel Aviv — available worldwide.
            </p>
            <div style={{ display: 'flex', flexDirection: 'column', borderTop: '1px solid #E8E8E8' }}>
              {socials.map(s => <SocialLink key={s.label} {...s} />)}
            </div>
            <div style={{ marginTop: 32, padding: '18px 20px', background: '#F7F7F7', borderRadius: 10 }}>
              <a href="mailto:natanelkaliner@gmail.com"
                style={{ fontFamily: "'Inter', sans-serif", fontSize: 15, fontWeight: 600, color: '#0A0A0A', textDecoration: 'none', letterSpacing: '-0.01em', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                natanelkaliner@gmail.com <span style={{ fontSize: 14 }}>↗</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── Footer link ─────────────────────────────────────────────────── */
function FooterLink({ label, href }) {
  const [hover, setHover] = useState(false);
  return (
    <a href={href}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        padding: '14px 0', borderTop: '1px solid rgba(255,255,255,0.08)',
        textDecoration: 'none',
        color: hover ? '#fff' : 'rgba(255,255,255,0.62)',
        transition: 'color 220ms cubic-bezier(.22,1,.36,1)',
      }}>
      <span style={{
        fontFamily: "'Inter', sans-serif", fontSize: 16, fontWeight: 600,
        transform: hover ? 'translateX(6px)' : 'translateX(0)',
        transition: 'transform 340ms cubic-bezier(.22,1,.36,1)',
        display: 'inline-block',
      }}>{label}</span>
      {/* Arrow trajectory on footer links */}
      <div style={{ position: 'relative', width: 20, height: 20, overflow: 'hidden' }}>
        <span style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 14, transform: hover ? 'translate(11px, -11px)' : 'translate(0, 0)',
          opacity: hover ? 0 : 1,
          transition: 'transform 300ms cubic-bezier(.22,1,.36,1), opacity 240ms',
        }}>↗</span>
        <span style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 14, transform: hover ? 'translate(0, 0)' : 'translate(-11px, 11px)',
          opacity: hover ? 1 : 0,
          transition: 'transform 300ms cubic-bezier(.22,1,.36,1), opacity 240ms',
        }}>↗</span>
      </div>
    </a>
  );
}

function Footer() {
  const isMobile = useMobile(768);
  const go = (id) => document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });
  const socials = [
    { label: 'Email',    href: 'mailto:natanelkaliner@gmail.com' },
    { label: 'LinkedIn', href: 'https://www.linkedin.com/in/natanel-kaliner-ab6966395' },
  ];
  return (
    <footer style={{ background: '#0A0A0A', color: '#fff', borderTop: '1px solid rgba(255,255,255,0.06)' }}>
      <div style={{ maxWidth: 1320, margin: '0 auto', padding: isMobile ? '56px 20px 40px' : '72px 24px 56px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1.4fr 1fr', gap: isMobile ? 40 : 60, alignItems: 'end' }}>
        <div>
          <div style={{ fontFamily: "'Anton', sans-serif", fontWeight: 400, fontSize: 'clamp(52px, 8vw, 120px)', lineHeight: 0.88, letterSpacing: '-0.02em', textTransform: 'uppercase', color: '#fff' }}>
            NATANEL<br/>KALINER
          </div>
          <div style={{ marginTop: 20, fontFamily: "'Inter', sans-serif", fontSize: 15, color: 'rgba(255,255,255,0.45)', maxWidth: 380, lineHeight: 1.6 }}>
            Product / UX Designer based in Tel Aviv. Available for freelance, full-time, and collaborations worldwide.
          </div>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
          <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.3)', marginBottom: 16 }}>Connect</div>
          {socials.map(s => <FooterLink key={s.label} {...s} />)}
          <div style={{ borderTop: '1px solid rgba(255,255,255,0.08)' }} />
        </div>
      </div>
      <div style={{ maxWidth: 1320, margin: '0 auto', padding: isMobile ? '16px 20px' : '20px 24px', borderTop: '1px solid rgba(255,255,255,0.06)', display: 'flex', flexDirection: isMobile ? 'column' : 'row', alignItems: isMobile ? 'flex-start' : 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: isMobile ? 12 : 16 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <div style={{ width: 7, height: 7, borderRadius: 999, background: '#fff', opacity: 0.7, animation: 'pulse 2.4s ease-in-out infinite' }} />
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.5)' }}>Open for Work · 2026</span>
          </div>
          <span style={{ color: 'rgba(255,255,255,0.15)', fontSize: 12 }}>·</span>
          <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, fontWeight: 500, letterSpacing: '0.10em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.2)' }}>© {new Date().getFullYear()} Natanel Kaliner</span>
        </div>
        {!isMobile && (
          <div style={{ display: 'flex', gap: 28, alignItems: 'center' }}>
            {[['Work','works'],['About','about'],['Skills','skills'],['Contact','contact']].map(([l,id]) => (
              <a key={id} onClick={() => go(id)}
                style={{ fontFamily: "'Inter', sans-serif", fontSize: 12, fontWeight: 500, color: 'rgba(255,255,255,0.35)', cursor: 'pointer', transition: 'color 200ms', letterSpacing: '0.04em' }}
                onMouseEnter={e => e.target.style.color = 'rgba(255,255,255,0.8)'}
                onMouseLeave={e => e.target.style.color = 'rgba(255,255,255,0.35)'}>{l}</a>
            ))}
          </div>
        )}
        <a href="mailto:natanelkaliner@gmail.com"
          style={{ fontFamily: "'Inter', sans-serif", fontSize: 12, fontWeight: 500, color: 'rgba(255,255,255,0.4)', textDecoration: 'none', letterSpacing: '-0.01em', transition: 'color 200ms' }}
          onMouseEnter={e => e.target.style.color = '#fff'}
          onMouseLeave={e => e.target.style.color = 'rgba(255,255,255,0.4)'}>
          natanelkaliner@gmail.com
        </a>
      </div>
    </footer>
  );
}

/* ─── App ────────────────────────────────────────────────────────── */
function App() {
  const [activeProject, setActiveProject] = useState(null);
  return (
    <>
      <Nav />
      <Hero />
      <About />
      <Marquee />
      <Skills />
      <Works onOpenProject={setActiveProject} />
      <Contact />
      <Footer />
      <ProjectModal project={activeProject} onClose={() => setActiveProject(null)} />
      <BackToTop />
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
