Remplace la silhouette SVG du hero par une vraie vidéo de joueur
L'illustration SVG derrière les stats de l'accueil ne rendait pas professionnel. Remplacée par une vraie vidéo (Pexels, licence libre d'usage commercial) d'un joueur en dribble continu, passée en noir et blanc via CSS et masquée en dégradé pour préserver le contraste du texte, comme pour la version précédente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
This commit is contained in:
6 files changed
+44
-114
No files matched your search
Binary file not shown.
@@ -1,60 +0,0 @@
|
||||
// Purely decorative basketball-player silhouette animated behind the hero
|
||||
// stats row. An original flat-illustration silhouette (not a photo/video),
|
||||
// built from rounded-capsule limb segments — the same construction as
|
||||
// classic flat sports pictograms (NBA/Jordan-style marks) — in a duotone
|
||||
// matching the site theme. Avoids any droit-à-l'image concern since it
|
||||
// does not depict a real identifiable person.
|
||||
export default function HeroPlayerSilhouette({ className = '' }) {
|
||||
return (
|
||||
<svg
|
||||
className={`hero-stats-silhouette ${className}`.trim()}
|
||||
viewBox="0 0 360 300"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
role="presentation"
|
||||
focusable="false"
|
||||
>
|
||||
<g className="hspl-figure" fill="var(--ink)">
|
||||
<g fill="none" stroke="var(--ink)" strokeLinecap="round">
|
||||
{/* trailing arm, swung back for balance */}
|
||||
<line x1="222" y1="88" x2="192" y2="64" strokeWidth="15" />
|
||||
<line x1="192" y1="64" x2="164" y2="50" strokeWidth="10" />
|
||||
{/* dribbling arm, reaching down to the ball */}
|
||||
<line x1="230" y1="96" x2="262" y2="136" strokeWidth="16" />
|
||||
<line x1="262" y1="136" x2="290" y2="186" strokeWidth="10" />
|
||||
{/* torso */}
|
||||
<line x1="240" y1="80" x2="215" y2="130" strokeWidth="34" />
|
||||
<line x1="215" y1="130" x2="198" y2="168" strokeWidth="24" />
|
||||
{/* planted / front leg */}
|
||||
<line x1="205" y1="168" x2="224" y2="220" strokeWidth="22" />
|
||||
<line x1="224" y1="220" x2="218" y2="272" strokeWidth="14" />
|
||||
<line x1="218" y1="272" x2="240" y2="280" strokeWidth="12" />
|
||||
{/* trailing leg, extended back */}
|
||||
<line x1="196" y1="170" x2="150" y2="196" strokeWidth="22" />
|
||||
<line x1="150" y1="196" x2="108" y2="204" strokeWidth="13" />
|
||||
<line x1="108" y1="204" x2="84" y2="212" strokeWidth="11" />
|
||||
</g>
|
||||
{/* joint fillers smoothing the width change between segments */}
|
||||
<circle cx="192" cy="64" r="7.5" />
|
||||
<circle cx="262" cy="136" r="8" />
|
||||
<circle cx="215" cy="130" r="17" />
|
||||
<circle cx="201" cy="169" r="13" />
|
||||
<circle cx="224" cy="220" r="11" />
|
||||
<circle cx="150" cy="196" r="11" />
|
||||
<circle cx="248" cy="54" r="23" />
|
||||
</g>
|
||||
|
||||
<g className="hspl-ball" fill="var(--ink)">
|
||||
<circle cx="300" cy="208" r="22" />
|
||||
<path d="M280,196 C293,203 307,203 320,196" fill="none" stroke="var(--bg)" strokeWidth="2" />
|
||||
<path d="M300,187 C293,197 293,220 300,231" fill="none" stroke="var(--bg)" strokeWidth="2" />
|
||||
</g>
|
||||
|
||||
<g className="hspl-speedlines" stroke="var(--ink)" strokeWidth="3" strokeLinecap="round" fill="none">
|
||||
<path className="hspl-speedline" d="M42,196 L78,201" />
|
||||
<path className="hspl-speedline" d="M34,214 L72,214" />
|
||||
<path className="hspl-speedline" d="M40,232 L76,226" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Purely decorative real video of a basketball player dribbling, animated
|
||||
// behind the hero stats row. Desaturated to black & white at runtime via
|
||||
// CSS (no source video processing available in this environment). Source:
|
||||
// Pexels stock footage (free commercial license, no attribution required,
|
||||
// anonymous player) — see web/public/assets/hero-player.mp4.
|
||||
export default function HeroPlayerVideo({ className = '' }) {
|
||||
const reduceMotion =
|
||||
typeof window !== 'undefined' &&
|
||||
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
return (
|
||||
<video
|
||||
className={`hero-stats-video ${className}`.trim()}
|
||||
src="/assets/hero-player.mp4"
|
||||
autoPlay={!reduceMotion}
|
||||
loop={!reduceMotion}
|
||||
muted
|
||||
playsInline
|
||||
preload="auto"
|
||||
aria-hidden="true"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -7,7 +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';
|
||||
import HeroPlayerVideo from '../components/HeroPlayerVideo.jsx';
|
||||
|
||||
export function InscriptionModal({ rencontre, onClose, onDone }) {
|
||||
const { user, login } = useAuth();
|
||||
@@ -267,7 +267,7 @@ export default function Home() {
|
||||
</Link>
|
||||
</div>
|
||||
<div className="hero-stats-wrap" style={{ position: 'relative', marginTop: 54, paddingTop: 34, borderTop: '1px solid var(--border)' }}>
|
||||
<HeroPlayerSilhouette />
|
||||
<HeroPlayerVideo />
|
||||
<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}>
|
||||
|
||||
+17
-52
@@ -43,58 +43,23 @@ input:focus, textarea:focus, select:focus { outline: none; border-color: var(--r
|
||||
.marquee-fade { width: 40px; }
|
||||
}
|
||||
|
||||
/* Hero stats background: an animated basketball-player silhouette behind
|
||||
the "entreprises membres / rencontres organisées / X ans" row. Original
|
||||
illustration (not a photo), decorative only — see .hspl-* below. */
|
||||
/* Hero stats background: a real video of a basketball player dribbling,
|
||||
behind the "entreprises membres / rencontres organisées / X ans" row.
|
||||
Pexels stock footage (free commercial license, no attribution required,
|
||||
anonymous player), desaturated at runtime via CSS. */
|
||||
.hero-stats-wrap { overflow: visible; }
|
||||
.hero-stats-silhouette {
|
||||
position: absolute; right: -20px; bottom: -34px; width: 300px; height: auto;
|
||||
.hero-stats-video {
|
||||
position: absolute; right: -20px; bottom: -34px;
|
||||
width: 420px; height: 130px;
|
||||
object-fit: cover; object-position: 60% 35%;
|
||||
pointer-events: none;
|
||||
/* Fades the silhouette out over the stat text (left) and lets it show at
|
||||
full (still very low) opacity only over the clear whitespace (right),
|
||||
so it never degrades the existing text contrast. */
|
||||
mask-image: linear-gradient(100deg, transparent 0%, transparent 24%, black 48%, black 100%);
|
||||
-webkit-mask-image: linear-gradient(100deg, transparent 0%, transparent 24%, black 48%, black 100%);
|
||||
}
|
||||
.hspl-figure {
|
||||
opacity: .08; transform-origin: 50% 100%;
|
||||
animation: hspl-drift 7s ease-in-out infinite alternate, hspl-glow 5s ease-in-out infinite;
|
||||
}
|
||||
.hspl-ball {
|
||||
opacity: .14; transform-box: fill-box; transform-origin: 50% 100%;
|
||||
animation: hspl-ball-bounce 1.4s infinite;
|
||||
}
|
||||
.hspl-speedline {
|
||||
opacity: .3;
|
||||
animation: hspl-speedline 2.4s ease-out infinite;
|
||||
}
|
||||
.hspl-speedline:nth-child(2) { animation-delay: .3s; }
|
||||
.hspl-speedline:nth-child(3) { animation-delay: .6s; }
|
||||
|
||||
@keyframes hspl-drift {
|
||||
from { transform: translateY(0) rotate(0deg); }
|
||||
to { transform: translateY(-10px) rotate(-1.4deg); }
|
||||
}
|
||||
@keyframes hspl-glow {
|
||||
0%, 100% { filter: drop-shadow(2px 0 0 rgba(193, 39, 45, 0)); }
|
||||
50% { filter: drop-shadow(2px 0 0 rgba(193, 39, 45, .18)); }
|
||||
}
|
||||
@keyframes hspl-ball-bounce {
|
||||
0% { transform: translateY(0); animation-timing-function: cubic-bezier(.55, 0, 1, .45); }
|
||||
18% { transform: translateY(38px) scaleY(.82) scaleX(1.1); animation-timing-function: cubic-bezier(0, .55, .45, 1); }
|
||||
50% { transform: translateY(0); animation-timing-function: cubic-bezier(.55, 0, 1, .45); }
|
||||
68% { transform: translateY(38px) scaleY(.82) scaleX(1.1); animation-timing-function: cubic-bezier(0, .55, .45, 1); }
|
||||
100% { transform: translateY(0); }
|
||||
}
|
||||
@keyframes hspl-speedline {
|
||||
0% { opacity: 0; transform: translateX(6px); }
|
||||
30% { opacity: 1; transform: translateX(0); }
|
||||
70% { opacity: 1; transform: translateX(-4px); }
|
||||
100% { opacity: 0; transform: translateX(-10px); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.hspl-figure, .hspl-ball { animation: none !important; }
|
||||
.hspl-speedline { display: none !important; }
|
||||
filter: grayscale(1) contrast(1.05) brightness(1.05);
|
||||
opacity: .22;
|
||||
/* Fades the video out over the stat text (left) and lets it show only
|
||||
over the clear whitespace (right), so it never degrades the existing
|
||||
text contrast. */
|
||||
mask-image: linear-gradient(100deg, transparent 0%, transparent 26%, black 52%, black 100%);
|
||||
-webkit-mask-image: linear-gradient(100deg, transparent 0%, transparent 26%, black 52%, black 100%);
|
||||
}
|
||||
|
||||
.container { max-width: 1180px; margin: 0 auto; padding-left: 32px; padding-right: 32px; }
|
||||
@@ -302,7 +267,7 @@ input:focus, textarea:focus, select:focus { outline: none; border-color: var(--r
|
||||
@media (max-width: 960px) {
|
||||
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr !important; }
|
||||
.hero-grid { grid-template-columns: 1fr !important; }
|
||||
.hero-stats-silhouette { width: 190px; right: -10px; bottom: -10px; }
|
||||
.hero-stats-video { width: 260px; height: 100px; right: -10px; bottom: -10px; }
|
||||
}
|
||||
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
|
||||
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
|
||||
@@ -329,7 +294,7 @@ input:focus, textarea:focus, select:focus { outline: none; border-color: var(--r
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container { padding-left: 20px; padding-right: 20px; }
|
||||
.hero-stats-silhouette { display: none; }
|
||||
.hero-stats-video { display: none; }
|
||||
.admin-nav { grid-template-columns: 1fr; gap: 20px; }
|
||||
.admin-sidebar-footer { align-items: stretch; flex-direction: column; }
|
||||
.admin-sidebar-action { width: 100%; }
|
||||
|
||||
Reference in new issue
Block a user