// Pages secondaires : Repas, Photos, Programme, Enfants, Bénévoles, FAQ

function FoodPage({ setPage, state, actions, currentUserName = '' }) {
  const [Toast, showToast] = useToast();
  const userName = currentUserName.trim();
  const [votes, setVotes] = useState(() => ({
    meat: state.myVotes?.meat || null,
    side: state.myVotes?.side || null,
    sauce: state.myVotes?.sauce || null,
    dessert: state.myVotes?.dessert || null,
  }));
  const [submitted, setSubmitted] = useState(false);
  const tallies = state.foodTallies || {};
  const totalFamilies = Object.values(tallies).reduce((sum, group) => Math.max(sum, ...Object.values(group || {})), 0);
  const choicesMade = Object.values(votes).filter(Boolean).length;
  const pickVote = (key, v) => { setVotes({ ...votes, [key]: v }); setSubmitted(false); };
  const submitVotes = () => {
    if (choicesMade < 4) { showToast(`Encore ${4 - choicesMade} choix à faire`); return; }
    actions.saveVotes(votes, userName);
    setSubmitted(true);
    showToast('Vos votes sont enregistrés ✓');
  };
  const activeRsvps = (state.rsvps || []).filter((rsvp) => !rsvp.cancelledAt);
  const potluck = (state.potluck || []).filter((entry) => !entry.retiredAt);
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(() => ({ who: userName, dish: '', kind: 'Accompagnement', servings: '8' }));
  const submitDish = () => {
    if (!form.who.trim() || !form.dish.trim()) { showToast('Remplis ton nom et le plat'); return; }
    actions.reservePotluck({ ...form });
    setForm({ who: userName, dish: '', kind: 'Accompagnement', servings: '8' });
    setShowForm(false);
    showToast('Plat réservé ✓ Merci !');
  };
  useEffect(() => {
    setForm((current) => current.who.trim() ? current : { ...current, who: userName });
  }, [userName]);
  return (
    <div>
      <PageHero title="Repas, votes & auberge espagnole" sub="Aidez-nous à composer le menu — votez pour vos favoris et réservez votre plat." kind="warm" label="Buffet grillé sur table de pique-nique" />

      <div className="container" style={{ paddingBottom: 36 }}>
        <H2 kicker="VOTEZ">Choisissez vos préférés du BBQ</H2>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 14 }}>
          <VoteGroup title="Viande préférée" options={['Porc-Gulu', 'Taba', 'PouletBBQ', 'Steak']} value={votes.meat} tallies={tallies.meat || {}} total={totalFamilies} onChange={v => pickVote('meat', v)} />
          <VoteGroup title="Meilleur accompagnement" options={['Mac & Cheese', 'Salade', 'Pain de maïs', 'Poisson']} value={votes.side} tallies={tallies.side || {}} total={totalFamilies} onChange={v => pickVote('side', v)} />
          <VoteGroup title="Sauce favorite" options={['SauceBBQ', 'Sucrée-fumée', 'Mayo Ketchup', 'Vinaigre épicé']} value={votes.sauce} tallies={tallies.sauce || {}} total={totalFamilies} onChange={v => pickVote('sauce', v)} />
          <VoteGroup title="Meilleur dessert" options={['Pasteque', 'Mousse choco', 'Tiramisu fraise', 'Verrine fruits']} value={votes.dessert} tallies={tallies.dessert || {}} total={totalFamilies} onChange={v => pickVote('dessert', v)} />
        </div>

        <div style={{ marginTop: 16, padding: '14px 18px', background: submitted ? 'var(--green-100)' : 'var(--cream-2)', border: `1px solid ${submitted ? 'var(--green-700)' : 'var(--line)'}`, borderRadius: 10, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <div style={{ display: 'flex', gap: 4 }}>
              {[0,1,2,3].map(i => (
                <div key={i} style={{ width: 10, height: 10, borderRadius: '50%', background: i < choicesMade ? 'var(--green-700)' : 'rgba(0,0,0,0.12)' }} />
              ))}
            </div>
            <div style={{ fontSize: 13, color: 'var(--ink-2)' }}>
              {submitted
                ? <span style={{ color: 'var(--green-800)', fontWeight: 600 }}>✓ Vos votes sont enregistrés. Vous pouvez les modifier jusqu'au 15 juin.</span>
                : <><strong style={{ color: 'var(--green-900)' }}>{choicesMade}/4 choix faits</strong> · {totalFamilies} vote{totalFamilies === 1 ? '' : 's'} enregistré{totalFamilies === 1 ? '' : 's'}</>
              }
            </div>
          </div>
          <button className="btn btn-coral" onClick={submitVotes} disabled={submitted} style={submitted ? { opacity: 0.5, cursor: 'default' } : {}}>
            {submitted ? '✓ Enregistré' : 'Enregistrer mes votes'} {!submitted && <Icon.ArrowRight />}
          </button>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 18, marginTop: 32 }}>
          <div className="card">
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
              <div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)' }}>Inscriptions à l'auberge espagnole</div>
                <div style={{ fontSize: 13, color: 'var(--ink-2)' }}>{potluck.length} plat{potluck.length === 1 ? '' : 's'} réservé{potluck.length === 1 ? '' : 's'} pour le moment.</div>
              </div>
              <button className="btn btn-coral" onClick={() => setShowForm(!showForm)}><Icon.Plus /> {showForm ? 'Annuler' : 'Réserver un plat'}</button>
            </div>
            {showForm && (
              <div style={{ background: 'var(--cream-2)', border: '1px solid var(--line)', borderRadius: 10, padding: 14, marginBottom: 14 }}>
                <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.12em', color: 'var(--coral)', textTransform: 'uppercase', marginBottom: 10 }}>Votre contribution</div>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 10, marginBottom: 10 }}>
                  <input className="input" placeholder="Votre nom" value={form.who} onChange={e => setForm({...form, who: e.target.value})} />
                  <input className="input" placeholder="Plat / item (ex : Salade niçoise)" value={form.dish} onChange={e => setForm({...form, dish: e.target.value})} />
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr auto', gap: 10 }}>
                  <select className="select" value={form.kind} onChange={e => setForm({...form, kind: e.target.value})}>
                    <option>Apéritif</option><option>Salade</option><option>Accompagnement</option><option>Plat principal</option><option>Dessert</option><option>Boissons</option><option>Mikaté</option>
                  </select>
                  <select className="select" value={form.servings} onChange={e => setForm({...form, servings: e.target.value})}>
                    <option>4–6</option><option>6–8</option><option>8</option><option>10–12</option><option>15+</option><option>20+</option>
                  </select>
                  <button className="btn btn-green" onClick={submitDish}>Enregistrer <Icon.Check /></button>
                </div>
              </div>
            )}
            <div style={{ borderTop: '1px solid var(--line)' }}>
              {potluck.length === 0 ? (
                <div style={{ padding: '18px 0', color: 'var(--ink-2)', fontSize: 14 }}>Aucun plat réservé pour le moment.</div>
              ) : potluck.map((p, i) => (
                <div key={p.id || i} style={{ display: 'grid', gridTemplateColumns: '1fr 1.6fr 130px 100px', padding: '10px 0', borderBottom: '1px solid var(--line)', alignItems: 'center', fontSize: 14 }}>
                  <div style={{ fontWeight: 600 }}>{p.who}</div>
                  <div>{p.dish}</div>
                  <div><span style={{ background: 'var(--cream-2)', padding: '3px 8px', borderRadius: 4, fontSize: 12, color: 'var(--green-800)' }}>{p.kind}</span></div>
                  <div style={{ color: 'var(--ink-2)', fontSize: 13 }}>Pour {p.servings}</div>
                </div>
              ))}
            </div>
          </div>

          <div className="card">
            <div className="serif" style={{ fontSize: 20, color: 'var(--green-900)', marginBottom: 4 }}>Allergies & régimes</div>
            <div style={{ fontSize: 12, color: 'var(--ink-2)', marginBottom: 14 }}>Signalés par les invités jusqu'ici. Aidez-nous à étiqueter !</div>
            <Tag count={activeRsvps.filter(r => (r.allergies || '').toLowerCase().includes('arachide')).length} label="Arachides" />
            <Tag count={activeRsvps.filter(r => (r.allergies || '').toLowerCase().includes('crustacé')).length} label="Crustacés" />
            <Tag count={activeRsvps.filter(r => r.dietary === 'Sans gluten').length} label="Sans gluten" />
            <Tag count={activeRsvps.filter(r => (r.allergies || '').toLowerCase().includes('lactose')).length} label="Sans lactose" />
            <Tag count={activeRsvps.filter(r => r.dietary === 'Végétarien').length} label="Végétarien" />
            <Tag count={activeRsvps.filter(r => r.dietary === 'Végétalien').length} label="Végétalien" />
            <Tag count={activeRsvps.filter(r => r.dietary === 'Halal').length} label="Halal" />
            <div className="h-divider" />
            <button className="btn btn-ghost" onClick={() => setPage('rsvp')} style={{ width: '100%' }}>Modifier via l'inscription <Icon.ArrowRight /></button>
          </div>
        </div>
      </div>
      <Leaves />
      {Toast}
    </div>
  );
}

function VoteGroup({ title, options, value, onChange, tallies = {}, total = 0 }) {
  const max = Math.max(1, ...options.map(o => tallies[o] || 0));
  return (
    <div className="card" style={{ padding: 16 }}>
      <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.16em', color: 'var(--coral)', textTransform: 'uppercase', marginBottom: 10 }}>{title}</div>
      <div style={{ display: 'grid', gap: 8 }}>
        {options.map(o => {
          const selected = value === o;
          const count = tallies[o] || 0;
          const pct = Math.round((count / max) * 100);
          return (
            <button key={o} onClick={() => onChange(o)} style={{
              position: 'relative', overflow: 'hidden',
              padding: '9px 12px', borderRadius: 8,
              background: selected ? 'var(--green-700)' : 'white',
              color: selected ? 'white' : 'var(--ink)',
              border: `1px solid ${selected ? 'var(--green-700)' : 'var(--line)'}`,
              textAlign: 'left', fontSize: 13, fontWeight: selected ? 600 : 500,
              display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8,
            }}>
              <span style={{ position: 'absolute', inset: 0, width: `${pct}%`, background: selected ? 'rgba(255,255,255,0.10)' : 'rgba(212,168,87,0.14)', pointerEvents: 'none' }} />
              <span style={{ position: 'relative', zIndex: 1 }}>{o}</span>
              <span style={{ position: 'relative', zIndex: 1, display: 'flex', alignItems: 'center', gap: 6, fontSize: 11, fontWeight: 500, opacity: selected ? 0.95 : 0.7 }}>
                {count} {selected && <Icon.Check />}
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}
function Tag({ count, label }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 0', borderBottom: '1px dashed var(--line)' }}>
      <div style={{ fontSize: 14 }}>{label}</div>
      <div style={{ fontSize: 12, color: 'var(--ink-2)', background: 'var(--cream-2)', padding: '2px 8px', borderRadius: 99 }}>{count} invité{count === 1 ? '' : 's'}</div>
    </div>
  );
}

function PageHero({ title, sub, kind = 'lights', label, src }) {
  const heroSrc = src || REAL_EVENT_HERO_BY_KIND[kind];
  return (
    <div style={{ position: 'relative', height: 200, overflow: 'hidden' }}>
      <Photo kind={kind} src={heroSrc} bg style={{ position: 'absolute', inset: 0 }} />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(14,46,34,0.4), rgba(14,46,34,0.6))', display: 'grid', placeItems: 'center', textAlign: 'center', color: 'white', padding: 24 }}>
        <div>
          <h1 className="serif" style={{ fontSize: 44, margin: 0, color: 'white' }}>{title}</h1>
          {sub && <div style={{ fontSize: 15, opacity: 0.92, marginTop: 4 }}>{sub}</div>}
        </div>
      </div>
    </div>
  );
}

function PhotosPage({ state, actions, currentUserName = '' }) {
  const [Toast, showToast] = useToast();
  const [activePhoto, setActivePhoto] = useState(null);
  const [activeAlbum, setActiveAlbum] = useState('2025');
  const userName = currentUserName.trim();
  const gallery2025 = REAL_BBQ_2025.map((p, i) => ({
    ...p,
    title: p.label || `Souvenir BBQ 2025 ${i + 1}`,
    fileName: `BBQ-2025-${String(i + 1).padStart(2, '0')}.jpg`,
    albumLabel: 'BBQ na Biso 2025',
    canDownload: true,
  }));
  const gallery2026 = (state.uploadedMemories || []).map((p, i) => ({
    ...p,
    src: p.src || p.dataUrl || null,
    title: p.title || p.label || `Souvenir BBQ 2026 ${i + 1}`,
    fileName: `BBQ-2026-${String(i + 1).padStart(2, '0')}.jpg`,
    albumLabel: 'BBQ na Biso 2026',
    canDownload: !!(p.src || p.dataUrl),
  }));
  const gallery = activeAlbum === '2026' ? gallery2026 : gallery2025;
  const addUploadedMemories = (items) => {
    items.forEach((item) => actions.addMemory(item, userName));
    setActiveAlbum('2026');
    showToast(`${items.length} photo${items.length === 1 ? '' : 's'} ajoutée${items.length === 1 ? '' : 's'} au BBQ 2026`);
  };
  const openPhoto = (index) => {
    const photo = gallery[index];
    if (photo) {
      actions.recordActivity(userName, 'photo_view', 'Photo agrandie', {
        page: 'photos',
        detail: `${photo.albumLabel || activeAlbum} · ${photo.title}`,
      });
    }
    setActivePhoto(index);
  };
  const recordPhotoDownload = (photo) => {
    actions.recordActivity(userName, 'photo_download', 'Photo téléchargée', {
      page: 'photos',
      detail: `${photo.albumLabel || activeAlbum} · ${photo.title || photo.fileName}`,
    });
  };
  return (
    <div>
      <PageHero title="Galerie photo" sub="Souvenirs des BBQ passés — et un endroit pour vos clichés de cette année." kind="dusk" label="Souvenir 2025" src="assets/real/bbq-2025-21.jpg" />
      <div className="container" style={{ paddingBottom: 32 }}>
        <div style={{ display: 'flex', gap: 8, marginTop: 18, marginBottom: 16, flexWrap: 'wrap' }}>
          <button className={`btn ${activeAlbum === '2025' ? 'btn-green' : 'btn-white'}`} onClick={() => { actions.recordActivity(userName, 'album_view', 'Album photo ouvert', { page: 'photos', detail: 'BBQ 2025' }); setActiveAlbum('2025'); setActivePhoto(null); }}>
            BBQ 2025
          </button>
          <button className={`btn ${activeAlbum === '2026' ? 'btn-green' : 'btn-white'}`} onClick={() => { actions.recordActivity(userName, 'album_view', 'Album photo ouvert', { page: 'photos', detail: 'BBQ 2026' }); setActiveAlbum('2026'); setActivePhoto(null); }}>
            BBQ 2026 ({gallery2026.length})
          </button>
          <div style={{ flex: 1 }} />
          <button className="btn btn-coral" onClick={() => { actions.addMemory({ title: 'Photo ajoutée depuis la galerie', kind: 'sun', label: 'Souvenir BBQ 2026' }, userName); setActiveAlbum('2026'); showToast('Photo ajoutée au BBQ 2026'); }}><Icon.Upload s={16} /> Téléverser des photos</button>
        </div>
        {gallery.length > 0 ? (
          <div className="photo-grid">
            {gallery.map((p, i) => (
              <div key={p.src || p.id || i} className="photo-tile" style={{ position: 'relative' }}>
                <button type="button" className="photo-open" onClick={() => openPhoto(i)} aria-label={`Agrandir ${p.title}`}>
                  <Photo src={p.src} kind={p.kind || 'warm'} label={p.label} style={{ aspectRatio: '1', borderRadius: 8 }} />
                </button>
                {p.canDownload && (
                  <a className="photo-download" href={p.src} download={p.fileName} title="Télécharger la photo" aria-label={`Télécharger ${p.title}`} onClick={() => recordPhotoDownload(p)}>
                    <Icon.Download s={17} />
                  </a>
                )}
              </div>
            ))}
          </div>
        ) : (
          <div className="card" style={{ background: 'var(--cream)', textAlign: 'center', marginTop: 8 }}>
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 4 }}>Aucune photo BBQ 2026 pour le moment</div>
            <div style={{ color: 'var(--ink-2)', fontSize: 14 }}>Téléversez quelques souvenirs et ils apparaîtront dans cet album.</div>
          </div>
        )}
        <div style={{ marginTop: 24 }}>
          <H2 kicker="CETTE ANNÉE">Déposez vos photos du BBQ 2026</H2>
          <UploadDrop
            onDrop={() => { actions.addMemory({ title: 'Souvenir BBQ 2026', kind: 'sun', label: 'Photo ajoutée localement' }, userName); setActiveAlbum('2026'); showToast('Photo ajoutée au BBQ 2026 — merci !'); }}
            onFiles={addUploadedMemories}
          />
        </div>
      </div>
      <Leaves />
      {activePhoto !== null && (
        <PhotoLightbox
          photos={gallery}
          index={activePhoto}
          onChange={setActivePhoto}
          onClose={() => setActivePhoto(null)}
          onDownload={recordPhotoDownload}
        />
      )}
      {Toast}
    </div>
  );
}

function PhotoLightbox({ photos, index, onChange, onClose, onDownload }) {
  const total = photos.length;
  const current = photos[index];
  const go = (direction) => onChange((index + direction + total) % total);

  useEffect(() => {
    const originalOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (event) => {
      if (event.key === 'Escape') onClose();
      if (event.key === 'ArrowLeft') go(-1);
      if (event.key === 'ArrowRight') go(1);
    };
    window.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = originalOverflow;
      window.removeEventListener('keydown', onKey);
    };
  }, [index, total]);

  if (!current) return null;

  return (
    <div className="lightbox" role="dialog" aria-modal="true" aria-label="Visionneuse photo">
      <div className="lightbox-top">
        <div>
          <div className="lightbox-count">{index + 1} / {total}</div>
          <div className="lightbox-title">{current.title}</div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          {current.canDownload && (
            <a className="lightbox-action" href={current.src} download={current.fileName} title="Télécharger cette photo" aria-label="Télécharger cette photo" onClick={() => onDownload && onDownload(current)}>
              <Icon.Download s={19} />
            </a>
          )}
          <button type="button" className="lightbox-action" onClick={onClose} title="Fermer" aria-label="Fermer">
            <Icon.X s={20} />
          </button>
        </div>
      </div>
      <div className="lightbox-stage">
        <button type="button" className="lightbox-nav lightbox-prev" onClick={() => go(-1)} aria-label="Photo précédente">
          <Icon.ChevronLeft s={28} />
        </button>
        {current.src
          ? <img className="lightbox-image" src={current.src} alt={current.title} />
          : <Photo kind={current.kind || 'warm'} label={current.label || current.title} style={{ width: 'min(100%, 760px)', aspectRatio: '4 / 3', borderRadius: 8 }} />}
        <button type="button" className="lightbox-nav lightbox-next" onClick={() => go(1)} aria-label="Photo suivante">
          <Icon.ChevronRight s={28} />
        </button>
      </div>
      <div className="lightbox-bottom">
        <div className="lightbox-caption">{current.albumLabel}</div>
        <div className="lightbox-caption">Utilisez les flèches pour parcourir l'album.</div>
      </div>
    </div>
  );
}

function SchedulePage() {
  const events = [
    { time: '14h00', title: 'Accueil', desc: 'Boisson fraîche et installation tranquille.', icon: <Icon.Sun /> },
    { time: '15h00', title: 'Photo de groupe (tout le monde !)', desc: 'Au jardin. Ne soyez pas en retard !', icon: <Icon.Camera /> },
    { time: '15h30', title: 'Jeux des enfants', desc: 'Chasse au trésor, arts & loisirs, coin lecture.', icon: <Icon.Game /> },
    { time: '16h30', title: 'BBQ servi', desc: 'Grillades, accompagnements et boissons.', icon: <Icon.Pot /> },
    { time: '18h30', title: 'Annonces familiales', desc: 'Grandes nouvelles, étapes importantes et toast familial.', icon: <Icon.Heart /> },
    { time: '19h00', title: 'Jeux famille', desc: 'Adultes vs ados — tableau familial et petits prix.', icon: <Icon.Game /> },
    { time: '19h30', title: 'Dessert + souvenirs', desc: 'Desserts, photos et souvenirs des BBQ passés.', icon: <Icon.Star fill="none" /> },
    { time: '20h30', title: 'Équipe rangement', desc: 'Plus on est, plus c\'est facile — merci !', icon: <Icon.Leaf /> },
    { time: '21h00', title: 'À l\'année prochaine', desc: 'Plus forts ensemble. Rentrez bien, la famille.', icon: <Icon.Heart fill="currentColor" /> },
  ];
  return (
    <div>
      <PageHero title="Programme de la journée" sub={`${BBQ_EVENT.dateLabel} · ${BBQ_EVENT.startTime} – ${BBQ_EVENT.endTime} · ${BBQ_EVENT.city}`} kind="green" label="Après-midi en famille" src="assets/real/bbq-2025-07.jpg" />
      <div className="container" style={{ paddingBottom: 36, maxWidth: 760, margin: '0 auto' }}>
        <div style={{ position: 'relative', paddingLeft: 28, marginTop: 24 }}>
          <div style={{ position: 'absolute', left: 12, top: 8, bottom: 8, width: 2, background: 'var(--line-2)' }} />
          {events.map((e, i) => (
            <div key={i} style={{ position: 'relative', padding: '8px 0 22px' }}>
              <div style={{ position: 'absolute', left: -22, top: 4, width: 28, height: 28, borderRadius: '50%', background: 'var(--green-700)', color: 'white', display: 'grid', placeItems: 'center' }}>
                {e.icon}
              </div>
              <div style={{ marginLeft: 16 }}>
                <div className="mono" style={{ fontSize: 11, color: 'var(--coral)', letterSpacing: '0.12em', fontWeight: 600 }}>{e.time}</div>
                <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', margin: '2px 0 4px' }}>{e.title}</div>
                <div style={{ color: 'var(--ink-2)', fontSize: 14 }}>{e.desc}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
      <Leaves />
    </div>
  );
}

function KidsPage() {
  const activities = [
    { title: 'Chasse au trésor', desc: '20 trésors cachés dans le jardin. Prix au gagnant.', src: 'assets/generated/kids/treasure-hunt.png' },
    { title: 'Tente arts & loisirs', desc: 'T-shirts tie-dye, bracelets d\'amitié, aquarelle.', src: 'assets/generated/kids/arts-crafts.png' },
    { title: 'Coin lecture avec Lola', desc: 'Un coin ombragé pour histoires et goûters.', src: 'assets/generated/kids/reading-corner.png' },
  ];
  return (
    <div>
      <PageHero title="Espace enfants" sub="Tout un après-midi de jeux, d'éclaboussures et de doigts collants." kind="water" label="Jardin familial" src="assets/generated/kids/children-hero.png" />
      <div className="container" style={{ paddingBottom: 36 }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14, marginTop: 24 }}>
          {activities.map((a, i) => (
            <div key={i} className="card">
              <Photo src={a.src} kind={i % 3 === 0 ? 'water' : i % 3 === 1 ? 'sun' : 'green'} label={a.title} style={{ height: 120, borderRadius: 8, marginBottom: 12 }} />
              <div className="serif" style={{ fontSize: 20, color: 'var(--green-900)', margin: '2px 0 6px' }}>{a.title}</div>
              <div style={{ fontSize: 13, color: 'var(--ink-2)' }}>{a.desc}</div>
            </div>
          ))}
        </div>
        <div className="card" style={{ marginTop: 20, background: 'var(--green-900)', color: 'var(--cream)', display: 'flex', gap: 18, alignItems: 'center' }}>
          <Icon.Heart s={28} fill="var(--coral)" />
          <div style={{ flex: 1 }}>
            <div className="serif" style={{ fontSize: 20, color: 'white' }}>Sécurité d'abord, famille toujours.</div>
            <div style={{ fontSize: 13, color: 'var(--cream)', opacity: 0.9 }}>Les enfants restent sous la surveillance de la famille pendant les activités.</div>
          </div>
        </div>
      </div>
      <Leaves />
    </div>
  );
}

function VolunteersPage({ state, actions, currentUserName = '' }) {
  const [Toast, showToast] = useToast();
  const roles = state.volunteerRoles || [];
  const signups = (state.volunteerSignups || []).filter((signup) => !signup.retiredAt);
  const userName = currentUserName.trim();
  const signRole = (role) => {
    if (!userName) {
      showToast('Reconnectez-vous avec votre nom avant de vous inscrire');
      return;
    }
    const alreadySigned = signups.some((signup) =>
      signup.role === role.role && (signup.name || '').trim().toLowerCase() === userName.toLowerCase()
    );
    if (alreadySigned) {
      showToast(`${userName} est déjà inscrit pour ${role.role}`);
      return;
    }
    actions.signVolunteer(role.id, userName);
    showToast(`${userName} est inscrit pour ${role.role} !`);
  };
  return (
    <div>
      <PageHero title="Inscription bénévoles" sub="Donnez un coup de main d'une heure pour rendre cette année inoubliable." kind="warm" label="Installation des tables" src="assets/real/bbq-2025-06.jpg" />
      <div className="container" style={{ paddingBottom: 36 }}>
        <div className="card volunteer-intro" style={{ marginTop: 24, background: 'var(--cream)' }}>
          <div>
            <div className="serif" style={{ fontSize: 22, color: 'var(--green-900)', marginBottom: 4 }}>Qui donne un coup de main ?</div>
            <div style={{ fontSize: 13, color: 'var(--ink-2)' }}>Les inscriptions utilisent le nom de la personne connectée.</div>
          </div>
          <div style={{ background: 'white', border: '1px solid var(--line)', borderRadius: 8, padding: '10px 12px', fontSize: 14, fontWeight: 700, color: 'var(--green-900)' }}>
            Connecté : {userName}
          </div>
        </div>
        <div className="volunteer-grid">
          {roles.map((r, i) => {
            const roleSignups = signups.filter((signup) => signup.role === r.role);
            const filled = Math.max(r.filled || 0, roleSignups.length);
            const full = filled >= r.need;
            const signedHere = roleSignups.some((signup) =>
              userName && (signup.name || '').trim().toLowerCase() === userName.toLowerCase()
            );
            return (
              <div key={i} className="card volunteer-card">
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                  <div>
                    <div className="serif" style={{ fontSize: 20, color: 'var(--green-900)' }}>{r.role}</div>
                    <div className="mono volunteer-time" style={{ fontSize: 11, letterSpacing: '0.12em' }}>{r.time}</div>
                  </div>
                  <div className={`volunteer-status${full ? ' full' : ''}`}>
                    {filled}/{r.need} {full ? 'COMPLET' : 'OUVERT'}
                  </div>
                </div>
                <div style={{ fontSize: 13, color: 'var(--ink-2)', margin: '8px 0 12px' }}>{r.desc}</div>
                <div className="volunteer-meter">
                  <div className="volunteer-meter-fill" style={{ width: `${Math.min(100, (filled / r.need) * 100)}%` }} />
                </div>
                <div className="volunteer-signups">
                  <div className="volunteer-signups-title">Inscrits</div>
                  {roleSignups.length > 0 ? (
                    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                      {roleSignups.map((signup) => (
                        <span key={signup.id} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, background: 'white', border: '1px solid var(--line)', borderRadius: 99, padding: '5px 9px', fontSize: 12, fontWeight: 600, color: 'var(--green-900)' }}>
                          <Icon.Check s={12} /> {signup.name}
                        </span>
                      ))}
                    </div>
                  ) : (
                    <div style={{ fontSize: 13, color: 'var(--ink-2)' }}>Personne encore — soyez le premier.</div>
                  )}
                </div>
                <button disabled={full || signedHere} onClick={() => signRole(r)} className={`btn ${full || signedHere ? 'btn-white' : 'btn-volunteer'}`} style={{ width: '100%', opacity: full || signedHere ? 0.5 : 1 }}>
                  {signedHere ? 'Déjà inscrit' : full ? 'Place pourvue' : 'Je m\'inscris'}
                </button>
              </div>
            );
          })}
        </div>
      </div>
      <Leaves />
      {Toast}
    </div>
  );
}

function FAQPage() {
  const [open, setOpen] = useState(0);
  const items = [
    { q: 'Que dois-je apporter ?', a: 'Vous-mêmes, votre bonne humeur, votre sourire et plein de joie ! Nous fournissons assiettes, couverts, boissons et sièges. Une chaise pliante est toujours la bienvenue si vous en avez une.' },
    { q: 'Quel est le code vestimentaire ?', a: 'Décontracté, confortable, prêt pour le BBQ. Pensez t-shirt, short, chaussures confortables.' },
    { q: 'Faut-il apporter une chaise ?', a: 'Nous avons ~40 chaises à l\'abri. Pour avoir une place garantie, apportez une chaise pliante (et étiquetez-la !).' },
    { q: 'Que se passe-t-il s\'il pleut ?', a: 'Pas de panique ! On a un grand carport pour s\'abriter, et si ça tombe vraiment fort, on rentre tous dans la maison. La fête continue quoi qu\'il arrive.' },
    { q: 'Puis-je amener un invité ?', a: 'Les amis-de-famille sont bienvenus — ajoutez-les à votre inscription pour qu\'on puisse prévoir le repas et les boissons.' },
    { q: 'Y a-t-il une limite d\'âge ?', a: 'Non ! De 6 mois à 96 ans, tout le monde a sa place à table.' },
    { q: 'Comment aider à couvrir les frais ?', a: 'Voir la carte « Contribuer » sur la page d\'accueil. Tout est utile.' },
  ];
  return (
    <div>
      <PageHero title="Questions fréquentes" sub="Les petits détails qui rendent la journée facile." kind="dusk" label="Famille à la table de pique-nique" src="assets/generated/faq-hero.png" />
      <div className="container" style={{ paddingBottom: 36, maxWidth: 760, margin: '0 auto' }}>
        <div style={{ marginTop: 24 }}>
          {items.map((it, i) => {
            const isOpen = open === i;
            return (
              <div key={i} style={{ borderBottom: '1px solid var(--line)' }}>
                <button onClick={() => setOpen(isOpen ? -1 : i)} style={{ width: '100%', background: 'none', border: 0, textAlign: 'left', padding: '16px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <span className="serif" style={{ fontSize: 18, color: 'var(--green-900)' }}>{it.q}</span>
                  <span style={{ width: 28, height: 28, borderRadius: '50%', background: isOpen ? 'var(--coral)' : 'var(--cream-2)', color: isOpen ? 'white' : 'var(--green-800)', display: 'grid', placeItems: 'center', flex: 'none' }}>
                    {isOpen ? <Icon.Minus /> : <Icon.Plus />}
                  </span>
                </button>
                {isOpen && (
                  <div style={{ paddingBottom: 16, fontSize: 14, color: 'var(--ink-2)', lineHeight: 1.6, paddingRight: 40 }}>
                    {it.a}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
      <Leaves />
    </div>
  );
}

window.FoodPage = FoodPage;
window.PhotosPage = PhotosPage;
window.SchedulePage = SchedulePage;
window.KidsPage = KidsPage;
window.VolunteersPage = VolunteersPage;
window.FAQPage = FAQPage;
