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

// ─── DATA ────────────────────────────────────────────────────────────────────
const PROJECTS = {
  "ML Apps": [
    {
      title: "Rock Classifier App",
      desc: "A deep learning system that identifies 41 rock types from a single field photograph, using a ConvNeXt-Tiny backbone with a custom dual-head architecture that predicts rock group (igneous / metamorphic / sedimentary) and specific rock type at once. It's a fully productionized system, not just a model: a FastAPI backend serving real-time inference, a React frontend, and a closed feedback loop where users can correct a wrong prediction — each correction is persisted to a managed database as future retraining data. When the original hosting provider unexpectedly took the backend offline, I migrated the entire service — inference backend and feedback pipeline alike — to a new cloud stack with zero data loss, redesigning it to scale to zero instead of running (and billing) around the clock.",
      stack: ["PyTorch","FastAPI","React","Google Cloud Run","Supabase","GitHub Actions CI/CD"],
      live: "https://fehintiti.github.io/Rock-Classifier-App/",
      github: "https://github.com/Fehintiti/Rock-Classifier-App",
      featured: true,
      img: window.ROCK_APP_SCREENSHOT,
    },
    {
      title: "Multiple Disease Prediction",
      desc: "Clinical ML app classifying Heart Disease, Parkinson's, and Diabetes from patient input data. Deployed as an accessible Streamlit application.",
      stack: ["Scikit-learn","Streamlit","Python","Pandas"],
      github: "https://github.com/Fehintiti/Multiple-Disease-Prediction-ML-App",
      img: "https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=600&q=80",
    },
    {
      title: "Zenodo Product Classification",
      desc: "NLP pipeline for automated product categorisation using TF-IDF, Word2Vec embeddings, SVM, XGBoost and neural networks with hyperparameter tuning.",
      stack: ["NLP","Text Classification","Python","Scikit-learn"],
      github: "https://github.com/Fehintiti/Zenodo-Product-Classification",
      img: "https://images.unsplash.com/photo-1555949963-ff9fe0c870eb?w=600&q=80",
    },
  ],
  "Cloud Pipelines": [
    {
      title: "Gold Price Intelligence Pipeline",
      desc: "Fully serverless data engineering pipeline ingesting, processing and serving live precious metals data. EventBridge triggers Lambda, raw files land in S3, Athena queries transform the data.",
      stack: ["EventBridge","Lambda","S3","Athena","JavaScript"],
      live: "https://fehintiti.github.io/gold-pipeline-dashboard/",
      github: "https://github.com/Fehintiti/gold-pipeline-dashboard",
      featured: true,
      img: "https://images.unsplash.com/photo-1611974789855-9c2a0a7236a3?w=1200&q=80",
    },
    {
      title: "Mining Operation Optimisation",
      desc: "Predictive maintenance model for industrial mining equipment. Processes sensor data to forecast failure events and fuel consumption, enabling proactive scheduling.",
      stack: ["Python","Predictive Maintenance","ML","Pandas"],
      github: "https://github.com/Fehintiti/Mining-Operation-Optimization-App-Project",
      img: "https://images.unsplash.com/photo-1504307651254-35680f356dfd?w=600&q=80",
    },
    {
      title: "Equipment Failure Prediction",
      desc: "Sensor-based failure prediction for industrial machinery. Time-series readings detect early failure signals, enabling maintenance teams to act before breakdowns occur.",
      stack: ["Python","Time Series","Classification","Scikit-learn"],
      github: "https://github.com/Fehintiti/Mining-Equipment-Failure-",
      img: "https://images.unsplash.com/photo-1581091226825-a6a2a5aee158?w=600&q=80",
    },
  ],
  "BI & Analytics": [
    {
      title: "Southern Water UK Dashboard",
      desc: "Full BI project processing 89,000+ operational records. SQL data pipeline feeds a Power BI dashboard surfacing key operational KPIs for non-technical stakeholders.",
      stack: ["SQL","Power BI","Data Modelling","ETL"],
      featured: true,
      linkedin: "https://www.linkedin.com/posts/activity-7434568295699099648-snUL?utm_source=share&utm_medium=member_desktop&rcm=ACoAABVw1KQBpKhZRw5AUfhVAMLuBpLNx6Ym3Ao",
      img: "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=1200&q=80",
    },
    {
      title: "NYC Green Taxi Challenge",
      desc: "Maven Analytics challenge entry — four years of NYC Green Taxi records analysed in SQL and visualised in Power BI with actionable pricing and demand recommendations.",
      stack: ["SQL","Power BI","Maven Challenge","Data Analysis"],
      github: "https://github.com/Fehintiti/NYC-Green-Taxi",
      img: "https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?w=600&q=80",
    },
    {
      title: "Gold Price Analysis 1978–2021",
      desc: "Longitudinal analysis of 43 years of precious metals data identifying macro trends across inflation cycles, financial crises, and commodity booms.",
      stack: ["Python","Pandas","Trend Analysis","Finance Data"],
      github: "https://github.com/Fehintiti/Gold_Price-Analysis-",
      img: "https://images.unsplash.com/photo-1618044733300-9472054094ee?w=600&q=80",
    },
  ],
  "Computer Vision": [
    {
      title: "Quartz Core Object Detection",
      desc: "YOLOv8 model trained to automatically identify and localise quartz minerals in diamond drill core images. Trained via Roboflow with full case study published on Medium.",
      stack: ["YOLOv8","Roboflow","Object Detection","Python"],
      github: "https://github.com/Fehintiti/Core-Images-Quartz-Object-Detection",
      medium: "https://medium.com/@Fehintiti/quartz-core-images-object-detection-af15b1c6c3fa",
      featured: true,
      img: "https://images.unsplash.com/photo-1507413245164-6160d8298b31?w=1200&q=80",
    },
  ],
  "Data Wrangling": [
    {
      title: "Nashville Housing Data Cleaning",
      desc: "SQL-only data quality project transforming raw Nashville housing records into a fully analysis-ready dataset — address standardisation, null handling, deduplication.",
      stack: ["SQL","Data Cleaning","ETL","Data Quality"],
      github: "https://github.com/Fehintiti/Nahville-Housing-Dataset-Cleaning",
      featured: true,
      img: "https://images.unsplash.com/photo-1558494949-ef010cbdcc31?w=1200&q=80",
    },
    {
      title: "Cyclist Bike Share Capstone",
      desc: "Google Data Analytics certificate capstone. Full analysis of Cyclistic bike-share usage patterns to identify behavioural differences and inform membership conversion strategy.",
      stack: ["SQL","R","Google Capstone","Data Analysis"],
      github: "https://github.com/Fehintiti/Cyclist-Bike-Share",
      img: "https://images.unsplash.com/photo-1534787238916-9ba6764efd4f?w=600&q=80",
    },
    {
      title: "Covid-19 Data Exploration",
      desc: "SQL-driven exploration of global Covid-19 infection, mortality, and vaccination data. Tracks rolling case rates across countries and documents vaccination rollout effects.",
      stack: ["SQL","Python","Exploratory Analysis","Public Health"],
      github: "https://github.com/Fehintiti/Covid-Project",
      img: "https://images.unsplash.com/photo-1584036561566-baf8f5f1b144?w=600&q=80",
    },
  ],
};

const SKILLS = [
  "Python","SQL","Power BI","PyTorch","FastAPI","React",
  "Scikit-learn","Streamlit","Pandas","Git","Docker",
  "Jupyter","Matplotlib","NLP","TensorFlow","Tableau","Spark","dbt",
];

const STATIC_ARTICLES = [
  { title: "Can AI Really Identify Rocks? A Data Scientist's Challenge", date: "Feb 2026", desc: "A 5-phase ML experiment testing whether computer vision can replicate geological expertise — and what the results reveal about the real limits of AI.", url: "https://medium.com/@Fehintiti/can-ai-really-identify-rocks-a-data-scientists-challenge-347cde82e203" },
  { title: "I Bought Gold. Then It Crashed. So I Built a Pipeline to Track It.", date: "Apr 2026", desc: "How a personal investment decision became a full serverless data engineering system with automated ingestion, cloud storage, SQL analytics, and a live dashboard.", url: "https://medium.com/@Fehintiti/i-bought-gold-then-it-crashed-so-i-built-a-pipeline-to-track-it-039211d306db" },
  { title: "Git and GitHub: The Data Scientist's Best Friend", date: "Aug 2025", desc: "A practical guide to version control that transforms how data scientists manage, share, and showcase their work across projects and collaborators.", url: "https://medium.com/@Fehintiti/git-and-github-the-data-scientists-best-friend-you-didn-t-know-you-needed-6101d9032f42" },
  { title: "Quartz Core Images: Object Detection", date: "Aug 2024", desc: "A full walkthrough of training YOLOv8 to detect quartz minerals in diamond drill core photographs, from Roboflow dataset preparation through to results.", url: "https://medium.com/@Fehintiti/quartz-core-images-object-detection-af15b1c6c3fa" },
  { title: "Multi-Element Gold Prediction with Machine Learning", date: "Apr 2023", desc: "Building and deploying a Random Forest model to predict gold concentration from geochemical assay data, with a Streamlit interface for non-technical users.", url: "https://medium.com/@Fehintiti/multi-element-gold-prediction-with-machine-learning-f7608d7bbaa" },
  { title: "Exploratory Data Analysis on Mining Geochemical Data", date: "Jun 2023", desc: "Step-by-step EDA across three mineral survey zones covering data cleaning, QA/QC, anomaly detection, and multi-element correlation analysis.", url: "https://medium.com/@Fehintiti/exploratory-data-analysis-eda-on-mining-geochemical-data-4d6657c16058" },
];

// ─── ICONS ─────────────────────────────────────────────────────────────────
const GithubIcon = () => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>;
const LinkedInIcon = () => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>;
const MediumIcon = () => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M13.54 12a6.8 6.8 0 01-6.77 6.82A6.8 6.8 0 010 12a6.8 6.8 0 016.77-6.82A6.8 6.8 0 0113.54 12zM20.96 12c0 3.54-1.51 6.42-3.38 6.42-1.87 0-3.39-2.88-3.39-6.42s1.52-6.42 3.39-6.42 3.38 2.88 3.38 6.42M24 12c0 3.17-.53 5.75-1.19 5.75-.66 0-1.19-2.58-1.19-5.75s.53-5.75 1.19-5.75C23.47 6.25 24 8.83 24 12z"/></svg>;
const TwitterIcon = () => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.73-8.835L1.254 2.25H8.08l4.259 5.631 5.905-5.631zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>;
const EmailIcon = () => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>;
const ArrowIcon = () => <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2"><path d="M7 17L17 7M17 7H7M17 7v10"/></svg>;

// ─── COUNTER ─────────────────────────────────────────────────────────────────
function useCounter(target, duration, triggered) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    if (!triggered) return;
    let start = 0;
    const numTarget = parseInt(target.replace(/\D/g, ""));
    const step = Math.ceil(numTarget / (duration / 16));
    const timer = setInterval(() => {
      start += step;
      if (start >= numTarget) { setCount(numTarget); clearInterval(timer); }
      else setCount(start);
    }, 16);
    return () => clearInterval(timer);
  }, [triggered]);
  return count;
}

// ─── SKILL BUBBLES ────────────────────────────────────────────────────────────
function SkillBubbles() {
  const canvasRef = useRef(null);
  const bubblesRef = useRef([]);
  const animRef = useRef(null);
  const activeRef = useRef(true);

  const initBubbles = useCallback((canvas) => {
    const tones = ["#222222","#333333","#444444","#555555","#666666","#7B7B7B","#888888","#999999"];
    bubblesRef.current = SKILLS.map((skill, i) => {
      const radius = Math.max(40, Math.min(62, skill.length * 5 + 32));
      return {
        x: radius + Math.random() * (canvas.width - radius * 2),
        y: radius + Math.random() * (canvas.height - radius * 2),
        vx: (Math.random() - 0.5) * 1.2,
        vy: (Math.random() - 0.5) * 1.2,
        radius, label: skill,
        color: tones[i % tones.length],
        opacity: 0,
      };
    });
  }, []);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const resize = () => {
      canvas.width = canvas.offsetWidth;
      canvas.height = canvas.offsetHeight;
      initBubbles(canvas);
    };
    resize();
    window.addEventListener("resize", resize);
    const handleVisibility = () => {
      if (!document.hidden) { activeRef.current = true; if (!animRef.current) animate(); }
      else activeRef.current = false;
    };
    document.addEventListener("visibilitychange", handleVisibility);
    const animate = () => {
      if (!activeRef.current) { animRef.current = null; return; }
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      bubblesRef.current.forEach((b, i) => {
        b.opacity = Math.min(1, b.opacity + 0.018);
        b.x += b.vx; b.y += b.vy;
        if (b.x - b.radius < 0) { b.x = b.radius; b.vx = Math.abs(b.vx); }
        if (b.x + b.radius > canvas.width) { b.x = canvas.width - b.radius; b.vx = -Math.abs(b.vx); }
        if (b.y - b.radius < 0) { b.y = b.radius; b.vy = Math.abs(b.vy); }
        if (b.y + b.radius > canvas.height) { b.y = canvas.height - b.radius; b.vy = -Math.abs(b.vy); }
        bubblesRef.current.forEach((b2, j) => {
          if (i >= j) return;
          const dx = b2.x - b.x, dy = b2.y - b.y;
          const dist = Math.sqrt(dx*dx+dy*dy);
          const minDist = b.radius + b2.radius + 4;
          if (dist < minDist && dist > 0) {
            const angle = Math.atan2(dy, dx), overlap = (minDist - dist) / 2;
            b.x -= Math.cos(angle)*overlap; b.y -= Math.sin(angle)*overlap;
            b2.x += Math.cos(angle)*overlap; b2.y += Math.sin(angle)*overlap;
            const tmpVx = b.vx, tmpVy = b.vy;
            b.vx = b2.vx*0.92; b.vy = b2.vy*0.92;
            b2.vx = tmpVx*0.92; b2.vy = tmpVy*0.92;
          }
        });
        ctx.save();
        ctx.globalAlpha = b.opacity;
        ctx.beginPath(); ctx.arc(b.x, b.y, b.radius, 0, Math.PI*2);
        ctx.fillStyle = b.color; ctx.fill();
        ctx.fillStyle = "#ffffff";
        ctx.font = `500 ${Math.max(11, Math.floor(b.radius * 0.28))}px 'DM Sans', sans-serif`;
        ctx.textAlign = "center"; ctx.textBaseline = "middle";
        ctx.fillText(b.label, b.x, b.y);
        ctx.restore();
      });
      animRef.current = requestAnimationFrame(animate);
    };
    animate();
    return () => { cancelAnimationFrame(animRef.current); window.removeEventListener("resize", resize); document.removeEventListener("visibilitychange", handleVisibility); };
  }, [initBubbles]);

  return (
    <canvas ref={canvasRef}
      style={{ width:"100%", height:"480px", display:"block", borderRadius:16, background:"#F8F8F8" }}
    />
  );
}

// ─── MAIN COMPONENT ──────────────────────────────────────────────────────────
function Portfolio() {
  const [activeSection, setActiveSection]   = useState("Home");
  const [activeCategory, setActiveCategory] = useState("ML Apps");
  const [scrolled, setScrolled]             = useState(false);
  const [statsVisible, setStatsVisible]     = useState(false);
  const [articles, setArticles]             = useState(STATIC_ARTICLES.slice(0,3));
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const statsRef = useRef(null);

  function useInView(threshold = 0.12) {
    const ref = useRef(null);
    const [inView, setInView] = useState(false);
    useEffect(() => {
      const obs = new IntersectionObserver(
        ([e]) => { if (e.isIntersecting) { setInView(true); obs.disconnect(); } },
        { threshold }
      );
      if (ref.current) obs.observe(ref.current);
      return () => obs.disconnect();
    }, []);
    return [ref, inView];
  }

  const [expRef,     expIn]     = useInView(0.08);
  const [projRef,    projIn]    = useInView(0.06);
  const [artRef,     artIn]     = useInView(0.08);
  const [aboutRef,   aboutIn]   = useInView(0.08);
  const [skillRef,   skillIn]   = useInView(0.1);
  const [contactRef, contactIn] = useInView(0.1);
  const [heroRef,    heroIn]    = useInView(0.01);

  const [winW, setWinW] = useState(window.innerWidth);
  useEffect(() => {
    const fn = () => setWinW(window.innerWidth);
    window.addEventListener("resize", fn);
    return () => window.removeEventListener("resize", fn);
  }, []);
  const isMobile = winW <= 600;
  const isTablet = winW <= 900;

  // ── 3D About Carousel ──────────────────────────────────────
  const [carouselIdx, setCarouselIdx] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setCarouselIdx(p => (p + 1) % 3), 4200);
    return () => clearInterval(t);
  }, []);

  // ── Stacked Article Deck ───────────────────────────────────
  const [deckArts, setDeckArts] = useState([0, 1, 2]);
  const [deckExiting, setDeckExiting] = useState(false);
  function nextDeckCard() {
    if (deckExiting) return;
    setDeckExiting(true);
    const nextIdx = (deckArts[2] + 1) % STATIC_ARTICLES.length;
    setTimeout(() => {
      setDeckArts(prev => [prev[1], prev[2], nextIdx]);
      setDeckExiting(false);
    }, 480);
  }
  function getDeckStyle(pos) {
    if (deckExiting) {
      if (pos === 0) return { ty: 340, scale: 1,    zi: 10, op: 0 };
      if (pos === 1) return { ty: 0,   scale: 1,    zi: 3,  op: 1 };
      return              { ty: -20,  scale: 0.95,  zi: 2,  op: 1 };
    }
    if (pos === 0) return { ty: 0,   scale: 1,    zi: 3, op: 1 };
    if (pos === 1) return { ty: -20, scale: 0.95, zi: 2, op: 1 };
    return              { ty: -44, scale: 0.9,  zi: 1, op: 1 };
  }

  const WORK_EXP = [
    {
      role: "Returns Data Admin",
      company: "Alloga (Cencora / UDG Healthcare)",
      period: "March 2025 – Present",
      tags: ["Excel","Power BI","PowerPoint","Data Analysis","Reporting"],
      bullets: [
        "Generate data-driven reports using Excel, Power BI, and PowerPoint to track returns processing metrics, supporting management decision-making with actionable insights.",
        "Streamline returns administration workflows through data analysis, identifying process inefficiencies and contributing to improved operational accuracy across the supply chain.",
      ],
    },
    {
      role: "Data Scientist",
      company: "Thor Explorations, Nigeria",
      period: "2021 – 2023",
      tags: ["Python","Scikit-learn","SQL","Power BI","Anomaly Detection"],
      bullets: [
        "Developed Python and Scikit-learn models for anomaly detection and predictive analysis of laboratory assay data across 3 project sites, reducing manual processing time by 35%.",
        "Designed and built a centralised database for 3 regional projects using Python and SQL, improving data retrieval efficiency by 58%.",
        "Built automated Power BI reports with scheduled refreshes, replacing manual reporting and saving approximately 8 hours per week.",
      ],
    },
  ];

  useEffect(() => {
    const fn = () => {
      setScrolled(window.scrollY > 60);
      const sections = ["home","about","experience","projects","articles","skills","contact"];
      for (const id of sections) {
        const el = document.getElementById(id);
        if (el) {
          const rect = el.getBoundingClientRect();
          if (rect.top <= 100 && rect.bottom >= 100) {
            setActiveSection(id.charAt(0).toUpperCase() + id.slice(1));
            break;
          }
        }
      }
    };
    window.addEventListener("scroll", fn);
    return () => window.removeEventListener("scroll", fn);
  }, []);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => { if (entry.isIntersecting) setStatsVisible(true); },
      { threshold: 0.2 }
    );
    if (statsRef.current) observer.observe(statsRef.current);
    return () => observer.disconnect();
  }, []);

  useEffect(() => {
    fetch("https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/@Fehintiti&api_key=public")
      .then(r => r.json())
      .then(data => {
        if (data.status === "ok" && data.items?.length) {
          const mapped = data.items.slice(0,3).map(item => ({
            title: item.title,
            date: new Date(item.pubDate).toLocaleDateString("en-GB", { month:"short", year:"numeric" }),
            desc: item.description.replace(/<[^>]*>/g,"").slice(0,160)+"...",
            url: item.link,
          }));
          setArticles(mapped);
        }
      })
      .catch(() => {});
  }, []);

  const scrollTo = (id) => {
    document.getElementById(id)?.scrollIntoView({ behavior:"smooth" });
    setMobileMenuOpen(false);
  };

  const NAV_LINKS = ["Home","About","Experience","Projects","Articles","Skills","Contact"];

  const photoSrc = window.PORTFOLIO_PHOTO ||
    (window.TOMISIN_JPG) ||
    "https://ui-avatars.com/api/?name=Tomisin+Okunlola&size=600&background=f0ebe3&color=222222&bold=true&font-size=0.28";

  const carouselImages = [
    photoSrc,
    "https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=600&q=80",
    "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=600&q=80",
  ];

  const c15 = useCounter("15",1600,statsVisible);
  const c3  = useCounter("3", 1600,statsVisible);
  const c6  = useCounter("6", 1600,statsVisible);

  const SOCIAL = [
    { icon:<GithubIcon />,   url:"https://github.com/Fehintiti",              label:"GitHub" },
    { icon:<LinkedInIcon />, url:"https://www.linkedin.com/in/fehintiti/",    label:"LinkedIn" },
    { icon:<MediumIcon />,   url:"https://medium.com/@Fehintiti",              label:"Medium" },
    { icon:<TwitterIcon />,  url:"https://twitter.com/fehintiti",              label:"Twitter" },
    { icon:<EmailIcon />,    url:"mailto:tokunlola12@gmail.com",               label:"Email" },
  ];

  return (
    <div style={{ fontFamily:"'DM Sans', sans-serif", background:"#FFFFFF", color:"#222222", overflowX:"hidden" }}>
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100;0,9..40,200;0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;0,9..40,900;1,9..40,300;1,9..40,400&display=swap');
        *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
        html { scroll-behavior: smooth; }

        @keyframes fadeUp   { from { opacity:0; transform:translateY(40px); } to { opacity:1; transform:translateY(0); } }
        @keyframes fadeIn   { from { opacity:0; } to { opacity:1; } }
        @keyframes slideLeft { from { opacity:0; transform:translateX(60px); } to { opacity:1; transform:translateX(0); } }
        @keyframes slideRight { from { opacity:0; transform:translateX(-60px); } to { opacity:1; transform:translateX(0); } }
        @keyframes pulseDot { 0%,100% { opacity:1; transform:scale(1); } 50% { opacity:0.4; transform:scale(0.7); } }
        @keyframes scrollDown { 0%,100% { transform:translateY(0); opacity:1; } 50% { transform:translateY(6px); opacity:0.5; } }

        .nav-link { transition:color 0.2s; cursor:pointer; }
        .nav-link:hover { color:#222222 !important; }
        .proj-card { transition:transform 0.32s ease, box-shadow 0.32s ease; cursor:pointer; }
        .proj-card:hover { transform:translateY(-8px); box-shadow:0 20px 60px rgba(0,0,0,0.12) !important; }
        .art-card { transition:transform 0.28s ease; }
        .art-card:hover { transform:translateY(-5px); }
        .exp-row:hover .exp-dot { background:#222222 !important; }
        .cat-btn:hover { background:#222222 !important; color:#fff !important; }
        .social-btn:hover { background:#222222 !important; color:#fff !important; border-color:#222222 !important; }
        .hire-link:hover { opacity:0.6; }
        .cta-link:hover { background:#222222 !important; color:#fff !important; }
        img { display:block; }

        /* ── TABLET ── */
        @media (max-width:900px) {
          .hero-sidebar { display:none !important; }
          .about-grid-3 { grid-template-columns:1fr 1fr !important; }
          .proj-feat-inner { flex-direction:column !important; }
          .nav-links-desktop { display:none !important; }
        }

        /* ── MOBILE ── */
        @media (max-width:600px) {
          .nav-links-desktop { display:none !important; }
          .about-grid-3 { grid-template-columns:1fr !important; }
          .exp-row-inner { flex-direction:column !important; gap:0.5rem !important; }
          .proj-feat-inner { flex-direction:column !important; }
          .proj-grid { grid-template-columns:1fr !important; }
          .art-grid { grid-template-columns:1fr !important; }
          .contact-inner { flex-direction:column !important; gap:2rem !important; }
          .skills-grid { gap:0.6rem !important; }

          /* Hero stacks: photo on top, text below */
          .hero-section { flex-direction:column !important; min-height:100vh !important; }
          .hero-sidebar { display:none !important; }
          .hero-photo {
            flex:0 0 55vw !important;
            width:100% !important;
            height:55vw !important;
            max-height:320px !important;
            padding:24px 20px 0 20px !important;
            order:-1;
          }
          .hero-photo img {
            border-radius:12px 12px 0 0 !important;
            height:100% !important;
            max-width:none !important;
            width:100% !important;
          }
          .hero-photo .hero-socials { display:none !important; }
          .hero-left {
            flex:1 !important;
            padding:28px 6% 40px 6% !important;
            justify-content:center !important;
          }
          .hero-stats { gap:1.8rem !important; margin-bottom:1.8rem !important; }
          .hero-h1 { font-size:clamp(3.5rem,16vw,5.5rem) !important; margin-bottom:1rem !important; }
        }
      `}</style>

      {/* ── NAV ─────────────────────────────────────────────── */}
      <nav style={{ position:"fixed", top:0, left:0, right:0, zIndex:300, height:68, display:"flex", alignItems:"center", justifyContent:"space-between", padding:"0 5%", background:scrolled?"rgba(255,255,255,0.97)":"transparent", backdropFilter:scrolled?"blur(24px)":"none", borderBottom:scrolled?"1px solid #EBEBEB":"none", transition:"all 0.35s ease" }}>
        <span onClick={()=>scrollTo("home")} style={{ fontSize:"1.25rem", fontWeight:700, color:"#222222", cursor:"pointer", letterSpacing:"-0.02em" }}>TO.</span>
        <div className="nav-links-desktop" style={{ display:"flex", gap:"2.5rem" }}>
          {NAV_LINKS.map(l=>(
            <span key={l} className="nav-link" onClick={()=>scrollTo(l.toLowerCase())} style={{ fontSize:"0.875rem", fontWeight:activeSection===l?600:400, color:activeSection===l?"#222222":"#7B7B7B", borderBottom:activeSection===l?"1.5px solid #222222":"1.5px solid transparent", paddingBottom:2 }}>{l}</span>
          ))}
        </div>
        <button className="hire-link" onClick={()=>scrollTo("contact")} style={{ fontSize:"0.85rem", fontWeight:500, background:"transparent", color:"#222222", border:"1px solid #222222", padding:"8px 22px", borderRadius:100, cursor:"pointer", transition:"opacity 0.2s", letterSpacing:"0.01em" }}>Hire Me ↗</button>
      </nav>

      {/* ── HERO ─────────────────────────────────────────────── */}
      <section id="home" ref={heroRef} className="hero-section" style={{ minHeight:"100vh", position:"relative", overflow:"hidden", background:"#FFFFFF", display:"flex", flexDirection:isMobile?"column":"row" }}>

        {/* Vertical sidebar label — desktop only */}
        {!isMobile && (
          <div className="hero-sidebar" style={{ position:"absolute", left:28, top:"50%", transform:"translateY(-50%) rotate(-90deg)", transformOrigin:"center center", whiteSpace:"nowrap", fontSize:"0.7rem", fontWeight:400, color:"#AAAAAA", letterSpacing:"0.14em", textTransform:"uppercase", zIndex:2, userSelect:"none" }}>
            Data Scientist · 2026
          </div>
        )}

        {/* Left/bottom content */}
        <div className="hero-left" style={{ flex:1, display:"flex", flexDirection:"column", justifyContent:isMobile?"flex-start":"space-between", padding:isMobile?"28px 6% 40px 6%":"140px 5% 60px 8%", position:"relative", zIndex:2, minWidth:0, gap:isMobile?"1.8rem":0 }}>

          {/* Stats row */}
          <div className="hero-stats" ref={statsRef} style={{ display:"flex", gap:isMobile?"1.8rem":"3.5rem", animation:heroIn?"fadeIn 0.8s ease 0.2s both":"none" }}>
            {[
              { n:c15, suffix:"+", label:"Projects built" },
              { n:c3,  suffix:"+", label:"Years experience" },
              { n:c6,  suffix:"",  label:"Articles published" },
            ].map((s,i)=>(
              <div key={i}>
                <div style={{ fontSize:isMobile?"1.8rem":"clamp(1.6rem,2.8vw,2.4rem)", fontWeight:300, color:"#222222", lineHeight:1, letterSpacing:"-0.03em" }}>{s.n}{s.suffix}</div>
                <div style={{ fontSize:"0.75rem", color:"#7B7B7B", marginTop:5, fontWeight:400 }}>{s.label}</div>
              </div>
            ))}
          </div>

          {/* Big heading + sub */}
          <div style={{ animation:heroIn?"fadeUp 0.9s cubic-bezier(0.22,0.68,0,1.05) 0.1s both":"none" }}>
            <h1 style={{ fontSize:isMobile?"clamp(3.8rem,18vw,5.5rem)":"clamp(5rem,13vw,11rem)", fontWeight:300, lineHeight:0.9, letterSpacing:"-0.04em", color:"#222222", marginBottom:"1rem" }}>Hello,</h1>
            <p style={{ fontSize:"clamp(0.95rem,1.4vw,1.1rem)", color:"#7B7B7B", fontWeight:400, letterSpacing:"0.01em" }}>— I'm Tomisin Okunlola, Data Scientist</p>
            <p style={{ fontSize:"0.9rem", color:"#AAAAAA", fontWeight:400, marginTop:"0.5rem", maxWidth:380 }}>ML models · Cloud pipelines · Business analytics</p>
            <div style={{ display:"flex", gap:"0.9rem", marginTop:"2rem", flexWrap:"wrap" }}>
              <button onClick={()=>scrollTo("projects")} style={{ fontSize:"0.9rem", fontWeight:500, background:"#222222", color:"#fff", border:"none", padding:"13px 30px", borderRadius:100, cursor:"pointer", letterSpacing:"0.01em" }}>View Work</button>
              <button onClick={()=>scrollTo("contact")} style={{ fontSize:"0.9rem", fontWeight:500, background:"transparent", color:"#222222", border:"1px solid #CCCCCC", padding:"12px 28px", borderRadius:100, cursor:"pointer", letterSpacing:"0.01em" }}>Let's Talk</button>
            </div>
          </div>

          {/* Scroll indicator */}
          {!isMobile && (
            <div style={{ display:"flex", alignItems:"center", gap:8, color:"#AAAAAA", fontSize:"0.78rem", fontWeight:400, animation:"scrollDown 2s ease-in-out infinite" }}>
              Scroll down ↓
            </div>
          )}

          {/* Mobile social row */}
          {isMobile && (
            <div style={{ display:"flex", gap:10, flexWrap:"wrap" }}>
              {SOCIAL.map((s,i)=>(
                <a key={i} href={s.url} target="_blank" rel="noreferrer" className="social-btn" style={{ width:40, height:40, borderRadius:"50%", background:"#F8F8F8", border:"1px solid #E8E8E8", display:"flex", alignItems:"center", justifyContent:"center", color:"#222222", textDecoration:"none" }}>{s.icon}</a>
              ))}
            </div>
          )}
        </div>

        {/* Photo — right on desktop, top on mobile via order:-1 */}
        <div className="hero-photo" style={isMobile
          ? { width:"100%", height:300, flexShrink:0, order:-1, overflow:"hidden", display:"flex", alignItems:"flex-end", justifyContent:"center", background:"#F0EBE3", padding:"24px 20px 0 20px", animation:heroIn?"fadeIn 1s ease 0.3s both":"none" }
          : { flex:"0 0 46%", position:"relative", overflow:"hidden", animation:heroIn?"fadeIn 1s ease 0.3s both":"none", display:"flex", alignItems:"flex-end", justifyContent:"center", background:"#F0EBE3", padding:"60px 40px 0 40px" }
        }>
          <img src={photoSrc} alt="Tomisin Okunlola" style={isMobile
            ? { width:"100%", maxWidth:280, height:"100%", objectFit:"cover", objectPosition:"50% 8%", borderRadius:"12px 12px 0 0", display:"block" }
            : { width:"100%", maxWidth:440, height:"90%", objectFit:"cover", objectPosition:"50% 8%", borderRadius:"16px 16px 0 0", display:"block" }
          } />
          {!isMobile && (
            <div className="hero-socials" style={{ position:"absolute", bottom:40, left:40, display:"flex", gap:10 }}>
              {SOCIAL.map((s,i)=>(
                <a key={i} href={s.url} target="_blank" rel="noreferrer" className="social-btn" style={{ width:38, height:38, borderRadius:"50%", background:"rgba(255,255,255,0.9)", border:"1px solid #E8E8E8", display:"flex", alignItems:"center", justifyContent:"center", color:"#222222", textDecoration:"none", transition:"all 0.2s", backdropFilter:"blur(8px)" }}>{s.icon}</a>
              ))}
            </div>
          )}
        </div>
      </section>

      {/* ── ABOUT ─────────────────────────────────────────────── */}
      <section id="about" ref={aboutRef} style={{ background:"#F8F8F8", padding:isMobile?"4rem 6%":"8rem 5%" }}>
        <div style={{ maxWidth:1200, margin:"0 auto" }}>
          <div className="about-grid-3" style={{ display:"grid", gridTemplateColumns:isMobile?"1fr":isTablet?"1fr 1fr":"1fr 1fr 1fr", gap:isMobile?"2rem":"3rem", alignItems:"start" }}>

            {/* Left: text */}
            <div style={{ opacity:aboutIn?1:0, transform:aboutIn?"translateX(0)":"translateX(-40px)", transition:"opacity 0.8s ease, transform 0.8s ease" }}>
              <p style={{ fontSize:"0.7rem", fontWeight:500, color:"#AAAAAA", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1.25rem" }}>About Me</p>
              <h2 style={{ fontSize:"clamp(2rem,3.5vw,3rem)", fontWeight:300, color:"#222222", lineHeight:1.15, letterSpacing:"-0.03em", marginBottom:"1.75rem" }}>Data Scientist.<br/>Problem Solver.</h2>
              <p style={{ fontSize:"0.97rem", color:"#7B7B7B", lineHeight:1.85, marginBottom:"1.25rem" }}>MSc in Big Data Analytics. 3+ years of experience across geoscience, logistics, and pharmaceutical supply chain.</p>
              <p style={{ fontSize:"0.97rem", color:"#7B7B7B", lineHeight:1.85, marginBottom:"2.5rem" }}>I build predictive models, design interactive dashboards, and manage end-to-end data projects — proficient in Python, SQL, Power BI, and cloud pipelines.</p>
              <div style={{ display:"flex", flexDirection:"column", gap:"1rem" }}>
                {[
                  "End-to-end ML model development and deployment",
                  "Serverless cloud data pipelines at scale",
                  "Business intelligence that drives decisions",
                ].map((pt,i)=>(
                  <div key={i} style={{ display:"flex", alignItems:"flex-start", gap:12 }}>
                    <div style={{ width:24, height:24, borderRadius:"50%", background:"#222222", display:"flex", alignItems:"center", justifyContent:"center", flexShrink:0, marginTop:1 }}>
                      <svg viewBox="0 0 12 12" width="10" height="10" fill="none"><path d="M2 6l3 3 5-5" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
                    </div>
                    <p style={{ fontSize:"0.9rem", color:"#7B7B7B", lineHeight:1.6 }}>{pt}</p>
                  </div>
                ))}
              </div>
            </div>

            {/* Center: stat card + 3D carousel */}
            <div style={{ opacity:aboutIn?1:0, transform:aboutIn?"translateY(0)":"translateY(40px)", transition:"opacity 0.8s ease 0.15s, transform 0.8s ease 0.15s" }}>
              <div style={{ background:"#FFFFFF", borderRadius:20, padding:"2.5rem", boxShadow:"0 2px 24px rgba(0,0,0,0.06)", marginBottom:"1.5rem" }}>
                <svg viewBox="0 0 32 32" width="32" height="32" fill="none" style={{ marginBottom:"1.25rem" }}><circle cx="16" cy="16" r="15" stroke="#222222" strokeWidth="1.5"/><path d="M9 16a7 7 0 0014 0" stroke="#222222" strokeWidth="1.5" strokeLinecap="round"/><circle cx="11" cy="12" r="1.5" fill="#222222"/><circle cx="21" cy="12" r="1.5" fill="#222222"/></svg>
                <div style={{ fontSize:"clamp(2.8rem,5vw,4rem)", fontWeight:300, color:"#222222", letterSpacing:"-0.04em", lineHeight:1 }}>35%</div>
                <p style={{ fontSize:"0.9rem", color:"#7B7B7B", lineHeight:1.65, marginTop:"0.9rem" }}>Reduction in manual processing time achieved at Thor Explorations through ML model automation</p>
              </div>
              {/* 3D Image Carousel */}
              <div style={{ position:"relative", height:220, perspective:"900px", marginTop:"1.5rem", overflow:"visible" }}>
                {carouselImages.map((src, i) => {
                  const total = 3;
                  const isActive = i === carouselIdx;
                  const isLeft  = i === (carouselIdx - 1 + total) % total;
                  const style = isActive
                    ? { transform:"translateX(0px) translateY(0px) scale(1) rotateY(0deg)", opacity:1, zIndex:3, boxShadow:"0 12px 40px rgba(0,0,0,0.18)" }
                    : isLeft
                    ? { transform:"translateX(-52px) translateY(-28px) scale(0.8) rotateY(14deg)", opacity:0.75, zIndex:2, boxShadow:"0 6px 20px rgba(0,0,0,0.1)" }
                    : { transform:"translateX(52px) translateY(-28px) scale(0.8) rotateY(-14deg)", opacity:0.75, zIndex:2, boxShadow:"0 6px 20px rgba(0,0,0,0.1)" };
                  return (
                    <img key={i} src={src} alt="" onClick={() => setCarouselIdx(i)}
                      style={{ position:"absolute", inset:0, width:"100%", height:"100%", objectFit:"cover", objectPosition:"top center", borderRadius:16, cursor:"pointer", transition:"all 0.8s cubic-bezier(0.4,2,0.3,1)", ...style }}
                    />
                  );
                })}
                <div style={{ position:"absolute", bottom:-22, left:"50%", transform:"translateX(-50%)", display:"flex", gap:6, zIndex:10 }}>
                  {[0,1,2].map(i => (
                    <div key={i} onClick={() => setCarouselIdx(i)} style={{ width:6, height:6, borderRadius:"50%", background:i===carouselIdx?"#222222":"#DDDDDD", cursor:"pointer", transition:"background 0.3s" }} />
                  ))}
                </div>
              </div>
            </div>

            {/* Right: second stat + bullet points */}
            <div style={{ opacity:aboutIn?1:0, transform:aboutIn?"translateX(0)":"translateX(40px)", transition:"opacity 0.8s ease 0.3s, transform 0.8s ease 0.3s" }}>
              <div style={{ background:"#FFFFFF", borderRadius:20, padding:"2rem", boxShadow:"0 2px 24px rgba(0,0,0,0.06)", marginBottom:"2rem", display:"flex", gap:"1.5rem", alignItems:"center" }}>
                <img src={photoSrc} alt="Tomisin" style={{ width:64, height:64, borderRadius:12, objectFit:"cover", objectPosition:"top", flexShrink:0 }} />
                <div>
                  <div style={{ fontSize:"2rem", fontWeight:300, color:"#222222", letterSpacing:"-0.03em", lineHeight:1 }}>58%</div>
                  <p style={{ fontSize:"0.82rem", color:"#7B7B7B", marginTop:4, lineHeight:1.5 }}>DB efficiency improvement via centralised pipeline</p>
                </div>
              </div>
              <div style={{ display:"flex", flexDirection:"column", gap:"1.5rem" }}>
                {[
                  { title:"University of Derby", sub:"MSc Big Data Analytics — Distinction, 2023–2024" },
                  { title:"University of Lagos", sub:"BSc Geoscience, Geology — 2015–2020" },
                  { title:"Open to Opportunities", sub:"UK · Remote · Canada relocation" },
                ].map((item,i)=>(
                  <div key={i} style={{ paddingLeft:"1rem", borderLeft:"2px solid #E8E8E8" }}>
                    <div style={{ fontSize:"0.9rem", fontWeight:600, color:"#222222", marginBottom:3 }}>{item.title}</div>
                    <div style={{ fontSize:"0.82rem", color:"#7B7B7B" }}>{item.sub}</div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* ── EXPERIENCE ──────────────────────────────────────────── */}
      <section id="experience" ref={expRef} style={{ background:"#FFFFFF", padding:"8rem 5%" }}>
        <div style={{ maxWidth:1200, margin:"0 auto" }}>
          <div style={{ display:"flex", alignItems:"flex-end", justifyContent:"space-between", marginBottom:"4rem", flexWrap:"wrap", gap:"1.5rem" }}>
            <div style={{ opacity:expIn?1:0, transform:expIn?"translateY(0)":"translateY(30px)", transition:"opacity 0.8s, transform 0.8s" }}>
              <p style={{ fontSize:"0.7rem", fontWeight:500, color:"#AAAAAA", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1rem" }}>Career</p>
              <h2 style={{ fontSize:"clamp(2rem,4vw,3.5rem)", fontWeight:300, color:"#222222", lineHeight:1.1, letterSpacing:"-0.03em" }}>Where the work<br/>got done.</h2>
            </div>
            <p style={{ fontSize:"0.95rem", color:"#7B7B7B", maxWidth:400, lineHeight:1.8, opacity:expIn?1:0, transition:"opacity 0.8s ease 0.2s" }}>From mining operations in Nigeria to pharmaceutical supply chains in the UK — real roles, real data, measurable outcomes.</p>
          </div>

          <div style={{ borderTop:"1px solid #E8E8E8" }}>
            {WORK_EXP.map((job,i)=>(
              <div key={i} className="exp-row" style={{ borderBottom:"1px solid #E8E8E8", padding:"3rem 0", opacity:expIn?1:0, transform:expIn?"translateY(0)":"translateY(30px)", transition:`opacity 0.7s ease ${0.1+i*0.18}s, transform 0.7s ease ${0.1+i*0.18}s` }}>
                <div className="exp-row-inner" style={{ display:"flex", gap:"4rem", alignItems:"flex-start" }}>
                  {/* Left meta */}
                  <div style={{ flexShrink:0, width:200 }}>
                    <div style={{ fontSize:"0.72rem", fontWeight:500, color:"#AAAAAA", letterSpacing:"0.1em", textTransform:"uppercase", marginBottom:"0.5rem" }}>{job.period}</div>
                    <div className="exp-dot" style={{ width:8, height:8, borderRadius:"50%", background:"#CCCCCC", margin:"0.75rem 0", transition:"background 0.2s" }}></div>
                    <div style={{ display:"flex", flexWrap:"wrap", gap:5, marginTop:"0.75rem" }}>
                      {job.tags.map(t=>(
                        <span key={t} style={{ fontSize:"0.62rem", fontWeight:500, color:"#7B7B7B", background:"#F8F8F8", padding:"3px 10px", borderRadius:100, letterSpacing:"0.03em" }}>{t}</span>
                      ))}
                    </div>
                  </div>
                  {/* Right content */}
                  <div style={{ flex:1 }}>
                    <h3 style={{ fontSize:"clamp(1.3rem,2.2vw,1.8rem)", fontWeight:400, color:"#222222", marginBottom:"0.35rem", letterSpacing:"-0.02em" }}>{job.role}</h3>
                    <p style={{ fontSize:"0.9rem", color:"#AAAAAA", fontWeight:400, marginBottom:"1.5rem" }}>{job.company}</p>
                    <div style={{ display:"flex", flexDirection:"column", gap:"0.85rem" }}>
                      {job.bullets.map((b,bi)=>(
                        <div key={bi} style={{ display:"flex", alignItems:"flex-start", gap:12 }}>
                          <div style={{ width:5, height:5, borderRadius:"50%", background:"#CCCCCC", flexShrink:0, marginTop:8 }}></div>
                          <p style={{ fontSize:"0.9rem", color:"#7B7B7B", lineHeight:1.75 }}>{b}</p>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* ── PROJECTS ──────────────────────────────────────────── */}
      <section id="projects" ref={projRef} style={{ background:"#F8F8F8", padding:"8rem 5%" }}>
        <div style={{ maxWidth:1200, margin:"0 auto" }}>
          <div style={{ display:"flex", alignItems:"flex-end", justifyContent:"space-between", marginBottom:"3.5rem", flexWrap:"wrap", gap:"1.5rem" }}>
            <div style={{ opacity:projIn?1:0, transform:projIn?"translateY(0)":"translateY(30px)", transition:"opacity 0.8s, transform 0.8s" }}>
              <p style={{ fontSize:"0.7rem", fontWeight:500, color:"#AAAAAA", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1rem" }}>Selected Work</p>
              <h2 style={{ fontSize:"clamp(2rem,4vw,3.5rem)", fontWeight:300, color:"#222222", lineHeight:1.1, letterSpacing:"-0.03em" }}>Real data.<br/>Measurable results.</h2>
            </div>
            <div style={{ display:"flex", gap:8, flexWrap:"wrap", opacity:projIn?1:0, transition:"opacity 0.8s ease 0.2s" }}>
              {Object.keys(PROJECTS).map(cat=>(
                <button key={cat} className="cat-btn" onClick={()=>setActiveCategory(cat)} style={{ fontSize:"0.82rem", fontWeight:500, padding:"8px 20px", borderRadius:100, border:"1px solid", cursor:"pointer", transition:"all 0.22s", background:activeCategory===cat?"#222222":"transparent", color:activeCategory===cat?"#fff":"#7B7B7B", borderColor:activeCategory===cat?"#222222":"#D8D8D8", letterSpacing:"0.01em" }}>
                  {cat}
                </button>
              ))}
            </div>
          </div>

          {/* Featured card */}
          {PROJECTS[activeCategory][0] && (
            <div style={{ borderRadius:20, overflow:"hidden", marginBottom:"1.5rem", background:"#222222", opacity:projIn?1:0, transform:projIn?"translateY(0)":"translateY(36px)", transition:"opacity 0.8s ease 0.1s, transform 0.8s ease 0.1s" }}>
              <div className="proj-feat-inner" style={{ display:"flex", height:340 }}>
                <div style={{ flex:1, padding:"3rem 3.5rem", display:"flex", flexDirection:"column", justifyContent:"space-between" }}>
                  <div>
                    <p style={{ fontSize:"0.65rem", fontWeight:600, color:"#7B7B7B", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1rem" }}>Featured Project</p>
                    <h3 style={{ fontSize:"clamp(1.4rem,2.8vw,2.2rem)", fontWeight:400, color:"#FFFFFF", lineHeight:1.2, letterSpacing:"-0.02em", marginBottom:"1rem" }}>{PROJECTS[activeCategory][0].title}</h3>
                    <p style={{ fontSize:"0.9rem", color:"#7B7B7B", lineHeight:1.75, display:"-webkit-box", WebkitLineClamp:2, WebkitBoxOrient:"vertical", overflow:"hidden" }}>{PROJECTS[activeCategory][0].desc}</p>
                  </div>
                  <div>
                    <div style={{ display:"flex", gap:6, flexWrap:"wrap", marginBottom:"1.5rem" }}>
                      {PROJECTS[activeCategory][0].stack.slice(0,5).map(t=>(
                        <span key={t} style={{ fontSize:"0.62rem", fontWeight:500, padding:"4px 12px", borderRadius:100, background:"rgba(255,255,255,0.08)", color:"#AAAAAA", letterSpacing:"0.04em" }}>{t}</span>
                      ))}
                    </div>
                    <div style={{ display:"flex", gap:12 }}>
                      {PROJECTS[activeCategory][0].live && <a href={PROJECTS[activeCategory][0].live} target="_blank" rel="noreferrer" style={{ fontSize:"0.85rem", fontWeight:600, color:"#FFFFFF", textDecoration:"none", display:"flex", alignItems:"center", gap:5 }}>Live App <ArrowIcon /></a>}
                      {PROJECTS[activeCategory][0].github && <a href={PROJECTS[activeCategory][0].github} target="_blank" rel="noreferrer" style={{ fontSize:"0.85rem", fontWeight:500, color:"#7B7B7B", textDecoration:"none", display:"flex", alignItems:"center", gap:5 }}>GitHub <ArrowIcon /></a>}
                      {PROJECTS[activeCategory][0].linkedin && <a href={PROJECTS[activeCategory][0].linkedin} target="_blank" rel="noreferrer" style={{ fontSize:"0.85rem", fontWeight:600, color:"#FFFFFF", textDecoration:"none", display:"flex", alignItems:"center", gap:5 }}>View Project <ArrowIcon /></a>}
                    </div>
                  </div>
                </div>
                <div style={{ flex:"0 0 42%", overflow:"hidden", position:"relative" }}>
                  <div style={{ position:"absolute", inset:0, background:"linear-gradient(to right,#222222 0%,transparent 25%)", zIndex:1 }}/>
                  <img src={PROJECTS[activeCategory][0].img} alt={PROJECTS[activeCategory][0].title} style={{ width:"100%", height:"100%", objectFit:"cover", opacity:0.7 }}/>
                </div>
              </div>
            </div>
          )}

          {/* Grid cards */}
          <div style={{ display:"grid", gridTemplateColumns:isMobile?"1fr":isTablet?"1fr 1fr":"1fr 1fr 1fr", gap:"1.25rem", marginBottom:"2.5rem" }}>
            {PROJECTS[activeCategory].slice(1,3).map((p,i)=>(
              <div key={i} className="proj-card" style={{ background:"#FFFFFF", borderRadius:16, overflow:"hidden", border:"1px solid #EBEBEB", display:"flex", flexDirection:"column", opacity:projIn?1:0, transform:projIn?"translateY(0)":"translateY(36px)", transition:`opacity 0.7s ease ${0.22+i*0.12}s, transform 0.7s ease ${0.22+i*0.12}s` }}>
                <div style={{ height:180, overflow:"hidden", position:"relative" }}>
                  <img src={p.img} alt={p.title} style={{ width:"100%", height:"100%", objectFit:"cover", transition:"transform 0.5s ease" }}/>
                </div>
                <div style={{ padding:"1.5rem", flex:1, display:"flex", flexDirection:"column", gap:"0.7rem" }}>
                  <h4 style={{ fontSize:"1.05rem", fontWeight:500, color:"#222222", lineHeight:1.35 }}>{p.title}</h4>
                  <p style={{ fontSize:"0.85rem", color:"#7B7B7B", lineHeight:1.75, flex:1 }}>{p.desc}</p>
                  <div style={{ display:"flex", gap:5, flexWrap:"wrap", paddingTop:"0.75rem", borderTop:"1px solid #F0F0F0" }}>
                    {p.stack.slice(0,3).map(t=>(<span key={t} style={{ fontSize:"0.6rem", fontWeight:500, padding:"3px 10px", borderRadius:100, background:"#F8F8F8", color:"#7B7B7B" }}>{t}</span>))}
                  </div>
                  <div style={{ display:"flex", gap:12, marginTop:2 }}>
                    {p.github && <a href={p.github} target="_blank" rel="noreferrer" style={{ fontSize:"0.82rem", fontWeight:600, color:"#222222", textDecoration:"none", display:"flex", alignItems:"center", gap:4 }}>GitHub <ArrowIcon /></a>}
                    {p.live && <a href={p.live} target="_blank" rel="noreferrer" style={{ fontSize:"0.82rem", fontWeight:500, color:"#7B7B7B", textDecoration:"none", display:"flex", alignItems:"center", gap:4 }}>Live <ArrowIcon /></a>}
                    {p.linkedin && <a href={p.linkedin} target="_blank" rel="noreferrer" style={{ fontSize:"0.82rem", fontWeight:600, color:"#222222", textDecoration:"none", display:"flex", alignItems:"center", gap:4 }}>View Project <ArrowIcon /></a>}
                  </div>
                </div>
              </div>
            ))}
          </div>

          {/* See all on GitHub */}
          <div style={{ textAlign:"center", paddingTop:"2rem", borderTop:"1px solid #E8E8E8", opacity:projIn?1:0, transition:"opacity 0.7s ease 0.5s" }}>
            <p style={{ fontSize:"0.9rem", color:"#AAAAAA", marginBottom:"1.25rem" }}>15+ projects across ML, cloud, computer vision and business intelligence.</p>
            <a href="https://github.com/Fehintiti" target="_blank" rel="noreferrer" className="cta-link" style={{ fontSize:"0.88rem", fontWeight:500, padding:"11px 28px", borderRadius:100, border:"1px solid #222222", color:"#222222", textDecoration:"none", display:"inline-flex", alignItems:"center", gap:8, transition:"all 0.2s" }}><GithubIcon /> See all on GitHub</a>
          </div>
        </div>
      </section>

      {/* ── ARTICLES ──────────────────────────────────────────── */}
      <section id="articles" ref={artRef} style={{ background:"#FFFFFF", padding:"8rem 5%" }}>
        <div style={{ maxWidth:1200, margin:"0 auto" }}>
          <div style={{ display:"flex", alignItems:"flex-end", justifyContent:"space-between", marginBottom:"4rem", flexWrap:"wrap", gap:"1.5rem" }}>
            <div style={{ opacity:artIn?1:0, transform:artIn?"translateY(0)":"translateY(30px)", transition:"opacity 0.8s, transform 0.8s" }}>
              <p style={{ fontSize:"0.7rem", fontWeight:500, color:"#AAAAAA", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1rem" }}>Writing</p>
              <h2 style={{ fontSize:"clamp(2rem,4vw,3.5rem)", fontWeight:300, color:"#222222", lineHeight:1.1, letterSpacing:"-0.03em" }}>The work,<br/>documented.</h2>
            </div>
            <a href="https://medium.com/@Fehintiti" target="_blank" rel="noreferrer" className="cta-link" style={{ fontSize:"0.85rem", fontWeight:500, padding:"10px 24px", borderRadius:100, border:"1px solid #D8D8D8", color:"#7B7B7B", textDecoration:"none", whiteSpace:"nowrap", flexShrink:0, transition:"all 0.2s", opacity:artIn?1:0 }}>View all on Medium ↗</a>
          </div>

          {/* ── Stacked Article Deck ── */}
          <div style={{ opacity:artIn?1:0, transform:artIn?"translateY(0)":"translateY(36px)", transition:"opacity 0.8s ease 0.15s, transform 0.8s ease 0.15s" }}>
            <div style={{ position:"relative", height:300, width:"100%", maxWidth:560, margin:"0 auto" }}>
              {deckArts.map((artIdx, pos) => {
                const art = STATIC_ARTICLES[artIdx];
                const { ty, scale, zi, op } = getDeckStyle(pos);
                return (
                  <div key={artIdx} style={{
                    position:"absolute", bottom:0, left:"50%",
                    transform:`translateX(-50%) translateY(${ty}px) scale(${scale})`,
                    width: isMobile ? "88%" : 520,
                    height: 260,
                    borderRadius: 20,
                    background: "#FFFFFF",
                    border: "1px solid #EBEBEB",
                    boxShadow: "0 4px 32px rgba(0,0,0,0.07)",
                    zIndex: zi, opacity: op,
                    transition: "transform 0.5s cubic-bezier(0.4,0,0.2,1), opacity 0.42s ease",
                    overflow: "hidden",
                    padding: "1.8rem 2rem",
                    display: "flex", flexDirection: "column",
                  }}>
                    <div style={{ fontSize:"3rem", fontWeight:300, color:"rgba(0,0,0,0.05)", lineHeight:1, userSelect:"none" }}>0{artIdx + 1}</div>
                    <div style={{ display:"flex", alignItems:"center", gap:8, marginTop:"0.4rem" }}>
                      <span style={{ fontSize:"0.62rem", color:"#AAAAAA", fontWeight:500, letterSpacing:"0.1em" }}>{art.date}</span>
                      {artIdx === 0 && <span style={{ fontSize:"0.58rem", fontWeight:700, letterSpacing:"0.1em", background:"#222222", color:"#fff", padding:"2px 8px", borderRadius:100 }}>FEATURED</span>}
                    </div>
                    <h3 style={{ fontSize:"0.97rem", fontWeight:600, color:"#222222", lineHeight:1.4, marginTop:"0.7rem", flex:1 }}>{art.title}</h3>
                    <p style={{ fontSize:"0.8rem", color:"#7B7B7B", lineHeight:1.7, overflow:"hidden", display:"-webkit-box", WebkitLineClamp:2, WebkitBoxOrient:"vertical", marginTop:"0.4rem" }}>{art.desc}</p>
                    <a href={art.url} target="_blank" rel="noreferrer" style={{ display:"inline-flex", alignItems:"center", gap:5, fontSize:"0.8rem", fontWeight:600, color:"#222222", textDecoration:"none", marginTop:"1rem", borderTop:"1px solid #F0F0F0", paddingTop:"0.8rem" }}>
                      Read on Medium <ArrowIcon />
                    </a>
                  </div>
                );
              })}
            </div>

            {/* Controls */}
            <div style={{ display:"flex", alignItems:"center", justifyContent:"center", gap:"1.5rem", marginTop:"2rem" }}>
              <span style={{ fontSize:"0.78rem", color:"#AAAAAA", fontWeight:500 }}>
                {deckArts[0] + 1} / {STATIC_ARTICLES.length}
              </span>
              <button onClick={nextDeckCard} disabled={deckExiting} style={{ display:"flex", alignItems:"center", gap:8, fontSize:"0.85rem", fontWeight:500, background:"#222222", color:"#fff", border:"none", padding:"10px 24px", borderRadius:100, cursor:deckExiting?"default":"pointer", opacity:deckExiting?0.5:1, transition:"opacity 0.2s" }}>
                Next article <ArrowIcon />
              </button>
              <div style={{ display:"flex", gap:5 }}>
                {STATIC_ARTICLES.map((_,i) => (
                  <div key={i} style={{ width:5, height:5, borderRadius:"50%", background:i===deckArts[0]?"#222222":"#DDDDDD", transition:"background 0.3s" }} />
                ))}
              </div>
            </div>
          </div>

          <div style={{ textAlign:"center", marginTop:"3rem", paddingTop:"2.5rem", borderTop:"1px solid #E8E8E8", opacity:artIn?1:0, transition:"opacity 0.8s ease 0.5s" }}>
            <p style={{ fontSize:"0.9rem", color:"#AAAAAA", marginBottom:"1.25rem" }}>6 published articles — all projects, walkthroughs, and case studies.</p>
            <a href="https://medium.com/@Fehintiti" target="_blank" rel="noreferrer" className="cta-link" style={{ fontSize:"0.88rem", fontWeight:500, padding:"11px 28px", borderRadius:100, border:"1px solid #222222", color:"#222222", textDecoration:"none", display:"inline-flex", alignItems:"center", gap:6, transition:"all 0.2s" }}><MediumIcon /> See all articles on Medium</a>
          </div>
        </div>
      </section>

      {/* ── SKILLS ──────────────────────────────────────────────── */}
      <section id="skills" ref={skillRef} style={{ background:"#F8F8F8", padding:"8rem 5%" }}>
        <div style={{ maxWidth:1200, margin:"0 auto" }}>
          <div style={{ marginBottom:"3.5rem", opacity:skillIn?1:0, transform:skillIn?"translateY(0)":"translateY(30px)", transition:"opacity 0.8s, transform 0.8s" }}>
            <p style={{ fontSize:"0.7rem", fontWeight:500, color:"#AAAAAA", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1rem" }}>Stack</p>
            <h2 style={{ fontSize:"clamp(2rem,4vw,3.5rem)", fontWeight:300, color:"#222222", lineHeight:1.1, letterSpacing:"-0.03em" }}>The tools I use<br/>to build and ship.</h2>
          </div>
          <SkillBubbles />
        </div>
      </section>

      {/* ── CONTACT ─────────────────────────────────────────────── */}
      <section id="contact" ref={contactRef} style={{ background:"#222222", padding:"8rem 5%", position:"relative", overflow:"hidden" }}>
        <div style={{ position:"absolute", top:"-30%", right:"-10%", width:600, height:600, borderRadius:"50%", background:"rgba(255,255,255,0.03)", pointerEvents:"none" }}/>
        <div style={{ maxWidth:1100, margin:"0 auto", position:"relative", zIndex:1 }}>
          <div className="contact-inner" style={{ display:"grid", gridTemplateColumns:isMobile?"1fr":"1fr 1fr", gap:isMobile?"2.5rem":"5rem", alignItems:"center" }}>
            <div style={{ opacity:contactIn?1:0, transform:contactIn?"translateY(0)":"translateY(36px)", transition:"opacity 0.8s, transform 0.8s" }}>
              <p style={{ fontSize:"0.7rem", fontWeight:500, color:"#555555", letterSpacing:"0.14em", textTransform:"uppercase", marginBottom:"1.25rem" }}>Contact</p>
              <h2 style={{ fontSize:"clamp(2rem,4vw,3.5rem)", fontWeight:300, color:"#FFFFFF", lineHeight:1.1, letterSpacing:"-0.03em", marginBottom:"1.5rem" }}>Let's build something<br/>that matters.</h2>
              <p style={{ fontSize:"0.97rem", color:"#7B7B7B", lineHeight:1.85, maxWidth:420 }}>Open to data science and data engineering roles. Available for collaborations, consulting, and technical conversations.</p>
            </div>
            <div style={{ opacity:contactIn?1:0, transform:contactIn?"translateY(0)":"translateY(36px)", transition:"opacity 0.8s ease 0.2s, transform 0.8s ease 0.2s" }}>
              <div style={{ display:"flex", flexDirection:"column", gap:"1.25rem", marginBottom:"2.5rem" }}>
                {[
                  { label:"Email",    val:"tokunlola12@gmail.com",  href:"mailto:tokunlola12@gmail.com" },
                  { label:"LinkedIn", val:"@fehintiti",              href:"https://www.linkedin.com/in/fehintiti/" },
                  { label:"GitHub",   val:"@Fehintiti",              href:"https://github.com/Fehintiti" },
                  { label:"Medium",   val:"@Fehintiti",              href:"https://medium.com/@Fehintiti" },
                ].map((item,i)=>(
                  <a key={i} href={item.href} target="_blank" rel="noreferrer" style={{ display:"flex", alignItems:"center", justifyContent:"space-between", padding:"1.1rem 1.4rem", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.08)", borderRadius:12, textDecoration:"none", transition:"background 0.2s" }}>
                    <div>
                      <div style={{ fontSize:"0.65rem", color:"#555555", fontWeight:500, letterSpacing:"0.1em", textTransform:"uppercase", marginBottom:3 }}>{item.label}</div>
                      <div style={{ fontSize:"0.9rem", color:"#FFFFFF", fontWeight:400 }}>{item.val}</div>
                    </div>
                    <ArrowIcon />
                  </a>
                ))}
              </div>
            </div>
          </div>
          <div style={{ borderTop:"1px solid rgba(255,255,255,0.08)", paddingTop:"2rem", marginTop:"1rem", display:"flex", justifyContent:"space-between", alignItems:"center", flexWrap:"wrap", gap:"1rem", opacity:contactIn?1:0, transition:"opacity 0.8s ease 0.4s" }}>
            <p style={{ fontSize:"0.8rem", color:"#444444" }}>© 2026 Tomisin Okunlola · Built with React</p>
            <div style={{ display:"flex", gap:10 }}>
              {SOCIAL.map((s,i)=>(
                <a key={i} href={s.url} target="_blank" rel="noreferrer" className="social-btn" style={{ width:36, height:36, borderRadius:"50%", border:"1px solid rgba(255,255,255,0.15)", display:"flex", alignItems:"center", justifyContent:"center", color:"#7B7B7B", textDecoration:"none", transition:"all 0.2s" }}>{s.icon}</a>
              ))}
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

const _root = ReactDOM.createRoot(document.getElementById('root'));
_root.render(React.createElement(Portfolio));
