Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Lyric Muse - AI-Powered Lyrics Generator</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'); | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| min-height: 100vh; | |
| } | |
| .artist-card { | |
| transition: all 0.3s ease; | |
| transform: scale(0.95); | |
| } | |
| .artist-card:hover { | |
| transform: scale(1); | |
| box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); | |
| } | |
| .artist-card.selected { | |
| border: 3px solid #6366f1; | |
| transform: scale(1); | |
| } | |
| .lyrics-container { | |
| background: linear-gradient(to right, #f8fafc, #f1f5f9); | |
| border-left: 4px solid #6366f1; | |
| } | |
| .typewriter { | |
| overflow: hidden; | |
| border-right: .15em solid #6366f1; | |
| white-space: pre-wrap; | |
| margin: 0 auto; | |
| letter-spacing: .15em; | |
| animation: | |
| typing 3.5s steps(40, end), | |
| blink-caret .75s step-end infinite; | |
| } | |
| @keyframes typing { | |
| from { width: 0 } | |
| to { width: 100% } | |
| } | |
| @keyframes blink-caret { | |
| from, to { border-color: transparent } | |
| 50% { border-color: #6366f1; } | |
| } | |
| .fade-in { | |
| animation: fadeIn 1.5s; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen py-10 px-4 sm:px-6 lg:px-8"> | |
| <div class="max-w-6xl mx-auto"> | |
| <!-- Header --> | |
| <header class="text-center mb-12"> | |
| <h1 class="text-4xl font-bold text-indigo-600 mb-2">Lyric Muse</h1> | |
| <p class="text-lg text-gray-600">Generate lyrics inspired by your favorite artists</p> | |
| <div class="w-24 h-1 bg-indigo-400 mx-auto mt-4 rounded-full"></div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="bg-white rounded-xl shadow-xl overflow-hidden"> | |
| <!-- Generator Section --> | |
| <section class="p-6 md:p-8"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> | |
| <!-- Input Section --> | |
| <div> | |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Create Your Lyrics</h2> | |
| <!-- Artist Selection --> | |
| <div class="mb-8"> | |
| <h3 class="text-lg font-medium text-gray-700 mb-4">Select an Artist</h3> | |
| <div class="grid grid-cols-2 sm:grid-cols-3 gap-4" id="artist-grid"> | |
| <!-- Artists will be added here by JavaScript --> | |
| </div> | |
| </div> | |
| <!-- Theme Input --> | |
| <div class="mb-6"> | |
| <label for="theme" class="block text-lg font-medium text-gray-700 mb-2">Theme or Keywords</label> | |
| <input type="text" id="theme" placeholder="e.g. love, heartbreak, summer nights" | |
| class="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition"> | |
| </div> | |
| <!-- Mood Selection --> | |
| <div class="mb-8"> | |
| <label class="block text-lg font-medium text-gray-700 mb-2">Mood</label> | |
| <div class="flex flex-wrap gap-3"> | |
| <button class="mood-btn px-4 py-2 rounded-full bg-gray-100 hover:bg-indigo-100 text-gray-700 hover:text-indigo-700 transition" data-mood="happy">😊 Happy</button> | |
| <button class="mood-btn px-4 py-2 rounded-full bg-gray-100 hover:bg-indigo-100 text-gray-700 hover:text-indigo-700 transition" data-mood="sad">😢 Sad</button> | |
| <button class="mood-btn px-4 py-2 rounded-full bg-gray-100 hover:bg-indigo-100 text-gray-700 hover:text-indigo-700 transition" data-mood="romantic">❤️ Romantic</button> | |
| <button class="mood-btn px-4 py-2 rounded-full bg-gray-100 hover:bg-indigo-100 text-gray-700 hover:text-indigo-700 transition" data-mood="angry">😠 Angry</button> | |
| <button class="mood-btn px-4 py-2 rounded-full bg-gray-100 hover:bg-indigo-100 text-gray-700 hover:text-indigo-700 transition" data-mood="chill">😌 Chill</button> | |
| </div> | |
| </div> | |
| <!-- Generate Button --> | |
| <button id="generate-btn" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-semibold py-3 px-6 rounded-lg shadow-md transition transform hover:scale-105 active:scale-95"> | |
| <i class="fas fa-magic mr-2"></i> Generate Lyrics | |
| </button> | |
| </div> | |
| <!-- Output Section --> | |
| <div> | |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Your Generated Lyrics</h2> | |
| <div class="lyrics-container p-6 rounded-lg h-full min-h-[400px] relative"> | |
| <div id="lyrics-placeholder" class="text-center py-16 text-gray-400"> | |
| <i class="fas fa-music text-4xl mb-4"></i> | |
| <p>Your AI-generated lyrics will appear here</p> | |
| </div> | |
| <div id="lyrics-output" class="hidden whitespace-pre-line text-gray-800 font-medium"></div> | |
| <!-- Loading Animation --> | |
| <div id="loading-animation" class="hidden absolute inset-0 flex items-center justify-center bg-white bg-opacity-80"> | |
| <div class="flex flex-col items-center"> | |
| <div class="w-16 h-16 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin mb-4"></div> | |
| <p class="text-indigo-600 font-medium">Channeling the artist's creative energy...</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Action Buttons --> | |
| <div class="mt-4 flex gap-3"> | |
| <button id="copy-btn" class="hidden flex-1 bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-2 px-4 rounded-lg transition"> | |
| <i class="fas fa-copy mr-2"></i> Copy | |
| </button> | |
| <button id="save-btn" class="hidden flex-1 bg-indigo-100 hover:bg-indigo-200 text-indigo-700 font-medium py-2 px-4 rounded-lg transition"> | |
| <i class="fas fa-save mr-2"></i> Save | |
| </button> | |
| <button id="regenerate-btn" class="hidden flex-1 bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-lg transition"> | |
| <i class="fas fa-sync-alt mr-2"></i> Regenerate | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Featured Artists Section --> | |
| <section class="bg-gray-50 p-6 md:p-8 border-t border-gray-200"> | |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Featured Artists</h2> | |
| <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4"> | |
| <!-- Featured artists will be added here by JavaScript --> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="mt-12 text-center text-gray-500 text-sm"> | |
| <p>© 2023 Lyric Muse. All generated lyrics are AI-created parodies.</p> | |
| <p class="mt-1">This is a demo application for educational purposes.</p> | |
| </footer> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Artist data | |
| const artists = [ | |
| { id: 'taylor-swift', name: 'Taylor Swift', genre: 'Pop', era: 'Midnights', image: 'https://i.scdn.co/image/ab6761610000e5eb9e690225ad4445530612ccc9' }, | |
| { id: 'kendrick-lamar', name: 'Kendrick Lamar', genre: 'Hip-Hop', era: 'DAMN.', image: 'https://i.scdn.co/image/ab6761610000e5eb437b9e2a82505b3d93ff1022' }, | |
| { id: 'beyonce', name: 'Beyoncé', genre: 'R&B', era: 'Renaissance', image: 'https://i.scdn.co/image/ab6761610000e5eb0d66b3670294bf8016a6749e' }, | |
| { id: 'the-weeknd', name: 'The Weeknd', genre: 'R&B', era: 'After Hours', image: 'https://i.scdn.co/image/ab6761610000e5eb8ae7f2aaa9817a704a87ea36' }, | |
| { id: 'lana-del-rey', name: 'Lana Del Rey', genre: 'Alternative', era: 'Norman F***ing Rockwell!', image: 'https://i.scdn.co/image/ab6761610000e5eb6a8e5e8752d1dc2d7fcb12c2' }, | |
| { id: 'harry-styles', name: 'Harry Styles', genre: 'Pop', era: "Harry's House", image: 'https://i.scdn.co/image/ab6761610000e5eb0b4b3603d0c4a6de9a8f7851' }, | |
| { id: 'billie-eilish', name: 'Billie Eilish', genre: 'Alternative', era: 'Happier Than Ever', image: 'https://i.scdn.co/image/ab6761610000e5ebc36dd9eb55fb0db4911bc25d' }, | |
| { id: 'drake', name: 'Drake', genre: 'Hip-Hop', era: 'Her Loss', image: 'https://i.scdn.co/image/ab6761610000e5eb429bb5eea8b7867a9875dc5e' }, | |
| { id: 'ariana-grande', name: 'Ariana Grande', genre: 'Pop', era: 'Positions', image: 'https://i.scdn.co/image/ab6761610000e5ebcdce7620dc940db079bf4952' }, | |
| { id: 'ed-sheeran', name: 'Ed Sheeran', genre: 'Pop', era: '=', image: 'https://i.scdn.co/image/ab6761610000e5eb12a2ef08d00dd7431d226b90' }, | |
| { id: 'olivia-rodrigo', name: 'Olivia Rodrigo', genre: 'Pop', era: 'SOUR', image: 'https://i.scdn.co/image/ab6761610000e5eb9e690225ad4445530612ccc9' }, | |
| { id: 'post-malone', name: 'Post Malone', genre: 'Hip-Hop', era: 'Twelve Carat Toothache', image: 'https://i.scdn.co/image/ab6761610000e5ebd42a27be7148b59f3f2ba3a0' } | |
| ]; | |
| // Featured artists (subset of all artists) | |
| const featuredArtists = artists.slice(0, 6); | |
| // DOM elements | |
| const artistGrid = document.getElementById('artist-grid'); | |
| const featuredArtistsGrid = document.querySelector('.bg-gray-50 .grid'); | |
| const themeInput = document.getElementById('theme'); | |
| const generateBtn = document.getElementById('generate-btn'); | |
| const lyricsPlaceholder = document.getElementById('lyrics-placeholder'); | |
| const lyricsOutput = document.getElementById('lyrics-output'); | |
| const loadingAnimation = document.getElementById('loading-animation'); | |
| const copyBtn = document.getElementById('copy-btn'); | |
| const saveBtn = document.getElementById('save-btn'); | |
| const regenerateBtn = document.getElementById('regenerate-btn'); | |
| const moodButtons = document.querySelectorAll('.mood-btn'); | |
| // State | |
| let selectedArtist = null; | |
| let selectedMood = null; | |
| let currentLyrics = ''; | |
| // Initialize the app | |
| function init() { | |
| renderArtists(); | |
| renderFeaturedArtists(); | |
| setupEventListeners(); | |
| } | |
| // Render all artists in the selection grid | |
| function renderArtists() { | |
| artistGrid.innerHTML = ''; | |
| artists.forEach(artist => { | |
| const artistCard = document.createElement('div'); | |
| artistCard.className = 'artist-card bg-white rounded-lg overflow-hidden shadow-md cursor-pointer'; | |
| artistCard.dataset.id = artist.id; | |
| artistCard.innerHTML = ` | |
| <div class="h-32 sm:h-40 overflow-hidden"> | |
| <img src="${artist.image}" alt="${artist.name}" class="w-full h-full object-cover"> | |
| </div> | |
| <div class="p-3"> | |
| <h3 class="font-semibold text-gray-800">${artist.name}</h3> | |
| <p class="text-sm text-gray-500">${artist.genre} • ${artist.era}</p> | |
| </div> | |
| `; | |
| artistCard.addEventListener('click', () => selectArtist(artist.id)); | |
| artistGrid.appendChild(artistCard); | |
| }); | |
| } | |
| // Render featured artists | |
| function renderFeaturedArtists() { | |
| featuredArtistsGrid.innerHTML = ''; | |
| featuredArtists.forEach(artist => { | |
| const artistCard = document.createElement('div'); | |
| artistCard.className = 'bg-white rounded-lg overflow-hidden shadow-md cursor-pointer'; | |
| artistCard.dataset.id = artist.id; | |
| artistCard.innerHTML = ` | |
| <div class="h-32 overflow-hidden"> | |
| <img src="${artist.image}" alt="${artist.name}" class="w-full h-full object-cover"> | |
| </div> | |
| <div class="p-2"> | |
| <h3 class="font-medium text-sm text-gray-800 text-center">${artist.name}</h3> | |
| </div> | |
| `; | |
| artistCard.addEventListener('click', () => selectArtist(artist.id)); | |
| featuredArtistsGrid.appendChild(artistCard); | |
| }); | |
| } | |
| // Select an artist | |
| function selectArtist(artistId) { | |
| // Remove selected class from all cards | |
| document.querySelectorAll('.artist-card').forEach(card => { | |
| card.classList.remove('selected'); | |
| }); | |
| // Add selected class to clicked card | |
| const card = document.querySelector(`.artist-card[data-id="${artistId}"]`); | |
| if (card) { | |
| card.classList.add('selected'); | |
| } | |
| selectedArtist = artists.find(a => a.id === artistId); | |
| } | |
| // Set up event listeners | |
| function setupEventListeners() { | |
| // Mood buttons | |
| moodButtons.forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| moodButtons.forEach(b => b.classList.remove('bg-indigo-200', 'text-indigo-700')); | |
| this.classList.add('bg-indigo-200', 'text-indigo-700'); | |
| selectedMood = this.dataset.mood; | |
| }); | |
| }); | |
| // Generate button | |
| generateBtn.addEventListener('click', generateLyrics); | |
| // Copy button | |
| copyBtn.addEventListener('click', function() { | |
| navigator.clipboard.writeText(currentLyrics).then(() => { | |
| const originalText = copyBtn.innerHTML; | |
| copyBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Copied!'; | |
| setTimeout(() => { | |
| copyBtn.innerHTML = originalText; | |
| }, 2000); | |
| }); | |
| }); | |
| // Save button | |
| saveBtn.addEventListener('click', function() { | |
| // In a real app, this would save to a database or local storage | |
| alert('Lyrics saved to your collection!'); | |
| }); | |
| // Regenerate button | |
| regenerateBtn.addEventListener('click', generateLyrics); | |
| } | |
| // Generate lyrics (simulated) | |
| function generateLyrics() { | |
| if (!selectedArtist) { | |
| alert('Please select an artist first'); | |
| return; | |
| } | |
| const theme = themeInput.value.trim() || 'life'; | |
| // Show loading state | |
| lyricsPlaceholder.classList.add('hidden'); | |
| lyricsOutput.classList.add('hidden'); | |
| loadingAnimation.classList.remove('hidden'); | |
| // Hide action buttons during generation | |
| copyBtn.classList.add('hidden'); | |
| saveBtn.classList.add('hidden'); | |
| regenerateBtn.classList.add('hidden'); | |
| // Simulate API call with timeout | |
| setTimeout(() => { | |
| // Hide loading, show output | |
| loadingAnimation.classList.add('hidden'); | |
| // Generate mock lyrics based on artist and theme | |
| currentLyrics = generateMockLyrics(selectedArtist, theme, selectedMood); | |
| lyricsOutput.textContent = currentLyrics; | |
| lyricsOutput.classList.remove('hidden'); | |
| lyricsOutput.classList.add('fade-in', 'typewriter'); | |
| // Show action buttons | |
| copyBtn.classList.remove('hidden'); | |
| saveBtn.classList.remove('hidden'); | |
| regenerateBtn.classList.remove('hidden'); | |
| // Remove animations after they complete | |
| setTimeout(() => { | |
| lyricsOutput.classList.remove('typewriter'); | |
| }, 3500); | |
| }, 2000); | |
| } | |
| // Generate mock lyrics based on artist style | |
| function generateMockLyrics(artist, theme, mood) { | |
| const artistName = artist.name.toLowerCase(); | |
| let lyrics = ''; | |
| let verseCount = 2; | |
| let chorusCount = 1; | |
| // Common patterns for different artists | |
| if (artistName.includes('taylor swift')) { | |
| lyrics += `Lyrics in the style of Taylor Swift (${artist.era} era)\n\n`; | |
| lyrics += `Theme: ${theme}\nMood: ${mood || 'varies'}\n\n`; | |
| for (let i = 0; i < verseCount; i++) { | |
| lyrics += `[Verse ${i+1}]\n`; | |
| lyrics += getTaylorSwiftVerse(theme, mood, i+1); | |
| lyrics += '\n\n'; | |
| } | |
| lyrics += `[Chorus]\n`; | |
| lyrics += getTaylorSwiftChorus(theme, mood); | |
| lyrics += '\n\n'; | |
| lyrics += `[Bridge]\n`; | |
| lyrics += getTaylorSwiftBridge(theme, mood); | |
| lyrics += '\n\n'; | |
| lyrics += `[Outro]\n`; | |
| lyrics += getTaylorSwiftOutro(theme, mood); | |
| } else if (artistName.includes('kendrick')) { | |
| lyrics += `Lyrics in the style of Kendrick Lamar (${artist.era} era)\n\n`; | |
| lyrics += `Theme: ${theme}\nMood: ${mood || 'varies'}\n\n`; | |
| for (let i = 0; i < verseCount; i++) { | |
| lyrics += `[Verse ${i+1}]\n`; | |
| lyrics += getKendrickVerse(theme, mood, i+1); | |
| lyrics += '\n\n'; | |
| } | |
| lyrics += `[Chorus]\n`; | |
| lyrics += getKendrickChorus(theme, mood); | |
| lyrics += '\n\n'; | |
| lyrics += `[Bridge]\n`; | |
| lyrics += getKendrickBridge(theme, mood); | |
| lyrics += '\n\n'; | |
| } else if (artistName.includes('beyonce')) { | |
| lyrics += `Lyrics in the style of Beyoncé (${artist.era} era)\n\n`; | |
| lyrics += `Theme: ${theme}\nMood: ${mood || 'varies'}\n\n`; | |
| for (let i = 0; i < verseCount; i++) { | |
| lyrics += `[Verse ${i+1}]\n`; | |
| lyrics += getBeyonceVerse(theme, mood, i+1); | |
| lyrics += '\n\n'; | |
| } | |
| for (let i = 0; i < chorusCount; i++) { | |
| lyrics += `[Chorus]\n`; | |
| lyrics += getBeyonceChorus(theme, mood); | |
| lyrics += '\n\n'; | |
| } | |
| lyrics += `[Bridge]\n`; | |
| lyrics += getBeyonceBridge(theme, mood); | |
| lyrics += '\n\n'; | |
| } else { | |
| // Default generic lyrics | |
| lyrics += `Lyrics in the style of ${artist.name} (${artist.era} era)\n\n`; | |
| lyrics += `Theme: ${theme}\nMood: ${mood || 'varies'}\n\n`; | |
| for (let i = 0; i < verseCount; i++) { | |
| lyrics += `[Verse ${i+1}]\n`; | |
| lyrics += getGenericVerse(theme, mood, i+1); | |
| lyrics += '\n\n'; | |
| } | |
| for (let i = 0; i < chorusCount; i++) { | |
| lyrics += `[Chorus]\n`; | |
| lyrics += getGenericChorus(theme, mood); | |
| lyrics += '\n\n'; | |
| } | |
| lyrics += `[Bridge]\n`; | |
| lyrics += getGenericBridge(theme, mood); | |
| lyrics += '\n\n'; | |
| lyrics += `[Outro]\n`; | |
| lyrics += getGenericOutro(theme, mood); | |
| } | |
| return lyrics; | |
| } | |
| // Artist-specific lyric generators | |
| function getTaylorSwiftVerse(theme, mood, verseNum) { | |
| const themes = { | |
| love: [ | |
| "I remember it all too well", | |
| "The way you held me under the moonlight", | |
| "Your smile, my personal sunshine", | |
| "Every glance was a handwritten note" | |
| ], | |
| heartbreak: [ | |
| "You left like it was nothing", | |
| "All those promises turned to dust", | |
| "I'm picking up the pieces you scattered", | |
| "The calendar still marks your birthday" | |
| ], | |
| life: [ | |
| "Small town, big dreams in my pocket", | |
| "They said I'd never make it out", | |
| "Now I'm writing my name in the stars", | |
| "Every step was a lesson learned" | |
| ] | |
| }; | |
| const lines = themes[theme] || [ | |
| "Pages turn and bridges burn", | |
| "I keep your memory in a locket", | |
| "Time won't heal but it helps me forget", | |
| "We were a masterpiece, now just a sketch" | |
| ]; | |
| return shuffleArray(lines).slice(0, 4).join('\n'); | |
| } | |
| function getTaylorSwiftChorus(theme, mood) { | |
| const choruses = { | |
| love: [ | |
| "And I was enchanted to meet you", | |
| "This love is golden, shining bright", | |
| "You're my favorite melody", | |
| "I'd rewrite our story a thousand times" | |
| ], | |
| heartbreak: [ | |
| "And you call me up again just to break me like a promise", | |
| "So casually cruel in the name of being honest", | |
| "I'm a crumpled up piece of paper lying here", | |
| "Time turns flames to embers, you'll remember" | |
| ] | |
| }; | |
| return choruses[theme] ? shuffleArray(choruses[theme]).slice(0, 2).join('\n') : | |
| "This is me trying\nTo keep the fire alive"; | |
| } | |
| function getTaylorSwiftBridge(theme, mood) { | |
| return theme === 'love' ? | |
| "And I forget about you long enough\nTo forget why I needed to" : | |
| "You're not my homeland anymore\nSo what am I defending now?"; | |
| } | |
| function getTaylorSwiftOutro(theme, mood) { | |
| return "Just between us, did the love affair maim you too?\nJust between us, do you remember it all too well?"; | |
| } | |
| function getKendrickVerse(theme, mood, verseNum) { | |
| const themes = { | |
| life: [ | |
| "I grew up around the way, where the dreams get deferred", | |
| "Concrete jungle where the lions sleep", | |
| "Pray for me, I've been going through somethin'", | |
| "They judge you before they know you" | |
| ], | |
| struggle: [ | |
| "Ain't nobody prayin' for me", | |
| "My pain is my legacy", | |
| "The system got us trapped in cycles", | |
| "We was never meant to make it out" | |
| ], | |
| power: [ | |
| "I am an Israelite, don't call me black no mo'", | |
| "That word is only a color, it ain't facts no mo'", | |
| "Sit down, be humble, but don't sit too long", | |
| "The crown is heavy, but I wear it strong" | |
| ] | |
| }; | |
| const lines = themes[theme] || [ | |
| "I remember you was conflicted", | |
| "Misusing your influence", | |
| "Sometimes I did the same", | |
| "Abusing my power full of resentment" | |
| ]; | |
| return shuffleArray(lines).slice(0, 4).join('\n'); | |
| } | |
| function getKendrickChorus(theme, mood) { | |
| return theme === 'life' ? | |
| "We gon' be alright\nDo you hear me, do you feel me? We gon' be alright" : | |
| "I pray my dick get big as the Eiffel Tower\nSo I can fuck the world for 72 hours"; | |
| } | |
| function getKendrickBridge(theme, mood) { | |
| return "Loyalty, royalty\nInside my DNA\nSuccess is in my veins\nI need it more than fame"; | |
| } | |
| function getBeyonceVerse(theme, mood, verseNum) { | |
| const themes = { | |
| love: [ | |
| "I like my baby hair, with baby hair and afros", | |
| "I like my negro nose with Jackson Five nostrils", | |
| "You can't put your hands on my perfection", | |
| "My skin is dark, my hair is thick, my body is mine" | |
| ], | |
| empowerment: [ | |
| "I woke up like this, flawless", | |
| "Pretty hurts, we shine the light on whatever's worse", | |
| "Perfection is a disease of a nation", | |
| "I'm not too perfect to ever feel this worthless" | |
| ], | |
| life: [ | |
| "Texas, Texas, I'm a Texas girl", | |
| "Mama taught me how to take care of myself", | |
| "Daddy taught me how to love my haters", | |
| "Sister taught me how to speak my mind" | |
| ] | |
| }; | |
| const lines = themes[theme] || [ | |
| "I break chains all by myself", | |
| "Won't let my freedom rot in hell", | |
| "I'ma keep running cause a winner don't quit on themselves", | |
| "I was served lemons but I made lemonade" | |
| ]; | |
| return shuffleArray(lines).slice(0, 4).join('\n'); | |
| } | |
| function getBeyonceChorus(theme, mood) { | |
| return theme === 'empowerment' ? | |
| "I'm a grown woman\nI can do whatever I want" : | |
| "Hold up, they don't love you like I love you"; | |
| } | |
| function getBeyonceBridge(theme, mood) { | |
| return "Best revenge is your paper\nBetter yet your mama's setup\nBetter yet your daughter setup\nYour sister, your job, your sound, your name"; | |
| } | |
| // Generic lyric generators | |
| function getGenericVerse(theme, mood, verseNum) { | |
| const themes = { | |
| love: [ | |
| "Your eyes like oceans I could drown in", | |
| "Every touch sets my soul on fire", | |
| "I never knew love could feel this way", | |
| "You're the missing piece I've searched for" | |
| ], | |
| heartbreak: [ | |
| "The silence between us grew too loud", | |
| "Promises turned to empty words", | |
| "I'm learning to live with the ghost of you", | |
| "The bed feels colder since you left" | |
| ], | |
| life: [ | |
| "The city lights don't shine as bright", | |
| "We're all just trying to find our way", | |
| "Time moves faster than we realize", | |
| "Yesterday's mistakes are tomorrow's lessons" | |
| ] | |
| }; | |
| const lines = themes[theme] || [ | |
| "Another day, another dollar spent", | |
| "The road is long but I keep walking", | |
| "Dreams don't work unless you do", | |
| "The night is young but so are we" | |
| ]; | |
| return shuffleArray(lines).slice(0, 4).join('\n'); | |
| } | |
| function getGenericChorus(theme, mood) { | |
| return theme === 'love' ? | |
| "You're my sunrise and my sunset\nThe only love I'll never forget" : | |
| "I'm stronger than I seem\nBraver than I dream\nThis is my story to redeem"; | |
| } | |
| function getGenericBridge(theme, mood) { | |
| return "And if I had one chance\nOne shot to make it right\nI'd hold on tighter\nAnd never say goodbye"; | |
| } | |
| function getGenericOutro(theme, mood) { | |
| return "The end is just another beginning\nA new chapter waiting to be written"; | |
| } | |
| // Helper function to shuffle array | |
| function shuffleArray(array) { | |
| const newArray = [...array]; | |
| for (let i = newArray.length - 1; i > 0; i--) { | |
| const j = Math.floor(Math.random() * (i + 1)); | |
| [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; | |
| } | |
| return newArray; | |
| } | |
| // Initialize the app | |
| init(); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Voxefx/lyrical-muse" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |