![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/private_html/includes/ |
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
?>
<!-- Advanced Functions Modal -->
<div class="advanced-functions-modal-overlay" id="advancedFunctionsModalOverlay" style="display: none;">
<div class="advanced-functions-modal">
<div class="advanced-functions-modal-header">
<h3>🚀 Advanced AI Music Tools</h3>
<button class="close-advanced-functions-modal" onclick="closeAdvancedFunctionsModal()">×</button>
</div>
<div class="advanced-functions-modal-body">
<!-- Function Tabs -->
<div class="function-tabs">
<div class="function-tab active" data-function="lyrics">
<i class="fas fa-pen"></i>
<span>Lyrics Generation</span>
</div>
<div class="function-tab" data-function="vocalRemoval">
<i class="fas fa-layer-group"></i>
<span>Stem Separation</span>
</div>
<div class="function-tab" data-function="wavConversion">
<i class="fas fa-file-audio"></i>
<span>WAV Conversion</span>
</div>
<div class="function-tab" data-function="musicVideo">
<i class="fas fa-video"></i>
<span>Music Video</span>
</div>
<div class="function-tab" data-function="trackExtension">
<i class="fas fa-chart-line"></i>
<span>Track Extension</span>
</div>
</div>
<!-- Lyrics Generation Form -->
<div id="lyricsForm" class="function-form active">
<form method="POST" action="create_lyrics.php" enctype="multipart/form-data">
<?php
// SECURITY: CSRF Token
require_once __DIR__ . '/security.php';
?>
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars(generateCSRFToken(), ENT_QUOTES, 'UTF-8') ?>">
<div class="form-group">
<label for="lyricsPrompt">Describe the lyrics you want</label>
<textarea name="prompt" id="lyricsPrompt" class="form-input" rows="3" placeholder="e.g., 'Write lyrics about falling in love under the stars' (max 400 characters)" required></textarea>
<div class="char-count">0/400</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="lyricsTitle">Song Title</label>
<input type="text" name="title" id="lyricsTitle" class="form-input" placeholder="e.g., Starlight Love" maxlength="80">
</div>
<div class="form-group">
<label for="lyricsTheme">Theme</label>
<select name="theme" id="lyricsTheme" class="form-input">
<option value="">Auto (AI decides)</option>
<option value="love">Love & Romance</option>
<option value="heartbreak">Heartbreak</option>
<option value="friendship">Friendship</option>
<option value="party">Party & Celebration</option>
<option value="motivation">Motivation & Success</option>
<option value="nature">Nature & Peace</option>
<option value="adventure">Adventure & Travel</option>
<option value="nostalgia">Nostalgia & Memories</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="lyricsStyle">Style</label>
<select name="style" id="lyricsStyle" class="form-input">
<option value="">Auto (AI decides)</option>
<option value="pop">Pop</option>
<option value="rock">Rock</option>
<option value="hip-hop">Hip-Hop</option>
<option value="country">Country</option>
<option value="jazz">Jazz</option>
<option value="blues">Blues</option>
<option value="folk">Folk</option>
<option value="electronic">Electronic</option>
</select>
</div>
<div class="form-group">
<label for="lyricsLanguage">Language</label>
<select name="language" id="lyricsLanguage" class="form-input">
<option value="English" selected>English</option>
<option value="Spanish">Spanish</option>
<option value="French">French</option>
<option value="German">German</option>
<option value="Italian">Italian</option>
<option value="Portuguese">Portuguese</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="rhymeScheme">Rhyme Scheme</label>
<select name="rhymeScheme" id="rhymeScheme" class="form-input">
<option value="">Auto (AI decides)</option>
<option value="AABB">AABB (Simple)</option>
<option value="ABAB">ABAB (Alternating)</option>
<option value="ABBA">ABBA (Enclosed)</option>
<option value="AABA">AABA (Verse-Chorus)</option>
<option value="Free">Free Verse</option>
</select>
</div>
<div class="form-group">
<label for="hookFrequency">Hook Frequency</label>
<select name="hookFrequency" id="hookFrequency" class="form-input">
<option value="">Auto (AI decides)</option>
<option value="high">High (Catchy)</option>
<option value="medium">Medium (Balanced)</option>
<option value="low">Low (Subtle)</option>
</select>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-pen"></i>
Generate Lyrics (1 Credit)
</button>
</div>
</form>
</div>
<!-- Stem Separation Form -->
<div id="vocalRemovalForm" class="function-form">
<form method="POST" action="create_vocal_removal.php" enctype="multipart/form-data">
<div class="form-group">
<label for="vocalRemovalTitle">Output Track Title</label>
<input type="text" name="title" id="vocalRemovalTitle" class="form-input" placeholder="e.g., My Track - Stems" maxlength="80" required>
</div>
<div class="form-group">
<label>Audio Source</label>
<div class="radio-group" style="display: flex; gap: 1rem; margin-bottom: 1rem;">
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="radio" name="audioSource" value="library" id="audioSourceLibrary" checked onchange="toggleAudioSource()">
<span>Select from My Library</span>
</label>
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="radio" name="audioSource" value="upload" id="audioSourceUpload" onchange="toggleAudioSource()">
<span>Upload New File</span>
</label>
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="radio" name="audioSource" value="url" id="audioSourceUrl" onchange="toggleAudioSource()">
<span>Enter URL</span>
</label>
</div>
</div>
<!-- Library Track Selection -->
<div id="libraryTrackSelection" class="form-group">
<label for="selectedTrackId">Select Track from Library</label>
<select name="selectedTrackId" id="selectedTrackId" class="form-input" onchange="handleTrackSelection()">
<option value="">Loading your tracks...</option>
</select>
<small style="display: block; margin-top: 5px; color: #a0aec0;">
Select one of your existing tracks to separate
</small>
<input type="hidden" name="audioUrl" id="selectedTrackAudioUrl">
</div>
<!-- File Upload -->
<div id="fileUploadSection" class="form-group" style="display: none;">
<label for="audioFile">Upload Audio File</label>
<input type="file" name="audioFile" id="audioFile" class="form-input" accept="audio/*">
<small>Supported formats: MP3, WAV, M4A, FLAC (max 50MB)</small>
</div>
<!-- URL Input -->
<div id="urlInputSection" class="form-group" style="display: none;">
<label for="audioUrl">Audio URL</label>
<input type="url" name="audioUrl" id="audioUrl" class="form-input" placeholder="https://example.com/song.mp3">
<small>Enter a direct URL to an audio file</small>
</div>
<div class="form-group">
<label for="separationMode">Separation Mode</label>
<select name="separationMode" id="separationMode" class="form-input">
<option value="split_stem" selected>Full Stem Separation (All Instruments) ⭐ NEW</option>
<option value="separate_vocal">2-Stem Separation (Vocals/Instrumental)</option>
</select>
<small style="display: block; margin-top: 5px; color: #667eea; font-weight: 600;">
<strong>Full Stem:</strong> Separates into vocals, drums, bass, guitar, keyboard, strings, and more (3 Credits)<br>
<strong>2-Stem:</strong> Separates into vocals and instrumental tracks (2 Credits)
</small>
</div>
<div id="twoStemOptions" class="form-row">
<div class="form-group">
<label for="separationType">Separation Type</label>
<select name="separationType" id="separationType" class="form-input">
<option value="vocals" selected>Vocals Only</option>
<option value="instrumental">Instrumental Only</option>
<option value="both">Both (Vocals + Instrumental)</option>
</select>
</div>
<div class="form-group">
<label for="vocalQuality">Quality</label>
<select name="quality" id="vocalQuality" class="form-input">
<option value="high" selected>High Quality</option>
<option value="medium">Medium Quality</option>
<option value="low">Low Quality (Faster)</option>
</select>
</div>
</div>
<div id="fullStemOptions" class="form-row" style="display: none;">
<div class="form-group">
<label for="stemQuality">Quality</label>
<select name="quality" id="stemQuality" class="form-input">
<option value="high" selected>High Quality</option>
<option value="medium">Medium Quality</option>
<option value="low">Low Quality (Faster)</option>
</select>
</div>
</div>
<div class="form-group">
<label for="vocalFormat">Output Format</label>
<select name="format" id="vocalFormat" class="form-input">
<option value="mp3" selected>MP3</option>
<option value="wav">WAV</option>
<option value="m4a">M4A</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary" id="separationSubmitBtn">
<i class="fas fa-microphone-slash"></i>
<span id="separationButtonText">Separate Audio (2 Credits)</span>
</button>
</div>
</form>
<script>
// Load user tracks when modal opens (make it globally accessible)
window.loadUserTracksForSeparation = function(preSelectTrackId = null) {
const selectElement = document.getElementById('selectedTrackId');
if (!selectElement) {
console.warn('selectedTrackId element not found');
return;
}
selectElement.innerHTML = '<option value="">Loading your tracks...</option>';
fetch('/api/get_user_tracks.php?type=all')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Tracks loaded:', data);
if (data.success && data.tracks && data.tracks.length > 0) {
selectElement.innerHTML = '<option value="">-- Select a track --</option>';
data.tracks.forEach(track => {
const option = document.createElement('option');
option.value = track.id;
option.setAttribute('data-audio-url', track.audio_url || '');
const durationText = track.duration ? Math.round(track.duration) + 's' : 'N/A';
option.textContent = `${track.title || 'Untitled'} (${durationText})`;
selectElement.appendChild(option);
});
// Pre-select track if provided
if (preSelectTrackId) {
selectElement.value = preSelectTrackId;
handleTrackSelection();
}
} else {
selectElement.innerHTML = '<option value="">No tracks available. Create some music first!</option>';
}
})
.catch(error => {
console.error('Error loading tracks:', error);
selectElement.innerHTML = '<option value="">Error loading tracks. Please try again.</option>';
});
};
// Handle track selection (make it globally accessible)
window.handleTrackSelection = function() {
const selectElement = document.getElementById('selectedTrackId');
const hiddenInput = document.getElementById('selectedTrackAudioUrl');
const selectedOption = selectElement.options[selectElement.selectedIndex];
if (selectedOption && selectedOption.value) {
const audioUrl = selectedOption.getAttribute('data-audio-url');
if (hiddenInput) {
hiddenInput.value = audioUrl;
}
} else {
if (hiddenInput) {
hiddenInput.value = '';
}
}
};
// Toggle between audio source options (make it globally accessible)
window.toggleAudioSource = function() {
const libraryOption = document.getElementById('audioSourceLibrary');
const uploadOption = document.getElementById('audioSourceUpload');
const urlOption = document.getElementById('audioSourceUrl');
const librarySection = document.getElementById('libraryTrackSelection');
const uploadSection = document.getElementById('fileUploadSection');
const urlSection = document.getElementById('urlInputSection');
// Hide all sections first
librarySection.style.display = 'none';
uploadSection.style.display = 'none';
urlSection.style.display = 'none';
// Clear required attributes
document.getElementById('selectedTrackId').removeAttribute('required');
document.getElementById('audioFile').removeAttribute('required');
document.getElementById('audioUrl').removeAttribute('required');
// Show selected section
if (libraryOption.checked) {
librarySection.style.display = 'block';
document.getElementById('selectedTrackId').setAttribute('required', 'required');
} else if (uploadOption.checked) {
uploadSection.style.display = 'block';
document.getElementById('audioFile').setAttribute('required', 'required');
} else if (urlOption.checked) {
urlSection.style.display = 'block';
document.getElementById('audioUrl').setAttribute('required', 'required');
}
};
// Handle separation mode changes
document.addEventListener('DOMContentLoaded', function() {
const separationMode = document.getElementById('separationMode');
const twoStemOptions = document.getElementById('twoStemOptions');
const fullStemOptions = document.getElementById('fullStemOptions');
const submitBtn = document.getElementById('separationSubmitBtn');
const buttonText = document.getElementById('separationButtonText');
// Load tracks when modal is opened
const modalOverlay = document.getElementById('advancedFunctionsModalOverlay');
if (modalOverlay) {
// Watch for modal visibility changes
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
const isVisible = modalOverlay.style.display === 'flex';
if (isVisible) {
// Small delay to ensure tab switching is complete
setTimeout(function() {
// Check if we're on the stem separation tab
const stemTab = document.querySelector('.function-tab[data-function="vocalRemoval"]');
const stemForm = document.getElementById('vocalRemovalForm');
if (stemTab && stemTab.classList.contains('active') ||
(stemForm && stemForm.classList.contains('active'))) {
loadUserTracksForSeparation();
}
}, 200);
}
}
});
});
observer.observe(modalOverlay, { attributes: true, attributeFilter: ['style'] });
}
// Also load when tab is clicked
const stemTab = document.querySelector('.function-tab[data-function="vocalRemoval"]');
if (stemTab) {
stemTab.addEventListener('click', function() {
setTimeout(loadUserTracksForSeparation, 200);
});
}
// Load tracks immediately if form is already visible
const stemForm = document.getElementById('vocalRemovalForm');
if (stemForm && stemForm.classList.contains('active')) {
loadUserTracksForSeparation();
}
if (separationMode) {
function updateSeparationUI() {
const mode = separationMode.value;
if (mode === 'split_stem') {
// Full stem separation
twoStemOptions.style.display = 'none';
fullStemOptions.style.display = 'flex';
buttonText.textContent = 'Separate All Stems (3 Credits)';
submitBtn.querySelector('i').className = 'fas fa-layer-group';
} else {
// 2-stem separation
twoStemOptions.style.display = 'flex';
fullStemOptions.style.display = 'none';
buttonText.textContent = 'Separate Audio (2 Credits)';
submitBtn.querySelector('i').className = 'fas fa-microphone-slash';
}
}
separationMode.addEventListener('change', updateSeparationUI);
// Initialize on load - default to full stem separation
updateSeparationUI();
}
// Initialize audio source toggle
toggleAudioSource();
});
</script>
</div>
<!-- WAV Conversion Form -->
<div id="wavConversionForm" class="function-form">
<form method="POST" action="create_wav_conversion.php" enctype="multipart/form-data">
<div class="form-group">
<label for="wavConversionTitle">Track Title</label>
<input type="text" name="title" id="wavConversionTitle" class="form-input" placeholder="e.g., High-Quality WAV" maxlength="80" required>
</div>
<div class="form-group">
<label for="wavAudioUrl">Audio URL (Optional)</label>
<input type="url" name="audioUrl" id="wavAudioUrl" class="form-input" placeholder="https://example.com/song.mp3">
</div>
<div class="form-group">
<label for="wavAudioFile">Or Upload Audio File</label>
<input type="file" name="audioFile" id="wavAudioFile" class="form-input" accept="audio/*">
<small>Supported formats: MP3, M4A, FLAC (max 50MB)</small>
</div>
<div class="form-row">
<div class="form-group">
<label for="sampleRate">Sample Rate</label>
<select name="sampleRate" id="sampleRate" class="form-input">
<option value="44100" selected>44.1 kHz (CD Quality)</option>
<option value="48000">48 kHz (Professional)</option>
<option value="96000">96 kHz (High-End)</option>
</select>
</div>
<div class="form-group">
<label for="bitDepth">Bit Depth</label>
<select name="bitDepth" id="bitDepth" class="form-input">
<option value="16" selected>16-bit (CD Quality)</option>
<option value="24">24-bit (Professional)</option>
<option value="32">32-bit (Studio Quality)</option>
</select>
</div>
</div>
<div class="form-group">
<label for="channels">Channels</label>
<select name="channels" id="channels" class="form-input">
<option value="2" selected>Stereo (2 channels)</option>
<option value="1">Mono (1 channel)</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-file-audio"></i>
Convert to WAV (1 Credit)
</button>
</div>
</form>
</div>
<!-- Music Video Form -->
<div id="musicVideoForm" class="function-form">
<form method="POST" action="create_music_video.php" enctype="multipart/form-data">
<div class="form-group">
<label for="musicVideoTitle">Video Title</label>
<input type="text" name="title" id="musicVideoTitle" class="form-input" placeholder="e.g., Music Video" maxlength="80" required>
</div>
<div class="form-group">
<label for="videoAudioUrl">Audio URL (Optional)</label>
<input type="url" name="audioUrl" id="videoAudioUrl" class="form-input" placeholder="https://example.com/song.mp3">
</div>
<div class="form-group">
<label for="videoAudioFile">Or Upload Audio File</label>
<input type="file" name="audioFile" id="videoAudioFile" class="form-input" accept="audio/*">
<small>Supported formats: MP3, WAV, M4A (max 50MB)</small>
</div>
<div class="form-row">
<div class="form-group">
<label for="videoStyle">Video Style</label>
<select name="videoStyle" id="videoStyle" class="form-input">
<option value="abstract" selected>Abstract</option>
<option value="nature">Nature</option>
<option value="urban">Urban</option>
<option value="artistic">Artistic</option>
<option value="geometric">Geometric</option>
<option value="particles">Particles</option>
<option value="waveform">Waveform</option>
</select>
</div>
<div class="form-group">
<label for="videoDuration">Video Duration</label>
<select name="videoDuration" id="videoDuration" class="form-input">
<option value="15">15 seconds</option>
<option value="30" selected>30 seconds</option>
<option value="60">60 seconds</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="videoQuality">Video Quality</label>
<select name="videoQuality" id="videoQuality" class="form-input">
<option value="720p">720p HD</option>
<option value="1080p" selected>1080p Full HD</option>
<option value="4K">4K Ultra HD</option>
</select>
</div>
<div class="form-group">
<label for="visualEffects">Visual Effects</label>
<select name="visualEffects" id="visualEffects" class="form-input">
<option value="waveform" selected>Waveform</option>
<option value="particles">Particles</option>
<option value="geometric">Geometric</option>
<option value="flow">Flow</option>
<option value="pulse">Pulse</option>
</select>
</div>
</div>
<div class="form-group">
<label for="colorScheme">Color Scheme</label>
<select name="colorScheme" id="colorScheme" class="form-input">
<option value="auto" selected>Auto (Based on audio)</option>
<option value="warm">Warm</option>
<option value="cool">Cool</option>
<option value="vibrant">Vibrant</option>
<option value="monochrome">Monochrome</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-video"></i>
Create Music Video (3 Credits)
</button>
</div>
</form>
</div>
<!-- Track Extension Form -->
<div id="trackExtensionForm" class="function-form">
<form method="POST" action="create_track_extension.php" enctype="multipart/form-data">
<div class="form-group">
<label for="trackExtensionTitle">Track Title</label>
<input type="text" name="title" id="trackExtensionTitle" class="form-input" placeholder="e.g., Extended Version" maxlength="80" required>
</div>
<div class="form-group">
<label for="extensionAudioUrl">Audio URL (Optional)</label>
<input type="url" name="audioUrl" id="extensionAudioUrl" class="form-input" placeholder="https://example.com/song.mp3">
</div>
<div class="form-group">
<label for="extensionAudioFile">Or Upload Audio File</label>
<input type="file" name="audioFile" id="extensionAudioFile" class="form-input" accept="audio/*">
<small>Supported formats: MP3, WAV, M4A (max 50MB)</small>
</div>
<div class="form-row">
<div class="form-group">
<label for="extensionDuration">Extension Duration</label>
<select name="extensionDuration" id="extensionDuration" class="form-input">
<option value="15">15 seconds</option>
<option value="30" selected>30 seconds</option>
<option value="60">60 seconds</option>
</select>
</div>
<div class="form-group">
<label for="startTime">Start Time (seconds)</label>
<input type="number" name="startTime" id="startTime" class="form-input" value="0" min="0" step="1">
<small>When to start the extension (0 = end of track)</small>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="extensionStyle">Extension Style</label>
<select name="style" id="extensionStyle" class="form-input">
<option value="continue" selected>Continue (Seamless)</option>
<option value="evolve">Evolve (Progressive)</option>
<option value="contrast">Contrast (Different)</option>
</select>
</div>
<div class="form-group">
<label for="maintainStructure">Maintain Structure</label>
<select name="maintainStructure" id="maintainStructure" class="form-input">
<option value="true" selected>Yes (Keep original structure)</option>
<option value="false">No (Allow changes)</option>
</select>
</div>
</div>
<div class="form-group">
<label for="enhanceQuality">Enhance Quality</label>
<select name="enhanceQuality" id="enhanceQuality" class="form-input">
<option value="true" selected>Yes (Improve audio quality)</option>
<option value="false">No (Keep original quality)</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-chart-line"></i>
Extend Track (2 Credits)
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<style>
/* Advanced Functions Modal Styles */
.advanced-functions-modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(10px);
}
.advanced-functions-modal {
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
width: 90%;
max-width: 800px;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
}
.advanced-functions-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.advanced-functions-modal-header h3 {
color: #e2e8f0;
font-size: 2.4rem;
font-weight: 700;
margin: 0;
}
.close-advanced-functions-modal {
background: none;
border: none;
color: #a0aec0;
font-size: 2.4rem;
cursor: pointer;
padding: 0.5rem;
border-radius: 50%;
transition: all 0.3s ease;
}
.close-advanced-functions-modal:hover {
color: #e2e8f0;
background: rgba(255, 255, 255, 0.1);
}
.advanced-functions-modal-body {
padding: 2rem;
}
/* Function Tabs */
.function-tabs {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
flex-wrap: wrap;
}
.function-tab {
display: flex;
align-items: center;
gap: 0.8rem;
padding: 1rem 1.5rem;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
color: #a0aec0;
font-size: 1.4rem;
font-weight: 600;
}
.function-tab:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(102, 126, 234, 0.3);
color: #e2e8f0;
}
.function-tab.active {
background: linear-gradient(45deg, #667eea, #764ba2);
border-color: rgba(102, 126, 234, 0.5);
color: white;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
.function-tab i {
font-size: 1.6rem;
}
/* Function Forms */
.function-form {
display: none;
}
.function-form.active {
display: block;
}
.form-group {
margin-bottom: 2rem;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin-bottom: 2rem;
}
.form-input {
width: 100%;
padding: 1.2rem;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 10px;
color: #e2e8f0;
font-size: 1.4rem;
transition: all 0.3s ease;
}
.form-input:focus {
outline: none;
border-color: rgba(102, 126, 234, 0.5);
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-input::placeholder {
color: #718096;
}
label {
display: block;
margin-bottom: 0.8rem;
color: #e2e8f0;
font-size: 1.4rem;
font-weight: 600;
}
small {
color: #718096;
font-size: 1.2rem;
margin-top: 0.5rem;
display: block;
}
.char-count {
text-align: right;
color: #718096;
font-size: 1.2rem;
margin-top: 0.5rem;
}
.form-actions {
margin-top: 3rem;
text-align: center;
}
.btn {
padding: 1.2rem 2.4rem;
border: none;
border-radius: 10px;
font-size: 1.6rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 0.8rem;
}
.btn-primary {
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
/* Radio Group Styling */
.radio-group {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
padding: 1rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
margin-bottom: 1rem;
}
.radio-group label {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
padding: 0.5rem 1rem;
border-radius: 8px;
transition: all 0.3s ease;
color: #e2e8f0;
font-size: 1.4rem;
}
.radio-group label:hover {
background: rgba(102, 126, 234, 0.1);
}
.radio-group input[type="radio"] {
width: 18px;
height: 18px;
cursor: pointer;
accent-color: #667eea;
}
.radio-group input[type="radio"]:checked + span {
color: #667eea;
font-weight: 600;
}
/* Responsive Design */
@media (max-width: 768px) {
.advanced-functions-modal {
width: 95%;
margin: 1rem;
}
.function-tabs {
flex-direction: column;
}
.form-row {
grid-template-columns: 1fr;
}
.advanced-functions-modal-header h3 {
font-size: 2rem;
}
}
</style>
<script>
// Advanced Functions Modal JavaScript
function openAdvancedFunctionsModal(tabName = null, trackId = null) {
const modal = document.getElementById('advancedFunctionsModalOverlay');
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
// If a specific tab is requested, switch to it
if (tabName) {
setTimeout(() => {
const tab = document.querySelector(`.function-tab[data-function="${tabName}"]`);
const form = document.getElementById(tabName + 'Form');
if (tab && form) {
// Remove active from all
document.querySelectorAll('.function-tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.function-form').forEach(f => f.classList.remove('active'));
// Add active to requested tab
tab.classList.add('active');
form.classList.add('active');
// If trackId is provided and we're on stem separation, pre-select it
if (trackId && tabName === 'vocalRemoval') {
// Select library option first
const libraryOption = document.getElementById('audioSourceLibrary');
if (libraryOption) {
libraryOption.checked = true;
if (typeof toggleAudioSource === 'function') {
toggleAudioSource();
}
}
// Load tracks and pre-select
if (typeof loadUserTracksForSeparation === 'function') {
loadUserTracksForSeparation(trackId);
}
} else if (tabName === 'vocalRemoval') {
// Load tracks for stem separation
if (typeof loadUserTracksForSeparation === 'function') {
setTimeout(() => loadUserTracksForSeparation(), 300);
}
}
}
}, 100);
}
}
function closeAdvancedFunctionsModal() {
document.getElementById('advancedFunctionsModalOverlay').style.display = 'none';
document.body.style.overflow = 'auto';
}
// Function tab switching
document.addEventListener('DOMContentLoaded', function() {
const functionTabs = document.querySelectorAll('.function-tab');
const functionForms = document.querySelectorAll('.function-form');
functionTabs.forEach(tab => {
tab.addEventListener('click', function() {
const functionType = this.getAttribute('data-function');
// Remove active class from all tabs and forms
functionTabs.forEach(t => t.classList.remove('active'));
functionForms.forEach(f => f.classList.remove('active'));
// Add active class to clicked tab and corresponding form
this.classList.add('active');
document.getElementById(functionType + 'Form').classList.add('active');
});
});
// Character count for textareas
const textareas = document.querySelectorAll('textarea');
textareas.forEach(textarea => {
const charCount = textarea.parentNode.querySelector('.char-count');
if (charCount) {
textarea.addEventListener('input', function() {
charCount.textContent = this.value.length + '/' + this.getAttribute('maxlength');
});
}
});
});
// Close modal when clicking outside
document.getElementById('advancedFunctionsModalOverlay').addEventListener('click', function(e) {
if (e.target === this) {
closeAdvancedFunctionsModal();
}
});
</script>