// Alban — editorial portfolio
const { useState, useEffect, useRef } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "accentHue": 35,
  "ballStyle": "solid"
}/*EDITMODE-END*/;

// ---- Data ----
const PROJECTS = [
  {
    n: "01", year: "2026", title: "Moment.AI", priority: true, featured: true,
    desc: "AI-led contextual advertising built on emotional peaks, delivering 800+ integrations and measurable brand lift",
    videoUrl: "https://www.youtube.com/embed/qpPkGJRLYX4?autoplay=1",
    thumb: "https://img.youtube.com/vi/qpPkGJRLYX4/maxresdefault.jpg",
    cs: {
      problem: "Brand integrations were static and disconnected from narrative context.",
      approach: "Built an AI-led system using Gemini and worked across data science, traffic, and presentation teams to control the end-to-end integration pipeline. AI identified emotional peaks across GEC content, generating ~80 daily opportunities, from which high-impact moments were curated and executed.",
      outcome: [
        "800+ integrations delivered in one month",
        "Turnaround reduced from ~15 days to under 8 hours",
        "1.4x awareness, 1.6x recall, 1.9x purchase intent",
      ],
    },
  },
  {
    n: "02", year: "2023", title: "Disney Delicious (IKEA)", priority: true,
    desc: "Content-commerce IP for IKEA leveraging co-viewing, driving 270M+ views and household influence",
    videoUrl: "https://www.youtube.com/embed/txLwvdXAeDk?autoplay=1",
    thumb: "https://img.youtube.com/vi/txLwvdXAeDk/maxresdefault.jpg",
    cs: {
      problem: "IKEA needed to drive consideration for modular kitchens in a new market.",
      approach: "Built a content-commerce IP leveraging kids' content and co-viewing behaviour of mothers to influence household decision-making.",
      outcome: [
        "270M+ views across platforms",
        "Promax Asia Gold and Kyoorius Purple Elephant winner",
        "Positioned kids' content as an entry point into household consideration",
      ],
    },
  },
  {
    n: "03", year: "2022", title: "Don't Bite Your Nails Campaign", priority: true,
    desc: "Short-form behavioural storytelling designed for high recall and habit disruption",
    videoUrl: "https://www.youtube.com/embed/-Qarp3gcNlc?autoplay=1",
    thumb: "https://img.youtube.com/vi/-Qarp3gcNlc/maxresdefault.jpg",
    cs: {
      problem: "Health messaging for kids often lacks retention and recall.",
      approach: "Created short-form behavioural storytelling with strong visual hooks and tight pacing designed for high recall.",
      outcome: [
        "High recall-driven content designed for behaviour change",
        "Award-winning short-form impact storytelling",
      ],
    },
  },
  {
    n: "04", year: "2016", title: "Toonami Launch Campaign",
    desc: "₹5 Cr multi-platform launch with celebrity-led promos and nationwide reach",
    videoUrl: "https://www.youtube.com/embed/MWOtUjBKvko?autoplay=1",
    thumb: "https://img.youtube.com/vi/MWOtUjBKvko/maxresdefault.jpg",
    cs: {
      problem: "Needed to relaunch a youth-focused animation block as a full channel.",
      approach: "Built a multi-platform campaign using celebrity-led promos and high-frequency rollout strategy.",
      outcome: [
        "₹5 Cr campaign executed across TV and 500 cinema screens",
        "Strong youth reach and brand recall",
      ],
    },
  },
  {
    n: "05", year: "2025", title: "Star Parivaar Awards",
    desc: "Large-scale brand integrations within flagship GEC property, balancing storytelling with sponsor visibility",
    videoUrl: "https://www.youtube.com/embed/3agXoC2DzxU?autoplay=1",
    thumb: "https://img.youtube.com/vi/3agXoC2DzxU/maxresdefault.jpg",
    cs: {
      problem: "Integrating brands into a large-format GEC property without disrupting storytelling.",
      approach: "Designed narrative-aligned integrations within key emotional moments of the show.",
      outcome: [
        "Delivered 120% of revenue target",
        "Scaled brand presence within high-engagement television",
      ],
    },
  },
  {
    n: "06", year: "2025", title: "Quick Style Crew Integration",
    desc: "Executed international talent integration within 3 days, converting deal into high-impact on-air moment",
    videoUrl: "https://www.youtube.com/embed/OBdpSPLtdBc?autoplay=1",
    thumb: "https://img.youtube.com/vi/OBdpSPLtdBc/maxresdefault.jpg",
    cs: {
      problem: "Brand required a high-impact integration within tight turnaround timelines.",
      approach: "Executed international talent integration within 3 days by aligning production, brand, and on-ground execution.",
      outcome: [
        "Delivered a high-impact on-air performance moment",
        "Became a viral moment reshared by Quick Style Crew and multiple digital platforms",
      ],
    },
  },
  {
    n: "07", year: "2022", title: "Bhaagam Bhaag",
    desc: "Original kids IP scaled to 72 episodes with strong TV performance and digital traction",
    videoUrl: "https://www.youtube.com/embed/Av2YljfnMlM?autoplay=1",
    thumb: "https://img.youtube.com/vi/Av2YljfnMlM/maxresdefault.jpg",
    cs: {
      problem: "Need for a scalable original kids IP with consistent engagement.",
      approach: "Built and produced a 72-episode animated series, collaborating with leading creators Vaibhav Kumaresh and Arnab Choudhary, along with top studios including Cosmos Maya and Toonz.",
      outcome: [
        "Strong TV performance and digital traction",
        "Established as a repeatable and scalable IP",
      ],
    },
  },
  {
    n: "08", year: "2013", title: "MTV Coke Studio Season 2",
    desc: "Assistant direction on one of India's most iconic music formats, supporting multi-artist production at scale",
    videoUrl: "https://www.youtube.com/embed/1gukvtH_a3I?autoplay=1",
    thumb: "https://img.youtube.com/vi/1gukvtH_a3I/maxresdefault.jpg",
    cs: {
      problem: "Managing multi-artist production for a high-profile music format.",
      approach: "Supported direction, rehearsals, and live shoot coordination across episodes, working with multiple artists and production teams.",
      outcome: [
        "Contributed to one of India's most iconic music seasons with enduring recall",
      ],
    },
  },
];

const BRANDS = [
  { name: "Coca-Cola", src: "assets/logos/coca-cola.png",            h: 56 },
  { name: "Cadbury",   src: "assets/logos/cadbury.png",              h: 76 },
  { name: "HUL",       src: "assets/logos/hul.png",                  h: 70 },
  { name: "Colgate",   src: "assets/logos/colgate.svg",              h: 52 },
  { name: "Garnier",   src: "assets/logos/garnier.png",              h: 64 },
  { name: "Tata Sky",  src: "assets/logos/tata-sky.png",             h: 60 },
  { name: "Lifebuoy",  src: "assets/logos/lifebuoy.png",             h: 64 },
  { name: "Whisper",   src: "assets/logos/whisper.webp",             h: 56 },
  { name: "IKEA",      src: "assets/logos/ikea logo.png",            h: 56 },
  { name: "ITC",       src: "assets/logos/ITC_Limited_Logo.svg.png", h: 60 },
  { name: "Kelloggs",  src: "assets/logos/Kellogg's-Logo.svg",       h: 64 },
  { name: "Nivea",     src: "assets/logos/Nivea_Logo.png",           h: 52 },
];

const EXPERIENCE = [
  {
    co: "JioStar", period: "2023 — Present", role: "Ad Innovation Lead",
    summary: "Driving product-led monetization across a ₹3000 Cr+ ecosystem",
    bullets: [
      "Built and scaled AI-led formats like MegaBlast and Moment.AI",
      "Delivered measurable brand outcomes through contextual integrations and improved purchase intent",
    ],
  },
  {
    co: "Disney", period: "2018 — 2023", role: "Branded Content & Partnerships",
    summary: "Led branded content and integrations across multi-genre network",
    bullets: [
      "Delivered 120%+ revenue on flagship properties",
      "Built partnerships with Coca-Cola, Mondelez, HUL",
    ],
  },
  {
    co: "Turner", period: "2013 — 2018", role: "Content & Campaigns",
    summary: "Built content and campaigns across leading kids IPs",
    bullets: [
      "Led Toonami launch campaign (~₹5 Cr budget)",
      "Won APAC Innovation Challenge and secured $10,000 seed funding",
    ],
  },
];

const THINK = [
  {
    n: "01",
    title: "The problem with first episodes",
    hero: "The audience decides in minutes whether to care.",
    body: `Most shows do not lose you because the story is weak.
They lose you because they ask for patience you did not agree to.

It is like meeting someone who says,
I am interesting, just give me time.
You will not.

Everything after that just confirms the decision.`,
  },
  {
    n: "02",
    title: "People do not fit into segments. They leak.",
    hero: "Taste travels. Behaviour overlaps.",
    body: `We like clean buckets.
Gen Z. Millennials. Separate, defined.
Real life does not work like that.

People borrow from each other.
What looks like noise in data
is usually just life refusing to be sorted.`,
  },
  {
    n: "03",
    title: "Placement is like background music",
    hero: "Advertising works the same way.",
    body: `You do not notice the music in a café
until it matches your mood.
That is when it lands.

Not when it appears.
When it aligns with what you are already feeling.
Everything else is interruption wearing better clothes.`,
  },
  {
    n: "04",
    title: "Big brands do not introduce themselves",
    hero: "The product earns the trust.",
    body: `Nobody says,
I trust Procter and Gamble.
They say, I use Vicks. Or I buy Tide.

The parent stays invisible.
Like a good host,
you do not notice them, but the room works because of them.`,
  },
];

const GLOBE_PINS = [
  {
    key: "jiostar", label: "JioStar", lon: 78.96, lat: 20.59,
    co: "JioStar", period: "2023 — Present", role: "Ad Innovation Lead",
    summary: "Driving product-led monetization across a ₹3000 Cr+ ecosystem. Built and scaled AI-led formats like MegaBlast and Moment.AI.",
  },
  {
    key: "disney", label: "Disney", lon: -100, lat: 38,
    co: "Disney", period: "2018 — 2023", role: "Branded Content & Partnerships",
    summary: "Led branded content and integrations across a multi-genre network. Delivered 120%+ revenue on flagship properties.",
  },
  {
    key: "turner", label: "Turner", lon: 114.17, lat: 22.32,
    co: "Turner", period: "2013 — 2018", role: "Content & Campaigns",
    summary: "Built content and campaigns across leading kids IPs. Led Toonami launch and won APAC Innovation Challenge.",
  },
];

// Shared land geo cache — fetched once, reused by all globe instances
let _landCache = null;
let _landPromise = null;
function getLandGeo() {
  if (_landCache) return Promise.resolve(_landCache);
  if (!_landPromise) {
    _landPromise = fetch("https://unpkg.com/world-atlas@2.0.2/countries-110m.json")
      .then(r => r.json())
      .then(t => { _landCache = window.topojson.feature(t, t.objects.land); return _landCache; })
      .catch(() => null);
  }
  return _landPromise;
}

const THINK_TILTS = [
  "perspective(800px) rotateY(-4deg) rotateX(2deg) translateY(-6px)",
  "perspective(800px) rotateY(4deg) rotateX(-1deg) translateY(-6px)",
  "perspective(800px) rotateY(-3deg) rotateX(-2deg) translateY(-6px)",
  "perspective(800px) rotateY(3deg) rotateX(1deg) translateY(-6px)",
];

// ---- Reveal hook ----
function useReveal() {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const rect = el.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (rect.top < vh && rect.bottom > 0) { setSeen(true); return; }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setSeen(true); io.disconnect(); }
    }, { threshold: 0, rootMargin: "0px 0px -10% 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, seen];
}

function Reveal({ children, delay = 0, className = "", as = "div", ...rest }) {
  const [ref, seen] = useReveal();
  const Tag = as;
  return (
    <Tag ref={ref} className={`reveal ${seen ? "in" : ""} ${className}`}
      style={{ transitionDelay: `${delay}ms` }} {...rest}>
      {children}
    </Tag>
  );
}

// ---- Loader ----
function Loader() {
  const [pct, setPct] = useState(0);
  const [done, setDone] = useState(false);
  const [gone, setGone] = useState(false);
  useEffect(() => {
    let v = 0;
    const iv = setInterval(() => {
      v += Math.random() * 22 + 10;
      if (v >= 100) {
        v = 100;
        clearInterval(iv);
        setTimeout(() => setDone(true), 200);
        setTimeout(() => setGone(true), 800);
      }
      setPct(Math.floor(v));
    }, 70);
    return () => clearInterval(iv);
  }, []);
  if (gone) return null;
  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: 9000,
      background: "var(--ink)", color: "var(--bg)",
      display: "flex", alignItems: "center", justifyContent: "center",
      opacity: done ? 0 : 1, transition: "opacity 0.5s ease",
      pointerEvents: done ? "none" : "all",
    }}>
      <div className="serif" style={{ fontSize: "clamp(64px, 12vw, 140px)", letterSpacing: "-0.04em", lineHeight: 1 }}>
        {pct}
      </div>
    </div>
  );
}

// ---- Cursor ----
function useCursor() {
  useEffect(() => {
    const c = document.getElementById("cursor");
    if (!c) return;
    const move = (e) => { c.style.left = e.clientX + "px"; c.style.top = e.clientY + "px"; };
    const over = (e) => {
      if (e.target.closest("a, button, [data-cursor-big]")) c.classList.add("big");
      else c.classList.remove("big");
    };
    window.addEventListener("mousemove", move);
    window.addEventListener("mouseover", over);
    return () => { window.removeEventListener("mousemove", move); window.removeEventListener("mouseover", over); };
  }, []);
}

// ---- Active section ----
function useActiveSection(ids) {
  const [active, setActive] = useState(ids[0]);
  useEffect(() => {
    const handler = () => {
      for (let i = ids.length - 1; i >= 0; i--) {
        const el = document.getElementById(ids[i]);
        if (!el) continue;
        if (el.getBoundingClientRect().top <= 100) { setActive(ids[i]); return; }
      }
      setActive(ids[0]);
    };
    window.addEventListener("scroll", handler, { passive: true });
    return () => window.removeEventListener("scroll", handler);
  }, []);
  return active;
}

// ---- Underline scribble ----
const UnderlineSVG = () => (
  <svg className="underline-svg" viewBox="0 0 200 30" preserveAspectRatio="none" fill="none">
    <path d="M2 18 C 40 4, 80 4, 120 14 S 180 24, 198 12"
      stroke="currentColor" strokeWidth="3" strokeLinecap="round" />
  </svg>
);

// ---- Floating balloon ball (scroll-driven) ----
const NOISE_URI = "url(\"data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E\")";

function FloatingBall() {
  const outerRef = useRef(null);

  useEffect(() => {
    const SIZE = 300; // base px (we scale via transform)
    let sv = 0;
    let rafId = null;

    const easeInOut = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;

    const render = () => {
      rafId = null;
      const el = outerRef.current;
      if (!el) return;

      const maxS = document.documentElement.scrollHeight - window.innerHeight;
      const p = maxS > 0 ? Math.max(0, Math.min(1, sv / maxS)) : 0;

      // Fade: invisible during hero, fades in as you scroll away
      const fadeIn = p < 0.06 ? 0 : p < 0.12 ? (p - 0.06) / 0.06 : 1;
      // Fade out near bottom
      const fadeOut = p > 0.92 ? 1 - (p - 0.92) / 0.08 : 1;

      // Hide while Work section is in viewport
      const vh = window.innerHeight;
      const workEl = document.getElementById("work");
      let workFade = 1;
      if (workEl) {
        const wTop = workEl.offsetTop;
        const wBot = wTop + workEl.offsetHeight;
        const TRANS = 140;
        const hideStart = wTop - vh - TRANS;
        const hideEnd   = wTop - vh + TRANS;
        const showStart = wBot - TRANS;
        const showEnd   = wBot + TRANS;
        if (sv <= hideStart) workFade = 1;
        else if (sv <= hideEnd)   workFade = 1 - (sv - hideStart) / (2 * TRANS);
        else if (sv <= showStart) workFade = 0;
        else if (sv <= showEnd)   workFade = (sv - showStart) / (2 * TRANS);
        else workFade = 1;
        workFade = Math.max(0, Math.min(1, workFade));
      }

      const opacity = fadeIn * fadeOut * workFade * 0.88;

      if (opacity <= 0) {
        el.style.opacity = 0;
        return;
      }

      // Lissajous-like path — feels like a balloon drifting
      // X: oscillates across the right 60-90% of the screen, 3 full sweeps
      const xPct = 75 + Math.sin(p * Math.PI * 5) * 16;
      // Y: slower vertical drift with a cosine wave, 2 sweeps
      const yPct = 30 + Math.cos(p * Math.PI * 3.5) * 22 + p * 14;

      const vw = window.innerWidth;
      const px = (xPct / 100) * vw - SIZE / 2;
      const py = (yPct / 100) * vh - SIZE / 2;

      // Scale: large early (1.0), shrinks as you go deeper (min 0.22)
      const scale = Math.max(0.22, 1 - p * 0.78);

      // Rotation: slow spin (1.5 full turns)
      const rot = p * 540;

      el.style.transform = `translate3d(${px}px, ${py}px, 0) rotate(${rot}deg) scale(${scale})`;
      el.style.opacity = opacity;
    };

    const onScroll = () => {
      sv = window.scrollY;
      if (!rafId) rafId = requestAnimationFrame(render);
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    render();
    return () => {
      window.removeEventListener("scroll", onScroll);
      if (rafId) cancelAnimationFrame(rafId);
    };
  }, []);

  return (
    <div
      ref={outerRef}
      style={{
        position: "fixed",
        top: 0, left: 0,
        width: 300, height: 300,
        borderRadius: "50%",
        background: "var(--accent)",
        pointerEvents: "none",
        zIndex: 40,
        opacity: 0,
        willChange: "transform, opacity",
        overflow: "hidden",
      }}
    >
      {/* light radial sheen */}
      <div style={{
        position: "absolute", inset: 0,
        background: "radial-gradient(circle at 28% 28%, rgba(255,255,255,0.32) 0%, transparent 54%), radial-gradient(circle at 72% 78%, rgba(0,0,0,0.22) 0%, transparent 52%)",
        borderRadius: "50%",
      }} />
      {/* grain texture */}
      <div style={{
        position: "absolute", inset: 0,
        backgroundImage: NOISE_URI,
        backgroundSize: "cover",
        opacity: 0.26,
        mixBlendMode: "overlay",
        borderRadius: "50%",
      }} />
    </div>
  );
}

// ---- Hero Globe (auto-rotate + drag + location pins) ----
function HeroGlobe() {
  const svgRef   = useRef(null);
  const landRef  = useRef(null);
  const gratRef  = useRef(null);
  const pinRefs  = useRef([]);
  const [hoveredPin, setHoveredPin] = useState(null);

  // Animation state — all mutable, no re-renders
  const st = useRef({
    rot: [20, -12, 0], dragging: false, pinHovered: false,
    lx: 0, ly: 0, vx: 0, vy: 0,
    proj: null, geoPath: null, grat: null, rafId: null,
  });

  // Keep hoveredPin accessible in animation loop without stale closure
  const hovPinRef = useRef(null);
  const setHovPin = (pin) => {
    hovPinRef.current = pin;
    st.current.pinHovered = !!pin;
    setHoveredPin(pin);
  };

  useEffect(() => {
    const s    = st.current;
    const svgEl  = svgRef.current;
    const landEl = landRef.current;
    const gratEl = gratRef.current;
    if (!svgEl || !landEl || !gratEl || !window.d3 || !window.topojson) return;

    s.proj    = window.d3.geoOrthographic().scale(140).translate([200, 200]).clipAngle(90).precision(0.6);
    s.geoPath = window.d3.geoPath(s.proj);
    s.grat    = window.d3.geoGraticule10();

    const draw = () => {
      s.proj.rotate(s.rot);
      gratEl.setAttribute('d', s.geoPath(s.grat) || '');
      if (s.landGeo) landEl.setAttribute('d', s.geoPath(s.landGeo) || '');
      updatePins();
    };

    const updatePins = () => {
      GLOBE_PINS.forEach((pin, idx) => {
        const el = pinRefs.current[idx];
        if (!el) return;
        const projected = s.proj([pin.lon, pin.lat]);
        // Smooth fade near limb via great-circle distance
        const viewCenter = [-s.rot[0], -s.rot[1]];
        const dist = window.d3.geoDistance(viewCenter, [pin.lon, pin.lat]);
        const LIMB = Math.PI / 2;
        const opacity = projected === null ? 0
          : dist > LIMB - 0.18 ? Math.max(0, (LIMB - dist) / 0.18)
          : 1;

        if (opacity <= 0.01) {
          el.style.opacity = '0';
          el.style.pointerEvents = 'none';
        } else {
          el.style.opacity = String(opacity);
          el.style.pointerEvents = 'auto';
          el.style.left  = (projected[0] / 400 * 100) + '%';
          el.style.top   = (projected[1] / 400 * 100) + '%';
        }
      });
    };

    // Load land geo (cached)
    getLandGeo().then(geo => { if (geo) { s.landGeo = geo; draw(); } });
    draw();

    // --- Animation loop: auto-rotate + inertia ---
    const AUTO = 0.035;
    const SENS = 0.38;
    const DAMP = 0.91;

    const loop = () => {
      if (!s.dragging && !s.pinHovered) {
        if (Math.abs(s.vx) > 0.04 || Math.abs(s.vy) > 0.04) {
          s.vx *= DAMP; s.vy *= DAMP;
          s.rot[0] += s.vx * SENS;
          s.rot[1]  = Math.max(-89, Math.min(89, s.rot[1] - s.vy * SENS));
        } else {
          s.vx = 0; s.vy = 0;
          s.rot[0] += AUTO;
        }
        draw();
      }
      s.rafId = requestAnimationFrame(loop);
    };
    s.rafId = requestAnimationFrame(loop);

    // --- Drag handlers ---
    const xy = (e) => e.touches
      ? { x: e.touches[0].clientX, y: e.touches[0].clientY }
      : { x: e.clientX,            y: e.clientY };

    const onDown = (e) => {
      s.dragging = true;
      const p = xy(e); s.lx = p.x; s.ly = p.y; s.vx = 0; s.vy = 0;
      svgEl.style.cursor = 'grabbing';
    };
    const onMove = (e) => {
      if (!s.dragging) return;
      const p = xy(e);
      s.vx = p.x - s.lx; s.vy = p.y - s.ly;
      s.lx = p.x; s.ly = p.y;
      s.rot[0] += s.vx * SENS;
      s.rot[1]  = Math.max(-89, Math.min(89, s.rot[1] - s.vy * SENS));
      draw();
    };
    const onUp = () => {
      if (!s.dragging) return;
      s.dragging = false;
      svgEl.style.cursor = 'grab';
      // inertia handled by loop
    };

    svgEl.addEventListener('mousedown',  onDown);
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup',   onUp);
    svgEl.addEventListener('touchstart', onDown, { passive: true });
    window.addEventListener('touchmove', onMove, { passive: false });
    window.addEventListener('touchend',  onUp);
    svgEl.style.cursor = 'grab';

    return () => {
      cancelAnimationFrame(s.rafId);
      svgEl.removeEventListener('mousedown',  onDown);
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseup',   onUp);
      svgEl.removeEventListener('touchstart', onDown);
      window.removeEventListener('touchmove', onMove);
      window.removeEventListener('touchend',  onUp);
    };
  }, []);

  return (
    <>
      {/* SVG globe */}
      <svg ref={svgRef} viewBox="0 0 400 400" className="hero-globe__svg"
        aria-label="Interactive globe — drag to spin" style={{ width: '100%', height: '100%' }}>
        <defs>
          <clipPath id="hero-globe-clip">
            <circle cx="200" cy="200" r="140" />
          </clipPath>
        </defs>
        <g className="hero-globe__whirl hero-globe__whirl--a">
          <circle cx="200" cy="200" r="172" strokeWidth="1" strokeDasharray="2 8" />
          <circle cx="200" cy="200" r="186" strokeWidth="0.6" strokeDasharray="1 14" opacity="0.6" />
        </g>
        <g className="hero-globe__whirl hero-globe__whirl--b">
          <circle cx="200" cy="200" r="158" strokeWidth="0.8" strokeDasharray="40 10 4 10" />
          <circle cx="200" cy="200" r="195" strokeWidth="0.5" strokeDasharray="0.5 6" opacity="0.5" />
        </g>
        <g className="hero-globe__whirl hero-globe__whirl--c">
          <path d="M 200 32 A 168 168 0 0 1 332 138" strokeWidth="1.4" strokeLinecap="round" />
          <path d="M 200 368 A 168 168 0 0 1 68 262" strokeWidth="1.4" strokeLinecap="round" opacity="0.7" />
        </g>
        <g className="hero-globe__whirl hero-globe__whirl--a">
          <circle className="hero-globe__particle" cx="200" cy="28" r="2.5" />
        </g>
        <g className="hero-globe__whirl hero-globe__whirl--b">
          <circle className="hero-globe__particle" cx="200" cy="372" r="1.8" opacity="0.7" />
        </g>
        <circle className="hero-globe__sphere" cx="200" cy="200" r="140" />
        <g clipPath="url(#hero-globe-clip)">
          <path ref={gratRef} className="hero-globe__graticule" />
          <path ref={landRef} className="hero-globe__land" />
        </g>
      </svg>

      {/* Location pins — positioned as % of SVG viewBox, updated by D3 loop */}
      {GLOBE_PINS.map((pin, idx) => (
        <div
          key={pin.key}
          ref={el => pinRefs.current[idx] = el}
          onMouseEnter={() => setHovPin(pin)}
          onMouseLeave={() => setHovPin(null)}
          onClick={() => {
            setHovPin(null);
            const el = document.getElementById('exp-' + pin.key);
            if (el) {
              el.scrollIntoView({ behavior: 'smooth', block: 'center' });
              el.classList.add('exp-highlight');
              setTimeout(() => el.classList.remove('exp-highlight'), 2400);
            }
          }}
          style={{
            position: 'absolute', opacity: 0, pointerEvents: 'none',
            transform: 'translate(-50%, calc(-100% - 4px))',
            zIndex: 10, userSelect: 'none',
          }}
        >
          {/* Chip label */}
          <div style={{
            background: 'var(--accent)', color: '#fff',
            padding: '3px 7px 3px 5px', borderRadius: 4,
            fontSize: 9, fontFamily: 'var(--mono)', letterSpacing: '0.07em',
            textTransform: 'uppercase', whiteSpace: 'nowrap',
            boxShadow: '0 2px 10px rgba(0,0,0,0.35)',
            display: 'flex', alignItems: 'center', gap: 4, cursor: 'pointer',
          }}>
            <span style={{ width: 4, height: 4, borderRadius: '50%', background: 'rgba(255,255,255,0.8)', flexShrink: 0 }} />
            {pin.label}
          </div>
          {/* Stem */}
          <div style={{ width: 1, height: 7, background: 'var(--accent)', opacity: 0.8, margin: '0 auto' }} />
          {/* Dot */}
          <div style={{
            width: 6, height: 6, borderRadius: '50%',
            background: 'var(--accent)', margin: '0 auto',
            boxShadow: '0 0 6px 2px oklch(0.62 0.16 var(--accent-h) / 0.55)',
          }} />
        </div>
      ))}

      {/* Hover card — fixed center of screen */}
      {hoveredPin && <GlobePinCard pin={hoveredPin} />}
    </>
  );
}

// ---- Globe Pin Card ----
function GlobePinCard({ pin }) {
  return (
    <div style={{
      position: 'fixed', top: '50%', left: '50%',
      transform: 'translate(-50%, -50%)',
      zIndex: 300, pointerEvents: 'none',
      background: 'oklch(0.96 0.035 var(--accent-h))',
      border: '1px solid oklch(0.90 0.06 var(--accent-h))',
      borderRadius: 14,
      padding: 'clamp(20px, 2.5vw, 36px)',
      maxWidth: 360, width: '82vw',
      boxShadow: '0 24px 64px rgba(0,0,0,0.13)',
      animation: 'pinCardIn 0.18s cubic-bezier(0.2,0.7,0.2,1) both',
    }}>
      <h3 style={{
        fontFamily: 'var(--serif)', fontWeight: 300,
        fontSize: 'clamp(28px, 3.8vw, 46px)',
        lineHeight: 1.0, letterSpacing: '-0.03em',
        color: 'var(--ink)', marginBottom: 10,
      }}>{pin.co}</h3>
      <div className="mono" style={{ color: 'var(--accent)', letterSpacing: '0.06em' }}>
        {pin.role}
      </div>
      <div className="mono" style={{ color: 'var(--ink-mute)', marginTop: 14, fontSize: 10 }}>
        Click to view in Experience ↓
      </div>
    </div>
  );
}

// ---- Mini Globe (contact links) ----
function MiniGlobe({ href }) {
  const svgRef  = useRef(null);
  const landRef = useRef(null);
  const gratRef = useRef(null);
  const [hov, setHov] = useState(false);
  const st = useRef({
    rot: [Math.random() * 360, -20, 0],
    proj: null, geoPath: null, grat: null, rafId: null,
  });

  useEffect(() => {
    const s    = st.current;
    const svgEl  = svgRef.current;
    const landEl = landRef.current;
    const gratEl = gratRef.current;
    if (!svgEl || !landEl || !gratEl || !window.d3 || !window.topojson) return;

    s.proj    = window.d3.geoOrthographic().scale(140).translate([200, 200]).clipAngle(90).precision(1.2);
    s.geoPath = window.d3.geoPath(s.proj);
    s.grat    = window.d3.geoGraticule10();

    const draw = () => {
      s.proj.rotate(s.rot);
      gratEl.setAttribute('d', s.geoPath(s.grat) || '');
      if (s.landGeo) landEl.setAttribute('d', s.geoPath(s.landGeo) || '');
    };

    getLandGeo().then(geo => { if (geo) { s.landGeo = geo; draw(); } });
    draw();

    const loop = () => {
      s.rot[0] += 0.22;
      draw();
      s.rafId = requestAnimationFrame(loop);
    };
    s.rafId = requestAnimationFrame(loop);

    return () => cancelAnimationFrame(s.rafId);
  }, []);

  return (
    <a href={href} target="_blank" rel="noopener noreferrer"
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      style={{
        position: 'relative', display: 'inline-flex',
        width: 88, height: 88, borderRadius: '50%',
        overflow: 'hidden', cursor: 'pointer',
        flexShrink: 0,
        border: '1px solid oklch(0.62 0.16 var(--accent-h) / 0.3)',
        transition: 'border-color 0.3s ease, box-shadow 0.3s ease',
        boxShadow: hov ? '0 0 0 3px oklch(0.62 0.16 var(--accent-h) / 0.22)' : 'none',
      }}
    >
      <svg ref={svgRef} viewBox="0 0 400 400" style={{ width: '100%', height: '100%' }}>
        <circle cx="200" cy="200" r="140" fill="none" stroke="var(--accent)" strokeWidth="1.4" />
        <path ref={gratRef} fill="none" stroke="var(--accent)" strokeWidth="0.5" opacity="0.3" />
        <path ref={landRef} fill="var(--accent)" fillOpacity="0.18" stroke="var(--accent)" strokeWidth="0.7" />
      </svg>
      {/* Hover overlay */}
      <div style={{
        position: 'absolute', inset: 0, borderRadius: '50%',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: `oklch(0.62 0.16 var(--accent-h) / ${hov ? 0.78 : 0})`,
        transition: 'background 0.28s ease',
      }}>
        <span style={{
          fontFamily: 'var(--mono)', fontSize: 10,
          letterSpacing: '0.1em', textTransform: 'uppercase',
          color: '#fff',
          opacity: hov ? 1 : 0,
          transform: hov ? 'translateY(0)' : 'translateY(5px)',
          transition: 'opacity 0.22s ease, transform 0.22s ease',
        }}>open</span>
      </div>
    </a>
  );
}

// ---- Accent Ball Link ----
function BallLink({ href, label }) {
  const [hov, setHov] = useState(false);
  return (
    <a href={href} target="_blank" rel="noopener noreferrer"
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      style={{
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        width: 92, height: 92, borderRadius: "50%",
        background: "var(--accent)",
        color: "#fff",
        fontFamily: "var(--mono)", fontSize: 10,
        letterSpacing: "0.1em", textTransform: "uppercase",
        transition: "transform 0.4s cubic-bezier(0.2,0.8,0.2,1)",
        transform: hov ? "scale(1.12) rotate(12deg)" : "scale(1)",
        textDecoration: "none", flexShrink: 0,
        position: "relative", overflow: "hidden",
      }}
    >
      <span style={{ position: "relative", zIndex: 1 }}>{label}</span>
      <span style={{
        position: "absolute", inset: 0, borderRadius: "50%",
        background: "radial-gradient(circle at 30% 30%, rgba(255,255,255,0.28) 0%, transparent 58%), radial-gradient(circle at 72% 80%, rgba(0,0,0,0.18) 0%, transparent 55%)",
      }} />
    </a>
  );
}

// ---- Nav ----
function Nav() {
  const sections = ["work", "thinking", "experience", "brands", "about", "contact"];
  const labels   = ["Work", "Thinking", "Experience", "Brands", "About", "Contact"];
  const active = useActiveSection(sections);
  return (
    <nav className="top">
<div className="links hide-mobile">
        {sections.map((id, i) => (
          <a key={id} href={`#${id}`} style={{
            opacity: active === id ? 1 : 0.55,
            borderBottom: active === id ? "1px solid currentColor" : "1px solid transparent",
            paddingBottom: 2, transition: "opacity 0.3s ease",
          }}>{labels[i]}</a>
        ))}
      </div>
    </nav>
  );
}

// ---- Hero ----
function Hero() {
  const ballRef = useRef(null);
  const mouse = useRef({ x: 0, y: 0 });
  const scrollYRef = useRef(0);

  const applyHeroBall = () => {
    const el = ballRef.current;
    if (!el) return;
    const sy = scrollYRef.current;
    const opacity = Math.max(0, 1 - sy / 320);
    const mx = mouse.current.x;
    const my = mouse.current.y;
    el.style.opacity = opacity;
    // Keep globe centred in name block; offsets for parallax on top
    el.style.transform = `translate(calc(-50% + ${mx}px), calc(-50% + ${sy * 0.08 + my}px))`;
  };

  useEffect(() => {
    const onScroll = () => { scrollYRef.current = window.scrollY; applyHeroBall(); };
    const onMouse = (e) => {
      const cx = window.innerWidth / 2;
      const cy = window.innerHeight / 2;
      mouse.current = { x: (e.clientX - cx) / cx * 14, y: (e.clientY - cy) / cy * 9 };
      applyHeroBall();
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("mousemove", onMouse, { passive: true });
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("mousemove", onMouse);
    };
  }, []);

  return (
    <section id="top" className="hero">
      <Reveal delay={120}>
        <div className="hero-name">
          {/* Globe: absolutely centred over both words, behind text */}
          <div ref={ballRef} className="hero-globe-wrap" style={{
            position: "absolute", top: "50%", left: "50%",
            width: "clamp(300px, 40vw, 620px)",
            height: "clamp(300px, 40vw, 620px)",
            transform: "translate(-50%, -50%)",
            zIndex: 1, willChange: "transform, opacity",
          }}>
            <HeroGlobe />
          </div>
          {/* Text rows — in front of globe */}
          <div className="row" style={{ position: "relative", zIndex: 2, pointerEvents: "none" }}>
            <span>Alban</span>
          </div>
          <div className="row right" style={{ position: "relative", zIndex: 2, pointerEvents: "none" }}>
            <span style={{ position: "relative", display: "inline-block" }}>
              <em className="italic">Amikat</em>
              <UnderlineSVG />
            </span>
          </div>
        </div>
      </Reveal>

      <Reveal delay={300}>
        <div className="hero-desc" style={{ marginTop: "clamp(32px, 5vh, 60px)", maxWidth: "52ch" }}>
          <p className="serif" style={{
            fontSize: "clamp(18px, 1.8vw, 24px)", lineHeight: 1.45, color: "var(--ink-soft)",
          }}>
            Building products and integrations that convert attention into measurable revenue
          </p>
          <div style={{ display: "flex", gap: 12, marginTop: 32, flexWrap: "wrap" }}>
            <a href="#work" className="btn btn--solid">View Work <span className="arrow">→</span></a>
            <a href="#contact" className="btn">Contact <span className="arrow">→</span></a>
          </div>
        </div>
      </Reveal>

      <div className="scroll-cue">
        <span className="mono" style={{ fontSize: 10 }}>Scroll</span>
        <span className="line" />
      </div>
    </section>
  );
}

// ---- Marquee ----
function Marquee({ items, italicEvery = 2 }) {
  const all = [...items, ...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {all.map((t, i) => (
          <span key={i} className="marquee-item">
            <span className={i % italicEvery === 1 ? "italic" : ""}>{t}</span>
            <span className="dot" />
          </span>
        ))}
      </div>
    </div>
  );
}

// ---- Stats ----
function Stats() {
  const stats = [
    { n: "13",         l: "Years" },
    { n: "₹3000 Cr+",  l: "Business environment" },
    { n: "40+",        l: "Awards across projects" },
  ];
  return (
    <section style={{ padding: "100px var(--gutter)" }}>
      <Reveal>
        <div className="mono" style={{ marginBottom: 36 }}>— By the numbers</div>
      </Reveal>
      <div className="stats-grid" style={{
        display: "grid",
        gridTemplateColumns: "repeat(3, 1fr)",
        borderTop: "1px solid var(--rule)",
      }}>
        {stats.map((s, i) => (
          <Reveal key={i} delay={i * 80}>
            <div style={{
              paddingTop: 32,
              paddingLeft: 32,
              paddingRight: i < 2 ? 32 : 0,
              borderRight: i < 2 ? "1px solid var(--rule)" : "none",
              textAlign: "left",
            }}>
              <div className="serif" style={{
                fontSize: "clamp(44px, 6vw, 96px)",
                lineHeight: 0.9, letterSpacing: "-0.04em",
                whiteSpace: "nowrap",
              }}>{s.n}</div>
              <div className="mono" style={{ marginTop: 14, color: "var(--accent)" }}>{s.l}</div>
            </div>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ---- Video Modal ----
function VideoModal({ project, onClose, onCaseStudy }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = ""; };
  }, []);

  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, zIndex: 2000,
      background: "rgba(0,0,0,0.93)",
      display: "flex", alignItems: "center", justifyContent: "center", padding: "20px",
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{ position: "relative", width: "90vw", maxWidth: 920 }}>
        <button onClick={onClose} style={{
          position: "absolute", top: -48, right: 0,
          color: "#fff", fontSize: 28, background: "none", border: "none", cursor: "pointer", lineHeight: 1, padding: 8,
        }}>✕</button>
        <div style={{ position: "relative", paddingBottom: "56.25%", height: 0, background: "#000", borderRadius: 8, overflow: "hidden" }}>
          <iframe src={project.videoUrl} allow="autoplay; fullscreen; picture-in-picture" allowFullScreen
            style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", border: "none" }} />
        </div>
        {project.cs && (
          <div style={{ marginTop: 20, textAlign: "center" }}>
            <button onClick={onCaseStudy} className="btn" style={{ color: "#fff", borderColor: "rgba(255,255,255,0.4)" }}>
              See My Contribution <span className="arrow">→</span>
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

// ---- Case Study Modal ----
function CaseStudyModal({ project, onClose }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = ""; };
  }, []);

  const { cs } = project;
  const sections = [
    { label: "Problem",  text: cs.problem  },
    { label: "Approach", text: cs.approach },
  ];

  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, zIndex: 2100,
      background: "rgba(0,0,0,0.94)",
      display: "flex", alignItems: "center", justifyContent: "center", padding: "20px",
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        background: "var(--bg)", color: "var(--ink)",
        padding: "clamp(28px, 4vw, 52px)", maxWidth: 620, width: "100%",
        borderRadius: 14, position: "relative", maxHeight: "88vh", overflowY: "auto",
      }}>
        <button onClick={onClose} style={{
          position: "absolute", top: 20, right: 20,
          fontSize: 22, background: "none", border: "none", cursor: "pointer",
          color: "var(--ink-mute)", lineHeight: 1, padding: 4,
        }}>✕</button>

        {/* Header */}
        <div className="mono" style={{ marginBottom: 10, color: "var(--ink-mute)" }}>
          {project.n} — My Contribution
        </div>
        <h2 className="serif" style={{
          fontSize: "clamp(26px, 3.5vw, 40px)", lineHeight: 1.05,
          letterSpacing: "-0.03em", marginBottom: 36,
        }}>{project.title}</h2>

        {/* Problem + Approach */}
        {sections.map(({ label, text }) => (
          <div key={label} style={{ marginBottom: 28, paddingBottom: 28, borderBottom: "1px solid var(--rule)" }}>
            <div className="mono" style={{ marginBottom: 10, color: "var(--accent)" }}>{label}</div>
            <p style={{ fontSize: "clamp(14px, 1.2vw, 16px)", lineHeight: 1.7, color: "var(--ink-soft)" }}>{text}</p>
          </div>
        ))}

        {/* Outcome */}
        <div>
          <div className="mono" style={{ marginBottom: 14, color: "var(--accent)" }}>Outcome</div>
          <ul style={{ listStyle: "none", padding: 0, display: "flex", flexDirection: "column", gap: 12 }}>
            {cs.outcome.map((item) => (
              <li key={item} style={{
                fontSize: "clamp(14px, 1.2vw, 16px)", lineHeight: 1.5,
                display: "flex", gap: 14, alignItems: "baseline",
              }}>
                <span style={{ color: "var(--accent)", fontFamily: "var(--mono)", fontSize: 10, flexShrink: 0 }}>◆</span>
                {item}
              </li>
            ))}
          </ul>
        </div>
      </div>
    </div>
  );
}

// ---- Work Card ----
function WorkCard({ p, onOpen }) {
  const [hov, setHov] = useState(false);
  const feat  = !!p.featured;
  const prior = !!p.priority;
  return (
    <article
      onClick={() => onOpen(p)}
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      data-cursor-big
      style={{
        position: "relative",
        borderRadius: 10,
        overflow: "hidden",
        cursor: "pointer",
        aspectRatio: "4 / 3",
        background: "#0a0a0a",
        transform: hov ? `scale(${feat ? 1.04 : 1.03})` : "scale(1)",
        boxShadow: hov
          ? prior ? "0 28px 72px rgba(0,0,0,0.55)" : "0 20px 52px rgba(0,0,0,0.38)"
          : prior ? "0 6px 24px rgba(0,0,0,0.28)" : "0 4px 18px rgba(0,0,0,0.18)",
        transition: "transform 0.4s cubic-bezier(0.2,0.7,0.2,1), box-shadow 0.4s ease",
        zIndex: hov ? 2 : 1,
        willChange: "transform",
        outline: prior ? "1px solid rgba(var(--accent-h), 0.0)" : "none",
      }}
    >
      {/* Priority accent line at top */}
      {prior && (
        <div style={{
          position: "absolute", top: 0, left: 0, right: 0,
          height: 2, background: "var(--accent)", zIndex: 3,
          opacity: hov ? 1 : 0.6,
          transition: "opacity 0.3s ease",
        }} />
      )}
      {/* Thumbnail */}
      <img
        src={p.thumb} alt={p.title} loading="lazy"
        style={{
          position: "absolute", inset: 0,
          width: "100%", height: "100%", objectFit: "cover",
          transform: hov ? "scale(1.07)" : "scale(1)",
          transition: "transform 0.55s ease",
        }}
      />

      {/* Base gradient — always on */}
      <div style={{
        position: "absolute", inset: 0,
        background: "linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.12) 55%, transparent 100%)",
      }} />

      {/* Hover dark overlay */}
      <div style={{
        position: "absolute", inset: 0,
        background: "rgba(0,0,0,0.38)",
        opacity: hov ? 1 : 0,
        transition: "opacity 0.35s ease",
      }} />

      {/* Bottom content */}
      <div style={{
        position: "absolute", bottom: 0, left: 0, right: 0,
        padding: "clamp(14px, 1.8vw, 24px)",
      }}>
        {/* Number + year row */}
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
          <span className="mono" style={{ color: "rgba(255,255,255,0.45)", fontSize: 10 }}>{p.n}</span>
          <span className="mono" style={{ color: "rgba(255,255,255,0.45)", fontSize: 10 }}>{p.year}</span>
        </div>

        {/* Title */}
        <h3 style={{
          fontFamily: "var(--serif)", fontWeight: 300,
          fontSize: feat ? "clamp(16px, 1.4vw, 21px)" : "clamp(13px, 1.1vw, 17px)",
          lineHeight: 1.2, letterSpacing: "-0.02em",
          color: "#fff", margin: 0,
        }}>{p.title}</h3>

        {/* Description — hidden until hover */}
        <div style={{
          overflow: "hidden",
          maxHeight: hov ? "110px" : 0,
          opacity: hov ? 1 : 0,
          marginTop: hov ? 10 : 0,
          transition: "max-height 0.42s cubic-bezier(0.2,0.7,0.2,1), opacity 0.3s ease 0.06s, margin-top 0.3s ease",
        }}>
          <p style={{
            fontSize: "clamp(10px, 0.82vw, 12px)",
            color: "rgba(255,255,255,0.75)",
            lineHeight: 1.65,
            margin: 0,
            transform: hov ? "translateY(0)" : "translateY(8px)",
            transition: "transform 0.38s cubic-bezier(0.2,0.7,0.2,1) 0.06s",
          }}>{p.desc}</p>
        </div>

        {/* Featured accent line */}
        {feat && (
          <div style={{
            position: "absolute", top: 0, left: "clamp(14px, 1.8vw, 24px)",
            width: 28, height: 2,
            background: "var(--accent)",
            transform: "translateY(-100%) translateY(-12px)",
            opacity: hov ? 1 : 0.55,
            transition: "opacity 0.3s ease",
          }} />
        )}
      </div>
    </article>
  );
}

// ---- Work ----
function Work() {
  const [modal, setModal] = useState(null);
  const [caseStudy, setCaseStudy] = useState(null);

  return (
    <section id="work" style={{ padding: "100px 0" }}>
      <div style={{ padding: "0 var(--gutter)", marginBottom: 48 }}>
        <Reveal>
          <div className="mono" style={{ marginBottom: 20 }}>— Selected work / 01 — 08</div>
        </Reveal>
        <Reveal delay={80}>
          <h2 className="display" style={{ fontSize: "clamp(56px, 11vw, 180px)", maxWidth: "11ch" }}>
            Stories that <em className="italic">earn</em>.
          </h2>
        </Reveal>
      </div>

      <div className="work-grid" style={{ padding: "0 var(--gutter)" }}>
        {PROJECTS.map((p, i) => (
          <Reveal key={p.n} delay={i * 40}>
            <WorkCard p={p} onOpen={setModal} />
          </Reveal>
        ))}
      </div>

      {modal && (
        <VideoModal project={modal} onClose={() => setModal(null)}
          onCaseStudy={() => { setCaseStudy(modal); setModal(null); }} />
      )}
      {caseStudy && <CaseStudyModal project={caseStudy} onClose={() => setCaseStudy(null)} />}
    </section>
  );
}

// ---- Think Card ----
function ThinkCard({ t, i }) {
  const [hov, setHov] = useState(false);
  return (
    <div
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      style={{
        padding: "clamp(28px, 3.5vw, 48px)",
        borderRadius: 14,
        background: hov ? "var(--bg)" : "oklch(0.97 0.03 var(--accent-h))",
        border: hov
          ? "1px solid var(--rule)"
          : "1px solid oklch(0.91 0.05 var(--accent-h))",
        boxShadow: hov
          ? "0 24px 56px rgba(0,0,0,0.10)"
          : "0 2px 8px rgba(0,0,0,0.03)",
        transform: hov ? THINK_TILTS[i] : "none",
        transition: "transform 0.4s cubic-bezier(0.2,0.7,0.2,1), box-shadow 0.4s ease, background 0.25s ease, border-color 0.25s ease",
        transformStyle: "preserve-3d",
        willChange: "transform",
        cursor: "default",
      }}
    >
      {/* Number */}
      <div className="serif italic" style={{
        fontSize: "clamp(22px, 2.2vw, 32px)",
        color: "var(--accent)", lineHeight: 1, marginBottom: 18,
      }}>{t.n}</div>

      {/* Title — always visible */}
      <p style={{
        fontFamily: "var(--serif)", fontWeight: 300,
        fontSize: "clamp(15px, 1.3vw, 18px)",
        lineHeight: 1.4, letterSpacing: "-0.015em",
        color: "var(--ink)",
        marginBottom: hov ? 20 : 0,
        transition: "margin-bottom 0.3s ease",
      }}>{t.title}</p>

      {/* Hero line — orange, slides in on hover */}
      <div style={{
        overflow: "hidden",
        maxHeight: hov ? "6em" : 0,
        opacity: hov ? 1 : 0,
        transition: "max-height 0.4s cubic-bezier(0.2,0.7,0.2,1), opacity 0.3s ease",
      }}>
        <p style={{
          fontFamily: "var(--serif)", fontStyle: "italic",
          fontSize: "clamp(17px, 1.5vw, 22px)",
          lineHeight: 1.35, letterSpacing: "-0.02em",
          color: "var(--accent)",
          marginBottom: 20,
        }}>{t.hero}</p>
      </div>

      {/* Body — slides in on hover */}
      <div style={{
        overflow: "hidden",
        maxHeight: hov ? "400px" : 0,
        opacity: hov ? 1 : 0,
        transition: "max-height 0.5s cubic-bezier(0.2,0.7,0.2,1), opacity 0.35s ease 0.05s",
      }}>
        <p style={{
          fontFamily: "var(--sans)",
          fontSize: "clamp(13px, 1vw, 14px)",
          lineHeight: 1.75,
          color: "var(--ink-soft)",
          whiteSpace: "pre-line",
        }}>{t.body}</p>
      </div>
    </div>
  );
}

// ---- How I Think ----
function Think() {
  return (
    <section id="thinking" style={{ padding: "120px 0", background: "var(--bg-2)" }}>
      <div style={{ padding: "0 var(--gutter)", marginBottom: 72 }}>
        <Reveal>
          <div className="mono" style={{ marginBottom: 18 }}>— How I think</div>
        </Reveal>
        <Reveal delay={100}>
          <h2 className="display" style={{ fontSize: "clamp(48px, 9vw, 140px)", maxWidth: "16ch" }}>
            Juicing the <em className="italic">content</em>.
          </h2>
        </Reveal>
      </div>

      <div style={{ padding: "0 var(--gutter)", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }} className="think-grid">
        {THINK.map((t, i) => (
          <Reveal key={t.n} delay={i * 80}>
            <ThinkCard t={t} i={i} />
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ---- Experience ----
function Experience() {
  return (
    <section id="experience" style={{ padding: "120px var(--gutter)" }}>
      <Reveal>
        <div className="mono" style={{ marginBottom: 18 }}>— Experience</div>
      </Reveal>
      <Reveal delay={80}>
        <h2 className="display" style={{ fontSize: "clamp(48px, 9vw, 120px)", maxWidth: "14ch", marginBottom: 80 }}>
          13 years. <em className="italic">Three chapters.</em>
        </h2>
      </Reveal>
      <div>
        {EXPERIENCE.map((e, i) => (
          <Reveal key={e.co} delay={i * 80}>
            <div id={`exp-${e.co.toLowerCase()}`} className="exp-entry" style={{
              padding: "48px 0",
              borderTop: "1px solid var(--rule)",
              display: "grid", gridTemplateColumns: "1fr 2fr",
              gap: "clamp(24px, 6vw, 80px)",
              borderRadius: 8,
              transition: "background 0.4s ease",
            }}>
              <div>
                <h3 className="serif" style={{ fontSize: "clamp(28px, 3vw, 44px)", letterSpacing: "-0.02em", marginBottom: 10 }}>
                  {e.co}
                </h3>
                <div className="mono" style={{ marginBottom: 4 }}>{e.period}</div>
                <div className="mono" style={{ color: "var(--ink-mute)" }}>{e.role}</div>
              </div>
              <div>
                <p style={{ fontSize: "clamp(16px, 1.4vw, 20px)", lineHeight: 1.45, marginBottom: 20, color: "var(--ink-soft)" }}>
                  {e.summary}
                </p>
                <ul style={{ listStyle: "none", padding: 0, display: "flex", flexDirection: "column", gap: 8 }}>
                  {e.bullets.map((b) => (
                    <li key={b} style={{ fontSize: 15, color: "var(--ink-mute)", display: "flex", gap: 10 }}>
                      <span style={{ color: "var(--accent)", flexShrink: 0 }}>—</span>{b}
                    </li>
                  ))}
                </ul>
              </div>
            </div>
          </Reveal>
        ))}
        <div style={{ borderTop: "1px solid var(--rule)" }} />
      </div>
    </section>
  );
}

// ---- Brands ----
function Brands() {
  return (
    <section id="brands" style={{ padding: "80px var(--gutter) 100px" }}>
      <Reveal>
        <div className="mono" style={{ marginBottom: 20 }}>— Brands</div>
      </Reveal>
      <Reveal delay={80}>
        <p className="serif" style={{ fontSize: "clamp(18px, 1.8vw, 24px)", maxWidth: "44ch", marginBottom: 52, color: "var(--ink-soft)", lineHeight: 1.45 }}>
          Worked with leading brands across integrated content and advertising solutions
        </p>
      </Reveal>
      <Reveal delay={140}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", borderTop: "1px solid var(--rule)", borderLeft: "1px solid var(--rule)" }}>
          {BRANDS.map((b) => (
            <div key={b.name} title={b.name} className="brand-logo" style={{
              borderRight: "1px solid var(--rule)", borderBottom: "1px solid var(--rule)",
              padding: "40px 24px", display: "grid", placeItems: "center", minHeight: 130,
              transition: "transform 0.3s ease, filter 0.3s ease",
              filter: "grayscale(1) opacity(0.48)",
            }}
            onMouseEnter={(e) => { e.currentTarget.style.transform = "scale(1.05)"; e.currentTarget.style.filter = "grayscale(0) opacity(1)"; }}
            onMouseLeave={(e) => { e.currentTarget.style.transform = "none"; e.currentTarget.style.filter = "grayscale(1) opacity(0.48)"; }}
            >
              <img src={b.src} alt={b.name} loading="lazy" style={{ height: b.h, width: "auto", maxWidth: "80%", objectFit: "contain" }} />
            </div>
          ))}
        </div>
      </Reveal>
    </section>
  );
}

// ---- About ----
function About() {
  return (
    <section id="about" style={{ paddingTop: 120, paddingBottom: 120 }}>
      <div style={{ padding: "0 var(--gutter)" }}>
        <div className="about-grid" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(40px, 6vw, 100px)", alignItems: "start" }}>
          <Reveal>
            <div className="portrait-frame">
              <div className="portrait-img" />
              <div className="portrait-tag"><span className="mono">◐ Alban Amikat — Mumbai, '26</span></div>
              <div className="portrait-mark serif italic">A.A.</div>
            </div>
          </Reveal>
          <Reveal delay={120}>
            <div style={{ paddingTop: 20 }}>
              <div className="mono" style={{ marginBottom: 24 }}>— About</div>
              <h2 className="display" style={{ fontSize: "clamp(40px, 5vw, 80px)", maxWidth: "20ch" }}>
                Strategist's rigour. <em className="italic" style={{ color: "var(--accent)" }}>Storyteller's instinct.</em>
              </h2>
              <p style={{ marginTop: 36, fontSize: 19, lineHeight: 1.6, color: "var(--ink-soft)", maxWidth: "44ch" }}>
                13 years building IP, branded content, and ad products. Started with cuts and music. Now leading ad innovation at one of the world's largest TV networks.
              </p>
              <p style={{ marginTop: 20, fontSize: 19, lineHeight: 1.6, color: "var(--ink-soft)", maxWidth: "44ch" }}>
                Operating at the intersection of creativity and commercial thinking, I bring the analytical rigour of a strategist to creative work and the creative instinct of a storyteller to business problems.
              </p>
              <div style={{ marginTop: 40, paddingTop: 24, borderTop: "1px solid var(--rule)" }}>
                <div className="mono" style={{ marginBottom: 6 }}>Based</div>
                <div className="serif" style={{ fontSize: 18 }}>Mumbai, India</div>
              </div>
            </div>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

// ---- Contact ----
function Contact() {
  return (
    <footer id="contact">
      <Reveal>
        <div className="mono" style={{ color: "oklch(0.6 0.01 80)", marginBottom: 28 }}>— Let's talk</div>
      </Reveal>
      <Reveal delay={100}>
        <h2 className="big">
          Let's build
          <br />
          something <em className="italic" style={{ color: "var(--accent)" }}>interesting.</em>
        </h2>
      </Reveal>

      <Reveal delay={220}>
        <div className="contact-links" style={{
          marginTop: 80, display: "grid",
          gridTemplateColumns: "repeat(3, 1fr)", gap: 40,
          paddingTop: 40, borderTop: "1px solid oklch(0.32 0.012 80)",
        }}>
          <div>
            <div className="mono" style={{ color: "oklch(0.6 0.012 80)", marginBottom: 16 }}>Resume</div>
            <MiniGlobe href="https://canva.link/ub08xww59azxnw2" />
          </div>
          <div>
            <div className="mono" style={{ color: "oklch(0.6 0.012 80)", marginBottom: 16 }}>LinkedIn</div>
            <MiniGlobe href="https://www.linkedin.com/in/albanamikat" />
          </div>
          <div>
            <div className="mono" style={{ color: "oklch(0.6 0.012 80)", marginBottom: 16 }}>Instagram</div>
            <MiniGlobe href="https://www.instagram.com/albanbam/" />
          </div>
        </div>
      </Reveal>

      <div style={{
        marginTop: 100, paddingTop: 24,
        borderTop: "1px solid oklch(0.28 0.012 80)",
        display: "flex", justifyContent: "space-between",
        color: "oklch(0.55 0.012 80)",
      }}>
        <span className="mono">© 2026 Alban Amikat</span>
        <span className="mono">Mumbai · Worldwide</span>
      </div>
    </footer>
  );
}

// ---- App ----
function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useCursor();

  useEffect(() => {
    const root = document.documentElement;
    root.setAttribute("data-theme", tweaks.theme);
    root.style.setProperty("--accent-h", tweaks.accentHue);
  }, [tweaks.theme, tweaks.accentHue]);

  return (
    <div data-screen-label="Portfolio">
      <Loader />
      <Nav />
      <Hero />
      <Marquee items={["Brand strategy", "Content × Commerce", "Ad Innovation", "IP design", "Revenue", "Storytelling"]} />
      <Stats />
      <Work />
      <Think />
      <Experience />
      <Brands />
      <About />
      <Contact />

      <TweaksPanel title="Tweaks">
        <TweakSection title="Theme">
          <TweakRadio label="Mode" value={tweaks.theme} onChange={(v) => setTweak("theme", v)}
            options={[{ value: "light", label: "Light" }, { value: "dark", label: "Dark" }]} />
          <TweakSlider label="Accent hue" value={tweaks.accentHue} onChange={(v) => setTweak("accentHue", v)}
            min={0} max={360} step={1} unit="°" />
          <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: 4 }}>
            {[{n:"Terracotta",h:35},{n:"Olive",h:110},{n:"Forest",h:145},{n:"Cobalt",h:240},{n:"Plum",h:320}].map(p => (
              <button key={p.n} onClick={() => setTweak("accentHue", p.h)} title={p.n}
                style={{
                  width: 24, height: 24, borderRadius: "50%",
                  background: `oklch(0.62 0.16 ${p.h})`,
                  border: tweaks.accentHue === p.h ? "2px solid #000" : "1px solid #ccc",
                  cursor: "pointer", padding: 0,
                }} />
            ))}
          </div>
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

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