// Wistia thumbnail + media-id resolution.
// The naive URL `embed-ssl.wistia.com/deliveries/<media_id>.jpg` does NOT work —
// that path requires a delivery hash, not a media id. Instead we hit Wistia's
// CORS-enabled oembed endpoint to get the real thumbnail_url, cache it, and use
// that.
//
// The `key` here is either a 10-char Wistia media ID (e.g. "5akmdqt1f9") or a
// full share URL like "https://acct.wistia.com/s/<token>". For share URLs we
// hit oembed with the share URL itself, then parse the actual media ID out of
// the returned html embed string — that media ID is what the player API needs
// for the `wistia_async_<id>` class.
const __wistiaInfoCache = new Map();
const __wistiaInfoInflight = new Map();
function isWistiaShareUrl(v) { return typeof v === 'string' && /^https?:\/\//i.test(v); }
function fetchWistiaInfo(key) {
  if (__wistiaInfoCache.has(key)) return Promise.resolve(__wistiaInfoCache.get(key));
  if (__wistiaInfoInflight.has(key)) return __wistiaInfoInflight.get(key);
  const oembedUrl = isWistiaShareUrl(key)
    ? `https://fast.wistia.com/oembed.json?url=${encodeURIComponent(key)}`
    : `https://fast.wistia.com/oembed.json?url=https://fast.wistia.net/embed/iframe/${key}`;
  const p = fetch(oembedUrl)
    .then(r => r.ok ? r.json() : Promise.reject(new Error('oembed ' + r.status)))
    .then(j => {
      // Strip oembed's small crop and request a bigger one. IMPORTANT: use
      // `image_resize` (preserves aspect ratio) — NOT `image_crop_resized=WxH`
      // which forces a square crop.
      let thumb = (j.thumbnail_url || '').replace(/\?.*$/, '');
      if (thumb) thumb += '?image_resize=900';
      let mediaId = isWistiaShareUrl(key) ? null : key;
      if (!mediaId && typeof j.html === 'string') {
        const m =
          j.html.match(/embed\/iframe\/([a-z0-9]+)/i) ||
          j.html.match(/wistia_async_([a-z0-9]+)/i) ||
          j.html.match(/medias\/([a-z0-9]+)/i);
        if (m) mediaId = m[1];
      }
      const info = { thumb, mediaId };
      __wistiaInfoCache.set(key, info);
      return info;
    })
    .catch(() => {
      const info = {
        thumb: isWistiaShareUrl(key) ? '' : `https://fast.wistia.com/embed/medias/${key}/swatch`,
        mediaId: isWistiaShareUrl(key) ? null : key,
      };
      __wistiaInfoCache.set(key, info);
      return info;
    });
  __wistiaInfoInflight.set(key, p);
  return p;
}
function useWistiaInfo(key) {
  const [info, setInfo] = useState(() => (key && __wistiaInfoCache.get(key)) || null);
  useEffect(() => {
    if (!key) { setInfo(null); return; }
    if (__wistiaInfoCache.has(key)) { setInfo(__wistiaInfoCache.get(key)); return; }
    let cancelled = false;
    fetchWistiaInfo(key).then(i => { if (!cancelled) setInfo(i); });
    return () => { cancelled = true; };
  }, [key]);
  return info;
}

function WistiaThumb({ id, alt, hover, style }) {
  const info = useWistiaInfo(id);
  const url = info && info.thumb;
  return (
    <div style={{ position: 'absolute', inset: 0, background: '#0a0e18' }}>
      {url && (
        <img
          src={url}
          alt={alt}
          loading="lazy"
          onError={(e) => {
            const swatch = `https://fast.wistia.com/embed/medias/${id}/swatch`;
            if (e.currentTarget.src !== swatch) e.currentTarget.src = swatch;
          }}
          style={{
            width: '100%', height: '100%', objectFit: 'cover', display: 'block',
            transition: 'transform 0.6s ease, opacity 0.4s ease',
            opacity: 1,
            transform: hover ? 'scale(1.04)' : 'none',
            ...style,
          }}
        />
      )}
    </div>
  );
}

function PortfolioPage() {
  // Each project has: format (cat), audience (industry), quality tier.
  // Curated: Ultra → Pro → Air → Lite within each audience; strongest
  // catalogs (Adam, Keaton, Sarizza) lead. Empty drop-slots removed.
  const projects = [
    // ═══════════════ REELS & SHORTS ═══════════════

    // ─── Founders — Adam (Ultra · 6) ───
    { id: 'adam-1', title: 'Adam — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Ultra', client: 'Adam', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'q2ewlwhf5t', desc: 'Adam — founder-niche reel.' },
    { id: 'adam-2', title: 'Adam — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Ultra', client: 'Adam', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '3mk4f15f6v', desc: 'Adam — founder-niche reel.' },
    { id: 'adam-3', title: 'Adam — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Ultra', client: 'Adam', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '5mwzunxy7g', desc: 'Adam — founder-niche reel.' },
    { id: 'adam-4', title: 'Adam — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Ultra', client: 'Adam', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'mgdr07w6w2', desc: 'Adam — founder-niche reel.' },
    { id: 'adam-5', title: 'Adam — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Ultra', client: 'Adam', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'l5r73pthka', desc: 'Adam — founder-niche reel.' },
    { id: 'adam-6', title: 'Adam — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Ultra', client: 'Adam', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '21f90qnorg', desc: 'Adam — founder-niche reel.' },

    // ─── Founders — Benjamin (Pro · 4) ───
    { id: 'benjamin-1', title: 'Benjamin — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Pro', client: 'Benjamin', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'umb05fhhib', desc: 'Benjamin — founder reel.' },
    { id: 'benjamin-2', title: 'Benjamin — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Pro', client: 'Benjamin', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '5chx12nmxb', desc: 'Benjamin — founder reel.' },
    { id: 'benjamin-3', title: 'Benjamin — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Pro', client: 'Benjamin', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'shvd8j9050', desc: 'Benjamin — founder reel.' },
    { id: 'benjamin-4', title: 'Benjamin — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Pro', client: 'Benjamin', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '43m64ar6q2', desc: 'Benjamin — founder reel.' },

    // ─── Founders — Comp AI (Air · 3) ───
    { id: 'compai-1', title: 'Comp AI — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Air', client: 'Comp AI', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'bvce2y8kd1', desc: 'Comp AI — founder reel.' },
    { id: 'compai-2', title: 'Comp AI — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Air', client: 'Comp AI', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'bbu30la3i0', desc: 'Comp AI — founder reel.' },
    { id: 'compai-3', title: 'Comp AI — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Air', client: 'Comp AI', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'vc1ope5b7i', desc: 'Comp AI — founder reel.' },

    // ─── Founders — Finovamoney (Lite · 4) ───
    { id: 'finova-1', title: 'Finovamoney — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Lite', client: 'Finovamoney', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '581aphxpya', desc: 'Finovamoney founder reel.' },
    { id: 'finova-2', title: 'Finovamoney — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Lite', client: 'Finovamoney', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '6wbc4h48ew', desc: 'Finovamoney founder reel.' },
    { id: 'finova-3', title: 'Finovamoney — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Lite', client: 'Finovamoney', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'mjutvv9dyj', desc: 'Finovamoney founder reel.' },
    { id: 'finova-4', title: 'Finovamoney — Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Lite', client: 'Finovamoney', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'freqe0rsqd', desc: 'Finovamoney founder reel.' },

    // ─── Founders — Other (Air · 1) — reclassified from "Business" ───
    { id: 'biz-6r6', title: 'Founder Reel', cat: 'Reels & Shorts', audience: 'Founders', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '6r6hbqtdki', desc: 'Founder-niche reel.' },

    // ─── Fitness Coach — Keaton (Ultra · 11) ───
    { id: 'keaton-1', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'b7uzkvsztd', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-2', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'au3369aqzy', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-3', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'p0lsuky40s', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-4', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'a1wsqjfult', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-5', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'sm2k921157', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-6', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'h9g1uuks5x', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-7', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'dnivn1tnow', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-8', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 's3z1hv9k33', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-9', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '5sfpsieeni', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-10', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'gjjit7avqw', desc: 'Keaton fitness coaching reel.' },
    { id: 'keaton-11', title: 'Keaton — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Keaton', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '8rkfz7m3j0', desc: 'Keaton fitness coaching reel.' },

    // ─── Fitness Coach — Mica (Ultra · 9) ───
    { id: 'mica-1', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'h1j4stibi7', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-2', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '6eeidbo46n', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-3', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '9s1hlru11j', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-4', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'whcxpsocv3', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-5', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'e91pmrx51y', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-6', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'p7vvd6i2et', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-7', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'l30ppron5b', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-8', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'rjcyvuxk8z', desc: 'Mica fitness coaching reel.' },
    { id: 'mica-9', title: 'Mica — Fitness Reel', cat: 'Reels & Shorts', audience: 'Fitness Coach', quality: 'Ultra', client: 'Mica', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'jufxjm54z4', desc: 'Mica fitness coaching reel.' },

    // ─── Premium Brands — Sarizza (Ultra · 5) ───
    { id: 'sarizza-1', title: 'Sarizza — Premium Brand Reel', cat: 'Reels & Shorts', audience: 'Premium Brands', quality: 'Ultra', client: 'Sarizza', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '42d8na69u5', desc: 'Sarizza — premium brand reel.' },
    { id: 'sarizza-2', title: 'Sarizza — Premium Brand Reel', cat: 'Reels & Shorts', audience: 'Premium Brands', quality: 'Ultra', client: 'Sarizza', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'sbbw91notg', desc: 'Sarizza — premium brand reel.' },
    { id: 'sarizza-3', title: 'Sarizza — Premium Brand Reel', cat: 'Reels & Shorts', audience: 'Premium Brands', quality: 'Ultra', client: 'Sarizza', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '0vj5onyq07', desc: 'Sarizza — premium brand reel.' },
    { id: 'sarizza-4', title: 'Sarizza — Premium Brand Reel', cat: 'Reels & Shorts', audience: 'Premium Brands', quality: 'Ultra', client: 'Sarizza', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'x3fpr9tjj2', desc: 'Sarizza — premium brand reel.' },
    { id: 'sarizza-5', title: 'Sarizza — Premium Brand Reel', cat: 'Reels & Shorts', audience: 'Premium Brands', quality: 'Ultra', client: 'Sarizza', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'fzocys2zcc', desc: 'Sarizza — premium brand reel.' },

    // ─── Personal Brand — Mia (Pro · 3) ───
    { id: 'mia-1', title: 'Mia — Personal Brand Reel', cat: 'Reels & Shorts', audience: 'Personal Brand', quality: 'Pro', client: 'Mia', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '5akmdqt1f9', desc: 'Mia — personal-brand reel.' },
    { id: 'mia-2', title: 'Mia — Personal Brand Reel', cat: 'Reels & Shorts', audience: 'Personal Brand', quality: 'Pro', client: 'Mia', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'f4xdjihqs8', desc: 'Mia — personal-brand reel.' },
    { id: 'mia-3', title: 'Mia — Personal Brand Reel', cat: 'Reels & Shorts', audience: 'Personal Brand', quality: 'Pro', client: 'Mia', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'inf2paypxt', desc: 'Mia — personal-brand reel.' },

    // ─── Local Services (Ultra/Pro/Air · 6) ───
    { id: 'siam-featured-1', title: 'Local Service Reel', cat: 'Reels & Shorts', audience: 'Local Services', quality: 'Ultra', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'https://siamworking1.wistia.com/medias/r862hqp8sm', desc: 'Local-service reel.' },
    { id: 'siamworking-1', title: 'Local Service Reel', cat: 'Reels & Shorts', audience: 'Local Services', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'ubjjnuyzxj', desc: 'Local-service reel.' },
    { id: 'localpro-1', title: 'Local Service Reel', cat: 'Reels & Shorts', audience: 'Local Services', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'rrexau61aq', desc: 'Local-service reel.' },
    { id: 'localpro-2', title: 'Local Service Reel', cat: 'Reels & Shorts', audience: 'Local Services', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'd1mhzu9ps2', desc: 'Local-service reel.' },
    { id: 'localpro-3', title: 'Local Service Reel', cat: 'Reels & Shorts', audience: 'Local Services', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'as2s4uw2jr', desc: 'Local-service reel.' },
    { id: 'greenladder-1', title: 'Local Service Reel', cat: 'Reels & Shorts', audience: 'Local Services', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '0xofwrtfrp', desc: 'Local-service reel.' },

    // ─── Professionals (Pro · 4 / Air · 1 / Lite · 2) ───
    { id: 'pro-1', title: 'Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'tb10b4o5qg', desc: 'Professionals-niche reel.' },
    { id: 'pro-2', title: 'Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '2nz36jo4ca', desc: 'Professionals-niche reel.' },
    { id: 'pro-3', title: 'Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '0y80ehrqw5', desc: 'Professionals-niche reel.' },
    { id: 'pro-4', title: 'Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '1gm957wc22', desc: 'Professionals-niche reel.' },
    { id: 'pro-5', title: 'Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'x16vl3o4mi', desc: 'Professionals-niche reel.' },
    { id: 'aron-1', title: 'Aron Thomas — Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Lite', client: 'Aron Thomas', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'm6eoqxnes5', desc: 'Aron Thomas — professionals-niche reel.' },
    { id: 'aron-2', title: 'Aron Thomas — Professional Reel', cat: 'Reels & Shorts', audience: 'Professionals', quality: 'Lite', client: 'Aron Thomas', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'gfd5kpajv8', desc: 'Aron Thomas — professionals-niche reel.' },

    // ─── Storytelling / Style Cuts (Pro · 1 / Air · 5) — incl. former "Misc" ───
    { id: 'misc-2nj', title: 'Style Cut', cat: 'Reels & Shorts', audience: 'Storytelling', quality: 'Pro', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '2nj977dche', desc: 'Story-driven style cut.' },
    { id: 'helen-1', title: 'Helen — Storytelling Reel', cat: 'Reels & Shorts', audience: 'Storytelling', quality: 'Air', client: 'Helen', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: '46s4siig5w', desc: 'Helen — storytelling reel.' },
    { id: 'story-1', title: 'Storytelling Reel', cat: 'Reels & Shorts', audience: 'Storytelling', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'rj185ax0bp', desc: 'Story-driven reel.' },
    { id: 'story-2', title: 'Storytelling Reel', cat: 'Reels & Shorts', audience: 'Storytelling', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'wkkxsg8k4j', desc: 'Story-driven reel.' },
    { id: 'story-3', title: 'Storytelling Reel', cat: 'Reels & Shorts', audience: 'Storytelling', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'mz4tp17x5w', desc: 'Story-driven reel.' },
    { id: 'story-4', title: 'Storytelling Reel', cat: 'Reels & Shorts', audience: 'Storytelling', quality: 'Air', client: '—', kind: 'Vertical Reel · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/t3kwbxuwhpe1nkr', desc: 'Story-driven reel.' },

    // ═══════════════ VSL & TALKING HEAD ═══════════════
    { id: 'vsl-tgeb', title: 'Vertical VSL', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Pro', client: '—', kind: 'Vertical VSL · 9:16', ratio: '9/16', wistia: 'tgeb9ryq14', desc: 'Vertical VSL cut.' },
    { id: 'th-e348', title: 'Talking Head', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Pro', client: '—', kind: 'YouTube Long Form · 16:9', ratio: '16/9', wistia: 'https://arafat5nexcutmedia.wistia.com/s/e348j6whdb2vbqp', desc: 'Horizontal talking-head long-form.' },
    { id: 'th-s30m', title: 'Talking Head', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Pro', client: '—', kind: 'YouTube Long Form · 16:9', ratio: '16/9', wistia: 'https://arafat5nexcutmedia.wistia.com/s/s30msvbolyla16l', desc: 'Horizontal talking-head long-form.' },
    { id: 'th-h3ks', title: 'Talking Head', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Pro', client: '—', kind: 'YouTube Long Form · 16:9', ratio: '16/9', wistia: 'https://arafat5nexcutmedia.wistia.com/s/h3ks57pgig2dwsg', desc: 'Horizontal talking-head long-form.' },
    { id: 'th-y8fs', title: 'Talking Head', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Pro', client: '—', kind: 'YouTube Long Form · 16:9', ratio: '16/9', wistia: 'https://arafat5nexcutmedia.wistia.com/s/y8fsiutn9k9nst1', desc: 'Horizontal talking-head long-form.' },
    { id: 'th-gp3k', title: 'Talking Head', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Pro', client: '—', kind: 'YouTube Long Form · 16:9', ratio: '16/9', wistia: 'https://arafat5nexcutmedia.wistia.com/s/gp3knv7zpslcggk', desc: 'Horizontal talking-head long-form.' },
    { id: 'th-q2g', title: 'Talking Head', cat: 'VSL & Talking Head', audience: 'Founders', quality: 'Lite', client: '—', kind: 'YouTube Long Form · 16:9', ratio: '16/9', wistia: 'q2ghgynw4r', desc: 'Horizontal talking-head long-form.' },

    // ═══════════════ ADS / PAID SOCIAL ═══════════════
    { id: 'ad-xses', title: 'Paid Social Ad', cat: 'Ads / Paid Social', audience: 'Founders', quality: 'Ultra', client: '—', kind: 'Performance Ad · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/xsesjkiysrd2vym', desc: 'Vertical performance ad.' },
    { id: 'ad-8c61', title: 'Paid Social Ad', cat: 'Ads / Paid Social', audience: 'Founders', quality: 'Pro', client: '—', kind: 'Performance Ad · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/8c616empkgk2huc', desc: 'Vertical performance ad.' },
    { id: 'ad-btil', title: 'Paid Social Ad', cat: 'Ads / Paid Social', audience: 'Founders', quality: 'Air', client: '—', kind: 'Performance Ad · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/btilu20yehdusf5', desc: 'Vertical performance ad.' },
    { id: 'ad-el68', title: 'Paid Social Ad', cat: 'Ads / Paid Social', audience: 'Founders', quality: 'Ultra', client: '—', kind: 'Performance Ad · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/el68tyvfmlckfp2', desc: 'Vertical performance ad.' },
    { id: 'ad-pl4b', title: 'Paid Social Ad', cat: 'Ads / Paid Social', audience: 'Founders', quality: 'Pro', client: '—', kind: 'Performance Ad · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/pl4bea34dxthhgq', desc: 'Vertical performance ad.' },
    { id: 'ad-0uwv', title: 'Paid Social Ad', cat: 'Ads / Paid Social', audience: 'Founders', quality: 'Air', client: '—', kind: 'Performance Ad · 9:16', ratio: '9/16', wistia: 'https://arafat5nexcutmedia.wistia.com/s/0uwvh2ppzly1950', desc: 'Vertical performance ad.' },
  ];

  const formats = ['All', 'Reels & Shorts', 'VSL & Talking Head', 'Ads / Paid Social'];
  // Column count per format. "All" uses bento-grid-6 (true CSS-grid masonry,
  // no gaps); other formats keep the flex-bento or column masonry that already
  // looked clean for their tighter set of aspect ratios.
  const formatCols = {
    'All': 'bento-grid-6',
    'Reels & Shorts': 'masonry-5',
    'VSL & Talking Head': 'bento-5',
    'Ads / Paid Social': 'bento-5',
  };
  // Curated subsection order for the Reels & Shorts view. Ordered to lead
  // with strongest catalogs (Adam Ultra, Keaton/Mica Ultra, Sarizza Ultra),
  // then Pro/Air work, then ambient + local. Empty audiences ("Coaches",
  // "Business", "Hair Salons & Beauty", "Misc") were removed when the
  // placeholder slots were retired.
  const audiences = ['All', 'Founders', 'Fitness Coach', 'Premium Brands', 'Personal Brand', 'Local Services', 'Professionals', 'Storytelling'];
  const qualities = ['All', 'Lite', 'Air', 'Pro', 'Ultra'];

  const [format, setFormat] = useState('All');
  const [audience, setAudience] = useState('All');
  const [quality, setQuality] = useState('All');

  // Assign a stable roll number to every project based on its position in the
  // source array (1-indexed). This is the canonical identifier the user uses
  // to say "keep #12, drop #34" — it must NOT change with filters.
  const rollById = useMemo(() => {
    const m = new Map();
    projects.forEach((p, i) => m.set(p.id, i + 1));
    return m;
  }, []);

  const filtered = useMemo(() => {
    const list = projects
      .map(p => ({ ...p, roll: rollById.get(p.id) }))
      .filter(p =>
        (format === 'All' || p.cat === format) &&
        (audience === 'All' || p.audience === audience) &&
        (quality === 'All' || p.quality === quality)
      );

    // For "All" we want a true bento mix — interleave items by format and by
    // aspect ratio so portraits (9:16), landscapes (16:9) and squares (1:1)
    // are sprinkled throughout instead of stacking by source-order.
    if (format !== 'All') return list;

    // Bucket by format, then round-robin pull. Within each bucket we also
    // alternate the aspect ratios we have available so a wide 16:9 doesn't
    // immediately follow another wide 16:9.
    const buckets = new Map();
    for (const p of list) {
      if (!buckets.has(p.cat)) buckets.set(p.cat, []);
      buckets.get(p.cat).push(p);
    }
    // Sub-shuffle each bucket so multiple wides spread out within the bucket.
    for (const arr of buckets.values()) {
      // Deterministic interleave by ratio inside each bucket.
      const byRatio = new Map();
      for (const p of arr) {
        const k = p.ratio;
        if (!byRatio.has(k)) byRatio.set(k, []);
        byRatio.get(k).push(p);
      }
      const ratioQueues = [...byRatio.values()];
      arr.length = 0;
      while (ratioQueues.some(q => q.length)) {
        for (const q of ratioQueues) if (q.length) arr.push(q.shift());
      }
    }
    // Round-robin across formats. Reels are the biggest bucket so they
    // naturally fill the gaps; the other formats interject for rhythm.
    const queues = [...buckets.values()];
    const out = [];
    while (queues.some(q => q.length)) {
      for (const q of queues) if (q.length) out.push(q.shift());
    }
    return out;
  }, [format, audience, quality, rollById]);

  useEffect(() => {
    if (document.getElementById('wistia-script')) return;
    const s = document.createElement('script');
    s.id = 'wistia-script';
    s.src = 'https://fast.wistia.com/assets/external/E-v1.js';
    s.async = true;
    document.body.appendChild(s);
  }, []);

  // Reels & Shorts groups by audience with small subheadings; everything else is flat.
  const groups = useMemo(() => {
    if (format === 'Reels & Shorts') {
      const order = audiences.slice(1);
      return order
        .map(a => ({ key: a, audience: a, items: filtered.filter(p => p.audience === a) }))
        .filter(g => g.items.length);
    }
    return [{ key: 'all', items: filtered }];
  }, [format, filtered]);

  return (
    <div style={{ minHeight: '100vh' }}>
      {/* Top bar */}
      <header style={{
        position: 'relative', zIndex: 50,
        background: 'rgba(7,10,20,0.78)',
        backdropFilter: 'blur(18px)',
        borderBottom: '1px solid var(--line)',
      }}>
        <div className="container container-wide" style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '18px 24px',
        }}>
          <a href="index.html" style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <span style={{
              width: 28, height: 28, borderRadius: 8,
              border: '1px solid var(--line-2)',
              background: 'rgba(255,255,255,0.04)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              color: 'var(--ink-dim)',
            }}>
              <svg width="12" height="12" viewBox="0 0 14 14" fill="none">
                <path d="M9 11L5 7L9 3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </span>
            <Logo size={32} />
          </a>
          <a href="index.html#book-a-call" className="btn btn-primary" style={{ padding: '10px 18px' }}>
            Book a Call <IconArrow size={11} />
          </a>
        </div>
      </header>

      {/* Hero */}
      <section style={{ position: 'relative', padding: '80px 0 40px', overflow: 'hidden' }}>
        <div aria-hidden style={{
          position: 'absolute', top: -120, left: '50%', transform: 'translateX(-50%)',
          width: 1100, height: 520,
          background: 'radial-gradient(ellipse at center, rgba(74,142,255,0.32), rgba(74,142,255,0.08) 40%, transparent 70%)',
          filter: 'blur(80px)', pointerEvents: 'none',
        }} />
        <div className="container" style={{ textAlign: 'center', position: 'relative' }}>
          <SectionEyebrow label="The Portfolio" />
          <h1 className="display pf-hero-title" style={{ fontSize: 'clamp(48px, 7vw, 88px)', marginTop: 22, lineHeight: 1.0 }}>
            <span className="serif-italic" style={{ color: 'var(--ink-dim)' }}>Some Of Our</span><br />
            Featured Projects
          </h1>
          <p className="pf-hero-sub" style={{ marginTop: 22, fontSize: 17, color: 'var(--ink-dim)', maxWidth: 640, marginLeft: 'auto', marginRight: 'auto', lineHeight: 1.55 }}>
            A working archive of recent cuts — filter by format, industry and tier, or browse the full mix.
          </p>
        </div>
      </section>

      {/* Filter bar */}
      <section style={{ position: 'sticky', top: 0, zIndex: 40, padding: '18px 0', background: 'rgba(7,10,20,0.82)', backdropFilter: 'blur(18px)', borderBottom: '1px solid var(--line)' }}>
        <div className="container container-wide" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <FilterRow label="Format" options={formats} active={format} onChange={setFormat} counts={(o) => o === 'All' ? projects.length : projects.filter(p => p.cat === o).length} />
          <FilterRow label="Tier" options={qualities} active={quality} onChange={setQuality} kind="quality" subtle />

          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 4, gap: 16, flexWrap: 'wrap' }}>
            <div style={{ fontSize: 12.5, color: 'var(--ink-muted)', fontFamily: "'Geist Mono', ui-monospace, monospace", whiteSpace: 'nowrap' }}>
              Showing <span style={{ color: 'var(--ink)' }}>{filtered.length}</span> / {projects.length}
            </div>
            {(format !== 'All' || audience !== 'All' || quality !== 'All') && (
              <button
                onClick={() => { setFormat('All'); setAudience('All'); setQuality('All'); }}
                style={{
                  background: 'transparent',
                  border: '1px solid var(--line)',
                  color: 'var(--ink-dim)',
                  padding: '6px 12px',
                  borderRadius: 999,
                  fontSize: 12,
                  cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', gap: 6,
                }}
              >
                <IconClose size={10} /> Clear filters
              </button>
            )}
          </div>
        </div>
      </section>

      {/* Grid */}
      <section style={{ padding: '36px 0 90px' }}>
        <div className="container container-wide">
          {groups.length === 0 || filtered.length === 0 ? (
            <div style={{ padding: '80px 0', textAlign: 'center', color: 'var(--ink-muted)' }}>
              No projects match this combination. Try clearing a filter.
            </div>
          ) : (
            groups.map((g, gi) => {
              // Split by client when an audience has multiple distinct named clients (e.g. Fitness Coach → Keaton row, Mica row).
              const clientOrder = (() => {
                if (format !== 'Reels & Shorts' || !g.audience) return null;
                const seen = [];
                for (const p of g.items) {
                  if (p.client && p.client !== '—' && !seen.includes(p.client)) seen.push(p.client);
                }
                return seen.length > 1 ? seen : null;
              })();
              return (
                <div key={g.key} style={{ marginBottom: gi < groups.length - 1 ? 48 : 0 }}>
                  {format === 'Reels & Shorts' && g.audience && (
                    <SubsectionHeading audience={g.audience} count={g.items.length} />
                  )}
                  {clientOrder ? (
                    <>
                      {clientOrder.map((client, ci) => {
                        const named = g.items.filter(p => p.client === client);
                        if (!named.length) return null;
                        return (
                          <div key={client} style={{ marginBottom: 20 }}>
                            <ClientRowLabel name={client} count={named.length} />
                            <div className="client-row-grid">
                              {named.map((p) => (
                                <PortfolioTile key={p.id} project={p} />
                              ))}
                            </div>
                          </div>
                        );
                      })}
                      {(() => {
                        const unnamed = g.items.filter(p => !p.client || p.client === '—');
                        if (!unnamed.length) return null;
                        return (
                          <div>
                            <ClientRowLabel name="Other" count={unnamed.length} />
                            <div className="client-row-grid">
                              {unnamed.map((p) => (
                                <PortfolioTile key={p.id} project={p} />
                              ))}
                            </div>
                          </div>
                        );
                      })()}
                    </>
                  ) : format === 'Reels & Shorts' ? (
                    <div className="client-row-grid">
                      {g.items.map((p) => (
                        <PortfolioTile key={p.id} project={p} />
                      ))}
                    </div>
                  ) : (
                    (() => {
                      const cls = formatCols[format] || 'masonry-4';
                      const container =
                        cls.startsWith('bento-grid') ? 'bento-grid' :
                        cls.startsWith('bento') ? 'bento' : 'masonry';
                      return (
                        <BentoGrid className={`${container} ${cls}`} isGrid={container === 'bento-grid'}>
                          {g.items.map((p) => (
                            <PortfolioTile key={p.id} project={p} />
                          ))}
                        </BentoGrid>
                      );
                    })()
                  )}
                </div>
              );
            })
          )}

          {/* CTA strip */}
          <div className="pf-cta-strip" style={{
            marginTop: 80,
            padding: '48px',
            borderRadius: 24,
            border: '1px solid var(--line)',
            background: 'linear-gradient(135deg, rgba(74,142,255,0.10), rgba(74,142,255,0.02))',
            display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 32, flexWrap: 'wrap',
          }}>
            <div>
              <h3 className="display" style={{ fontSize: 'clamp(24px, 3vw, 34px)', lineHeight: 1.1 }}>
                <span className="serif-italic" style={{ color: 'var(--ink-dim)' }}>Like what you see?</span><br />
                Let's build your content system.
              </h3>
            </div>
            <a href="index.html#book-a-call" className="btn btn-primary">Book a 30-min call <IconArrow size={12} /></a>
          </div>
        </div>
      </section>
    </div>
  );
}

function FilterRow({ label, options, active, onChange, counts, kind, subtle }) {
  const tierColors = {
    'Lite':  { dot: '#8fa7c4', bg: 'rgba(143,167,196,0.10)', border: 'rgba(143,167,196,0.35)' },
    'Air':   { dot: '#6ea7ff', bg: 'rgba(110,167,255,0.12)', border: 'rgba(110,167,255,0.40)' },
    'Pro':   { dot: '#a78bff', bg: 'rgba(167,139,255,0.14)', border: 'rgba(167,139,255,0.45)' },
    'Ultra': { dot: '#ffc46e', bg: 'rgba(255,196,110,0.14)', border: 'rgba(255,196,110,0.45)' },
  };

  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>
      <div style={{
        flex: '0 0 64px',
        fontSize: 11,
        color: 'var(--ink-muted)',
        fontFamily: "'Geist Mono', ui-monospace, monospace",
        textTransform: 'uppercase',
        letterSpacing: '0.08em',
      }}>{label}</div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        {options.map((o) => {
          const isActive = o === active;
          const count = counts ? counts(o) : null;
          const tier = kind === 'quality' && o !== 'All' ? tierColors[o] : null;
          if (subtle) {
            return (
              <button
                key={o}
                onClick={() => onChange(o)}
                style={{
                  display: 'inline-flex', alignItems: 'center', gap: 6,
                  padding: '4px 10px',
                  borderRadius: 999,
                  border: '1px solid transparent',
                  background: 'transparent',
                  color: isActive ? 'var(--ink)' : 'var(--ink-muted)',
                  fontSize: 12,
                  fontWeight: 500,
                  cursor: 'pointer',
                  transition: 'color 0.18s ease, background 0.18s ease',
                  letterSpacing: '-0.005em',
                  opacity: isActive ? 1 : 0.75,
                  whiteSpace: 'nowrap',
                }}
                onMouseEnter={(e) => { if (!isActive) { e.currentTarget.style.color = 'var(--ink-dim)'; e.currentTarget.style.opacity = '1'; } }}
                onMouseLeave={(e) => { if (!isActive) { e.currentTarget.style.color = 'var(--ink-muted)'; e.currentTarget.style.opacity = '0.75'; } }}
              >
                {tier && (
                  <span style={{ width: 5, height: 5, borderRadius: '50%', background: tier.dot, opacity: isActive ? 1 : 0.7 }} />
                )}
                {o}
              </button>
            );
          }
          return (
            <button
              key={o}
              onClick={() => onChange(o)}
              style={{
                display: 'inline-flex', alignItems: 'center', gap: 8,
                padding: '8px 14px',
                borderRadius: 999,
                border: isActive
                  ? (tier ? `1px solid ${tier.border}` : '1px solid rgba(74,142,255,0.55)')
                  : '1px solid var(--line)',
                background: isActive
                  ? (tier ? tier.bg : 'linear-gradient(180deg, rgba(74,142,255,0.22), rgba(74,142,255,0.08))')
                  : 'rgba(255,255,255,0.02)',
                color: isActive ? '#fff' : 'var(--ink-dim)',
                fontSize: 13,
                fontWeight: 500,
                cursor: 'pointer',
                transition: 'all 0.18s ease',
                letterSpacing: '-0.005em',
                whiteSpace: 'nowrap',
              }}
              onMouseEnter={(e) => { if (!isActive) e.currentTarget.style.borderColor = 'var(--line-2)'; }}
              onMouseLeave={(e) => { if (!isActive) e.currentTarget.style.borderColor = 'var(--line)'; }}
            >
              {tier && (
                <span style={{ width: 7, height: 7, borderRadius: '50%', background: tier.dot, boxShadow: `0 0 8px ${tier.dot}` }} />
              )}
              {o}
              {count !== null && (
                <span style={{
                  fontSize: 10.5,
                  padding: '2px 6px',
                  borderRadius: 999,
                  background: isActive ? 'rgba(255,255,255,0.18)' : 'rgba(255,255,255,0.05)',
                  color: isActive ? '#fff' : 'var(--ink-muted)',
                }}>{count}</span>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}

function FeaturedStrip({ picks }) {
  const [big, p2, p3] = picks;
  return (
    <div style={{ marginBottom: 36 }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        marginBottom: 16,
      }}>
        <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#ffc46e', boxShadow: '0 0 10px #ffc46e' }} />
        <span style={{
          fontSize: 11.5,
          letterSpacing: '0.08em',
          textTransform: 'uppercase',
          color: '#ffc46e',
          fontFamily: "'Geist Mono', ui-monospace, monospace",
        }}>Editor’s Picks</span>
        <span style={{ flex: 1, height: 1, background: 'var(--line)' }} />
      </div>
      <div style={{
        display: 'grid',
        gridTemplateColumns: 'minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr)',
        gap: 14,
      }}
      className="featured-strip"
      >
        <FeaturedTile project={big} large />
        <FeaturedTile project={p2} />
        <FeaturedTile project={p3} />
      </div>
    </div>
  );
}

function FeaturedTile({ project, large }) {
  const [hover, setHover] = useState(false);
  const [playing, setPlaying] = useState(false);
  const canPlay = !project.placeholder && project.wistia;
  const tierColors = {
    'Lite':  { dot: '#8fa7c4' }, 'Air': { dot: '#6ea7ff' },
    'Pro':   { dot: '#a78bff' }, 'Ultra': { dot: '#ffc46e' },
  };
  const tier = tierColors[project.quality];
  return (
    <div
      onClick={() => canPlay && !playing && setPlaying(true)}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative',
        aspectRatio: large ? '16/10' : '9/12',
        borderRadius: 20,
        overflow: 'hidden',
        border: '1px solid var(--line)',
        background: '#0a0e18',
        cursor: canPlay && !playing ? 'pointer' : 'default',
        transition: 'transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease',
        transform: hover && !playing ? 'translateY(-3px)' : 'none',
        boxShadow: hover ? '0 24px 60px -20px rgba(74,142,255,0.45)' : '0 0 0 transparent',
        borderColor: hover ? 'rgba(110,167,255,0.4)' : 'var(--line)',
      }}
    >
      {playing ? (
        <div
          className={`wistia_embed wistia_async_${project.wistia} autoPlay=true videoFoam=true playerColor=2949E5`}
          style={{ width: '100%', height: '100%', position: 'absolute', inset: 0 }}
        >&nbsp;</div>
      ) : project.gif ? (
        <img src={project.gif} alt={project.title} loading="lazy"
          style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', transition: 'transform 0.7s ease', transform: hover ? 'scale(1.05)' : 'none' }} />
      ) : (
        <WistiaThumb id={project.wistia} alt={project.title} hover={hover}
          style={{ transition: 'transform 0.7s ease', transform: hover ? 'scale(1.05)' : 'none' }} />
      )}
      {!playing && (
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(180deg, rgba(0,0,0,0.0) 25%, rgba(0,0,0,0.45) 65%, rgba(0,0,0,0.92))',
          pointerEvents: 'none',
        }} />
      )}
      {!playing && (
        <>
          <div style={{
            position: 'absolute', top: 14, left: 14,
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '5px 10px',
            borderRadius: 999,
            background: 'rgba(255,196,110,0.16)',
            backdropFilter: 'blur(10px)',
            border: '1px solid rgba(255,196,110,0.45)',
            fontSize: 10.5, fontWeight: 600,
            color: '#fff',
            letterSpacing: '0.05em', textTransform: 'uppercase',
          }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#ffc46e', boxShadow: '0 0 8px #ffc46e' }} />
            Featured
          </div>
          {!project.placeholder && (
            <div style={{
              position: 'absolute', bottom: 16, right: 16,
              width: large ? 52 : 40, height: large ? 52 : 40, borderRadius: '50%',
              background: hover ? '#fff' : 'rgba(255,255,255,0.16)',
              backdropFilter: 'blur(10px)',
              border: '1px solid rgba(255,255,255,0.22)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              color: hover ? '#000' : '#fff',
              transition: 'all 0.3s ease',
            }}>
              <svg width={large ? 16 : 13} height={large ? 16 : 13} viewBox="0 0 20 20"><path d="M5 3 L17 10 L5 17 Z" fill="currentColor" /></svg>
            </div>
          )}
          <div style={{
            position: 'absolute', left: 18, right: 18, bottom: 18,
            paddingRight: large ? 68 : 52,
          }}>
            <div style={{
              fontSize: 10.5,
              color: 'rgba(255,255,255,0.7)',
              letterSpacing: '0.06em',
              textTransform: 'uppercase',
              marginBottom: 6,
              display: 'inline-flex', alignItems: 'center', gap: 8,
            }}>
              {tier && <span style={{ width: 5, height: 5, borderRadius: '50%', background: tier.dot, boxShadow: `0 0 6px ${tier.dot}` }} />}
              {project.audience} · {project.quality}
            </div>
            <div style={{
              fontSize: large ? 22 : 15.5,
              fontWeight: 600,
              color: '#fff',
              letterSpacing: '-0.015em',
              lineHeight: 1.2,
              textShadow: '0 1px 12px rgba(0,0,0,0.55)',
            }}>{project.title}</div>
          </div>
        </>
      )}
    </div>
  );
}

function StatsBar({ projects }) {
  const real = projects.filter(p => !p.placeholder);
  const ultra = projects.filter(p => p.quality === 'Ultra').length;
  const audiences = new Set(real.map(p => p.audience));
  const formats = new Set(real.map(p => p.cat));
  const items = [
    { v: real.length, l: 'cuts shipped' },
    { v: audiences.size, l: 'industries' },
    { v: formats.size, l: 'formats' },
    { v: ultra, l: 'ultra-tier picks' },
  ];
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: 'repeat(4, minmax(0, 1fr))',
      gap: 0,
      marginBottom: 36,
      padding: '22px 28px',
      borderRadius: 18,
      border: '1px solid var(--line)',
      background: 'linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.005))',
    }}
    className="stats-bar"
    >
      {items.map((it, i) => (
        <div key={it.l} style={{
          padding: '0 18px',
          borderLeft: i === 0 ? 'none' : '1px solid var(--line)',
        }}>
          <div style={{
            fontSize: 30,
            fontWeight: 600,
            letterSpacing: '-0.025em',
            lineHeight: 1,
            color: 'var(--ink)',
          }}>{it.v}</div>
          <div style={{
            marginTop: 6,
            fontSize: 11.5,
            color: 'var(--ink-muted)',
            fontFamily: "'Geist Mono', ui-monospace, monospace",
            letterSpacing: '0.04em',
            textTransform: 'uppercase',
          }}>{it.l}</div>
        </div>
      ))}
    </div>
  );
}

function ClientRowLabel({ name, count }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      marginBottom: 10,
    }}>
      <span style={{
        fontSize: 12.5,
        color: 'var(--ink)',
        fontWeight: 500,
        letterSpacing: '-0.005em',
      }}>{name}</span>
      <span style={{
        fontSize: 11,
        color: 'var(--ink-muted)',
        fontFamily: "'Geist Mono', ui-monospace, monospace",
      }}>{count}</span>
      <span style={{ flex: 1, height: 1, background: 'var(--line)' }} />
    </div>
  );
}

function SubsectionHeading({ audience, count }) {
  const meta = {
    'Founders': { caption: 'Hook-first reels built for startup founders building in public.' },
    'Business': { caption: 'Business-niche reels for operators, agencies and B2B brands.' },
    'Coaches': { caption: 'High-retention shorts for coaches and creators selling 1:1 or cohorts.' },
    'Personal Brand': { caption: 'Identity-first reels for creators and operators building a face-of-the-brand presence.' },
    'Fitness Coach': { caption: 'Energetic motion-driven reels for fitness coaches and courses.' },
    'Premium Brands': { caption: 'Editorial, fashion-grade cuts for premium and luxury brands.' },
    'Professionals': { caption: 'Sharp talking-head reels for lawyers, advisors, consultants and other licensed pros.' },
    'Storytelling': { caption: 'Narrative-led style cuts with cinematic pacing and visual rhythm.' },
    'Local Services': { caption: 'Cuts for roofers, plumbers, HVAC and other local service businesses.' },
    'Hair Salons & Beauty': { caption: 'Cinematic before/after moments for salons and beauty brands.' },
    'Misc': { caption: 'A grab-bag of one-off reels and experimental cuts.' },
  };
  const cap = (meta[audience] || {}).caption || '';
  return (
    <div style={{
      display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
      gap: 16, flexWrap: 'wrap',
      padding: '4px 0 16px',
      marginBottom: 16,
    }}>
      <div>
        <h3 className="display" style={{
          fontSize: 26,
          fontWeight: 700,
          lineHeight: 1.1,
          letterSpacing: '-0.02em',
          color: 'var(--ink)',
        }}>{audience}</h3>
        {cap && (
          <p style={{
            marginTop: 6,
            fontSize: 13.5,
            color: 'var(--ink-dim)',
            maxWidth: 520,
            lineHeight: 1.45,
          }}>{cap}</p>
        )}
      </div>
      <span style={{
        fontSize: 11.5,
        color: 'var(--ink-muted)',
        fontFamily: "'Geist Mono', ui-monospace, monospace",
      }}>{count} {count === 1 ? 'project' : 'projects'}</span>
    </div>
  );
}

function SectionHeading({ audience, count }) {
  const meta = {
    'Founders': { caption: 'For startup founders', desc: 'Talking-head reels, long-form essays and personal-brand cuts for solo founders and operators.' },
    'Business': { caption: 'For business operators', desc: 'Reels and cuts for business-niche creators, agencies and B2B brands.' },
    'Coaches': { caption: 'For coaches & creators', desc: 'High-retention coaching reels and long-form course content.' },
    'Personal Brand': { caption: 'For personal brands', desc: 'Identity-first reels and signature cuts for creators and operators building a face-of-the-brand presence.' },
    'Fitness Coach': { caption: 'For fitness coaches & courses', desc: 'Energetic motion-driven reels, course explainers and conversion-focused ad creative.' },
    'Premium Brands': { caption: 'For premium & luxury brands', desc: 'Editorial, fashion-grade cuts with cinematic pacing for premium and luxury brand creators.' },
    'Professionals': { caption: 'For licensed professionals', desc: 'Authoritative reels for lawyers, advisors, consultants and other industry professionals.' },
    'Storytelling': { caption: 'For story-driven creators', desc: 'Narrative-led reels and style cuts with cinematic pacing, voiceover and visual rhythm.' },
    'Local Services': { caption: 'For roofers, plumbers & trades', desc: 'Conversion-focused reels for roofers, plumbers, HVAC, electricians and other local service businesses.' },
    'Hair Salons & Beauty': { caption: 'For salons & beauty brands', desc: 'Cinematic before/after reels and lifestyle moments for beauty businesses.' },
    'Misc': { caption: 'For everything else', desc: 'A grab-bag of one-off reels and experimental cuts.' },
  }[audience] || { caption: audience, desc: '' };

  return (
    <div style={{
      display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
      gap: 24, flexWrap: 'wrap',
      padding: '4px 0 22px',
      marginBottom: 18,
      borderBottom: '1px solid var(--line)',
    }}>
      <div>
        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 8,
          fontSize: 12, color: 'var(--accent-2)',
          fontFamily: "'Geist Mono', ui-monospace, monospace",
          letterSpacing: '0.06em', textTransform: 'uppercase',
          marginBottom: 10,
        }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--accent-2)', boxShadow: '0 0 10px var(--accent-2)' }} />
          {meta.caption}
        </div>
        <h2 className="display" style={{ fontSize: 'clamp(26px, 3.2vw, 36px)', lineHeight: 1.05, letterSpacing: '-0.02em' }}>
          {audience}
        </h2>
        {meta.desc && (
          <p style={{ marginTop: 8, fontSize: 14, color: 'var(--ink-dim)', maxWidth: 560 }}>{meta.desc}</p>
        )}
      </div>
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: '8px 14px',
        borderRadius: 999,
        border: '1px solid var(--line)',
        background: 'rgba(255,255,255,0.02)',
        fontSize: 12.5,
        color: 'var(--ink-dim)',
        fontFamily: "'Geist Mono', ui-monospace, monospace",
      }}>
        <span style={{ color: 'var(--ink)' }}>{count}</span> projects
      </div>
    </div>
  );
}

// Bento masonry container. For `isGrid=true` (CSS-grid mode), it measures each
// child's rendered height and writes a grid-row span so the grid behaves like
// a true masonry — no gaps below short tiles. For non-grid modes it just
// renders a plain div passthrough.
function BentoGrid({ className, isGrid, children }) {
  const ref = useRef(null);

  useEffect(() => {
    if (!isGrid) return;
    const grid = ref.current;
    if (!grid) return;

    const compute = () => {
      const styles = getComputedStyle(grid);
      const rowH = parseFloat(styles.gridAutoRows) || 1;
      // We use row-gap: 0 and column-gap: var(--tile-gap), then add the
      // desired tile gap into each tile's row-span so the vertical gap
      // below the tile exactly matches the horizontal column-gap.
      const targetGap = parseFloat(styles.columnGap) || 10;
      const items = grid.querySelectorAll(':scope > .masonry-item');
      items.forEach((it, idx) => {
        // Temporarily clear so we measure the natural (aspect-ratio-driven) height
        it.style.gridRowEnd = '';
        const h = it.getBoundingClientRect().height;
        if (!h) return;
        // Span = ceil(tile height / rowH) + the gap tracks below it (omit
        // the gap on the absolute last tile so the grid doesn't trail blank
        // space — but in practice the next row's tiles cover this).
        const span = Math.max(1, Math.ceil(h / rowH) + Math.round(targetGap / rowH));
        it.style.gridRowEnd = `span ${span}`;
      });
    };

    // Compute now, after fonts/layout settle, and again on resize.
    compute();
    const raf = requestAnimationFrame(compute);
    const ro = new ResizeObserver(compute);
    ro.observe(grid);
    grid.querySelectorAll(':scope > .masonry-item').forEach((it) => ro.observe(it));
    window.addEventListener('resize', compute);

    // Re-measure once images/iframes load — Wistia thumbs swap in async.
    const imgs = grid.querySelectorAll('img');
    imgs.forEach((img) => {
      if (!img.complete) img.addEventListener('load', compute, { once: true });
    });

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
      window.removeEventListener('resize', compute);
    };
  }, [isGrid, children]);

  return <div ref={ref} className={className}>{children}</div>;
}

function PortfolioTile({ project }) {
  const [hover, setHover] = useState(false);
  const [playing, setPlaying] = useState(false);
  const ref = useReveal();
  const ratioLabel = project.ratio.replace('/', ':');
  // Resolve to the real media ID. For plain 10-char IDs this is a no-op; for
  // share URLs (`https://*.wistia.com/s/<token>`) we wait on the oembed lookup
  // — `info?.mediaId` becomes available after fetchWistiaInfo resolves.
  const info = useWistiaInfo(project.wistia);
  const wistiaId = (info && info.mediaId) || (isWistiaShareUrl(project.wistia) ? null : project.wistia);
  const canPlay = !project.placeholder && !!wistiaId;

  const tierColors = {
    'Lite':  { dot: '#8fa7c4', bg: 'rgba(143,167,196,0.12)', border: 'rgba(143,167,196,0.35)' },
    'Air':   { dot: '#6ea7ff', bg: 'rgba(110,167,255,0.16)', border: 'rgba(110,167,255,0.40)' },
    'Pro':   { dot: '#a78bff', bg: 'rgba(167,139,255,0.18)', border: 'rgba(167,139,255,0.45)' },
    'Ultra': { dot: '#ffc46e', bg: 'rgba(255,196,110,0.18)', border: 'rgba(255,196,110,0.50)' },
  };
  const tier = tierColors[project.quality];

  const handleClick = () => {
    if (canPlay && !playing) setPlaying(true);
  };

  return (
    <div
      ref={ref}
      className={`reveal masonry-item${project.ratio === '16/9' ? ' masonry-item-wide' : ''}`}
      onClick={handleClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative',
        aspectRatio: project.ratio,
        borderRadius: 18,
        overflow: 'hidden',
        border: '1px solid var(--line)',
        background: '#0a0e18',
        cursor: canPlay && !playing ? 'pointer' : 'default',
        transition: 'transform 0.3s ease, border-color 0.3s ease',
        transform: hover && !playing ? 'translateY(-3px)' : 'none',
        borderColor: hover ? 'var(--line-2)' : 'var(--line)',
      }}
    >
      {playing ? (
        <div
          className={`wistia_embed wistia_async_${wistiaId} autoPlay=true videoFoam=true playerColor=2949E5`}
          style={{ width: '100%', height: '100%', position: 'absolute', inset: 0 }}
        >&nbsp;</div>
      ) : project.placeholder ? (
        <Placeholder ratioLabel={ratioLabel} kind={project.kind} />
      ) : project.gif ? (
        <img src={project.gif} alt={project.title} loading="lazy"
          style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', transition: 'transform 0.6s ease', transform: hover ? 'scale(1.04)' : 'none' }} />
      ) : (
        <WistiaThumb id={project.wistia} alt={project.title} hover={hover} />
      )}

      {!project.placeholder && !playing && (
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(180deg, rgba(0,0,0,0.0) 35%, rgba(0,0,0,0.55) 75%, rgba(0,0,0,0.92))',
          pointerEvents: 'none',
        }} />
      )}

      {/* Roll number — internal identifier, kept subtle so visitors barely notice */}
      {!playing && project.roll != null && (
        <div style={{
          position: 'absolute', top: 8, left: 10,
          fontSize: 10,
          fontWeight: 500,
          fontFamily: "'Geist Mono', ui-monospace, monospace",
          color: 'rgba(255,255,255,0.32)',
          letterSpacing: '0.04em',
          textShadow: '0 1px 2px rgba(0,0,0,0.5)',
          pointerEvents: 'none',
          mixBlendMode: 'screen',
          zIndex: 2,
        }}>
          #{String(project.roll).padStart(2, '0')}
        </div>
      )}

      {/* Top-right stack: ratio + tier */}
      {!playing && (
        <div style={{ position: 'absolute', top: 12, right: 12, display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'flex-end' }}>
          <div style={{
            padding: '4px 9px',
            borderRadius: 7,
            background: 'rgba(8,12,22,0.7)',
            backdropFilter: 'blur(10px)',
            border: '1px solid rgba(255,255,255,0.10)',
            fontSize: 10.5,
            fontFamily: "'Geist Mono', ui-monospace, monospace",
            color: 'var(--ink-dim)',
            letterSpacing: '0.04em',
          }}>{ratioLabel}</div>
          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '4px 10px',
            borderRadius: 999,
            background: tier.bg,
            backdropFilter: 'blur(10px)',
            border: `1px solid ${tier.border}`,
            fontSize: 10.5,
            fontWeight: 500,
            color: '#fff',
            letterSpacing: '0.04em',
            textTransform: 'uppercase',
          }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: tier.dot, boxShadow: `0 0 8px ${tier.dot}` }} />
            {project.quality}
          </div>
        </div>
      )}

      {/* Play button */}
      {!project.placeholder && !playing && (
        <div style={{
          position: 'absolute', bottom: 14, right: 14,
          width: 38, height: 38, borderRadius: '50%',
          background: hover ? '#fff' : 'rgba(255,255,255,0.14)',
          backdropFilter: 'blur(10px)',
          border: '1px solid rgba(255,255,255,0.18)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: hover ? '#000' : '#fff',
          transition: 'all 0.3s ease',
        }}>
          <svg width="12" height="12" viewBox="0 0 20 20"><path d="M5 3 L17 10 L5 17 Z" fill="currentColor" /></svg>
        </div>
      )}

      {/* Title block removed — tiles are pure video previews; metadata lives in filters + tier pill */}
    </div>
  );
}

function Placeholder({ ratioLabel, kind }) {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: `
        repeating-linear-gradient(135deg, rgba(255,255,255,0.025) 0 12px, transparent 12px 24px),
        radial-gradient(ellipse at center, rgba(74,142,255,0.10), transparent 60%),
        #0b1020
      `,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <div style={{
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
        padding: '24px',
        textAlign: 'center',
      }}>
        <div style={{
          width: 48, height: 48, borderRadius: 14,
          border: '1px dashed rgba(110,167,255,0.45)',
          background: 'rgba(74,142,255,0.06)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: 'var(--accent-2)',
        }}>
          <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
            <path d="M10 4v12M4 10h12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
          </svg>
        </div>
        <div>
          <div style={{ fontSize: 12, color: 'var(--accent-2)', fontFamily: "'Geist Mono', ui-monospace, monospace", letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 6 }}>
            {ratioLabel} placeholder
          </div>
          <div style={{ fontSize: 13.5, color: 'var(--ink-dim)', lineHeight: 1.45, maxWidth: 200 }}>
            Drop {kind.split('·')[0].trim().toLowerCase()} here
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PortfolioPage, PortfolioTile, Placeholder, FilterRow, SectionHeading, SubsectionHeading, ClientRowLabel, FeaturedStrip, FeaturedTile, StatsBar, BentoGrid });
