From 2867a8ff236cbb4954bba2269d838ddd7ad944bc Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Sun, 27 Jul 2025 21:46:48 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20Rarity-Based=20Gradients=20&?= =?UTF-8?q?=20Animated=20Particles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎨 Rarity-Based Visual System: - Replaced TCG-based gradients with subtle rarity-based backgrounds - Common: Subtle gray gradient (no particles) - Uncommon: Subtle green gradient (15 particles) - Rare: Subtle gold gradient (25 particles) - Mythic: Rich gold gradient (40 particles) - Holographic: Subtle pink gradient (50 particles) - Enchanted: Subtle purple gradient (60 particles) - Super Rare: Subtle blue gradient (45 particles) - Legendary: Vibrant gold gradient (80 particles) ✨ Animated Particle Effects: - Floating particle animation with random positioning - Particles match rarity colors with glowing effects - Random animation delays and durations for natural movement - More rare cards = more magical particle effects - Particles are pointer-events-none (do not interfere with UI) 🎯 Smart Text Contrast: - Light rarities (common/uncommon/rare) use dark text - Dark rarities (mythic+) use white text for readability - Automatic contrast adaptation based on background 🌟 Enhanced Atmosphere: - Subtle background patterns (reduced opacity) - Rarity-appropriate visual hierarchy - Immersive, magical feel for rare cards The hero section now creates a truly magical experience --- pages/card/[id].js | 84 +++++++++++++++++++++++++++++++++++++++++----- styles/globals.css | 24 +++++++++++++ 2 files changed, 99 insertions(+), 9 deletions(-) diff --git a/pages/card/[id].js b/pages/card/[id].js index a366b8e..d55aeed 100644 --- a/pages/card/[id].js +++ b/pages/card/[id].js @@ -132,13 +132,49 @@ export default function CardDetail() { } }, [card, id]); - const getTCGGradient = (game) => { + const getRarityGradient = (rarity) => { + const rarityKey = rarity?.toLowerCase(); const gradients = { - 'MTG': '#9333ea, #8b5cf6, #4f46e5', - 'Pokemon': '#2563eb, #3b82f6, #0891b2', - 'Lorcana': '#db2777, #ec4899, #a855f7' + 'common': '#f3f4f6, #e5e7eb, #d1d5db', // Subtle gray + 'uncommon': '#ecfdf5, #d1fae5, #a7f3d0', // Subtle green + 'rare': '#fef3c7, #fde68a, #fcd34d', // Subtle gold + 'mythic': '#fef9c3, #fef08a, #facc15', // Rich gold + 'holographic': '#fce7f3, #fbcfe8, #f9a8d4', // Subtle pink + 'enchanted': '#f3e8ff, #e9d5ff, #c4b5fd', // Subtle purple + 'super rare': '#dbeafe, #bfdbfe, #93c5fd', // Subtle blue + 'legendary': '#fef3c7, #fde68a, #f59e0b' // Vibrant gold }; - return gradients[game] || '#4b5563, #374151'; + return gradients[rarityKey] || '#f9fafb, #f3f4f6, #e5e7eb'; + }; + + const getParticleCount = (rarity) => { + const rarityKey = rarity?.toLowerCase(); + const particleCounts = { + 'common': 0, + 'uncommon': 15, + 'rare': 25, + 'mythic': 40, + 'holographic': 50, + 'enchanted': 60, + 'super rare': 45, + 'legendary': 80 + }; + return particleCounts[rarityKey] || 0; + }; + + const getParticleColor = (rarity) => { + const rarityKey = rarity?.toLowerCase(); + const colors = { + 'common': '#ffffff', + 'uncommon': '#10b981', + 'rare': '#f59e0b', + 'mythic': '#ffd700', + 'holographic': '#ff6b6b', + 'enchanted': '#a855f7', + 'super rare': '#3b82f6', + 'legendary': '#ffd700' + }; + return colors[rarityKey] || '#ffffff'; }; const getTCGIcon = (game) => { @@ -338,13 +374,39 @@ export default function CardDetail() {
+ {/* Animated Particles Background */} + {getParticleCount(card.rarity) > 0 && ( +
+ {Array.from({ length: getParticleCount(card.rarity) }).map((_, i) => ( +
+
+
+ ))} +
+ )} + {/* Background Pattern */} -
+
@@ -385,7 +447,11 @@ export default function CardDetail() {
{/* Card Info */} -
+

{card.name}

{card.oracle_text || card.card_type}

diff --git a/styles/globals.css b/styles/globals.css index 6bc069b..dbb15ad 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -673,4 +673,28 @@ body { -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; +} + +/* Floating particle animation */ +@keyframes float { + 0%, 100% { + transform: translateY(0px) translateX(0px) scale(1); + opacity: 0.6; + } + 25% { + transform: translateY(-20px) translateX(10px) scale(1.1); + opacity: 0.8; + } + 50% { + transform: translateY(-10px) translateX(-15px) scale(0.9); + opacity: 1; + } + 75% { + transform: translateY(-25px) translateX(5px) scale(1.05); + opacity: 0.7; + } +} + +.animate-float { + animation: float 4s ease-in-out infinite; } \ No newline at end of file