{
  "manifest_version": 3,
  "name": "Media Loader",
  "version": "1.4",
  "description": "Load and play music and videos from YouTube and Vimeo",
  "permissions": ["storage", "tabs"],
  "host_permissions": [
    "https://www.youtube.com/*",
    "https://youtu.be/*",
    "https://player.vimeo.com/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Open Media Loader",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'; frame-src https://www.youtube.com https://youtu.be https://player.vimeo.com"
  },
  "web_accessible_resources": [
    {
      "resources": ["lib/player.js"],
      "matches": ["<all_urls>"]
    },
    {
      "resources": ["youtube-sandbox.html", "sandbox.js"],
      "matches": ["<all_urls>"]
    }
  ],
  "options_page": "dashboard.html"
}

// background.js

chrome.action.onClicked.addListener(() => {
    const dashboardURL = chrome.runtime.getURL("dashboard.html");

    // Query for any existing tabs with the dashboard URL
    chrome.tabs.query({ url: dashboardURL }, (tabs) => {
        if (chrome.runtime.lastError) {
            console.error("Tab Query Error:", chrome.runtime.lastError);
            return;
        }

        if (tabs.length > 0) {
            // Activate the first existing dashboard tab
            chrome.tabs.update(tabs[0].id, { active: true }, (updatedTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Update Error:", chrome.runtime.lastError);
                }
            });
        } else {
            // Create a new dashboard tab
            chrome.tabs.create({ url: dashboardURL, active: true }, (newTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Creation Error:", chrome.runtime.lastError);
                }
            });
        }
    });
});

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Media Loader Dashboard</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <!-- Header with Settings Button and Title -->
        <div class="header">
            <button id="settings-button" class="settings-button" aria-label="Open Settings">
                <img src="icons/icon48.png" alt="Settings" class="settings-icon">
            </button>
            <h1 class="main-title">Media Loader</h1>
        </div>

        <!-- Load Audio Section -->
        <section class="section" id="load-music-section">
            <fieldset>
                <legend>Load Audio</legend>
                <label for="music-url">Audio URL</label>
                <input type="text" id="music-url" name="music-url" placeholder="Enter YouTube or Vimeo URL" aria-label="Enter YouTube or Vimeo Audio URL">

                <label for="music-file">Local Audio File</label>
                <input type="file" id="music-file" name="music-file" accept="audio/*" aria-label="Select Local Audio File">

                <label for="music-start">Start Time (seconds)</label>
                <input type="number" id="music-start" name="music-start" placeholder="Start Time (seconds)" min="0" aria-label="Set Start Time in Seconds">

                <button type="button" id="load-music" class="load-button">Load Audio</button>
            </fieldset>
            <div id="music-player-container" class="player-container" aria-live="polite"></div>
        </section>

        <!-- Load Video Section -->
        <section class="section" id="load-video-section">
            <fieldset>
                <legend>Load Video</legend>
                <label for="video-url">Video URL</label>
                <input type="text" id="video-url" name="video-url" placeholder="Enter YouTube or Vimeo URL" aria-label="Enter YouTube or Vimeo Video URL">

                <label for="video-file">Local Video File</label>
                <input type="file" id="video-file" name="video-file" accept="video/*" aria-label="Select Local Video File">

                <label for="video-start">Start Time (seconds)</label>
                <input type="number" id="video-start" name="video-start" placeholder="Start Time (seconds)" min="0" aria-label="Set Start Time in Seconds">

                <button type="button" id="load-video" class="load-button">Load Video</button>
            </fieldset>
            <div id="video-player-container" class="player-container" aria-live="polite"></div>
        </section>

        <!-- Playback Controls -->
        <section class="controls">
            <button type="button" id="play-button" class="play-button" disabled aria-label="Play from Start">Play from Start</button>
            <button type="button" id="pause-button" class="pause-button" disabled aria-label="Pause">Pause</button>
            <button type="button" id="resume-button" class="resume-button" disabled aria-label="Resume">Resume</button>
        </section>

        <!-- Message Container -->
        <section id="message-container" class="message-container" role="alert" aria-live="assertive"></section>

        <!-- Settings Modal -->
        <div id="settings-modal" class="modal" role="dialog" aria-labelledby="settings-modal-title" aria-modal="true" hidden>
            <div class="modal-content">
                <button class="close-button" aria-label="Close Settings Modal">&times;</button>
                <h2 id="settings-modal-title">Settings</h2>
                <form>
                    <label for="fullscreen-toggle">
                        <input type="checkbox" id="fullscreen-toggle" name="fullscreen-toggle">
                        Full Screen on Play
                    </label>
                    <!-- Additional settings can go here -->
                </form>
            </div>
        </div>

        <!-- YouTube Sandbox Iframe (Hidden) -->
        <iframe id="youtube-sandbox-iframe" src="youtube-sandbox.html" style="display: none;"></iframe>
    </div>

    <script src="dashboard.js"></script>
</body>
</html>

"use strict";

// Utility function to capitalize first letter
function capitalize(text) {
    if (!text) return '';
    return text.charAt(0).toUpperCase() + text.slice(1);
}

// Function to display messages
function showMessage(message, type) {
    const messageContainer = document.getElementById('message-container');
    messageContainer.innerHTML = '';
    const msgDiv = document.createElement('div');
    msgDiv.textContent = message;
    msgDiv.classList.add('message', type); // 'success', 'error', 'info'
    messageContainer.appendChild(msgDiv);
    // Automatically hide message after 5 seconds
    setTimeout(() => {
        if (messageContainer.contains(msgDiv)) {
            messageContainer.removeChild(msgDiv);
        }
    }, 5000);
}

// Function to show loading spinner
function showLoading(container) {
    container.innerHTML = '';
    const loader = document.createElement('div');
    loader.classList.add('loader');
    container.appendChild(loader);
}

// Function to hide loading spinner
function hideLoading(container) {
    const loader = container.querySelector('.loader');
    if (loader) {
        container.removeChild(loader);
    }
}

// Function to validate media URLs
function isValidMediaURL(url) {
    try {
        const parsedUrl = new URL(url);
        const hostname = parsedUrl.hostname.toLowerCase();

        if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
            const videoId = extractYouTubeID(url);
            return videoId.length === 11;
        } else if (hostname.includes('vimeo.com')) {
            const videoId = extractVimeoID(url);
            return videoId.length > 0;
        }
        return false;
    } catch (e) {
        return false;
    }
}

// Function to extract YouTube Video ID
function extractYouTubeID(url) {
    try {
        const parsedUrl = new URL(url);
        const hostname = parsedUrl.hostname.toLowerCase();
        if (hostname === 'youtu.be') {
            return parsedUrl.pathname.slice(1);
        }
        return parsedUrl.searchParams.get('v') || '';
    } catch (e) {
        return '';
    }
}

// Function to extract Vimeo Video ID
function extractVimeoID(url) {
    try {
        const parsedUrl = new URL(url);
        const vimeoMatch = parsedUrl.pathname.match(/\/(?:video\/)?(\d+)/);
        return vimeoMatch ? vimeoMatch[1] : '';
    } catch (e) {
        return '';
    }
}

// Function to embed YouTube video
function embedYouTubeVideo(videoId, container, startTime = 0) {
    container.innerHTML = ''; // Clear previous content
    const iframe = document.createElement('iframe');
    iframe.width = '640';
    iframe.height = '360';
    iframe.src = `https://www.youtube.com/embed/${videoId}?start=${startTime}&enablejsapi=1`;
    iframe.frameBorder = '0';
    iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture';
    iframe.allowFullscreen = true;
    iframe.setAttribute('aria-label', 'YouTube Video Player');
    container.appendChild(iframe);
    hideLoading(container);
    showMessage(`YouTube video loaded.`, 'success');

    // Notify the sandbox iframe that the YouTube player is ready
    sendMessageToYouTubeSandbox({
        type: 'playerReady',
        mediaType: 'music' // or 'video' based on context
    });
}

// Function to embed Vimeo video
function embedVimeoVideo(videoId, container, startTime = 0) {
    container.innerHTML = ''; // Clear previous content
    const iframe = document.createElement('iframe');
    iframe.src = `https://player.vimeo.com/video/${videoId}#t=${startTime}s`;
    iframe.width = '640';
    iframe.height = '360';
    iframe.frameBorder = '0';
    iframe.allow = 'autoplay; fullscreen; picture-in-picture';
    iframe.allowFullscreen = true;
    iframe.setAttribute('aria-label', 'Vimeo Video Player');
    container.appendChild(iframe);
    hideLoading(container);
    showMessage(`Vimeo video loaded.`, 'success');
}

// Function to embed local video file
function embedLocalVideo(file, container, startTime = 0) {
    container.innerHTML = ''; // Clear previous content
    const videoElement = document.createElement('video');
    videoElement.controls = true;
    videoElement.src = URL.createObjectURL(file);
    videoElement.setAttribute('aria-label', 'Local Video Player');
    videoElement.style.width = '100%';
    videoElement.style.height = 'auto';
    videoElement.currentTime = startTime;
    videoElement.onloadedmetadata = () => {
        if (startTime > 0 && videoElement.duration > startTime) {
            videoElement.currentTime = startTime;
        }
    };
    container.appendChild(videoElement);
    hideLoading(container);
    showMessage(`Local video file loaded.`, 'success');
}

// Function to embed local audio file
function embedLocalAudio(file, container, startTime = 0) {
    container.innerHTML = ''; // Clear previous content
    const audioElement = document.createElement('audio');
    audioElement.controls = true;
    audioElement.src = URL.createObjectURL(file);
    audioElement.setAttribute('aria-label', 'Local Audio Player');
    audioElement.style.width = '100%';
    audioElement.style.height = 'auto';
    audioElement.currentTime = startTime;
    audioElement.onloadedmetadata = () => {
        if (startTime > 0 && audioElement.duration > startTime) {
            audioElement.currentTime = startTime;
        }
    };
    container.appendChild(audioElement);
    hideLoading(container);
    showMessage(`Local audio file loaded.`, 'success');
}

// Function to load music
function handleLoadMusic() {
    const url = document.getElementById('music-url').value.trim();
    const fileInput = document.getElementById('music-file');
    const file = fileInput.files[0];
    const startTime = parseInt(document.getElementById('music-start').value) || 0;
    const container = document.getElementById('music-player-container');

    showLoading(container);

    if (file) {
        // Load local audio file
        embedLocalAudio(file, container, startTime);
    } else if (url && isValidMediaURL(url)) {
        const hostname = new URL(url).hostname.toLowerCase();
        if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
            const videoId = extractYouTubeID(url);
            embedYouTubeVideo(videoId, container, startTime);
        } else if (hostname.includes('vimeo.com')) {
            const videoId = extractVimeoID(url);
            embedVimeoVideo(videoId, container, startTime);
        }
    } else {
        hideLoading(container);
        showMessage('Please enter a valid YouTube/Vimeo URL or select a local audio file.', 'error');
    }

    checkReadyToPlay();
}

// Function to load video
function handleLoadVideo() {
    const url = document.getElementById('video-url').value.trim();
    const fileInput = document.getElementById('video-file');
    const file = fileInput.files[0];
    const startTime = parseInt(document.getElementById('video-start').value) || 0;
    const container = document.getElementById('video-player-container');

    showLoading(container);

    if (file) {
        // Load local video file
        embedLocalVideo(file, container, startTime);
    } else if (url && isValidMediaURL(url)) {
        const hostname = new URL(url).hostname.toLowerCase();
        if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
            const videoId = extractYouTubeID(url);
            embedYouTubeVideo(videoId, container, startTime);
        } else if (hostname.includes('vimeo.com')) {
            const videoId = extractVimeoID(url);
            embedVimeoVideo(videoId, container, startTime);
        }
    } else {
        hideLoading(container);
        showMessage('Please enter a valid YouTube/Vimeo URL or select a local video file.', 'error');
    }

    checkReadyToPlay();
}

// Function to check if media is ready to play
function checkReadyToPlay() {
    const playButton = document.getElementById('play-button');
    const pauseButton = document.getElementById('pause-button');
    const resumeButton = document.getElementById('resume-button');

    const musicContainer = document.getElementById('music-player-container');
    const videoContainer = document.getElementById('video-player-container');

    const musicLoaded = musicContainer.innerHTML.trim().length > 0;
    const videoLoaded = videoContainer.innerHTML.trim().length > 0;

    if (musicLoaded || videoLoaded) {
        playButton.disabled = false;
        pauseButton.disabled = false;
    } else {
        playButton.disabled = true;
        pauseButton.disabled = true;
    }

    resumeButton.disabled = true; // Initially disabled
}

// Playback control functions (Basic implementation)

function handlePlay() {
    // Play all players
    playAudio();
    playVideo();

    // Handle Fullscreen if enabled
    const fullscreenToggle = document.getElementById('fullscreen-toggle');
    if (fullscreenToggle.checked) {
        enterFullscreen();
    }

    showMessage('Playback started!', 'success');
}

function handlePause() {
    // Pause all players
    pauseAudio();
    pauseVideo();
    showMessage('Playback paused.', 'info');
}

function handleResume() {
    // Resume all players
    resumeAudio();
    resumeVideo();
    showMessage('Playback resumed.', 'success');
}

// Play Audio
function playAudio() {
    const musicContainer = document.getElementById('music-player-container');
    const audio = musicContainer.querySelector('audio');
    if (audio) {
        audio.play();
        return;
    }

    const iframe = musicContainer.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        // YouTube iframe autoplay
        iframe.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
    }
    // Vimeo autoplay via URL parameter is handled through iframe src
}

// Pause Audio
function pauseAudio() {
    const musicContainer = document.getElementById('music-player-container');
    const audio = musicContainer.querySelector('audio');
    if (audio) {
        audio.pause();
        return;
    }

    const iframe = musicContainer.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        // YouTube iframe pause
        iframe.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
    }
}

// Resume Audio
function resumeAudio() {
    const musicContainer = document.getElementById('music-player-container');
    const audio = musicContainer.querySelector('audio');
    if (audio) {
        audio.play();
        return;
    }

    const iframe = musicContainer.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        // YouTube iframe resume play
        iframe.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
    }
}

// Play Video
function playVideo() {
    const videoContainer = document.getElementById('video-player-container');
    const video = videoContainer.querySelector('video');
    if (video) {
        video.play();
        return;
    }

    const iframe = videoContainer.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        // YouTube iframe autoplay
        iframe.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
    }
    // Vimeo autoplay via URL parameter is handled through iframe src
}

// Pause Video
function pauseVideo() {
    const videoContainer = document.getElementById('video-player-container');
    const video = videoContainer.querySelector('video');
    if (video) {
        video.pause();
        return;
    }

    const iframe = videoContainer.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        // YouTube iframe pause
        iframe.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
    }
}

// Resume Video
function resumeVideo() {
    const videoContainer = document.getElementById('video-player-container');
    const video = videoContainer.querySelector('video');
    if (video) {
        video.play();
        return;
    }

    const iframe = videoContainer.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        // YouTube iframe resume play
        iframe.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
    }
}

// Function to enter fullscreen mode
function enterFullscreen() {
    const containers = ['music-player-container', 'video-player-container'];
    containers.forEach(id => {
        const element = document.getElementById(id);
        if (element) {
            if (element.requestFullscreen) {
                element.requestFullscreen().catch(err => {
                    console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                    showMessage('Failed to enter fullscreen mode.', 'error');
                });
            }
        }
    });
}

// Function to send messages to the YouTube sandbox iframe
function sendMessageToYouTubeSandbox(message) {
    const iframe = document.getElementById('youtube-sandbox-iframe');
    iframe.contentWindow.postMessage(message, '*');
}

// Settings Modal Functions
function openSettingsModal() {
    const modal = document.getElementById('settings-modal');
    modal.removeAttribute('hidden');
    modal.setAttribute('aria-hidden', 'false');
    modal.querySelector('.close-button').focus();
    trapFocus(modal);
}

function closeSettingsModal() {
    const modal = document.getElementById('settings-modal');
    modal.setAttribute('hidden', '');
    modal.setAttribute('aria-hidden', 'true');
    document.getElementById('settings-button').focus();
    removeTrapFocus();
}

// Focus Trap Functions
let focusableElements = [];
let firstFocusableElement = null;
let lastFocusableElement = null;
let previouslyFocusedElement = null;

function trapFocus(element) {
    previouslyFocusedElement = document.activeElement;
    focusableElements = element.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]),' +
        ' textarea:not([disabled]), button:not([disabled]), [tabindex="0"], [contenteditable]');
    firstFocusableElement = focusableElements[0];
    lastFocusableElement = focusableElements[focusableElements.length - 1];

    element.addEventListener('keydown', handleTrapFocus);
    firstFocusableElement.focus();
}

function handleTrapFocus(e) {
    if (e.key === 'Tab') {
        if (e.shiftKey) { // Shift + Tab
            if (document.activeElement === firstFocusableElement) {
                e.preventDefault();
                lastFocusableElement.focus();
            }
        } else { // Tab
            if (document.activeElement === lastFocusableElement) {
                e.preventDefault();
                firstFocusableElement.focus();
            }
        }
    }
}

function removeTrapFocus() {
    const modal = document.getElementById('settings-modal');
    modal.removeEventListener('keydown', handleTrapFocus);
    if (previouslyFocusedElement) {
        previouslyFocusedElement.focus();
    }
}

// Settings Persistence Functions
function loadSettings() {
    try {
        chrome.storage.local.get(['mediaSettings'], (result) => {
            if (chrome.runtime.lastError) {
                console.error('Tab Query Error:', chrome.runtime.lastError);
                showMessage('Failed to load settings.', 'error');
                return;
            }
            if (result.mediaSettings) {
                const { music, video, fullscreenOnPlay } = result.mediaSettings;

                if (music) {
                    if (music.type === 'youtube') {
                        const url = `https://www.youtube.com/watch?v=${music.id}`;
                        document.getElementById('music-url').value = url;
                        document.getElementById('music-start').value = music.start || 0;
                    } else if (music.type === 'vimeo') {
                        const url = `https://vimeo.com/${music.id}`;
                        document.getElementById('music-url').value = url;
                        document.getElementById('music-start').value = music.start || 0;
                    }
                    // Note: Local file loading cannot be restored from storage for security reasons
                }

                if (video) {
                    if (video.type === 'youtube') {
                        const url = `https://www.youtube.com/watch?v=${video.id}`;
                        document.getElementById('video-url').value = url;
                        document.getElementById('video-start').value = video.start || 0;
                    } else if (video.type === 'vimeo') {
                        const url = `https://vimeo.com/${video.id}`;
                        document.getElementById('video-url').value = url;
                        document.getElementById('video-start').value = video.start || 0;
                    }
                    // Note: Local file loading cannot be restored from storage for security reasons
                }

                if (typeof fullscreenOnPlay === 'boolean') {
                    document.getElementById('fullscreen-toggle').checked = fullscreenOnPlay;
                }
            }
        });
    } catch (error) {
        console.error('Error loading settings:', error);
        showMessage('Failed to load settings.', 'error');
    }
}

function saveSettings() {
    const settings = {
        music: getCurrentMediaState('music'),
        video: getCurrentMediaState('video'),
        fullscreenOnPlay: document.getElementById('fullscreen-toggle').checked
    };
    try {
        chrome.storage.local.set({ mediaSettings: settings }, () => {
            if (chrome.runtime.lastError) {
                throw new Error(chrome.runtime.lastError);
            }
            console.log('Settings saved.');
        });
    } catch (error) {
        console.error('Error saving settings:', error);
        showMessage('Error saving settings.', 'error');
    }
}

function getCurrentMediaState(mediaType) {
    const container = mediaType === 'music' ? document.getElementById('music-player-container') : document.getElementById('video-player-container');
    const iframe = container.querySelector('iframe');
    if (iframe && iframe.src.includes('youtube.com')) {
        const url = new URL(iframe.src);
        const videoId = url.pathname.split('/').pop();
        return { type: 'youtube', id: videoId, start: getStartTimeFromURL(url) };
    } else if (iframe && iframe.src.includes('vimeo.com')) {
        const url = new URL(iframe.src);
        const videoId = url.pathname.split('/').pop().split('?')[0];
        return { type: 'vimeo', id: videoId, start: getStartTimeFromURL(url) };
    }
    // For local files, we cannot store the file URL for security reasons
    return null;
}

function getStartTimeFromURL(url) {
    if (url.searchParams.has('start')) {
        return parseInt(url.searchParams.get('start')) || 0;
    } else if (url.hash.includes('t=')) {
        const match = url.hash.match(/t=(\d+)s/);
        return match ? parseInt(match[1]) : 0;
    }
    return 0;
}

// Event Listeners Setup
document.addEventListener('DOMContentLoaded', () => {
    document.getElementById('load-music').addEventListener('click', handleLoadMusic);
    document.getElementById('load-video').addEventListener('click', handleLoadVideo);
    document.getElementById('play-button').addEventListener('click', handlePlay);
    document.getElementById('pause-button').addEventListener('click', handlePause);
    document.getElementById('resume-button').addEventListener('click', handleResume);

    // Settings Modal Event Listeners
    document.getElementById('settings-button').addEventListener('click', openSettingsModal);
    document.querySelector('.close-button').addEventListener('click', closeSettingsModal);
    window.addEventListener('click', (event) => {
        const modal = document.getElementById('settings-modal');
        if (event.target === modal) {
            closeSettingsModal();
        }
    });
    document.addEventListener('keydown', (event) => {
        const modal = document.getElementById('settings-modal');
        if (event.key === 'Escape' && !modal.hasAttribute('hidden')) {
            closeSettingsModal();
        }
    });

    // Load Settings from Storage
    loadSettings();

    // Save settings when fullscreen toggle changes
    document.getElementById('fullscreen-toggle').addEventListener('change', saveSettings);
});

// Handling messages from YouTube Sandbox (if used)
window.addEventListener('message', (event) => {
    // For security, you can check event.origin here if necessary
    const data = event.data;
    if (data.type === 'playerReady') {
        showMessage(`YouTube ${capitalize(data.mediaType)} loaded and ready.`, 'success');
        // hideLoading(elements[data.mediaType].playerContainer); // Already handled in embed functions
    } else if (data.type === 'playerError') {
        showMessage(`Error loading YouTube ${capitalize(data.mediaType)}.`, 'error');
        // hideLoading(elements[data.mediaType].playerContainer); // Already handled in embed functions
    }
});

/* General Styles */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    max-width: 1200px; /* Increased max-width for larger displays */
    margin: 0 auto;
}

.section {
    width: 100%;
    margin-bottom: 20px;
    background-color: #fff;
    padding: 20px; /* Increased padding for better spacing */
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Header with Settings Button and Title */
.header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center; /* Center the content */
    margin-bottom: 30px; /* Increased margin for better spacing */
    position: relative;
}

.settings-button {
    position: absolute;
    left: 0;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 8px;
    cursor: pointer;
    width: 50px; /* Increased size for better touch targets */
    height: 50px; /* Increased size for better touch targets */
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.settings-button:hover {
    background-color: #f0f0f0;
    border-color: #999;
}

.settings-icon {
    width: 24px;
    height: 24px;
}

/* Main Title with Animation */
.main-title {
    font-size: 3em; /* Increased font size for better visibility */
    font-weight: bold;
    margin: 0;
    animation: titleAnimation 3s infinite;
}

/* Title Animation Keyframes */
@keyframes titleAnimation {
    0% { color: #4285f4; transform: scale(1); }
    50% { color: #ea4335; transform: scale(1.05); }
    100% { color: #4285f4; transform: scale(1); }
}

/* Section Headers */
.section > fieldset > legend {
    font-size: 1.5em;
    font-weight: bold;
    margin-bottom: 15px;
}

/* Controls */
.controls {
    display: flex;
    gap: 15px; /* Increased gap for better spacing */
    margin-bottom: 30px; /* Increased margin for better spacing */
}

.controls button {
    padding: 15px 30px; /* Increased padding for better accessibility */
    cursor: pointer;
    border: none;
    border-radius: 8px;
    background-color: #4285f4;
    color: #fff;
    transition: background-color 0.3s ease;
    font-size: 1.2em; /* Increased font size for better readability */
}

.controls button:disabled {
    background-color: #a0c3ff;
    cursor: not-allowed;
}

.controls button:hover:not(:disabled) {
    background-color: #357ae8;
}

/* Play Button Specific Styles */
.play-button {
    background-color: #34a853; /* Green */
}

.play-button:hover:not(:disabled) {
    background-color: #2c8e46;
}

/* Pause Button Specific Styles */
.pause-button {
    background-color: #fbbc05; /* Yellow */
}

.pause-button:hover:not(:disabled) {
    background-color: #e0a800;
}

/* Resume Button Specific Styles */
.resume-button {
    background-color: #ea4335; /* Red */
}

.resume-button:hover:not(:disabled) {
    background-color: #c33c2c;
}

/* Modal Styles */
.modal[hidden] {
    display: none;
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.6); /* Darker backdrop for better contrast */
    display: flex; /* Visible when not hidden */
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.modal-content {
    background-color: #fff;
    padding: 25px 35px; /* Increased padding for better spacing */
    border-radius: 10px; /* More pronounced rounding */
    width: 90%;
    max-width: 600px; /* Increased max-width for better layout */
    position: relative;
    box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}

.close-button {
    position: absolute;
    top: 15px;
    right: 20px;
    background: none;
    border: none;
    font-size: 28px;
    cursor: pointer;
    color: #333;
}

.modal-content h2 {
    margin-top: 0;
    font-size: 2em; /* Increased font size for better visibility */
}

/* Form Elements */
fieldset {
    border: none;
    padding: 0;
}

fieldset label {
    display: block;
    margin-bottom: 8px;
    font-weight: bold;
}

fieldset input[type="text"],
fieldset input[type="number"],
fieldset input[type="file"] {
    width: 100%;
    padding: 12px; /* Increased padding for better usability */
    margin-bottom: 20px; /* Increased margin for better spacing */
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 6px;
    font-size: 1em; /* Increased font size for better readability */
}

fieldset .load-button {
    width: 100%;
    padding: 15px;
    background-color: #4285f4; /* Blue */
    color: #fff;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.3s ease;
    font-size: 1.2em; /* Increased font size for better readability */
}

fieldset .load-button:hover {
    background-color: #357ae8;
}

/* Player Containers */
.player-container {
    margin-top: 10px;
    width: 100%;
    max-width: 100%;
    min-height: 120px; /* Increased minimum height for better visibility */
    box-sizing: border-box;
    overflow: hidden; /* Prevent overflow */
    position: relative;
}

/* Responsive Video and Audio Elements */
.player-container video,
.player-container iframe {
    width: 100%;
    height: 360px; /* Fixed height for larger displays */
    border-radius: 8px;
    display: block;
}

.player-container audio {
    width: 100%;
    height: auto;
    border-radius: 5px;
    margin-top: 10px; /* Increased margin for better spacing */
}

/* Messages */
.message-container {
    position: fixed;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1001; /* Above other content */
    width: 90%;
    max-width: 700px;
}

.message {
    padding: 15px 25px;
    border-radius: 8px;
    margin-bottom: 15px;
    color: #fff;
    font-size: 1.1em;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    opacity: 0.95;
    animation: fadeInOut 6s forwards;
}

.message.success {
    background-color: #4caf50;
}

.message.error {
    background-color: #f44336;
}

.message.info {
    background-color: #2196f3;
}

/* Loader */
.loader {
    border: 8px solid #f3f3f3; /* Light grey */
    border-top: 8px solid #4285f4; /* Blue */
    border-radius: 50%;
    width: 80px; /* Increased size for better visibility */
    height: 80px; /* Increased size for better visibility */
    animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Fade In and Out for Messages */
@keyframes fadeInOut {
    0% { opacity: 0; transform: translateY(-20px); }
    10% { opacity: 0.95; transform: translateY(0); }
    90% { opacity: 0.95; transform: translateY(0); }
    100% { opacity: 0; transform: translateY(-20px); }
}

/* Responsive Design */
@media (max-width: 1000px) {
    .container {
        padding: 25px;
    }

    .controls {
        flex-direction: column;
        gap: 10px;
    }

    .controls button {
        width: 100%;
    }

    .main-title {
        font-size: 2.5em;
    }

    .player-container video,
    .player-container iframe {
        height: 280px; /* Adjusted height for smaller screens */
    }

    .loader {
        width: 60px; /* Adjusted size for smaller screens */
        height: 60px; /* Adjusted size for smaller screens */
    }
}

@media (max-width: 700px) {
    .section {
        padding: 15px;
    }

    .modal-content {
        padding: 20px 25px;
    }

    .main-title {
        font-size: 2em;
    }

    .player-container video,
    .player-container iframe {
        height: 220px; /* Further adjusted height for even smaller screens */
    }

    .loader {
        width: 50px; /* Further adjusted size for even smaller screens */
        height: 50px; /* Further adjusted size for even smaller screens */
    }
}

@media (max-width: 500px) {
    .container {
        padding: 15px;
    }

    .controls button {
        padding: 12px;
        font-size: 1em;
    }

    .modal-content {
        padding: 15px 20px;
    }

    .main-title {
        font-size: 1.8em;
    }

    .player-container video,
    .player-container iframe {
        height: 180px; /* Further adjusted height for very small screens */
    }

    .loader {
        width: 40px; /* Further adjusted size for very small screens */
        height: 40px; /* Further adjusted size for very small screens */
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>YouTube Sandbox</title>
</head>
<body>
    <!-- YouTube Player Container -->
    <div id="youtube-player"></div>

    <!-- External Sandbox Script -->
    <script src="sandbox.js"></script>
</body>
</html>

"use strict";

let player;
let mediaType = ''; // 'music' or 'video'

// Function to send messages to the parent
function sendMessageToParent(message) {
    window.parent.postMessage(message, '*');
}

// Listen for messages from the parent
window.addEventListener('message', (event) => {
    // Security Check: Optionally verify event.origin here
    const data = event.data;
    if (data.type === 'init') {
        mediaType = data.mediaType; // 'music' or 'video'
        createYouTubePlayer(data.videoId, data.startTime);
    } else if (data.type === 'play') {
        if (player && typeof player.playVideo === 'function') {
            player.playVideo();
        }
    } else if (data.type === 'pause') {
        if (player && typeof player.pauseVideo === 'function') {
            player.pauseVideo();
        }
    } else if (data.type === 'seek') {
        if (player && typeof player.seekTo === 'function') {
            player.seekTo(data.time, true);
        }
    }
});

/**
 * Creates a YouTube player.
 * @param {string} videoId - The YouTube video ID.
 * @param {number} startTime - The start time in seconds.
 */
function createYouTubePlayer(videoId, startTime = 0) {
    const container = document.getElementById('youtube-player');
    container.innerHTML = ''; // Clear any existing content

    player = new YT.Player('youtube-player', {
        height: '360',
        width: '640',
        videoId: videoId,
        playerVars: {
            'autoplay': 0,
            'controls': 1,
            'start': startTime,
            'mute': 1,
            'rel': 0,
            'disablekb': 1,
            'modestbranding': 1,
            'iv_load_policy': 3,
            'fs': 1
        },
        events: {
            'onReady': () => {
                sendMessageToParent({
                    type: 'playerReady',
                    mediaType: mediaType
                });
            },
            'onError': (error) => {
                sendMessageToParent({
                    type: 'playerError',
                    mediaType: mediaType,
                    error: error.data
                });
            }
        }
    });

    // Load YouTube IFrame API
    loadYouTubeIframeAPI();
}

function loadYouTubeIframeAPI() {
    const script = document.createElement('script');
    script.src = 'https://www.youtube.com/iframe_api';
    document.head.appendChild(script);
}

// Function to handle YouTube IFrame API callback
function onYouTubeIframeAPIReady() {
    // Player is already created in createYouTubePlayer
}

i only want the completed updated files. i only want the completed updated files. when i press the load buttons i want the vimeo and youtube videos to load then wait till done then play at least a eighth of a second then pause then set them to the user set start time.