Italian-Brainrot / index.html
NeuralFalcon's picture
Update index.html
1b19a1e verified
<!DOCTYPE html>
<html lang="en" class=""> <!-- Start without 'dark' class -->
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Italian Brainrot - Soundboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
/* Base styles */
body {
font-family: 'Poppins', sans-serif;
/* Smooth transition for theme changes */
@apply transition-colors duration-300 ease-in-out;
}
/* Light theme base */
body {
background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%);
}
/* Dark theme base */
.dark body {
background: linear-gradient(135deg, #1f2937 0%, #111827 100%); /* Dark gradient */
}
.character-card {
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
perspective: 1000px;
@apply transition-colors duration-300 ease-in-out; /* Transition background */
}
.character-card:hover {
transform: translateY(-8px);
/* Enhanced hover shadow for both themes */
@apply shadow-xl dark:shadow-2xl dark:shadow-indigo-500/20;
}
/* Specific light/dark styles will be applied via Tailwind classes directly */
.image-container {
/* Keep the gradient or simplify */
background: linear-gradient(145deg, #ffffff, #e6e6e6);
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
@apply transition-colors duration-300 ease-in-out;
}
.dark .image-container {
background: linear-gradient(145deg, #4b5563, #374151); /* Darker bg for image */
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
}
.play-btn {
transition: all 0.2s ease;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.play-btn.playing {
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); /* Red gradient for playing */
}
.play-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(118, 75, 162, 0.4);
}
.play-btn.playing:hover {
box-shadow: 0 5px 15px rgba(239, 68, 68, 0.4); /* Red shadow */
}
.play-btn:active {
transform: translateY(0);
}
.gradient-text {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
/* Optional: Slightly adjust gradient text for dark mode if needed */
/* .dark .gradient-text { ... } */
.header-divider {
height: 4px;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
@apply transition-all duration-300 ease-in-out;
}
.dark .header-divider {
background: linear-gradient(90deg, #818cf8 0%, #a78bfa 100%); /* Brighter gradient for dark */
}
/* Theme toggle button */
#theme-toggle {
@apply fixed top-5 right-5 z-50;
@apply w-12 h-12 rounded-full ;
@apply flex items-center justify-center;
@apply bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm; /* Semi-transparent background */
@apply text-gray-600 dark:text-gray-300;
@apply hover:bg-white dark:hover:bg-gray-700;
@apply shadow-md hover:shadow-lg;
@apply transition-all duration-300 ease-in-out;
@apply cursor-pointer;
}
#theme-toggle i {
@apply text-xl;
}
@media (max-width: 640px) {
.character-name {
font-size: 1rem; /* Already adjusted */
}
#theme-toggle {
@apply top-3 right-3 w-10 h-10; /* Smaller on mobile */
}
#theme-toggle i {
@apply text-lg;
}
}
</style>
</head>
<body class="min-h-screen"> <!-- Body class will be updated by JS -->
<!-- Theme Toggle Button -->
<button id="theme-toggle" aria-label="Toggle dark mode">
<i class="fas fa-moon"></i> <!-- Moon icon for light theme -->
<i class="fas fa-sun hidden"></i> <!-- Sun icon for dark theme -->
</button>
<div class="container mx-auto px-4 py-12 md:py-16">
<!-- Header -->
<header class="text-center mb-12 md:mb-16">
<h1 class="text-4xl md:text-5xl lg:text-6xl font-bold gradient-text mb-3">Italian Brainrot</h1>
<div class="header-divider w-32 md:w-40 mx-auto rounded-full mb-6"></div>
<p class="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
Discover the magical sounds of Italian Brainrot characters
</p>
</header>
<!-- Character Grid -->
<div id="characterGrid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
<!-- Character cards will be injected here by JS -->
</div>
</div>
<!-- Embedded Character Data -->
<script>
const characterData =
{
"Bombardiro Crocodilo": {
"image_path": "./assets/Bombardiro_Crocodilo.png",
"audio_path": "./assets/Bombardiro_Crocodilo.wav"
},
"Tralalero Tralala": {
"image_path": "./assets/Tralalero_Tralala.png",
"audio_path": "./assets/Tralalero_Tralala.wav"
},
"Bombombini Gusini": {
"image_path": "./assets/Bombombini_Gusini.png",
"audio_path": "./assets/Bombombini_Gusini.wav"
},
"Tung Tung Tung Tung Tung Tung Tung Tung Tung Sahur": {
"image_path": "./assets/Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Sahur.png",
"audio_path": "./assets/Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Sahur.wav"
},
"Brr Brr Patapim": {
"image_path": "./assets/Brr_Brr_Patapim.png",
"audio_path": "./assets/Brr_Brr_Patapim.wav"
},
"Cappuccino Assassino": {
"image_path": "./assets/Cappuccino_Assassino.png",
"audio_path": "./assets/Cappuccino_Assassino.wav"
},
"Lirili Larila": {
"image_path": "./assets/Lirili_Larila.png",
"audio_path": "./assets/Lirili_Larila.wav"
},
"Trulimero Trulichina": {
"image_path": "./assets/Trulimero_Trulichina.png",
"audio_path": "./assets/Trulimero_Trulichina.wav"
},
"Boneca Ambalabu": {
"image_path": "./assets/Boneca_Ambalabu.png",
"audio_path": "./assets/Boneca_Ambalabu.wav"
},
"Chimpanzini Bananini": {
"image_path": "./assets/Chimpanzini_Bananini.png",
"audio_path": "./assets/Chimpanzini_Bananini.wav"
},
"Bananita Dolfinita": {
"image_path": "./assets/Bananita_Dolfinita.png",
"audio_path": "./assets/Bananita_Dolfinita.wav"
},
"Bluberini Octopusini": {
"image_path": "./assets/Bluberini_Octopusini.png",
"audio_path": "./assets/Bluberini_Octopusini.wav"
},
"Bobrito Bandito": {
"image_path": "./assets/Bobrito_Bandito.png",
"audio_path": "./assets/Bobrito_Bandito.wav"
},
"Brri Brri Bicus Dicus": {
"image_path": "./assets/Brri_Brri_Bicus_Dicus.png",
"audio_path": "./assets/Brri_Brri_Bicus_Dicus.wav"
},
"Burbaloni Luliloli": {
"image_path": "./assets/Burbaloni_Luliloli.png",
"audio_path": "./assets/Burbaloni_Luliloli.wav"
},
"Chimpanzini Ananasini": {
"image_path": "./assets/Chimpanzini_Ananasini.png",
"audio_path": "./assets/Chimpanzini_Ananasini.wav"
},
"Chimpanzini Cocosini": {
"image_path": "./assets/Chimpanzini_Cocosini.png",
"audio_path": "./assets/Chimpanzini_Cocosini.wav"
},
"Cocofanto Elefanto": {
"image_path": "./assets/Cocofanto_Elefanto.png",
"audio_path": "./assets/Cocofanto_Elefanto.wav"
},
"Frigo Camello Buffo Fardelo": {
"image_path": "./assets/Frigo Camello Buffo Fardelo.png",
"audio_path": "./assets/Frigo Camello Buffo Fardelo.wav"
},
"Giraffe Celeste": {
"image_path": "./assets/Giraffe_Celeste.png",
"audio_path": "./assets/Giraffe_Celeste.wav"
},
"Glorbo Fruttodrillo": {
"image_path": "./assets/Glorbo_Fruttodrillo.png",
"audio_path": "./assets/Glorbo_Fruttodrillo.wav"
},
"IL Cacto Hipopotoma": {
"image_path": "./assets/il_cacto_hipopotoma.png",
"audio_path": "./assets/il_cacto_hipopotoma.wav"
},
"La Vaca Saturno Saturnita": {
"image_path": "./assets/La_Vaca_Saturno_Saturnita.png",
"audio_path": "./assets/La_Vaca_Saturno_Saturnita.wav"
},
"Trippi Troppi Troppa Trippa": {
"image_path": "./assets/Trippi_Troppi_Troppa_Trippa.png",
"audio_path": "./assets/Trippi_Troppi_Troppa_Trippa.wav"
}
}
;
const characterGrid = document.getElementById('characterGrid');
const themeToggleButton = document.getElementById('theme-toggle');
const sunIcon = themeToggleButton.querySelector('.fa-sun');
const moonIcon = themeToggleButton.querySelector('.fa-moon');
const htmlElement = document.documentElement; // Target <html> for dark class
let currentlyPlayingAudio = null;
let currentlyPlayingButton = null;
// Function to apply the theme
function applyTheme(theme) {
if (theme === 'dark') {
htmlElement.classList.add('dark');
moonIcon.classList.add('hidden');
sunIcon.classList.remove('hidden');
localStorage.setItem('theme', 'dark');
} else {
htmlElement.classList.remove('dark');
moonIcon.classList.remove('hidden');
sunIcon.classList.add('hidden');
localStorage.setItem('theme', 'light');
}
}
// Function to toggle the theme
function toggleTheme() {
const currentTheme = htmlElement.classList.contains('dark') ? 'dark' : 'light';
applyTheme(currentTheme === 'dark' ? 'light' : 'dark');
}
// Function to load and display characters
function loadCharacters() {
characterGrid.innerHTML = ''; // Clear existing
Object.entries(characterData).forEach(([name, data]) => {
const card = document.createElement('div');
// Apply base and dark mode classes using Tailwind
card.className = `
character-card
bg-white dark:bg-gray-800
rounded-2xl overflow-hidden
shadow-md hover:shadow-xl dark:hover:shadow-2xl dark:hover:shadow-indigo-500/20
border border-gray-200 dark:border-gray-700/50
flex flex-col items-center p-6
transition-all duration-300 ease-in-out
`;
// Image container
const imageContainer = document.createElement('div');
imageContainer.className = `
image-container mb-5 w-40 h-40 lg:w-44 lg:h-44
flex items-center justify-center
rounded-2xl overflow-hidden
border-4 border-white/50 dark:border-gray-700/50
`; // Added slightly larger size on larger screens and border
const image = document.createElement('img');
image.src = data.image_path.replace(/\\/g, '/');
image.alt = name;
image.className = 'w-full h-full object-cover';
image.onerror = () => { // Basic error handling for images
image.src = 'placeholder.png'; // Provide a fallback image path
console.warn(`Image not found: ${data.image_path}`);
};
imageContainer.appendChild(image);
// Character name
const nameElement = document.createElement('h3');
nameElement.className = `
character-name text-lg md:text-xl font-semibold
text-gray-800 dark:text-gray-100
mb-4 text-center transition-colors duration-300
`;
nameElement.textContent = name;
// Play/Pause button
const playButton = document.createElement('button');
playButton.className = `
play-btn text-white font-medium py-2.5 px-7
rounded-full flex items-center justify-center
w-32 /* Fixed width for consistency */
`;
const playIcon = document.createElement('i');
playIcon.className = 'fas fa-play mr-2'; // Start with play
playButton.appendChild(playIcon);
playButton.appendChild(document.createTextNode('Play'));
// Audio element (keep it hidden)
const audio = new Audio(data.audio_path.replace(/\\/g, '/'));
audio.preload = 'metadata'; // Improve loading slightly
audio.style.display = 'none';
audio.onerror = () => {
console.error(`Error loading audio: ${data.audio_path}`);
playButton.disabled = true; // Disable button if audio fails
playButton.textContent = 'Error';
playButton.classList.add('opacity-50', 'cursor-not-allowed');
};
// --- Refined Play/Pause Logic ---
playButton.addEventListener('click', () => {
// If this audio is currently playing, pause it
if (currentlyPlayingAudio === audio) {
audio.pause();
currentlyPlayingAudio = null;
currentlyPlayingButton = null;
// Reset this button visually
playButton.innerHTML = '<i class="fas fa-play mr-2"></i>Play';
playButton.classList.remove('playing');
} else {
// If another audio is playing, stop it first
if (currentlyPlayingAudio) {
currentlyPlayingAudio.pause();
currentlyPlayingAudio.currentTime = 0; // Reset time
// Reset the *other* button visually
if (currentlyPlayingButton) {
currentlyPlayingButton.innerHTML = '<i class="fas fa-play mr-2"></i>Play';
currentlyPlayingButton.classList.remove('playing');
}
}
// Now play this audio
audio.currentTime = 0;
audio.play().catch(e => console.error("Audio play failed:", e)); // Catch potential play errors
currentlyPlayingAudio = audio;
currentlyPlayingButton = playButton;
// Update this button visually to 'Pause'
playButton.innerHTML = '<i class="fas fa-pause mr-2"></i>Pause';
playButton.classList.add('playing');
}
});
// When audio naturally ends, reset the button
audio.addEventListener('ended', () => {
if (currentlyPlayingAudio === audio) { // Ensure it's the one that just ended
playButton.innerHTML = '<i class="fas fa-play mr-2"></i>Play';
playButton.classList.remove('playing');
currentlyPlayingAudio = null;
currentlyPlayingButton = null;
}
});
// --- End Refined Play/Pause Logic ---
// Assemble the card
card.appendChild(imageContainer);
card.appendChild(nameElement);
card.appendChild(playButton);
card.appendChild(audio); // Add hidden audio element
// Add card to the grid
characterGrid.appendChild(card);
});
}
// --- Initialization ---
// 1. Set initial theme based on localStorage or system preference
const savedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (savedTheme) {
applyTheme(savedTheme);
} else if (prefersDark) {
applyTheme('dark');
} else {
applyTheme('light'); // Default to light
}
// 2. Add listener for the theme toggle button
themeToggleButton.addEventListener('click', toggleTheme);
// 3. Load characters when the page loads
window.addEventListener('DOMContentLoaded', loadCharacters);
</script>
</body>
</html>