// ============================================================
// Main App — Apple HIG inspired Engineering Director Portfolio
// ============================================================

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

// Apple-style scroll reveal — IntersectionObserver
const useScrollReveal = () => {
  useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    if (!els.length) return;
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('visible');
          observer.unobserve(entry.target);
        }
      });
    }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
    els.forEach(el => observer.observe(el));
    return () => observer.disconnect();
  }, []);
};

// Apple-style scroll gallery with bottom-right paddlenav
const ScrollGallery = ({ children, className = '' }) => {
  const scrollRef = useRef(null);
  const [canLeft, setCanLeft] = useState(false);
  const [canRight, setCanRight] = useState(true);

  const updateButtons = useCallback(() => {
    const el = scrollRef.current;
    if (!el) return;
    setCanLeft(el.scrollLeft > 4);
    setCanRight(el.scrollLeft < el.scrollWidth - el.clientWidth - 4);
  }, []);

  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    updateButtons();
    el.addEventListener('scroll', updateButtons, { passive: true });
    window.addEventListener('resize', updateButtons);
    return () => {
      el.removeEventListener('scroll', updateButtons);
      window.removeEventListener('resize', updateButtons);
    };
  }, [updateButtons]);

  const scroll = (dir) => {
    const el = scrollRef.current;
    if (!el) return;
    el.scrollBy({ left: dir * 392, behavior: 'smooth' });
  };

  return (
    <div className="scroll-gallery-wrap">
      <div ref={scrollRef} className={className}>
        {children}
      </div>
      <div className="paddlenav">
        <button className="paddlenav__btn" onClick={() => scroll(-1)} aria-label="Previous" disabled={!canLeft}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="m15 6-6 6 6 6"/></svg>
        </button>
        <button className="paddlenav__btn" onClick={() => scroll(1)} aria-label="Next" disabled={!canRight}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="m9 6 6 6-6 6"/></svg>
        </button>
      </div>
    </div>
  );
};

// Auto-scroll highlight gallery (Apple "Get the highlights" style)
const HighlightGallery = ({ items, t }) => {
  const [active, setActive] = useState(0);
  const [playing, setPlaying] = useState(true);
  const [progress, setProgress] = useState(0);
  const timerRef = useRef(null);
  const DURATION = 6150;

  const goTo = useCallback((idx) => {
    setActive(idx);
    setProgress(0);
  }, []);

  const next = useCallback(() => {
    setActive(a => {
      const n = (a + 1) % items.length;
      if (n === 0) { setPlaying(false); }
      return n;
    });
    setProgress(0);
  }, [items.length]);

  useEffect(() => {
    if (!playing) return;
    const start = Date.now();
    const tick = () => {
      const elapsed = Date.now() - start;
      setProgress(Math.min(elapsed / DURATION, 1));
      if (elapsed < DURATION) timerRef.current = requestAnimationFrame(tick);
      else next();
    };
    timerRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(timerRef.current);
  }, [active, playing, next]);

  const handleDotClick = (idx) => {
    setPlaying(true);
    goTo(idx);
  };

  const togglePlay = () => {
    if (!playing && active === items.length - 1) { goTo(0); setPlaying(true); }
    else setPlaying(p => !p);
  };

  // Gradient backgrounds per card
  const gradients = [
    "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)",
    "linear-gradient(135deg, #2d1b4e 0%, #1a1a2e 50%, #462b6e 100%)",
    "linear-gradient(135deg, #0a2647 0%, #144272 50%, #205295 100%)",
    "linear-gradient(135deg, #1b2838 0%, #2a4052 50%, #3d5a6e 100%)",
    "linear-gradient(135deg, #2c1810 0%, #45291e 50%, #5c3a2e 100%)",
  ];

  return (
    <div className="highlight-gallery">
      <div className="highlight-gallery__track">
        {items.map((a, i) => (
          <a
            key={i}
            href={a.url}
            target="_blank"
            rel="noreferrer"
            className="highlight-card"
            data-active={i === active}
            style={{ background: gradients[i % gradients.length] }}
          >
            <div className="highlight-card__overlay" />
            <div className="highlight-card__content">
              <div className="highlight-card__badge">{a.read}</div>
              <h3 className="highlight-card__title">{t(a.titleKey)}</h3>
              <p className="highlight-card__desc">{t(a.descKey)}</p>
              <div className="highlight-card__meta">{a.date}</div>
            </div>
          </a>
        ))}
      </div>
      <div className="highlight-gallery__controls">
        <button className="highlight-gallery__playpause" onClick={togglePlay} aria-label={playing ? "Pause" : "Play"}>
          {!playing && active === items.length - 1 ? (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M1 4v16l7-4V8z"/><path d="M10 4v16l7-4V8z"/><path d="M17 12h4"/><path d="M19 10v4"/></svg>
          ) : playing ? (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/></svg>
          ) : (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M6 4l14 8-14 8V4z"/></svg>
          )}
        </button>
        <div className="highlight-gallery__dots">
          {items.map((_, i) => (
            <button
              key={i}
              className="highlight-dot"
              data-active={i === active}
              onClick={() => handleDotClick(i)}
              aria-label={`Slide ${i + 1}`}
            >
              {i === active && <span className="highlight-dot__fill" style={{ width: `${progress * 100}%` }} />}
            </button>
          ))}
        </div>
      </div>
    </div>
  );
};

// Reveal wrapper component
const Reveal = ({ children, delay = 0, className = '' }) => {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        el.classList.add('visible');
        observer.unobserve(el);
      }
    }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
    observer.observe(el);
    return () => observer.disconnect();
  }, []);
  return (
    <div ref={ref} className={`reveal ${delay ? `reveal-delay-${delay}` : ''} ${className}`}>
      {children}
    </div>
  );
};

// Icon set — SF Symbols inspired inline SVGs
const Icon = ({ name, size = 18 }) => {
  const paths = {
    search: <path d="M11 19a8 8 0 1 1 5.3-14A8 8 0 0 1 11 19Zm10 2-4.3-4.3" strokeLinecap="round" strokeLinejoin="round"/>,
    command: <path d="M8 4a2 2 0 1 1-2 2v12a2 2 0 1 1 2-2h8a2 2 0 1 1 2 2V6a2 2 0 1 1-2 2H8z" strokeLinejoin="round"/>,
    sun: <g strokeLinecap="round"><circle cx="12" cy="12" r="4.5"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></g>,
    moon: <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z" strokeLinejoin="round"/>,
    arrowUpRight: <path d="M7 17 17 7M8 7h9v9" strokeLinecap="round" strokeLinejoin="round"/>,
    arrowRight: <path d="M5 12h14M13 5l7 7-7 7" strokeLinecap="round" strokeLinejoin="round"/>,
    close: <path d="M6 6l12 12M18 6 6 18" strokeLinecap="round"/>,
    github: <path d="M12 2a10 10 0 0 0-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.45-1.15-1.1-1.46-1.1-1.46-.9-.62.07-.6.07-.6 1 .07 1.52 1.03 1.52 1.03.89 1.52 2.34 1.08 2.91.83.1-.64.35-1.08.63-1.33-2.22-.25-4.55-1.11-4.55-4.94 0-1.09.39-1.98 1.03-2.68-.1-.25-.45-1.27.1-2.64 0 0 .84-.27 2.75 1.02a9.54 9.54 0 0 1 5 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.39.1 2.64.64.7 1.03 1.59 1.03 2.68 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.74c0 .27.18.58.69.48A10 10 0 0 0 12 2Z"/>,
    x: <path d="m3 3 7.5 10.2L3 21h2l6.5-7 5 7H22l-8-11 7.5-10H19l-6 6.5L8.5 3H3Z"/>,
    linkedin: <path d="M20.5 2h-17A1.5 1.5 0 0 0 2 3.5v17A1.5 1.5 0 0 0 3.5 22h17a1.5 1.5 0 0 0 1.5-1.5v-17A1.5 1.5 0 0 0 20.5 2ZM8 19H5V9h3v10Zm-1.5-11.2A1.7 1.7 0 1 1 8.2 6 1.7 1.7 0 0 1 6.5 7.8ZM19 19h-3v-5c0-1.6-.7-2.3-1.8-2.3-1 0-1.7.8-1.7 2.3V19h-3V9h3v1.3A3.5 3.5 0 0 1 15.7 9c2.2 0 3.3 1.4 3.3 4.2V19Z"/>,
    medium: <path d="M13.5 12a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0Zm7.1 0c0 3.5-.7 6.3-1.6 6.3-.9 0-1.6-2.8-1.6-6.3 0-3.5.7-6.3 1.6-6.3.9 0 1.6 2.8 1.6 6.3Zm3.4 0c0 3-.3 5.5-.6 5.5-.4 0-.6-2.5-.6-5.5s.2-5.5.6-5.5c.3 0 .6 2.5.6 5.5Z"/>,
    mail: <path d="M3 6.5A2.5 2.5 0 0 1 5.5 4h13A2.5 2.5 0 0 1 21 6.5v11a2.5 2.5 0 0 1-2.5 2.5h-13A2.5 2.5 0 0 1 3 17.5v-11Zm2.2-.5L12 11l6.8-5" strokeLinejoin="round"/>,
    star: <path d="m12 2 3 7 7 .6-5.3 4.7L18 22l-6-4-6 4 1.3-7.7L2 9.6 9 9l3-7Z" strokeLinejoin="round"/>,
    folder: <path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z" strokeLinejoin="round"/>,
    article: <path d="M5 4a2 2 0 0 1 2-2h7l5 5v13a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4Zm9-2v5h5M8 13h8M8 17h8M8 9h3" strokeLinejoin="round" strokeLinecap="round"/>,
    mic: <g strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3M8 21h8"/></g>,
    coffee: <path d="M4 8h13v7a5 5 0 0 1-5 5h-3a5 5 0 0 1-5-5V8Zm13 2h2a3 3 0 0 1 0 6h-2M7 2v3M11 2v3M15 2v3" strokeLinejoin="round" strokeLinecap="round"/>,
    home: <path d="m3 12 9-8 9 8v9a1 1 0 0 1-1 1h-5v-6h-6v6H4a1 1 0 0 1-1-1v-9Z" strokeLinejoin="round"/>,
    sparkle: <path d="M12 3v5M12 16v5M3 12h5M16 12h5M5.6 5.6l3.5 3.5M14.9 14.9l3.5 3.5M5.6 18.4l3.5-3.5M14.9 9.1l3.5-3.5"/>,
    chevronRight: <path d="m9 6 6 6-6 6" strokeLinecap="round" strokeLinejoin="round"/>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" aria-hidden>
      {paths[name]}
    </svg>
  );
};

// SF Symbol-style icons — clean Apple imagery for sections
const SFIcon = ({ name, size = 80 }) => {
  const icons = {
    leadership: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <circle cx="60" cy="36" r="14" stroke="currentColor" strokeWidth="3"/>
        <path d="M36 90c0-13.3 10.7-24 24-24s24 10.7 24 24" stroke="currentColor" strokeWidth="3" strokeLinecap="round"/>
        <circle cx="88" cy="44" r="10" stroke="currentColor" strokeWidth="2.5"/>
        <path d="M72 90c2-9 8.5-16 16-16" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
        <circle cx="32" cy="44" r="10" stroke="currentColor" strokeWidth="2.5"/>
        <path d="M48 90c-2-9-8.5-16-16-16" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
      </svg>
    ),
    java: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <path d="M44 26h32v12a16 16 0 0 1-16 16 16 16 0 0 1-16-16V26z" stroke="currentColor" strokeWidth="3"/>
        <path d="M76 34h6a8 8 0 0 1 0 16h-6" stroke="currentColor" strokeWidth="3"/>
        <path d="M50 20v6M60 20v6M70 20v6" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
        <path d="M38 68c0 0 8-4 22-4s22 4 22 4" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
        <path d="M42 78c0 0 6-3 18-3s18 3 18 3" stroke="currentColor" strokeWidth="2" strokeLinecap="round" opacity="0.6"/>
        <path d="M46 88c0 0 5-2 14-2s14 2 14 2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" opacity="0.4"/>
        <path d="M60 58v16" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeDasharray="4 4"/>
      </svg>
    ),
    architecture: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <rect x="28" y="28" width="64" height="64" rx="8" stroke="currentColor" strokeWidth="3"/>
        <rect x="42" y="42" width="36" height="36" rx="4" stroke="currentColor" strokeWidth="2.5"/>
        <rect x="54" y="54" width="12" height="12" rx="2" fill="currentColor" opacity="0.3"/>
        <path d="M28 60h14M78 60h14M60 28v14M60 78v14" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
      </svg>
    ),
    cloud: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <path d="M36 78a18 18 0 0 1 0-36c1-12 11-22 24-22s23 10 24 22a18 18 0 0 1 0 36H36z" stroke="currentColor" strokeWidth="3"/>
        <path d="M48 64l8 8 16-16" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    ),
    payments: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <rect x="22" y="36" width="76" height="48" rx="8" stroke="currentColor" strokeWidth="3"/>
        <path d="M22 52h76" stroke="currentColor" strokeWidth="3"/>
        <rect x="32" y="64" width="24" height="8" rx="3" fill="currentColor" opacity="0.25"/>
        <circle cx="82" cy="68" r="6" stroke="currentColor" strokeWidth="2"/>
      </svg>
    ),
    security: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <path d="M60 18L28 38v24c0 22 14 38 32 42 18-4 32-20 32-42V38L60 18z" stroke="currentColor" strokeWidth="3" strokeLinejoin="round"/>
        <path d="M48 62l8 8 16-16" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    ),
    repo: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <path d="M40 24v72" stroke="currentColor" strokeWidth="3" strokeLinecap="round"/>
        <circle cx="40" cy="36" r="6" fill="currentColor" opacity="0.3" stroke="currentColor" strokeWidth="2.5"/>
        <circle cx="40" cy="84" r="6" fill="currentColor" opacity="0.3" stroke="currentColor" strokeWidth="2.5"/>
        <circle cx="80" cy="52" r="6" fill="currentColor" opacity="0.3" stroke="currentColor" strokeWidth="2.5"/>
        <path d="M46 36h20c8 0 14 6 14 14v2" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
        <path d="M80 58v14c0 8-6 14-14 14H46" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
      </svg>
    ),
    education: (
      <svg width={size} height={size} viewBox="0 0 120 120" fill="none">
        <path d="M60 24L16 48l44 24 44-24L60 24z" stroke="currentColor" strokeWidth="3" strokeLinejoin="round"/>
        <path d="M32 58v26c0 0 12 14 28 14s28-14 28-14V58" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
        <path d="M104 48v32" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
        <circle cx="104" cy="84" r="4" fill="currentColor" opacity="0.3" stroke="currentColor" strokeWidth="2"/>
      </svg>
    ),
  };
  return icons[name] || null;
};

// ---------------- Company Logos (monochrome SVG paths) ----------------
const COMPANY_LOGOS = {
  Docker: {
    viewBox: "0 0 640 512",
    paths: ["M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"],
  },
  MongoDB: {
    viewBox: "0 0 24 24",
    paths: ["M17.193 9.555c-1.264-5.58-4.252-7.414-4.573-8.115-.28-.394-.53-.954-.735-1.44-.036.495-.055.685-.523 1.184-.723.566-4.438 3.682-4.74 10.02-.282 5.912 4.27 9.435 4.888 9.884l.07.05A73.49 73.49 0 0111.91 24h.481c.114-1.032.284-2.056.51-3.07.417-.296.604-.463.85-.693a11.342 11.342 0 003.639-8.464c.01-.814-.103-1.662-.197-2.218zm-5.336 8.195s0-8.291.275-8.29c.213 0 .49 10.695.49 10.695-.381-.045-.765-1.76-.765-2.405z"],
  },
  Facebook: {
    viewBox: "0 0 512 512",
    paths: ["M512 256C512 114.6 397.4 0 256 0S0 114.6 0 256c0 120 82.7 220.8 194.2 248.5V334.2h-56.6v-78.2h56.6v-61.3c0-56 33.3-86.9 84.4-86.9 24.4 0 50 4.4 50 4.4v55h-28.2c-27.8 0-36.4 17.2-36.4 34.9v42h61.9l-9.9 78.2h-52v170.3C429.3 476.8 512 376 512 256z"],
  },
  Google: {
    viewBox: "0 0 488 512",
    paths: ["M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"],
  },
  Apple: {
    viewBox: "0 0 384 512",
    paths: ["M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184 4 273.5c0 26.2 4.8 53.3 14.4 81.2 12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-62.1 24-72.5-24 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"],
  },
  GitHub: {
    viewBox: "0 0 496 512",
    paths: ["M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"],
  },
  Dropbox: {
    viewBox: "0 0 528 512",
    paths: ["M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-84.3L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"],
  },
  Zendesk: {
    viewBox: "0 0 448 512",
    paths: ["M0 217.3v246.4L224 281.5V35.1L0 217.3zm448-182.2L224 217.3 448 463.7V35.1zM0 463.7h224V281.5H0v182.2zm224-428.6v182.2h224V35.1H224z"],
  },
  Mozilla: {
    src: "https://www.mozilla.org/media/img/trademarks/mozilla-logo-tm.37d6edeabfd7.svg",
  },
  Intel: {
    viewBox: "0 0 24 24",
    paths: ["M20.42 7.345v9.18h1.651v-9.18zM0 7.475v1.737h1.737V7.474zm9.78.352v6.053c0 .513.044.945.13 1.292.087.34.235.618.44.828.203.21.475.359.803.451.334.093.754.136 1.255.136h.216v-1.533c-.24 0-.445-.012-.593-.037a.672.672 0 0 1-.39-.173.693.693 0 0 1-.173-.377 4.002 4.002 0 0 1-.037-.606v-2.182h1.193v-1.416h-1.193V7.827zm-3.505 2.312c-.396 0-.76.08-1.082.241-.327.161-.6.384-.822.668l-.087.117v-.902H2.658v6.256h1.639v-3.214c.018-.588.16-1.02.433-1.299.29-.297.642-.445 1.044-.445.476 0 .841.149 1.082.433.235.284.359.686.359 1.2v3.324h1.663V12.97c.006-.89-.229-1.595-.686-2.09-.458-.495-1.1-.742-1.917-.742zm10.065.006a3.252 3.252 0 0 0-2.306.946c-.29.29-.525.637-.692 1.033a3.145 3.145 0 0 0-.254 1.273c0 .452.08.878.241 1.274.161.395.39.742.674 1.032.284.29.637.526 1.045.693.408.173.86.26 1.342.26 1.397 0 2.262-.637 2.782-1.23l-1.187-.904c-.248.297-.841.699-1.583.699-.464 0-.847-.105-1.138-.321a1.588 1.588 0 0 1-.593-.872l-.019-.056h4.915v-.587c0-.451-.08-.872-.235-1.267a3.393 3.393 0 0 0-.661-1.033 3.013 3.013 0 0 0-1.02-.692 3.345 3.345 0 0 0-1.311-.248zm-16.297.118v6.256h1.651v-6.256zm16.278 1.286c1.132 0 1.664.797 1.664 1.255l-3.32.006c0-.458.525-1.255 1.656-1.261zm7.073 3.814a.606.606 0 0 0-.606.606.606.606 0 0 0 .606.606.606.606 0 0 0 .606-.606.606.606 0 0 0-.606-.606zm-.008.105a.5.5 0 0 1 .002 0 .5.5 0 0 1 .5.501.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .498-.5zm-.233.155v.699h.13v-.285h.093l.173.285h.136l-.18-.297a.191.191 0 0 0 .118-.056c.03-.03.05-.074.05-.136 0-.068-.02-.117-.063-.154-.037-.038-.105-.056-.185-.056zm.13.099h.154c.019 0 .037.006.056.012a.064.064 0 0 1 .037.031c.013.013.012.031.012.056a.124.124 0 0 1-.012.055.164.164 0 0 1-.037.031c-.019.006-.037.013-.056.013h-.154Z"],
  },
  Looker: {
    viewBox: "0 0 24 24",
    paths: ["M11.9475 0c-1.1598.0021-2.0982.944-2.096 2.1038a2.1 2.1 0 00.356 1.166l.895-.8959a.884.884 0 11.565.564l-.895.895c.9593.6478 2.2621.3953 2.91-.564.6478-.9593.3953-2.262-.564-2.91A2.096 2.096 0 0011.9475 0zm-.835 6.1128a3.2629 3.2629 0 00-.653-1.965l-1.164 1.162a1.667 1.667 0 01-.318 2.012l.632 1.5449a3.2819 3.2819 0 001.503-2.754zm-3.2499 1.666h-.03c-.9217.0009-1.6697-.7455-1.6707-1.6673-.001-.9217.7454-1.6697 1.6672-1.6707a1.669 1.669 0 01.9195.275l1.152-1.152c-1.4069-1.141-3.4724-.9257-4.6135.4811s-.9257 3.4723.481 4.6135a3.2799 3.2799 0 002.7275.6652l-.633-1.5439v-.001zm4.1279 1.3359c-.728 0-1.452.106-2.15.315l.922 2.2519c2.6872-.6819 5.4184.9438 6.1002 3.631.6818 2.6873-.9439 5.4184-3.6311 6.1002s-5.4184-.9439-6.1002-3.631c-.5682-2.2394.4655-4.5774 2.5041-5.6643l-.91-2.2449c-3.6908 1.808-5.2173 6.2657-3.4093 9.9567l.0005.001c1.808 3.6909 6.2657 5.2173 9.9567 3.4093l.001-.0005c3.6913-1.8071 5.2187-6.2645 3.4116-9.9558a7.4417 7.4417 0 00-6.6865-4.1696h-.008l-.001.001z"],
  },
  Elastic: {
    viewBox: "0 0 24 24",
    paths: ["M20.345 16.33l-3.959-.926-1.05-2.01 5.177-4.535a3.962 3.962 0 012.559 3.702 4.006 4.006 0 01-2.727 3.77m-2.976 4.68c-.616 0-1.22-.207-1.714-.587l.782-4.077 3.596.841c.115.31.172.642.172.987a2.839 2.839 0 01-2.836 2.836m-2.637-.586a5.92 5.92 0 01-4.908 2.6A5.947 5.947 0 014 15.905l5.167-4.67 5.272 2.403 1.167 2.23zM.928 11.443a4.007 4.007 0 012.726-3.77l3.95.933.927 1.98-5.05 4.565a3.97 3.97 0 01-2.553-3.708m5.703-8.45a2.841 2.841 0 011.723.58l-.789 4.092-3.598-.85a2.842 2.842 0 01-.172-.986A2.84 2.84 0 016.63 2.992m2.66.59A5.92 5.92 0 0120.1 6.93c0 .4-.038.781-.114 1.164l-5.299 4.643-5.251-2.394-1.026-2.19zM24 12.571a4.723 4.723 0 00-3.124-4.454 6.695 6.695 0 00.126-1.29A6.789 6.789 0 0014.22.047 6.769 6.769 0 008.727 2.86a3.586 3.586 0 00-2.204-.754A3.604 3.604 0 003.15 6.959 4.786 4.786 0 000 11.431 4.727 4.727 0 003.139 15.9a6.876 6.876 0 00-.124 1.289 6.773 6.773 0 006.765 6.765c2.19 0 4.22-1.052 5.49-2.824a3.568 3.568 0 002.207.769 3.603 3.603 0 003.374-4.854A4.785 4.785 0 0024 12.572"],
  },
  Amazon: {
    viewBox: "0 0 24 24",
    paths: ["M.045 18.02c.072-.116.187-.124.348-.022 3.636 2.11 7.594 3.166 11.87 3.166 2.852 0 5.668-.533 8.447-1.595l.315-.14c.138-.06.234-.1.293-.13.226-.088.39-.046.525.13.12.174.09.336-.12.48-.256.19-.6.41-1.006.654-1.244.743-2.64 1.316-4.185 1.726a17.617 17.617 0 01-10.951-.577 17.88 17.88 0 01-5.43-3.35c-.1-.074-.151-.15-.151-.22 0-.047.021-.09.051-.13zm6.565-6.218c0-1.005.247-1.863.743-2.577.495-.71 1.17-1.25 2.04-1.615.796-.335 1.756-.575 2.912-.72.39-.046 1.033-.103 1.92-.174v-.37c0-.93-.105-1.558-.3-1.875-.302-.43-.78-.65-1.44-.65h-.182c-.48.046-.896.196-1.246.46-.35.27-.575.63-.675 1.096-.06.3-.206.465-.435.51l-2.52-.315c-.248-.06-.372-.18-.372-.39 0-.046.007-.09.022-.15.247-1.29.855-2.25 1.82-2.88.976-.616 2.1-.975 3.39-1.05h.54c1.65 0 2.957.434 3.888 1.29.135.15.27.3.405.48.12.165.224.314.283.45.075.134.15.33.195.57.06.254.105.42.135.51.03.104.062.3.076.615.01.313.02.493.02.553v5.28c0 .376.06.72.165 1.036.105.313.21.54.315.674l.51.674c.09.136.136.256.136.36 0 .12-.06.226-.18.314-1.2 1.05-1.86 1.62-1.963 1.71-.165.135-.375.15-.63.045a6.062 6.062 0 01-.526-.496l-.31-.347a9.391 9.391 0 01-.317-.42l-.3-.435c-.81.886-1.603 1.44-2.4 1.665-.494.15-1.093.227-1.83.227-1.11 0-2.04-.343-2.76-1.034-.72-.69-1.08-1.665-1.08-2.94l-.05-.076zm3.753-.438c0 .566.14 1.02.425 1.364.285.34.675.512 1.155.512.045 0 .106-.007.195-.02.09-.016.134-.023.166-.023.614-.16 1.08-.553 1.424-1.178.165-.28.285-.58.36-.91.09-.32.12-.59.135-.8.015-.195.015-.54.015-1.005v-.54c-.84 0-1.484.06-1.92.18-1.275.36-1.92 1.17-1.92 2.43l-.035-.02zm9.162 7.027c.03-.06.075-.11.132-.17.362-.243.714-.41 1.05-.5a8.094 8.094 0 011.612-.24c.14-.012.28 0 .41.03.65.06 1.05.168 1.172.33.063.09.099.228.099.39v.15c0 .51-.149 1.11-.424 1.8-.278.69-.664 1.248-1.156 1.68-.073.06-.14.09-.197.09-.03 0-.06 0-.09-.012-.09-.044-.107-.12-.064-.24.54-1.26.806-2.143.806-2.64 0-.15-.03-.27-.087-.344-.145-.166-.55-.257-1.224-.257-.243 0-.533.016-.87.046-.363.045-.7.09-1 .135-.09 0-.148-.014-.18-.044-.03-.03-.036-.047-.02-.077 0-.017.006-.03.02-.063v-.06z"],
  },
  Oracle: {
    viewBox: "0 0 512 512",
    paths: ["M372.5 169.4h-233c-51.7 0-93.6 41.9-93.6 93.6s41.9 93.6 93.6 93.6h233c51.7 0 93.6-41.9 93.6-93.6s-41.9-93.6-93.6-93.6zm0 146.3h-233c-29.1 0-52.7-23.6-52.7-52.7s23.6-52.7 52.7-52.7h233c29.1 0 52.7 23.6 52.7 52.7s-23.6 52.7-52.7 52.7z"],
  },
};

const getCompanyLogo = (name) => {
  const baseName = name.replace(/ Brasil$/, "");
  return COMPANY_LOGOS[baseName] || null;
};

const CompanyLogo = ({ name }) => {
  const logo = getCompanyLogo(name);
  const displayName = name.replace(/ Brasil$/, "");
  if (!logo) return <span className="community-logo__name">{displayName}</span>;
  return (
    <React.Fragment>
      {logo.src ? (
        <img className="community-logo__img" src={logo.src} alt="" aria-hidden="true" />
      ) : (
        <svg className="community-logo__icon" viewBox={logo.viewBox} fill="currentColor" aria-hidden="true">
          {logo.paths.map((d, i) => <path key={i} d={d} />)}
        </svg>
      )}
      <span className="community-logo__name">{displayName}</span>
    </React.Fragment>
  );
};

// ---------------- i18n hook ----------------
const useI18n = () => {
  const [lang, setLang] = useState(() => window.I18N.detect());

  const t = useCallback((key) => {
    const dict = window.I18N.translations[lang] || window.I18N.translations.en;
    return dict[key] || window.I18N.translations.en[key] || key;
  }, [lang]);

  const changeLang = useCallback((newLang) => {
    setLang(newLang);
    localStorage.setItem("lang", newLang);
    document.documentElement.setAttribute("lang", newLang);
  }, []);

  useEffect(() => {
    document.documentElement.setAttribute("lang", lang);
  }, [lang]);

  return { lang, t, changeLang };
};

// Language picker labels
const LANG_LABELS = { en: "EN", pt: "PT", es: "ES", fr: "FR", it: "IT" };

// ---------------- Nav ----------------
const Nav = ({ onOpenSpotlight, theme, onToggleTheme, t, lang, onChangeLang }) => {
  const [langOpen, setLangOpen] = useState(false);
  const [activeSection, setActiveSection] = useState("work");
  const langRef = useRef(null);

  // Track which section is in view
  useEffect(() => {
    const ids = ["work", "skills", "writing", "oss", "speaking", "education", "community", "coffee", "contact"];
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) setActiveSection(entry.target.id);
      });
    }, { rootMargin: "-40% 0px -55% 0px" });
    ids.forEach(id => {
      const el = document.getElementById(id);
      if (el) observer.observe(el);
    });
    return () => observer.disconnect();
  }, []);

  const sections = [
    ["work", t("nav.work")],
    ["skills", t("nav.skills")],
    ["writing", t("nav.writing")],
    ["oss", t("nav.oss")],
    ["speaking", t("nav.speaking")],
    ["education", t("nav.education")],
    ["community", t("nav.community")],
    ["coffee", t("nav.coffee")],
    ["contact", t("nav.contact")],
  ];

  // Close dropdown on outside click
  useEffect(() => {
    if (!langOpen) return;
    const handler = (e) => {
      if (langRef.current && !langRef.current.contains(e.target)) setLangOpen(false);
    };
    document.addEventListener("click", handler);
    return () => document.removeEventListener("click", handler);
  }, [langOpen]);

  return (
    <nav className="nav" aria-label="Primary">
      <div className="nav__inner">
        <a href="#top" className="nav__logo" aria-label="Romulo Scampini — home">
          <span className="nav__logo-mark"><AppleMark /></span>
          <div className="nav__hello">
            {SF_HELLO.map((h, i) => (
              <svg key={i} className="nav__hello-svg" viewBox={h.viewBox} aria-label={h.lang}>
                <g transform={`scale(1, -1) translate(0, ${h.flipY})`}>
                  {h.paths.map((d, j) => <path key={j} d={d} />)}
                </g>
              </svg>
            ))}
          </div>
        </a>
        <div className="nav__links">
          {sections.map(([id, label]) => (
            <a key={id} href={`#${id}`} className={`nav__link${activeSection === id ? " nav__link--active" : ""}`}>{label}</a>
          ))}
        </div>
        <div className="nav__actions">
          <div className="lang-picker" ref={langRef}>
            <button className="nav-btn" onClick={() => setLangOpen(o => !o)} aria-label="Change language">
              {LANG_LABELS[lang]}
            </button>
            {langOpen && (
              <div className="lang-picker__dropdown">
                {window.I18N.supported.map(l => (
                  <button
                    key={l}
                    className="lang-picker__item"
                    data-active={l === lang}
                    onClick={() => { onChangeLang(l); setLangOpen(false); }}
                  >{LANG_LABELS[l]}</button>
                ))}
              </div>
            )}
          </div>
          <button className="nav-btn" onClick={onOpenSpotlight} aria-label="Open search">
            <Icon name="search" size={14}/>
            <span className="nav-btn__kbd">⌘K</span>
          </button>
          <button className="nav-btn" onClick={onToggleTheme} aria-label="Toggle appearance">
            <Icon name={theme === "dark" ? "sun" : "moon"} size={14}/>
          </button>
        </div>
      </div>
    </nav>
  );
};

const AppleMark = () => (
  <svg width="18" height="22" viewBox="0 0 24 28" fill="currentColor" aria-hidden>
    <path d="M19.6 14.4a5.8 5.8 0 0 1 2.8-4.9 6 6 0 0 0-4.7-2.5c-2-.2-3.9 1.2-4.9 1.2-1 0-2.6-1.1-4.3-1.1a6.3 6.3 0 0 0-5.3 3.2c-2.3 3.9-.6 9.7 1.6 12.8 1.1 1.6 2.4 3.3 4.1 3.2 1.6-.1 2.3-1 4.3-1 2 0 2.6 1 4.4 1 1.8 0 2.9-1.6 4-3.2a14 14 0 0 0 1.8-3.7 5.6 5.6 0 0 1-3.8-5ZM16.3 4.8a5.5 5.5 0 0 0 1.4-4 5.7 5.7 0 0 0-3.6 1.9 5.2 5.2 0 0 0-1.4 3.9 4.8 4.8 0 0 0 3.6-1.8Z"/>
  </svg>
);

// Apple SF Hello — official SVG path data per language (from github.com/hirajanwin/SF-Hello)
const SF_HELLO = [
  { lang: "en", viewBox: "-109 -9 2504 746", flipY: -728, paths: ["M-109.06,95.93 C1.95,157.64 103.11,237 217.88,372.08 C296,464.28 338,569.57 340,642.19 C341,696.19 314.67,737.16 266,737.16 C212,737.16 178,696.19 157,602.16 C134,498.82 117,380.24 74,0","M78.21,37.16 C100.23,230.68 184,372 291,372 C355,372 395.67,321 384.13,248 C377.62,205 370.09,161 361.31,110 C351.07,46 380.33,-4 468.96,-4 C598.22,-4 739.24,67.83 811.41,179.09 C836,217 846,251 847,284 C848,344 814,389 754,389 C678,389 620,303 620,193 C620,75 684,-8 819.92,-8 C1004.72,-8 1209.42,213.85 1303.48,461.42 C1330.04,531.33 1340,596.23 1340,641.59 C1340,695.38 1323,736.67 1275,736.67 C1228,736.67 1197,700.18 1169,642.55 C1136.19,575.72 1111.93,479.33 1102,370.36 C1077,96.94 1133,-4 1266.15,-4 C1427.61,-4 1607.12,220.93 1698.77,462.19 C1725.04,531.33 1735,596.23 1735,641.59 C1735,695.38 1718,736.67 1670,736.67 C1623,736.67 1592,700.18 1564,642.55 C1531.19,575.72 1506.93,479.33 1497,370.36 C1472,96.94 1528,-4 1646.91,-4 C1765.62,-4 1830.11,99.48 1868.78,209.37 C1907,318 1954,385 2052,385 C2133,385 2197,325 2197,212 C2197,87 2115.9,-7 2013.42,-8 C1923.23,-9 1864,64 1870,174 C1877,296 1951,385 2048,385 C2104,385 2151.04,360.11 2188,333 C2288.21,259.89 2365.43,305.07 2395,377.36"] },
  { lang: "pt", viewBox: "64 -9 1489 746", flipY: -728, paths: ["M266,387 C165.97,378.91 91.14,294.13 77,178 C64,72 123,-8 217,-8 C331,-8 405,90 410,212 C414,329 358,388 282,388 C222,388 190,343 192,288 C193.95,212.8 250.35,128.36 368.67,117.58 C532.8,102.61 757.26,223.95 847.9,462.52 C874.04,531.33 884,596.23 884,641.59 C884,695.38 867,736.67 819,736.67 C772,736.67 741,700.18 713,642.55 C680.19,575.72 655.93,479.33 646,370.36 C621,96.94 677,-4 796.8,-4 C918.22,-4 998.5,101.24 1033.22,222.96","M1348.6,312.43 C1329,357.54 1287.33,388 1221,388 C1111,388 1028.32,278 1022.9,160 C1018.17,52 1068,-8.71 1138.98,-8 C1239.74,-6.99 1313.79,91.97 1346.85,301.36 C1350.93,327.19 1355.16,354.17 1359.24,380","M1359.24,380 C1355.11,353.8 1350.98,327.59 1346.85,301.39 C1328.79,186.77 1320.46,141.56 1321.35,112 C1323.44,43 1348.25,-4 1410.25,-4 C1488.25,-4 1532,49 1553,107","M1378,690 C1332,638 1285,590 1235,544"] },
  { lang: "es", viewBox: "-87 -9 2197 746", flipY: -728, paths: ["M-87.41,84.5 C23.39,149.73 119.25,231.56 226.21,376.37 C301.28,478 338,569.38 340,642.19 C341,696.19 315,737.16 266,737.16 C212,737.16 178,696.19 157,602.16 C134,498.82 117,380.24 74,0","M78.21,37.16 C99.43,223.65 184,372 291,372 C355,372 395.67,321 384.13,248 C377.62,205 365.88,155 359.17,106 C351,44 374.33,-4 446.44,-4 C548.22,-4 612.3,94.83 640.03,211.85","M823,387 C722.97,378.91 648.14,294.13 634,178 C621,72 680,-8 774,-8 C888,-8 962,90 967,212 C971,329 915,388 839,388 C779,388 747,343 749,288 C750.95,212.8 807.35,128.36 925.67,117.58 C1089.8,102.61 1314.26,223.95 1404.9,462.52 C1431.04,531.33 1441,596.23 1441,641.59 C1441,695.38 1424,736.67 1376,736.67 C1329,736.67 1298,700.18 1270,642.55 C1237.19,575.72 1212.93,479.33 1203,370.36 C1178,96.94 1234,-4 1353.8,-4 C1475.22,-4 1555.5,101.24 1590.22,222.96","M1905.6,312.43 C1886,357.54 1844.33,388 1778,388 C1668,388 1585.32,278 1579.9,160 C1575.17,52 1625,-8.71 1696,-8 C1796.74,-6.99 1870.79,91.97 1903.85,301.36 C1907.93,327.19 1912.16,354.17 1916.24,380","M1916.24,380 C1912.11,353.8 1907.98,327.59 1903.85,301.39 C1885.79,186.77 1877.46,141.56 1878.35,112 C1880.44,43 1905.25,-4 1967.25,-4 C2045.25,-4 2089,49 2110,107"] },
  { lang: "fr", viewBox: "-92 -314 3754 1064", flipY: -436, paths: ["M-92.45,74.66 C71.47,131.75 183,246.97 298.66,489.4 C328.46,551.86 338.95,609.32 341.98,653.37 C345,709.44 322,749.62 277,749.62 C232,749.62 202,717.28 169,648.68 C130,566.36 107,468.36 95,370.36 C64,96.94 129,-4 238,-4 C328,-4 385,77 392,184 C396,274 358,344 290,377","M349.56,329.85 C450.06,205.14 613.73,294.55 689.69,351.09 C722.97,375.87 752.32,385 788,385 C867,385 929,325 929,212 C929,87 850,-7 750,-8 C662,-9 604,64 610,174 C617,296 689,385 784,385 C838,385 876,366 920,333 C1043.57,240.58 1167.88,285.29 1198,380","M1198,380 C1179,253 1163,128 1143,1","M1156.63,90.95 C1184.16,278.88 1268,388 1368,388 C1438,388 1474,340 1468,272 C1463,221 1446,162 1442,112 C1437,43 1469,-4 1538.5,-4 C1642.87,-4 1747,127.55 1777.24,290.31 C1782.61,319.17 1790.42,350.6 1794,381","M1794,381 C1775.33,222.67 1756.67,64.33 1738,-94 C1719.48,-251.06 1673,-314 1603,-314 C1556,-314 1522,-284.07 1522,-236 C1522,-171.77 1570.74,-125.66 1679.19,-92.18 C1866.23,-34.42 2002.83,75.93 2047.71,203.48 C2088,318 2135,385 2233,385 C2314,385 2378,325 2378,212 C2378,87 2296.9,-7 2194.42,-8 C2104.23,-9 2045,64 2051,174 C2058,296 2132,385 2229,385 C2285,385 2324,366 2369,333 C2506.08,233 2619.95,280.4 2660.4,379.28","M2660.4,379.28 C2643.12,306.22 2631.53,247 2625.38,203 C2620.27,171 2617.07,149 2615.82,122 C2614.17,51 2654,0 2731,0 C2843,0 2898.65,99.65 2932.39,263.09 C2940.46,302.18 2949.26,339.48 2956.37,378.76","M2956.37,378.76 C2931.37,240.76 2911,158 2911,112 C2911,43 2938,-4 3011.62,-4 C3130.49,-4 3231.97,164.47 3283,393","M3275.1,359.04 C3399.1,353.04 3454,328 3454,269 C3454,228 3434,165 3428,119 C3417,39 3446.51,-5 3510,-5 C3587.2,-5 3640.63,46.29 3661.47,98.4"] },
  { lang: "it", viewBox: "71 -9 1949 598", flipY: -580, paths: ["M374.8,325 C355.04,363 313.44,391 250,391 C129.89,391 70.84,287 70.84,185 C70.84,74 143.64,-8 267.18,-8 C427.03,-8 570.05,112.73 602.85,289.25 C608.41,319.17 615.84,349.74 620.95,380","M620.95,380 C609.46,312 598.88,256 592.25,206 C588.5,173 586.7,145 586.91,117 C587.45,45 615.8,-4 685.12,-4 C782.34,-4 877.16,104.26 911.02,222.96","M1226.4,312.43 C1206.8,357.54 1165.13,388 1098.79,388 C988.79,388 906.12,278 900.7,160 C895.97,52 945.8,-8.71 1016.78,-8 C1117.54,-6.99 1191.59,91.97 1224.65,301.36 C1228.73,327.19 1232.96,354.17 1237.04,380","M1237.04,380 C1232.91,353.8 1228.78,327.59 1224.65,301.39 C1206.59,186.77 1198.26,141.56 1199.15,112 C1201.24,43 1226.05,-4 1291.66,-4 C1382.33,-4 1456.49,103.97 1493.97,210.49 C1531.8,318 1578.8,385 1676.8,385 C1757.8,385 1821.8,325 1821.8,212 C1821.8,87 1740.7,-7 1638.22,-8 C1548.03,-9 1488.8,64 1494.8,174 C1501.8,296 1575.8,385 1672.8,385 C1728.8,385 1775.84,360.11 1812.8,333 C1913.01,259.89 1990.23,305.07 2019.8,377.36"] },
];

// ---------------- Hero ----------------
const Hero = ({ t }) => (
  <header className="hero" id="top">

    <Reveal delay={1}>
      <span className="hero__pre">
        {t("hero.badge")}
      </span>
    </Reveal>

    <Reveal delay={2}>
      <h1 className="hero__title">
      {t("hero.title.pre")}<br/><span className="grad">{t("hero.title.grad")}</span>
        <span dangerouslySetInnerHTML={{ __html: t("hero.title.mid") }} />
        <span>{t("hero.title.end")}</span><span className="inline-emoji">👨🏻‍💻</span>
      </h1>
    </Reveal>

    <Reveal delay={3}>
      <p className="hero__sub">
        {t("hero.sub.intro")}<strong style={{ color: "var(--label-primary)" }}>{t("hero.sub.name")}</strong>{t("hero.sub.rest")}
      </p>
    </Reveal>

    <Reveal delay={4}>
      <div className="hero__ctas">
        <a href="#work" className="btn btn--primary btn--lg">
          {t("hero.cta.work")} <span className="chev"><Icon name="arrowRight" size={16}/></span>
        </a>
        <a href="#contact" className="btn btn--secondary btn--lg">{t("hero.cta.contact")}</a>
      </div>
    </Reveal>

    <Reveal delay={4}>
      <div className="hero__stats">
        <div className="hero__stat">
          <div className="hero__stat-num">18+</div>
          <div className="hero__stat-label">{t("hero.stat.years")}</div>
        </div>
        <div className="hero__stat">
          <div className="hero__stat-num">100+</div>
          <div className="hero__stat-label">{t("hero.stat.engineers")}</div>
        </div>
        <div className="hero__stat">
          <div className="hero__stat-num">99.99%</div>
          <div className="hero__stat-label">{t("hero.stat.availability")}</div>
        </div>
        <div className="hero__stat">
          <div className="hero__stat-num">∞</div>
          <div className="hero__stat-label">{t("hero.stat.coffee")}</div>
        </div>
      </div>
    </Reveal>
  </header>
);

// ---------------- Projects feed — Apple carousel ----------------
const ProjectCard = ({ project, onOpen, t }) => (
  <article
    className="project-card"
    onClick={() => onOpen(project)}
    role="button" tabIndex="0"
    onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && (e.preventDefault(), onOpen(project))}
    aria-label={`Open project: ${t(project.titleKey)}`}
  >
    <div className="project-card__visual">
      <ProjectVisual kind={project.visual} accent={project.accent} />
    </div>
    <div className="project-card__body">
      <span className="project-card__eyebrow">{project.company} · {project.year}</span>
      <h3 className="project-card__title">{t(project.titleKey)}</h3>
      <p className="project-card__desc">{t(project.descKey)}</p>
    </div>
  </article>
);

const Projects = ({ onOpen, t }) => (
  <section className="projects" id="work">
    <div className="projects__inner">
      <Reveal>
        <div className="section__head">
          <div>
            <div className="eyebrow">{t("projects.eyebrow")}</div>
            <h2 className="section__title" dangerouslySetInnerHTML={{ __html: t("projects.title") }} />
          </div>
          <p className="section__subtitle">{t("projects.subtitle")}</p>
        </div>
      </Reveal>

      <Reveal delay={1}>
        <ScrollGallery className="projects__carousel">
          {window.SITE_DATA.projects.map(p => (
            <ProjectCard key={p.id} project={p} onOpen={onOpen} t={t} />
          ))}
        </ScrollGallery>
      </Reveal>
    </div>
  </section>
);

// ---------------- Currently — "And so much more" style ----------------
const Currently = ({ t }) => (
  <section className="sec-more" id="currently">
    <div className="sec-more__inner">
      <Reveal>
        <div className="sec-more__header">
          <div className="eyebrow">{t("currently.eyebrow")}</div>
          <h2 className="sec-more__title">{t("currently.title")}</h2>
          <p className="sec-more__sub">{t("currently.sub")}</p>
        </div>
      </Reveal>
      <div className="more-grid">
        {window.SITE_DATA.currently.map((w, i) => (
          <Reveal key={i} delay={Math.min(i + 1, 4)}>
            <div className="more-item">
              <span className="more-item__emoji">{w.icon}</span>
              <h3 className="more-item__title">{t(w.titleKey)}</h3>
              <p className="more-item__text">{t(w.textKey)}</p>
              <p className="more-item__meta">{t(w.metaKey)}</p>
            </div>
          </Reveal>
        ))}
      </div>
    </div>
  </section>
);

// ---------------- Skills — Apple Intelligence carousel ----------------
const Skills = ({ t }) => (
  <section className="sec-intelligence" id="skills">
    <div className="sec-intelligence__inner">
      <Reveal>
        <div className="sec-intelligence__header">
          <div className="sec-intelligence__eyebrow">{t("skills.eyebrow")}</div>
          <h2 className="sec-intelligence__title" dangerouslySetInnerHTML={{ __html: t("skills.title") }} />
          <p className="sec-intelligence__sub">{t("skills.sub")}</p>
        </div>
      </Reveal>

      <Reveal delay={1}>
        <ScrollGallery className="intelligence-gallery">
          {window.SITE_DATA.skills.map((s, i) => {
            const chips = t(s.chipsKey).split(", ");
            return (
              <div className="intelligence-card" key={i}>
                <div className="intelligence-card__img">
                  <SFIcon name={s.sfIcon} size={80} />
                </div>
                <div className="intelligence-card__body">
                  <h3 className="intelligence-card__title">{t(s.titleKey)}</h3>
                  <p className="intelligence-card__desc">{t(s.descKey)}</p>
                  <div className="intelligence-card__chips">
                    {chips.map(c => <span key={c} className="chip">{c}</span>)}
                  </div>
                </div>
              </div>
            );
          })}
        </ScrollGallery>
      </Reveal>
    </div>
  </section>
);

// ---------------- Writing — Apple "Get the highlights" auto-scroll ----------------
const Writing = ({ t }) => (
  <section className="sec-highlights" id="writing">
    <div className="sec-highlights__inner">
      <Reveal>
        <div className="sec-highlights__header">
          <div className="eyebrow sec-highlights__eyebrow">{t("writing.eyebrow")}</div>
          <h2 className="sec-highlights__title">{t("writing.title")}</h2>
          <a href="https://medium.com/@romuloscampini" target="_blank" rel="noreferrer" className="sec-highlights__link">
            {t("writing.link")} <Icon name="arrowUpRight" size={14}/>
          </a>
        </div>
      </Reveal>
      <Reveal delay={1}>
        <HighlightGallery items={window.SITE_DATA.articles} t={t} />
      </Reveal>
    </div>
  </section>
);

// ---------------- OSS — Apple Continuity style ----------------
const OSS = ({ t }) => (
  <section className="sec-continuity" id="oss">
    <div className="sec-continuity__inner">
      <Reveal>
        <div className="sec-continuity__header">
          <div className="eyebrow">{t("oss.eyebrow")}</div>
          <h2 className="sec-continuity__title" dangerouslySetInnerHTML={{ __html: t("oss.title") }} />
          <p className="sec-continuity__sub">{t("oss.sub")}</p>
        </div>
      </Reveal>
      <Reveal delay={1}>
        <ScrollGallery className="continuity-scroll">
          {window.SITE_DATA.repos.map((r, i) => (
            <a key={i} className="continuity-card" href={`https://github.com/romuloscampini/${r.name}`} target="_blank" rel="noreferrer">
              <div className="continuity-card__img">
                <span className="continuity-card__lang-dot" style={{ background: r.langColor }} />
                <SFIcon name="repo" size={64} />
              </div>
              <div className="continuity-card__body">
                <span className="continuity-card__name">{r.name}</span>
                <p className="continuity-card__desc">{t(r.descKey)}</p>
              </div>
              <div className="continuity-card__footer">
                <span className="continuity-card__lang">
                  <span className="continuity-card__lang-pip" style={{ background: r.langColor }} />
                  {r.lang}
                </span>
                <span className="continuity-card__github">
                  <i className="fa-brands fa-github" /> GitHub
                </span>
              </div>
            </a>
          ))}
        </ScrollGallery>
        <div className="sec-continuity__cta">
          <a href="https://github.com/romuloscampini" target="_blank" rel="noreferrer" className="btn btn--ghost">
            {t("oss.cta")} <Icon name="arrowUpRight" size={14}/>
          </a>
        </div>
      </Reveal>
    </div>
  </section>
);

// ---------------- Speaking ----------------
const Speaking = ({ t }) => (
  <section className="sec-speaking" id="speaking">
    <div className="sec-speaking__inner">
    <Reveal>
      <div className="section__head">
        <div>
          <div className="eyebrow">{t("speaking.eyebrow")}</div>
          <h2 className="section__title" dangerouslySetInnerHTML={{ __html: t("speaking.title") }} />
        </div>
        <p className="section__subtitle">{t("speaking.sub")}</p>
      </div>
    </Reveal>
    <Reveal delay={1}>
    <div className="talks">
      {window.SITE_DATA.talks.map((tk, i) => (
        <div key={i} className="talk">
          <div className="talk__when">{tk.when}</div>
          <div>
            <h3 className="talk__title">{t(tk.titleKey)}</h3>
            <p className="talk__where">{t(tk.whereKey)}</p>
          </div>
          <span className="talk__badge">{tk.badge}</span>
        </div>
      ))}
    </div>
    </Reveal>
    </div>
  </section>
);

// ---------------- Education & Certifications ----------------
const Education = ({ t }) => (
  <section className="sec-education" id="education">
    <div className="sec-education__inner">
      <Reveal>
        <div className="section__head">
          <div>
            <div className="eyebrow">{t("education.eyebrow")}</div>
            <h2 className="section__title" dangerouslySetInnerHTML={{ __html: t("education.title") }} />
          </div>
          <p className="section__subtitle">{t("education.sub")}</p>
        </div>
      </Reveal>

      <Reveal delay={1}>
        <div className="education-block">
          <div className="education-block__label">{t("education.degrees")}</div>
          <div className="education-list">
            <div className="education-item">
              <div className="education-item__icon"><img src="assets/logos/fgv.png" alt="FGV" className="education-item__logo" /></div>
              <div className="education-item__body">
                <h3 className="education-item__school">{"FGV - Funda\u00e7\u00e3o Getulio Vargas"}</h3>
                <p className="education-item__degree">{t("education.fgv.degree")}</p>
              </div>
            </div>
            <div className="education-item">
              <div className="education-item__icon"><img src="assets/logos/singularity.svg" alt="Singularity University" className="education-item__logo" /></div>
              <div className="education-item__body">
                <h3 className="education-item__school">Singularity University</h3>
                <p className="education-item__degree">{t("education.singularity.degree")}</p>
              </div>
            </div>
            <div className="education-item">
              <div className="education-item__icon"><img src="assets/logos/mit.svg" alt="MIT" className="education-item__logo" /></div>
              <div className="education-item__body">
                <h3 className="education-item__school">Massachusetts Institute of Technology</h3>
                <p className="education-item__degree">{t("education.mit.degree")}</p>
              </div>
            </div>
            <div className="education-item">
              <div className="education-item__icon"><img src="assets/logos/fiap.png" alt="FIAP" className="education-item__logo" /></div>
              <div className="education-item__body">
                <h3 className="education-item__school">FIAP</h3>
                <p className="education-item__degree">{t("education.fiap.degree")}</p>
              </div>
            </div>
          </div>
        </div>
      </Reveal>

      <Reveal delay={2}>
        <div className="education-block">
          <div className="education-block__label">{t("education.certs")}</div>
          <div className="education-certs">
            {["camel", "docker", "js", "http"].map(c => (
              <div key={c} className="cert-chip">
                <span className="cert-chip__name">{t(`cert.${c}.name`)}</span>
              </div>
            ))}
          </div>
        </div>
      </Reveal>
    </div>
  </section>
);

// ---------------- Community ----------------
const Community = ({ t }) => {
  const companies = window.SITE_DATA.community.companies;
  // Duplicate the list for seamless infinite scroll
  const doubled = [...companies, ...companies];

  return (
    <section className="sec-community" id="community">
      <div className="sec-community__inner">
        <Reveal>
          <div className="sec-community__header">
            <div className="eyebrow">{t("community.eyebrow")}</div>
            <h2 className="sec-community__title" dangerouslySetInnerHTML={{ __html: t("community.title") }} />
            <p className="sec-community__sub">{t("community.sub")}</p>
          </div>
        </Reveal>

        <Reveal delay={1}>
          <div className="community-block">
            <div className="community-block__label">{t("community.meetups")}</div>
            <div className="community-meetups">
              {window.SITE_DATA.community.meetups.map(m => (
                <div key={m} className="community-meetup">{m}</div>
              ))}
            </div>
          </div>
        </Reveal>

        <Reveal delay={2}>
          <div className="community-block">
            <div className="community-block__label">{t("community.companies")}</div>
            <p className="community-block__desc">{t("community.companies.desc")}</p>
            <div className="community-marquee">
              <div className="community-marquee__track">
                {doubled.map((c, i) => (
                  <span key={`${c}-${i}`} className="community-logo" title={c}><CompanyLogo name={c} /></span>
                ))}
              </div>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
};

// ---------------- Coffee ----------------
const Coffee = ({ t }) => (
  <section className="section section--narrow" id="coffee">
    <Reveal>
    <div className="coffee">
      <div className="coffee__grid">
        <div>
          <div className="eyebrow" style={{ color: "var(--cosmic-orange)" }}>{t("coffee.eyebrow")}</div>
          <h2 className="coffee__title" dangerouslySetInnerHTML={{ __html: t("coffee.title") }} />
          <p className="coffee__text">{t("coffee.text")}</p>
          <div className="coffee__stats">
            <div>
              <div className="coffee__stat-num">2,847</div>
              <div className="coffee__stat-label">{t("coffee.stat.cups")}</div>
            </div>
            <div>
              <div className="coffee__stat-num">93°C</div>
              <div className="coffee__stat-label">{t("coffee.stat.temp")}</div>
            </div>
            <div>
              <div className="coffee__stat-num">17:250</div>
              <div className="coffee__stat-label">{t("coffee.stat.ratio")}</div>
            </div>
          </div>
        </div>
        <div className="coffee__visual">
          <CoffeeArt />
        </div>
      </div>
    </div>
    </Reveal>
  </section>
);

const CoffeeArt = () => (
  <svg viewBox="0 0 320 320" width="100%" height="100%" aria-hidden>
    <defs>
      <radialGradient id="steamG" cx="50%" cy="30%">
        <stop offset="0%" stopColor="#FFF8E7" stopOpacity="0.7"/>
        <stop offset="100%" stopColor="#FFF8E7" stopOpacity="0"/>
      </radialGradient>
      <linearGradient id="mugG" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#FFF8E7"/>
        <stop offset="100%" stopColor="#E4D5B7"/>
      </linearGradient>
    </defs>
    {/* Steam */}
    <g opacity="0.5">
      <path d="M130 90 Q120 70 140 50 Q160 30 150 10" stroke="#FFF8E7" strokeWidth="3" strokeLinecap="round" fill="none">
        <animate attributeName="opacity" values="0.3;0.7;0.3" dur="3s" repeatCount="indefinite"/>
      </path>
      <path d="M160 80 Q170 60 155 40 Q140 20 160 0" stroke="#FFF8E7" strokeWidth="3" strokeLinecap="round" fill="none">
        <animate attributeName="opacity" values="0.7;0.3;0.7" dur="3s" repeatCount="indefinite"/>
      </path>
      <path d="M190 90 Q200 70 180 50 Q165 30 185 10" stroke="#FFF8E7" strokeWidth="3" strokeLinecap="round" fill="none">
        <animate attributeName="opacity" values="0.4;0.8;0.4" dur="3.5s" repeatCount="indefinite"/>
      </path>
    </g>
    {/* Mug */}
    <ellipse cx="160" cy="120" rx="70" ry="14" fill="#3E2723"/>
    <ellipse cx="160" cy="118" rx="64" ry="10" fill="#1a0e0a"/>
    <path d="M90 120 Q90 250 110 270 Q160 280 210 270 Q230 250 230 120 Z" fill="url(#mugG)"/>
    {/* handle */}
    <path d="M230 150 Q270 160 270 200 Q270 240 230 245" fill="none" stroke="url(#mugG)" strokeWidth="14"/>
    {/* Label */}
    <g transform="translate(160 200)" fill="#3E2723" textAnchor="middle" fontFamily="-apple-system, sans-serif">
      <text fontSize="11" fontWeight="590" letterSpacing="0.15em">COFFEE</text>
      <text y="18" fontSize="8" opacity="0.6" letterSpacing="0.1em">DRIVEN DEV</text>
    </g>
  </svg>
);

// ---------------- Contact ----------------
const Contact = ({ t }) => (
  <section className="contact" id="contact">
    <Reveal>
    <div className="eyebrow">{t("contact.eyebrow")}</div>
    <h2 className="contact__title" dangerouslySetInnerHTML={{ __html: t("contact.title") }} />
    <p className="contact__sub">{t("contact.sub")}</p>
    <div className="contact__ctas">
      <a href="mailto:hello@romuloscampini.com" className="btn btn--primary btn--lg">
        <i className="fa-solid fa-envelope" /> hello@romuloscampini.com
      </a>
      <a href="https://www.linkedin.com/in/romuloscampini/" target="_blank" rel="noreferrer" className="btn btn--secondary btn--lg">
        <i className="fa-brands fa-linkedin-in" /> LinkedIn
      </a>
    </div>
    </Reveal>
  </section>
);

// ---------------- Footer ----------------
const SiteFooter = ({ t }) => (
  <footer className="site-footer">
    <div>
      <div style={{ color: "var(--label-secondary)", fontWeight: 500 }}>Romulo Scampini</div>
      <div>{t("footer.copy")}</div>
    </div>
    <blockquote style={{ margin: 0, maxWidth: 340, fontSize: "var(--fs-footnote)", color: "var(--label-tertiary)", fontStyle: "italic", textAlign: "center" }}>
      {t("footer.quote")}
      <br/><span style={{ fontStyle: "normal" }}>{t("footer.author")}</span>
    </blockquote>
    <div className="site-footer__socials">
      <a className="socialbtn" href="https://github.com/romuloscampini" target="_blank" rel="noreferrer" aria-label="GitHub"><i className="fa-brands fa-github" /></a>
      <a className="socialbtn" href="https://twitter.com/romuloscampini" target="_blank" rel="noreferrer" aria-label="X"><i className="fa-brands fa-x-twitter" /></a>
      <a className="socialbtn" href="https://www.linkedin.com/in/romuloscampini/" target="_blank" rel="noreferrer" aria-label="LinkedIn"><i className="fa-brands fa-linkedin-in" /></a>
      <a className="socialbtn" href="https://medium.com/@romuloscampini" target="_blank" rel="noreferrer" aria-label="Medium"><i className="fa-brands fa-medium" /></a>
    </div>
  </footer>
);

// ---------------- Spotlight (⌘K) ----------------
const Spotlight = ({ open, onClose, t }) => {
  const [q, setQ] = useState("");
  const [active, setActive] = useState(0);
  const inputRef = useRef(null);

  const items = useMemo(() => {
    const nav = [
      { k: "nav", t: t("nav.work"), sub: t("projects.eyebrow"), ic: "🧭", href: "#work" },
      { k: "nav", t: t("nav.currently"), sub: t("currently.eyebrow"), ic: "✨", href: "#currently" },
      { k: "nav", t: t("nav.skills"), sub: t("skills.eyebrow"), ic: "🧰", href: "#skills" },
      { k: "nav", t: t("nav.writing"), sub: t("writing.eyebrow"), ic: "📝", href: "#writing" },
      { k: "nav", t: t("nav.oss"), sub: "GitHub repos", ic: "🐙", href: "#oss" },
      { k: "nav", t: t("nav.speaking"), sub: t("speaking.eyebrow"), ic: "🎤", href: "#speaking" },
      { k: "nav", t: t("nav.education"), sub: t("education.eyebrow"), ic: "🎓", href: "#education" },
      { k: "nav", t: t("nav.community"), sub: t("community.eyebrow"), ic: "🌐", href: "#community" },
      { k: "nav", t: t("nav.coffee"), sub: t("coffee.eyebrow"), ic: "☕", href: "#coffee" },
      { k: "nav", t: t("nav.contact"), sub: t("contact.eyebrow"), ic: "📬", href: "#contact" },
    ];
    const projects = window.SITE_DATA.projects.map(p => ({
      k: "proj", t: t(p.titleKey), sub: `${p.company} · ${p.year}`, ic: "📁", project: p,
    }));
    const articles = window.SITE_DATA.articles.map(a => ({
      k: "art", t: t(a.titleKey), sub: a.date, ic: "📰", href: a.url, ext: true,
    }));
    const actions = [
      { k: "act", t: t("action.theme"), sub: t("action.theme.sub"), ic: "◐", action: "theme" },
      { k: "act", t: t("action.email"), sub: "hello@romuloscampini.com", ic: "✉️", href: "mailto:hello@romuloscampini.com" },
      { k: "act", t: "GitHub", sub: "@romuloscampini", ic: "🐙", href: "https://github.com/romuloscampini", ext: true },
      { k: "act", t: "LinkedIn", sub: "/in/romuloscampini", ic: "💼", href: "https://www.linkedin.com/in/romuloscampini/", ext: true },
    ];
    return [...nav, ...projects, ...articles, ...actions];
  }, [t]);

  const filtered = useMemo(() => {
    const s = q.trim().toLowerCase();
    if (!s) return items;
    return items.filter(i => (i.t + " " + i.sub).toLowerCase().includes(s));
  }, [q, items]);

  useEffect(() => {
    if (open) {
      setQ(""); setActive(0);
      setTimeout(() => inputRef.current?.focus(), 50);
    }
  }, [open]);

  useEffect(() => { setActive(0); }, [q]);

  const runItem = (item) => {
    if (!item) return;
    if (item.action === "theme") {
      window.dispatchEvent(new CustomEvent("toggle-theme"));
      onClose();
      return;
    }
    if (item.project) {
      window.dispatchEvent(new CustomEvent("open-project", { detail: item.project }));
      onClose();
      return;
    }
    if (item.href) {
      if (item.ext) {
        window.open(item.href, "_blank", "noreferrer");
      } else {
        onClose();
        setTimeout(() => {
          const el = document.querySelector(item.href);
          if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
        }, 100);
        return;
      }
    }
    onClose();
  };

  useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (e.key === "Escape") { e.preventDefault(); onClose(); }
      else if (e.key === "ArrowDown") { e.preventDefault(); setActive(a => Math.min(a + 1, filtered.length - 1)); }
      else if (e.key === "ArrowUp") { e.preventDefault(); setActive(a => Math.max(a - 1, 0)); }
      else if (e.key === "Enter") { e.preventDefault(); runItem(filtered[active]); }
    };
    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, [open, filtered, active]);

  // Group
  const groups = useMemo(() => {
    const g = {};
    const labels = { nav: t("spotlight.navigate"), proj: t("spotlight.projects"), art: t("spotlight.articles"), act: t("spotlight.actions") };
    filtered.forEach((it, idx) => {
      if (!g[it.k]) g[it.k] = { label: labels[it.k], items: [] };
      g[it.k].items.push({ ...it, _idx: idx });
    });
    return Object.values(g);
  }, [filtered]);

  return (
    <div className="spotlight-overlay" data-open={open} onClick={onClose} aria-hidden={!open}>
      <div className="spotlight" onClick={(e) => e.stopPropagation()} role="dialog" aria-label="Search">
        <div className="spotlight__input-row">
          <Icon name="search" size={18} />
          <input
            ref={inputRef}
            className="spotlight__input"
            placeholder={t("spotlight.placeholder")}
            value={q}
            onChange={(e) => setQ(e.target.value)}
          />
          <span className="nav-btn__kbd">esc</span>
        </div>
        <div className="spotlight__results">
          {groups.length === 0 && <div className="spotlight__group-label">{t("spotlight.no_results")}</div>}
          {groups.map(g => (
            <div key={g.label}>
              <div className="spotlight__group-label">{g.label}</div>
              {g.items.map(it => (
                <div
                  key={it.t}
                  className="spotlight__item"
                  data-active={it._idx === active}
                  onMouseEnter={() => setActive(it._idx)}
                  onClick={() => runItem(it)}
                >
                  <div className="spotlight__item-ic">{it.ic}</div>
                  <div className="spotlight__item-text">
                    <div className="spotlight__item-title">{it.t}</div>
                    <div className="spotlight__item-sub">{it.sub}</div>
                  </div>
                  <Icon name="arrowRight" size={14}/>
                </div>
              ))}
            </div>
          ))}
        </div>
        <div className="spotlight__footer">
          <span className="spotlight__hint"><kbd>↑</kbd><kbd>↓</kbd> {t("spotlight.nav.navigate")}</span>
          <span className="spotlight__hint"><kbd>↵</kbd> {t("spotlight.nav.open")}</span>
          <span className="spotlight__hint"><kbd>esc</kbd> {t("spotlight.nav.close")}</span>
          <span style={{ marginLeft: "auto" }}>⌘K</span>
        </div>
      </div>
    </div>
  );
};

// ---------------- Project Sheet — Apple HIG content page style ----------------
const ProjectSheet = ({ project, onClose, t }) => {
  useEffect(() => {
    if (!project) return;
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [project, onClose]);

  return (
    <React.Fragment>
      <div className="sheet-overlay" data-open={!!project} onClick={onClose} aria-hidden={!project}/>
      <aside className="sheet" data-open={!!project} aria-hidden={!project} aria-label="Project detail">
        {project && (
          <React.Fragment>
            <div className="sheet__header">
              <div className="sheet__header-left">
                <span className="sheet__breadcrumb">{t("sheet.breadcrumb")}</span>
                <Icon name="chevronRight" size={12} />
                <span className="sheet__breadcrumb sheet__breadcrumb--current">{project.label}</span>
              </div>
              <button className="sheet__close" onClick={onClose} aria-label="Close">
                <Icon name="close" size={14}/>
              </button>
            </div>
            <div className="sheet__body">
              {/* Hero visual with Apple-style rounded container */}
              <div className="sheet__hero">
                <ProjectVisual kind={project.visual} accent={project.accent} size="wide" />
              </div>

              {/* Title block — Apple HIG page header style */}
              <div className="sheet__title-block">
                <div className="sheet__label-row">
                  <span className="sheet__category-badge" style={{ background: project.accent + '18', color: project.accent }}>
                    {project.label}
                  </span>
                  <span className="sheet__date">{project.company} · {project.year}</span>
                </div>
                <h2 className="sheet__title">{t(project.titleKey)}</h2>
                <div className="sheet__tags">
                  {t(project.tagsKey).split(", ").map(tag => <span key={tag} className="sheet__tag">{tag}</span>)}
                </div>
              </div>

              {/* Divider */}
              <hr className="sheet__divider" />

              {/* Overview — Apple HIG intro paragraph */}
              <div className="sheet__content-section">
                <p className="sheet__overview">{t(project.overviewKey)}</p>
              </div>

              {/* Impact — Apple HIG info cards grid */}
              <div className="sheet__content-section">
                <h3 className="sheet__heading">{t("sheet.impact")}</h3>
                <div className="sheet__metrics">
                  {project.metrics.map(m => (
                    <div key={m.lKey} className="sheet__metric">
                      <div className="sheet__metric-num" style={{ color: project.accent }}>{m.n}</div>
                      <div className="sheet__metric-label">{t(m.lKey)}</div>
                    </div>
                  ))}
                </div>
              </div>

              {/* Role — Apple HIG callout box */}
              <div className="sheet__content-section">
                <h3 className="sheet__heading">{t("sheet.role")}</h3>
                <div className="sheet__callout">
                  <div className="sheet__callout-icon">
                    <Icon name="sparkle" size={16} />
                  </div>
                  <p className="sheet__callout-text">{t(project.roleKey)}</p>
                </div>
              </div>

              {/* Tech stack — Apple HIG topic tiles */}
              <div className="sheet__content-section">
                <h3 className="sheet__heading">{t("sheet.stack")}</h3>
                <div className="sheet__stack-grid">
                  {project.stack.map(s => (
                    <div key={s} className="sheet__stack-tile">
                      <span className="sheet__stack-name">{s}</span>
                    </div>
                  ))}
                </div>
              </div>

              {/* Note — Apple HIG aside/note box */}
              <div className="sheet__aside">
                <div className="sheet__aside-bar" style={{ background: project.accent }} />
                <div className="sheet__aside-content">
                  <strong className="sheet__aside-label">{t("sheet.note")}</strong>
                  <p className="sheet__aside-text">{t("sheet.note.text")}</p>
                </div>
              </div>
            </div>
          </React.Fragment>
        )}
      </aside>
    </React.Fragment>
  );
};

// ---------------- Tweaks ----------------
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "variation": "marketing",
  "accent": "blue",
  "appearance": "auto"
}/*EDITMODE-END*/;

const ACCENT_MAP = {
  orange: { light: "#FF9500", dark: "#FF9F0A" },
  blue:   { light: "#007AFF", dark: "#0A84FF" },
  indigo: { light: "#5856D6", dark: "#5E5CE6" },
  green:  { light: "#34C759", dark: "#30D158" },
  pink:   { light: "#FF2D55", dark: "#FF375F" },
  graphite: { light: "#1c1c1e", dark: "#E5E5EA" },
};

const Tweaks = ({ visible, state, onChange }) => {
  if (!visible) return null;
  return (
    <div className="tweaks" data-visible="true">
      <div className="tweaks__head">
        <div className="tweaks__traffic">
          <span className="tweaks__dot" style={{ background: "#FF5F57" }}/>
          <span className="tweaks__dot" style={{ background: "#FEBC2E" }}/>
          <span className="tweaks__dot" style={{ background: "#28C840" }}/>
        </div>
        <div className="tweaks__title">Tweaks</div>
        <div style={{ width: 40 }}/>
      </div>
      <div className="tweaks__body">
        <div className="tweaks__group">
          <label className="tweaks__label">Direction</label>
          <div className="tweaks__segmented">
            {[
              ["marketing", "Marketing"],
              ["xcode", "Xcode"],
              ["bento", "Bento"],
            ].map(([v, l]) => (
              <button
                key={v}
                className="tweaks__seg-btn"
                data-active={state.variation === v}
                onClick={() => onChange({ variation: v })}
              >{l}</button>
            ))}
          </div>
        </div>
        <div className="tweaks__group">
          <label className="tweaks__label">Accent</label>
          <div className="tweaks__color-row">
            {Object.keys(ACCENT_MAP).map(k => (
              <button
                key={k}
                className="tweaks__swatch"
                data-active={state.accent === k}
                style={{ background: ACCENT_MAP[k].light }}
                aria-label={k}
                onClick={() => onChange({ accent: k })}
              />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

// ---------------- Scroll to Top ----------------
const ScrollToTop = () => {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const onScroll = () => setVisible(window.scrollY > 400);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const scrollUp = () => window.scrollTo({ top: 0, behavior: 'smooth' });

  return (
    <button
      className="scroll-top"
      data-visible={visible}
      onClick={scrollUp}
      aria-label="Scroll to top"
    >
      <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M12 19V5M5 12l7-7 7 7"/>
      </svg>
    </button>
  );
};

// ---------------- Intro Overlay — text scramble ----------------
const IntroOverlay = () => {
  const TARGET = "Romulo Scampini";
  const CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%&*";
  const STAGGER = 3;
  const CYCLES = 8;
  const TICK_MS = 40;

  const [displayChars, setDisplayChars] = useState(() => new Array(TARGET.length).fill(""));
  const [fading, setFading] = useState(false);
  const [visible, setVisible] = useState(() => !sessionStorage.getItem("intro-played"));
  const [showCursor, setShowCursor] = useState(true);

  useEffect(() => {
    if (!visible) return;
    document.body.style.overflow = "hidden";

    let tick = 0;
    const resolved = new Array(TARGET.length).fill(false);
    const display = new Array(TARGET.length).fill("");

    const interval = setInterval(() => {
      tick++;
      for (let i = 0; i < TARGET.length; i++) {
        if (TARGET[i] === " ") { display[i] = "\u00A0"; resolved[i] = true; continue; }
        const charStart = i * STAGGER;
        if (tick < charStart) { display[i] = ""; continue; }
        const elapsed = tick - charStart;
        if (elapsed >= CYCLES) {
          display[i] = TARGET[i];
          resolved[i] = true;
        } else {
          display[i] = CHARS[Math.floor(Math.random() * CHARS.length)];
        }
      }
      setDisplayChars([...display]);
      if (resolved.every(Boolean)) {
        clearInterval(interval);
        setShowCursor(false);
        setTimeout(() => setFading(true), 400);
        setTimeout(() => {
          setVisible(false);
          document.body.style.overflow = "";
          sessionStorage.setItem("intro-played", "1");
        }, 1000);
      }
    }, TICK_MS);

    return () => { clearInterval(interval); document.body.style.overflow = ""; };
  }, [visible]);

  if (!visible) return null;

  return (
    <div className={`intro-overlay${fading ? " intro-overlay--fading" : ""}`}>
      <div className="intro-content">
        <div className="intro-text">
          {displayChars.map((ch, i) => (
            <span key={i} className={`intro-char${TARGET[i] === " " ? " intro-char--space" : ""}`}>
              {ch}
            </span>
          ))}
          {showCursor && <span className="intro-cursor" />}
        </div>
      </div>
    </div>
  );
};

// ---------------- App Root ----------------
const App = () => {
  const { lang, t, changeLang } = useI18n();
  const [theme, setTheme] = useState(() => {
    return localStorage.getItem("theme") || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
  });
  const [spotlightOpen, setSpotlightOpen] = useState(false);
  const [activeProject, setActiveProject] = useState(null);
  const [wipe, setWipe] = useState(false);

  // Tweaks state
  const [tweakState, setTweakState] = useState(TWEAK_DEFAULTS);
  const [tweakVisible, setTweakVisible] = useState(false);

  // Apply theme
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("theme", theme);
  }, [theme]);

  // Apply variation + accent
  useEffect(() => {
    document.body.setAttribute("data-variation", tweakState.variation);
    const a = ACCENT_MAP[tweakState.accent] || ACCENT_MAP.blue;
    document.documentElement.style.setProperty("--accent", theme === "dark" ? a.dark : a.light);
    const hex = theme === "dark" ? a.dark : a.light;
    // derive soft / tint via alpha
    document.documentElement.style.setProperty("--accent-soft", hex + "1a");
    document.documentElement.style.setProperty("--accent-tint", hex + "26");
  }, [tweakState, theme]);

  // Toggle theme with diagonal wipe
  const toggleTheme = useCallback(() => {
    setWipe(true);
    setTimeout(() => setTheme(t => t === "dark" ? "light" : "dark"), 380);
    setTimeout(() => setWipe(false), 900);
  }, []);

  // ⌘K
  useEffect(() => {
    const h = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setSpotlightOpen(v => !v);
      }
    };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, []);

  // Events from spotlight
  useEffect(() => {
    const t = () => toggleTheme();
    const p = (e) => setActiveProject(e.detail);
    window.addEventListener("toggle-theme", t);
    window.addEventListener("open-project", p);
    return () => {
      window.removeEventListener("toggle-theme", t);
      window.removeEventListener("open-project", p);
    };
  }, [toggleTheme]);

  // Edit mode (Tweaks) integration with host
  useEffect(() => {
    const onMsg = (e) => {
      if (!e.data || !e.data.type) return;
      if (e.data.type === "__activate_edit_mode") setTweakVisible(true);
      if (e.data.type === "__deactivate_edit_mode") setTweakVisible(false);
    };
    window.addEventListener("message", onMsg);
    // Announce availability after listener is live
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const updateTweaks = useCallback((patch) => {
    setTweakState(s => {
      const next = { ...s, ...patch };
      window.parent.postMessage({ type: "__edit_mode_set_keys", edits: patch }, "*");
      return next;
    });
  }, []);

  // Body scroll lock when sheet/spotlight open
  useEffect(() => {
    const lock = spotlightOpen || !!activeProject;
    document.body.style.overflow = lock ? "hidden" : "";
  }, [spotlightOpen, activeProject]);

  return (
    <React.Fragment>
      <Nav
        theme={theme}
        onToggleTheme={toggleTheme}
        onOpenSpotlight={() => setSpotlightOpen(true)}
        t={t}
        lang={lang}
        onChangeLang={changeLang}
      />
      <main>
        <Hero t={t} />
        <Projects onOpen={setActiveProject} t={t} />
        <Skills t={t} />
        <Writing t={t} />
        <OSS t={t} />
        <Speaking t={t} />
        <Education t={t} />
        <Community t={t} />
        <Currently t={t} />
        <Coffee t={t} />
        <Contact t={t} />
      </main>
      <SiteFooter t={t} />

      <Spotlight open={spotlightOpen} onClose={() => setSpotlightOpen(false)} t={t} />
      <ProjectSheet project={activeProject} onClose={() => setActiveProject(null)} t={t} />

      <ScrollToTop />
      <div className="wipe" data-animating={wipe}/>
      <Tweaks visible={tweakVisible} state={tweakState} onChange={updateTweaks} />
      <IntroOverlay />
    </React.Fragment>
  );
};

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