Silhouette animée de joueur de basket derrière les stats du hero

Ajoute une illustration originale (SVG, pas une photo) d'un joueur en
plein dribble, en aplat noir/blanc avec liseré rouge de la marque, animée
derrière la ligne de statistiques du hero (rebond du ballon, léger
balancement du corps, traits de vitesse). Silhouette générique — aucune
personne réelle identifiable, donc aucune question de droit à l'image.

- Nouveau composant HeroPlayerSilhouette.jsx : figure construite à partir
  de segments à traits épais et jointures rondes (même logique que les
  pictogrammes sportifs plats type NBA/Jordan), plus fiable à main levée
  qu'un tracé bezier continu.
- Positionnement en arrière-plan avec un masque en dégradé qui estompe la
  silhouette exactement derrière le texte des statistiques (déjà proche du
  seuil de contraste WCAG) et ne la laisse apparaître que dans l'espace
  vide à droite — le contraste du texte reste inchangé.
- prefers-reduced-motion : figure et ballon figés, traits de vitesse
  masqués (première utilisation de cette media query dans le projet).
  aria-hidden + pointer-events:none (purement décoratif).
- Réduite à 960px, masquée sous 640px (pas de place pour coexister avec
  la ligne de stats sur petit écran).
- Aucun changement serveur, CSP, Docker ni nouvelle dépendance — CSS/SVG
  pur, dans l'esprit de l'animation marquee déjà existante.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
This commit is contained in:
Claude committed 2026-07-25 22:43:58 +00:00
1 parent 65213e812a
commit f5b2e26ee4
3 files changed
+127 -7

No files matched your search

+11 -7
View File
@@ -7,6 +7,7 @@ import Modal from '../components/Modal.jsx';
import PastEventCard from '../components/PastEventCard.jsx';
import { AdhesionForm, AdhesionModal } from '../components/AdhesionForm.jsx';
import { associationSettings } from '../lib/siteSettings.js';
import HeroPlayerSilhouette from '../components/HeroPlayerSilhouette.jsx';
export function InscriptionModal({ rencontre, onClose, onDone }) {
const { user, login } = useAuth();
@@ -265,13 +266,16 @@ export default function Home() {
<button className="btn btn-outline">Découvrir l'association</button>
</Link>
</div>
<div style={{ display: 'flex', gap: 42, marginTop: 54, paddingTop: 34, borderTop: '1px solid var(--border)' }}>
{[[String(members.length), 'entreprises membres'], [String(passees.length), 'rencontres organisées'], ['30 ans', 'de partenariat']].map(([n, l]) => (
<div key={l}>
<div className="serif" style={{ fontSize: 34, fontWeight: 600 }}>{n}</div>
<div style={{ fontSize: 13, color: 'var(--gray-light)', marginTop: 2 }}>{l}</div>
</div>
))}
<div className="hero-stats-wrap" style={{ position: 'relative', marginTop: 54, paddingTop: 34, borderTop: '1px solid var(--border)' }}>
<HeroPlayerSilhouette />
<div style={{ display: 'flex', gap: 42, position: 'relative', zIndex: 1 }}>
{[[String(members.length), 'entreprises membres'], [String(passees.length), 'rencontres organisées'], ['30 ans', 'de partenariat']].map(([n, l]) => (
<div key={l}>
<div className="serif" style={{ fontSize: 34, fontWeight: 600 }}>{n}</div>
<div style={{ fontSize: 13, color: 'var(--gray-light)', marginTop: 2 }}>{l}</div>
</div>
))}
</div>
</div>
</div>
<div style={{ position: 'relative' }}>