// hifi-contenu.jsx — Section Contenu : vidéos YouTube + articles du site
// Filtres : Tous | Vidéos | Articles

// Curated descriptions by video ID — rewrites the raw RSS description
// to give desire to watch. Falls back to RSS description for unknown IDs.
const VIDEO_DESCRIPTIONS = {
  'vhkt6vcSYDM': 'On gère l\'acquisition de 80+ clients B2B. Voici les deux outils qu\'on utilise sur chaque mission — et pourquoi cette stack bat tout le reste.',
  'tloC0NqPx0g': '80 clients B2B accompagnés, toujours la même méthode. Le système qu\'on réplique à chaque nouveau client pour générer des RDV qualifiés dès le premier mois.',
  'y4ZBu-fN7Hs': 'Et si vous pouviez construire votre propre OS d\'acquisition avec l\'IA ? Je montre comment on automatise la prospection de A à Z avec Claude Code.',
  'ffdC5CdrbHE': 'Arrêtez d\'acheter des listes au hasard. Le TAM Building vous donne le contrôle total sur votre marché adressable — et décuple votre précision de ciblage.',
  'Nzp2OoKOU78': 'Une seule astuce dans HubSpot, et vos sales récupèrent 3 à 5h par semaine. Simple à installer, immédiatement rentable.',
  'SC7YSKcsMSg': 'Si vous ne mesurez pas votre acquisition, vous pilotez à l\'aveugle. Ce workflow en 5 minutes vous donne une vision claire de ce qui génère vraiment du pipeline.',
  'QTJ9_3G3aVQ': '6 piliers que 90% des boîtes ratent : infrastructure, data, ciblage, messaging, nurturing, tracking. Identifiez les vôtres avant que ça coûte cher.',
  'Q5K-aqEhoLM': 'Un deal perdu, c\'est rarement définitif. Ce workflow détecte automatiquement les KO et relance au bon moment — et récupère 1 deal sur 3.',
  'u5Rwy5nDNvs': 'La masterclass complète : ICP fit, intent data, contenu social, workflows RevOps. 200+ RDV générés avec ce système — tout est dans cette vidéo.',
  'QTUCfdWPxpo': '70% de no-show, c\'est de l\'argent perdu. Cette méthode amène certains clients à 90% de show-up sur leurs RDV commerciaux. Applicable en une journée.',
  'Md1xl9ZYNPo': 'Vos sales perdent des heures à chercher des données dispersées. Ce workflow centralise tout et les rend opérationnels en quelques secondes.',
  'oGq5GC3zHOQ': 'Un CRM sale = un pipeline non fiable. Voici la méthode avec Clay pour nettoyer, déduper et enrichir vos données en automatique.',
  'rNgk7clRglc': 'Chaque nouvelle prise de poste est une opportunité. Ce workflow la détecte et envoie le bon message au bon moment — sans intervention manuelle.',
  'kxme_wOgFtM': 'Enrichir vos leads à la main avant de les entrer dans le CRM, c\'est fini. Ce workflow le fait à votre place, en temps réel, à chaque nouveau contact.',
  '4SzCB70LbRw': 'Retrouvez le profil LinkedIn de n\'importe quel prospect en quelques secondes — sans Sales Nav, avec Clay et ChatGPT. La méthode complète.',
};

// Fallback videos shown while API loads
const CONTENU_VIDEOS_FALLBACK = [
  { id: 'vhkt6vcSYDM', featured: true, type: 'video', title: 'La meilleure combinaison d\'outils pour votre prospection en 2026', summary: VIDEO_DESCRIPTIONS['vhkt6vcSYDM'], duration: '' },
  { id: 'tloC0NqPx0g', type: 'video', title: 'La meilleure méthode pour trouver des clients en 2026', summary: VIDEO_DESCRIPTIONS['tloC0NqPx0g'], duration: '' },
  { id: 'y4ZBu-fN7Hs', type: 'video', title: 'Créer son système d\'acquisition avec Claude Code', summary: VIDEO_DESCRIPTIONS['y4ZBu-fN7Hs'], duration: '' },
  { id: 'ffdC5CdrbHE', type: 'video', title: 'Pourquoi le TAM Building est la meilleure approche d\'acquisition en 2026', summary: VIDEO_DESCRIPTIONS['ffdC5CdrbHE'], duration: '' },
];

const CONTENU_ARTICLES = [
  {
    type: 'article',
    slug: 'gtm-on-demand-2026',
    category: 'GTM Strategy',
    title: 'Comment mettre en place du GTM on-demand en 2026 ?',
    excerpt: 'Le modèle GTM on-demand : une alternative aux équipes Sales et Marketing full-time pour les scaleups B2B.',
    date: '19 fév. 2026',
    readingTime: '8 min',
    accent: '#C9F26B',
  },
  {
    type: 'article',
    slug: 'outbound-gtm-playbook-2026',
    category: 'Outbound',
    title: 'Outbound GTM playbook for 2026',
    excerpt: 'Le playbook outbound complet pour 2026 : signaux, séquences, infrastructure et mesure de la performance.',
    date: '6 fév. 2026',
    readingTime: '15 min',
    accent: '#ECFF8E',
  },
  {
    type: 'article',
    slug: 'plg-vs-sales-led',
    category: 'GTM Strategy',
    title: 'Product-Led-Growth ou Sales-led : Quel modèle choisir ?',
    excerpt: 'PLG vs Sales-led : une analyse objective des deux modèles et des critères pour choisir le bon pour votre stade.',
    date: '6 fév. 2026',
    readingTime: '14 min',
    accent: '#E1FF6C',
  },
  {
    type: 'article',
    slug: 'gtm-scoring-playbook-2026',
    category: 'RevOps',
    title: 'The 2026 GTM Scoring Playbook',
    excerpt: 'Le framework de scoring GTM qu\'on utilise chez nos clients pour prioriser les comptes et déclencher les bonnes actions.',
    date: '4 juil. 2025',
    readingTime: '12 min',
    accent: '#C9F26B',
  },
  {
    type: 'article',
    slug: 'construire-son-tam-2025',
    category: 'Outbound',
    title: 'Construire son TAM en 2025 : Guide et méthodes',
    excerpt: 'Comment définir, segmenter et prioriser votre marché adressable total pour concentrer vos efforts là où ça compte.',
    date: '4 juil. 2025',
    readingTime: '9 min',
    accent: '#E1FF6C',
  },
  {
    type: 'article',
    slug: '3-stades-go-to-market',
    category: 'GTM Strategy',
    title: 'Les 3 stades go-to-market pour atteindre le premier million d\'ARR',
    excerpt: 'Chaque stade de croissance B2B requiert un modèle GTM différent. Voici comment pivoter au bon moment.',
    date: '4 juil. 2025',
    readingTime: '6 min',
    accent: '#C9F26B',
  },
];

const ytThumb = (id) => `https://img.youtube.com/vi/${id}/maxresdefault.jpg`;
const ytEmbed = (id) => `https://www.youtube.com/embed/${id}?autoplay=1&rel=0`;

// ── Icons ──────────────────────────────────────────────────────────
const CIconPlay = ({ size = 20 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
    <path d="M8 5v14l11-7z" />
  </svg>
);
const CIconArrow = ({ size = 14 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
       strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M5 12h14" /><path d="m12 5 7 7-7 7" />
  </svg>
);
const CIconClock = ({ size = 13 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
       strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" />
  </svg>
);
const CIconX = ({ size = 20 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
       strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M18 6 6 18M6 6l12 12" />
  </svg>
);
const CIconDoc = ({ size = 16 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
       strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
    <polyline points="14 2 14 8 20 8" />
    <line x1="16" y1="13" x2="8" y2="13" />
    <line x1="16" y1="17" x2="8" y2="17" />
    <polyline points="10 9 9 9 8 9" />
  </svg>
);

// ── VideoCard ──────────────────────────────────────────────────────
const ContenuVideoCard = ({ video, variant, onPlay }) => {
  const isFeatured = variant === 'featured';

  return (
    <article
      className={`cv-card cv-card--${variant}`}
      onClick={() => onPlay(video)}
      tabIndex={0}
      role="button"
      onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onPlay(video); } }}
      aria-label={`Lire : ${video.title}`}
    >
      <div className="cv-thumb">
        <img src={ytThumb(video.id)} alt="" loading="lazy" onError={(e) => { e.target.style.display = 'none'; }} />
        <div className="cv-shade" />
        <button
          type="button"
          className="cv-play"
          aria-label="Lire la vidéo"
          onClick={(e) => { e.stopPropagation(); onPlay(video); }}
        >
          <CIconPlay size={isFeatured ? 26 : 18} />
        </button>
        <span className="cv-duration">
          <CIconClock /> {video.duration}
        </span>
      </div>
      <div className="cv-body">
        {video.category && (
          <div className="cv-meta">
            <span className="cv-cat">{video.category}</span>
          </div>
        )}
        <h3 className="cv-title">{video.title}</h3>
        {isFeatured && <p className="cv-summary">{video.summary}</p>}
        <span className="cv-cta">Regarder l'épisode <CIconArrow /></span>
      </div>
    </article>
  );
};

// ── ArticleCard ────────────────────────────────────────────────────
const ContenuArticleCard = ({ article }) => {
  const navigate = () => {
    window.location.hash = `/ressources/${article.slug}`;
    window.scrollTo({ top: 0, behavior: 'auto' });
  };

  return (
    <article
      className="cv-card cv-acard"
      onClick={navigate}
      tabIndex={0}
      role="link"
      onKeyDown={(e) => { if (e.key === 'Enter') navigate(); }}
      aria-label={article.title}
    >
      <div className="cv-acard-accent" style={{ background: article.accent }} />
      <div className="cv-body">
        <div className="cv-meta">
          <span className="cv-cat">{article.category}</span>
          <span className="cv-acard-type">
            <CIconDoc size={11} /> Article
          </span>
        </div>
        <h3 className="cv-title">{article.title}</h3>
        <p className="cv-summary">{article.excerpt}</p>
        <div className="cv-acard-footer">
          <span className="cv-acard-meta">{article.date} · {article.readingTime} de lecture</span>
          <span className="cv-cta" style={{ border: 'none', paddingTop: 0, marginTop: 'auto' }}>
            Lire l'article <CIconArrow />
          </span>
        </div>
      </div>
    </article>
  );
};

// ── Modal ──────────────────────────────────────────────────────────
const ContenuModal = ({ video, onClose }) => {
  React.useEffect(() => {
    if (!video) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [video, onClose]);

  if (!video) return null;

  return ReactDOM.createPortal(
    <div className="cv-modal" onClick={onClose} role="dialog" aria-modal="true" aria-label={video.title}>
      <button type="button" className="cv-modal-close" onClick={onClose} aria-label="Fermer">
        <CIconX />
      </button>
      <div className="cv-modal-frame" onClick={(e) => e.stopPropagation()}>
        <div className="cv-modal-player">
          <iframe
            src={ytEmbed(video.id)}
            title={video.title}
            frameBorder="0"
            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
            allowFullScreen
          />
        </div>
        <div className="cv-modal-caption">
          <span className="cv-cat" style={{ background: 'rgba(255,255,255,0.12)', color: '#fff', border: '1px solid rgba(255,255,255,0.18)' }}>
            {video.category}
          </span>
          <h3 style={{ margin: 0, fontSize: 18, fontWeight: 600, color: '#fff', letterSpacing: '-0.02em' }}>{video.title}</h3>
        </div>
      </div>
    </div>,
    document.body
  );
};

// ── ContenuSection ─────────────────────────────────────────────────
const ContenuSection = ({ lang }) => {
  const [filter, setFilter] = React.useState('Vidéos');
  const [active, setActive] = React.useState(null);
  const [videos, setVideos] = React.useState(CONTENU_VIDEOS_FALLBACK);
  const [loadingVideos, setLoadingVideos] = React.useState(true);

  // Fetch live videos from RSS proxy
  React.useEffect(() => {
    fetch('/api/yt-feed')
      .then(r => r.json())
      .then(data => {
        if (data.videos && data.videos.length > 0) {
          const mapped = data.videos.map((v, i) => ({
            id: v.videoId,
            type: 'video',
            featured: i === 0,
            title: v.title,
            summary: VIDEO_DESCRIPTIONS[v.videoId] || (v.description ? v.description.slice(0, 160) : ''),
            duration: v.duration || '',
          }));
          setVideos(mapped);
        }
      })
      .catch(() => { /* keep fallback */ })
      .finally(() => setLoadingVideos(false));
  }, []);

  const showVideos = filter === 'Vidéos';
  const showArticles = filter === 'Articles';

  const featured = videos.find(v => v.featured) || videos[0];
  const others = videos.filter(v => v !== featured);

  const FILTERS = ['Vidéos', 'Articles'];

  return (
    <section className="u-section contenu-section">
      <style>{`
        .contenu-section { background: var(--bg); }

        /* Header */
        .contenu-head {
          display: grid;
          grid-template-columns: 1.1fr 1fr;
          gap: clamp(24px, 4vw, 80px);
          align-items: end;
          margin-bottom: clamp(28px, 3vw, 48px);
        }
        .contenu-lede {
          font-size: clamp(15px, 1.1vw, 17px);
          line-height: 1.6;
          color: var(--gray-4);
          max-width: 46ch;
          margin: 0;
        }

        /* Filters */
        .contenu-filters {
          display: flex;
          flex-wrap: wrap;
          gap: 8px;
          margin: 0 0 clamp(24px, 3vw, 40px);
          padding-bottom: 24px;
          border-bottom: 1px solid var(--line);
        }
        .cv-fchip {
          display: inline-flex; align-items: center; gap: 8px;
          height: 34px; padding: 0 16px;
          border-radius: 999px;
          background: transparent; color: var(--ink);
          border: 1px solid var(--line);
          font-family: var(--font-sans); font-weight: 500; font-size: 13px;
          letter-spacing: -0.01em; cursor: pointer;
          transition: background .15s ease, border-color .15s ease;
        }
        .cv-fchip:hover { background: rgba(0,0,0,0.04); border-color: rgba(0,0,0,0.18); }
        .cv-fchip--on { background: var(--accent); border-color: var(--accent-edge); }
        .cv-fchip--on:hover { background: var(--accent); }
        .cv-fchip-count {
          display: inline-flex; align-items: center; justify-content: center;
          min-width: 18px; height: 18px; padding: 0 5px;
          border-radius: 999px; background: rgba(0,0,0,0.75);
          color: #fff; font-size: 10px; font-weight: 700;
        }

        /* Featured video layout */
        .cv-layout-featured {
          display: grid;
          grid-template-columns: 1.35fr 1fr;
          gap: clamp(14px, 1.8vw, 24px);
        }
        .cv-layout-col {
          display: flex; flex-direction: column;
          gap: clamp(12px, 1.3vw, 18px);
        }

        /* Articles grid */
        .cv-articles-grid {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: clamp(12px, 1.5vw, 20px);
          margin-top: clamp(20px, 2.5vw, 36px);
        }
        .cv-section-label {
          font-family: var(--font-mono);
          font-size: 11px; font-weight: 600;
          letter-spacing: 0.07em; text-transform: uppercase;
          color: var(--gray-4);
          margin-bottom: 16px;
          display: flex; align-items: center; gap: 10px;
        }
        .cv-section-label::after {
          content: ''; flex: 1;
          height: 1px; background: var(--line);
        }

        /* Card base */
        .cv-card {
          position: relative; display: flex; flex-direction: column;
          background: #fff; border-radius: 16px; overflow: hidden;
          cursor: pointer;
          box-shadow: 0 0 0 1px rgba(227,225,222,0.45), 0 1px 2px rgba(95,74,46,0.07), 0 4px 8px rgba(95,74,46,0.04);
          transition: transform .2s cubic-bezier(.2,.6,.2,1), box-shadow .2s ease;
          outline: none; text-align: left;
        }
        .cv-card:hover {
          transform: translateY(-2px);
          box-shadow: 0 0 0 1px rgba(227,225,222,0.55), 0 4px 12px rgba(95,74,46,0.10), 0 12px 28px rgba(95,74,46,0.07);
        }

        /* Thumbnail */
        .cv-thumb {
          position: relative; aspect-ratio: 16 / 9;
          background: var(--line); overflow: hidden;
        }
        .cv-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.2,.6,.2,1); }
        .cv-card:hover .cv-thumb img { transform: scale(1.04); }
        .cv-shade { position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,0.52) 0%, rgba(0,0,0,0) 45%); pointer-events: none; }
        .cv-play {
          position: absolute; bottom: 14px; left: 14px;
          width: 46px; height: 46px; border-radius: 999px;
          border: 1.5px solid var(--accent-edge); background: var(--accent); color: var(--ink);
          display: inline-flex; align-items: center; justify-content: center;
          box-shadow: inset 0 1px 1px rgba(255,255,255,0.6), 0 4px 12px rgba(0,0,0,0.22);
          cursor: pointer; transition: transform .15s ease;
        }
        .cv-card:hover .cv-play { transform: scale(1.07); }
        .cv-duration {
          position: absolute; top: 10px; right: 10px;
          display: inline-flex; align-items: center; gap: 5px;
          height: 24px; padding: 0 9px; border-radius: 999px;
          background: rgba(18,18,18,0.76); color: #fff;
          font-size: 11px; font-weight: 600;
          backdrop-filter: blur(6px); font-variant-numeric: tabular-nums;
        }

        /* Card body */
        .cv-body { display: flex; flex-direction: column; gap: 9px; padding: 18px 20px 20px; flex: 1; }
        .cv-meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
        .cv-cat {
          display: inline-flex; align-items: center;
          height: 22px; padding: 0 9px; border-radius: 999px;
          background: rgba(0,0,0,0.05); color: var(--ink);
          font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
          border: 1px solid rgba(0,0,0,0.08);
        }
        .cv-acard-type {
          display: inline-flex; align-items: center; gap: 4px;
          font-family: var(--font-mono); font-size: 10px; color: var(--gray-4);
          letter-spacing: 0.03em;
        }
        .cv-title {
          font-family: var(--font-sans); font-weight: 600; font-size: 16px;
          line-height: 1.3; letter-spacing: -0.02em; color: var(--ink);
          margin: 0;
          display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
        }
        .cv-summary {
          font-size: 13px; line-height: 1.5; color: var(--gray-4); margin: 0;
          display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
        }
        .cv-cta {
          display: inline-flex; align-items: center; gap: 6px;
          margin-top: auto; padding-top: 12px;
          font-size: 12px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink);
          border-top: 1px dashed var(--line); transition: gap .15s ease;
        }
        .cv-card:hover .cv-cta { gap: 10px; }

        /* Article card specifics */
        .cv-acard-accent { height: 4px; background: var(--accent); flex-shrink: 0; }
        .cv-acard .cv-body { gap: 10px; }
        .cv-acard-footer {
          display: flex; align-items: center; justify-content: space-between;
          gap: 8px; margin-top: auto; flex-wrap: wrap;
        }
        .cv-acard-meta { font-size: 11px; color: var(--gray-4); font-family: var(--font-mono); letter-spacing: 0.02em; }
        .cv-acard .cv-cta { border: none; padding-top: 0; }

        /* Featured variant */
        .cv-card--featured .cv-body { padding: 24px 26px 26px; gap: 12px; }
        .cv-card--featured .cv-title { font-size: clamp(20px, 1.8vw, 26px); line-height: 1.18; }
        .cv-card--featured .cv-summary { font-size: 14px; -webkit-line-clamp: 3; }
        .cv-card--featured .cv-play { width: 56px; height: 56px; bottom: 20px; left: 20px; }
        .cv-card--featured .cv-duration { top: 16px; right: 16px; height: 28px; font-size: 12px; }

        /* Secondary (horizontal) variant */
        .cv-card--secondary { flex-direction: row; }
        .cv-card--secondary .cv-thumb { flex: 0 0 42%; aspect-ratio: 4 / 3; }
        .cv-card--secondary .cv-play { width: 34px; height: 34px; bottom: 10px; left: 10px; }
        .cv-card--secondary .cv-duration { top: 8px; right: 8px; height: 20px; padding: 0 7px; font-size: 10px; }
        .cv-card--secondary .cv-body { padding: 14px 16px 16px; gap: 7px; }
        .cv-card--secondary .cv-title { font-size: 14px; }
        .cv-card--secondary .cv-cta { font-size: 11px; padding-top: 8px; }

        /* CTA footer */
        .contenu-footer {
          display: flex; align-items: center; justify-content: center; gap: 18px;
          flex-wrap: wrap;
          margin-top: clamp(28px, 3.5vw, 52px);
          padding-top: clamp(24px, 3vw, 40px);
          border-top: 1px solid var(--line);
        }
        .contenu-footer-note { font-size: 13px; color: var(--gray-4); }

        /* Modal */
        .cv-modal {
          position: fixed; inset: 0; z-index: 9999;
          background: rgba(12,12,12,0.82);
          backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
          display: flex; align-items: center; justify-content: center;
          padding: 5vh 4vw;
          animation: cvFadeIn .2s ease;
        }
        @keyframes cvFadeIn { from { opacity: 0; } to { opacity: 1; } }
        .cv-modal-close {
          position: absolute; top: 20px; right: 20px;
          width: 40px; height: 40px; border-radius: 999px;
          border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.07);
          color: #fff; display: inline-flex; align-items: center; justify-content: center;
          cursor: pointer; transition: background .15s ease;
        }
        .cv-modal-close:hover { background: rgba(255,255,255,0.14); }
        .cv-modal-frame { width: 100%; max-width: 1160px; display: flex; flex-direction: column; gap: 16px; }
        .cv-modal-player {
          position: relative; width: 100%; aspect-ratio: 16 / 9;
          border-radius: 16px; overflow: hidden; background: #000;
          box-shadow: 0 28px 72px rgba(0,0,0,0.55);
        }
        .cv-modal-player iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
        .cv-modal-caption { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; color: #fff; }

        /* Responsive */
        @media (max-width: 900px) {
          .cv-layout-featured { grid-template-columns: 1fr; }
          .cv-articles-grid { grid-template-columns: repeat(2, 1fr); }
        }
        @media (max-width: 640px) {
          .contenu-head { grid-template-columns: 1fr; gap: 16px; align-items: start; }
          .cv-card--secondary { flex-direction: column; }
          .cv-card--secondary .cv-thumb { flex-basis: auto; aspect-ratio: 16 / 9; }
          .cv-articles-grid { grid-template-columns: 1fr; }
          /* Limit items shown on mobile */
          .cv-layout-col > *:nth-child(n+3) { display: none; }
          .cv-articles-grid > *:nth-child(n+4) { display: none; }
        }
      `}</style>

      <div className="u-container">
        {/* Header */}
        <div className="contenu-head">
          <div>
            <p className="u-eyebrow" style={{ marginBottom: 16 }}>
              <span style={{ display: 'inline-block', width: 7, height: 7, borderRadius: '50%', background: 'var(--accent)', marginRight: 8, verticalAlign: 'middle', boxShadow: '0 0 0 4px rgba(225,255,108,0.22)' }} />
              {lang === 'fr' ? 'Ressources' : 'Resources'}
            </p>
            <h2>
              {lang === 'fr'
                ? <><span className="u-mark">Contenu</span> Upscale</>
                : <>Upscale <span className="u-mark">Content</span></>}
            </h2>
          </div>
          <p className="contenu-lede">
            {lang === 'fr'
              ? 'Toutes nos vidéos et articles sur les meilleures stratégies d\'acquisition à mettre en place en 2026.'
              : 'All our videos and articles on the best acquisition strategies to implement in 2026.'}
          </p>
        </div>

        {/* Filters */}
        <nav className="contenu-filters" aria-label="Filtrer par type">
          {FILTERS.map((f) => (
            <button
              key={f}
              type="button"
              className={`cv-fchip${filter === f ? ' cv-fchip--on' : ''}`}
              onClick={() => setFilter(f)}
            >
              {f}
            </button>
          ))}
        </nav>

        {/* Vidéos */}
        {showVideos && (
          <>
            <div className="cv-layout-featured">
              {featured && <ContenuVideoCard video={featured} variant="featured" onPlay={setActive} />}
              <div className="cv-layout-col">
                {others.slice(0, 3).map((v, i) => (
                  <ContenuVideoCard key={i} video={v} variant="secondary" onPlay={setActive} />
                ))}
              </div>
            </div>
          </>
        )}

        {/* Articles */}
        {showArticles && (
          <>
            <div className="cv-articles-grid">
              {CONTENU_ARTICLES.map((a, i) => (
                <ContenuArticleCard key={i} article={a} />
              ))}
            </div>
          </>
        )}

      </div>

      <ContenuModal video={active} onClose={() => setActive(null)} />
    </section>
  );
};

window.ContenuSection = ContenuSection;
