From 0ada3b80a03e688d116de0f1565818b4dcbd08f7 Mon Sep 17 00:00:00 2001 From: Dev-Moulin Date: Tue, 17 Feb 2026 10:19:23 +0100 Subject: [PATCH] feat: dice button larger + jump & face pulse animations --- .../founder/AlphabetIndex/AlphabetBar.tsx | 20 ++++++++- .../founder/AlphabetIndex/alphabetIndex.css | 44 ++++++++++++++++--- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/apps/web/src/components/founder/AlphabetIndex/AlphabetBar.tsx b/apps/web/src/components/founder/AlphabetIndex/AlphabetBar.tsx index f91161d..e4f3f18 100644 --- a/apps/web/src/components/founder/AlphabetIndex/AlphabetBar.tsx +++ b/apps/web/src/components/founder/AlphabetIndex/AlphabetBar.tsx @@ -82,10 +82,26 @@ const FACE_DOTS: Record = { function DiceDockItem({ onClick }: { onClick: () => void }) { const [rolling, setRolling] = useState(false); + const [jumping, setJumping] = useState(false); const [showTooltip, setShowTooltip] = useState(false); + const rollingRef = useRef(false); + + useEffect(() => { rollingRef.current = rolling; }, [rolling]); + + // Jump d'attention toutes les 4.5s + useEffect(() => { + const interval = setInterval(() => { + if (!rollingRef.current) { + setJumping(true); + setTimeout(() => setJumping(false), 750); + } + }, 4500); + return () => clearInterval(interval); + }, []); const handleClick = () => { if (rolling) return; + setJumping(false); setRolling(true); setTimeout(() => { setRolling(false); @@ -95,9 +111,9 @@ function DiceDockItem({ onClick }: { onClick: () => void }) { return (
setShowTooltip(true)} + onMouseEnter={() => { setShowTooltip(true); setJumping(false); }} onMouseLeave={() => setShowTooltip(false)} >
diff --git a/apps/web/src/components/founder/AlphabetIndex/alphabetIndex.css b/apps/web/src/components/founder/AlphabetIndex/alphabetIndex.css index e585455..9ee118b 100644 --- a/apps/web/src/components/founder/AlphabetIndex/alphabetIndex.css +++ b/apps/web/src/components/founder/AlphabetIndex/alphabetIndex.css @@ -60,8 +60,8 @@ /* === DOCK DICE (random button after Z) === */ .dock-dice { - width: calc(26px * var(--s)); - height: calc(30px * var(--s)); + width: calc(32px * var(--s)); + height: calc(34px * var(--s)); border-radius: 6px; position: relative; transition: width 150ms ease, height 150ms ease; @@ -69,10 +69,10 @@ /* 3D dice scene — provides perspective */ .dice-scene { - --dice-half: calc(7px * var(--s)); - width: calc(14px * var(--s)); - height: calc(14px * var(--s)); - perspective: calc(84px * var(--s)); + --dice-half: calc(9px * var(--s)); + width: calc(18px * var(--s)); + height: calc(18px * var(--s)); + perspective: calc(108px * var(--s)); flex-shrink: 0; transition: width 150ms ease, height 150ms ease, perspective 150ms ease; } @@ -105,6 +105,23 @@ border-radius: 15%; background: rgba(20, 20, 40, 0.85); border: 1px solid rgba(255, 255, 255, 0.2); + animation: diceFacePulse 2s ease-in-out infinite; +} + +@keyframes diceFacePulse { + 0%, 100% { + border-color: rgba(255, 255, 255, 0.2); + box-shadow: none; + } + 50% { + border-color: rgba(255, 255, 255, 0.65); + box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.15), 0 0 6px rgba(255, 255, 255, 0.2); + } +} + +/* Pas de pulse pendant le roll */ +.dice-inner.rolling .dice-face { + animation: none; } .face-1 { transform: rotateY(0deg) translateZ(var(--dice-half)); } @@ -138,6 +155,21 @@ animation: diceRoll 800ms cubic-bezier(0.22, 0.61, 0.36, 1); } +/* Idle jump — attire l'attention toutes les ~4.5s */ +@keyframes diceJump { + 0% { transform: translateY(0) scaleX(1) scaleY(1); } + 12% { transform: translateY(0) scaleX(1.15) scaleY(0.82); } /* compression départ */ + 38% { transform: translateY(-9px) scaleX(0.88) scaleY(1.12); } /* en l'air */ + 55% { transform: translateY(-9px) scaleX(0.88) scaleY(1.12); } /* flottement */ + 78% { transform: translateY(0) scaleX(1.12) scaleY(0.88); } /* impact sol */ + 90% { transform: translateY(-3px) scaleX(0.97) scaleY(1.03); } /* mini rebond */ + 100% { transform: translateY(0) scaleX(1) scaleY(1); } +} + +.dock-dice.jumping { + animation: diceJump 750ms cubic-bezier(0.36, 0.07, 0.19, 0.97); +} + /* Glassmorphism tooltip (same glass style as .founder-mini-card) */ .dice-tooltip { position: absolute;