I already have a working music player UI, similar to the one shown in the screenshots. It includes: Date and time at the top Album cover (centered) Song title, artist, and album info below the cover Playback progress bar and controls at the bottom Do not rebuild it from scratch. I just want you to fix the issues without changing the structure or layout. Please fix the following: Alignment issues – make sure all elements (time, cover art, text, controls) are properly centered and spaced. Text readability – improve contrast and legibility of song title and artist text over the blurred background. Cover art scaling – keep the image centered and proportionate across screen sizes. Preserve the blurred background, but make sure it doesn’t wash out or overpower the UI. Do not remove or redesign any components. Make it responsive – ensure the layout works well on both desktop and mobile. Only clean up and improve the existing HTML/CSS/JS. Keep the aesthetic somewhat quirky/indie – it shouldn’t look corporate or overly polished. - Follow Up Deployment
cc72760 verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>iOS 18 Clock</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jsmediatags/3.9.5/jsmediatags.min.js"></script> | |
| <style> | |
| @font-face { | |
| font-family: 'SF Pro Display'; | |
| src: url('https://sf.abarba.me/SF-Pro-Display-Bold.otf') format('opentype'); | |
| font-weight: bold; | |
| font-style: normal; | |
| } | |
| body { | |
| background-color: transparent; | |
| background-size: cover; | |
| background-position: center; | |
| background-repeat: no-repeat; | |
| color: #fff; | |
| font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif; | |
| height: 100vh; | |
| margin: 0; | |
| -webkit-app-region: drag; | |
| } | |
| ======= | |
| </style> | |
| </head> | |
| <body class="wallpaper h-screen w-screen overflow-hidden flex flex-col items-center justify-between text-white font-sans"> | |
| <div class="clock-container"> | |
| <div id="time" class="clock-time">12:34</div> | |
| <div id="date" class="clock-date">Monday, September 25</div> | |
| </div> | |
| <button id="settings-button" style="position: fixed; bottom: 20px; right: 20px; background: rgba(30,30,30,0.7); color: white; border: none; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; -webkit-app-region: no-drag; z-index: 100;"> | |
| ️ | |
| </button> | |
| <div id="music-player" style="display: none; position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: transparent; padding: clamp(10px, 4vw, 15px); width: min(95%, 400px); border-radius: 20px; z-index: 50;"> | |
| <div style="display: flex; flex-direction: column; align-items: center; gap: 8px;"> | |
| <div id="album-art-container" style="width: min(250px, 60vw); aspect-ratio: 1/1; margin: -120px auto 10px; position: relative; z-index: 60; pointer-events: none;"> | |
| <div style="position: absolute; width: 100%; height: 100%; background: transparent; pointer-events: auto;"></div> | |
| <img id="album-art" src="" style="width: 100%; height: 100%; object-fit: cover; border-radius: 15px; box-shadow: 0 8px 20px rgba(0,0,0,0.3);"> | |
| </div> | |
| <div style="background: rgba(30,30,30,0.5); backdrop-filter: blur(20px); border-radius: 15px; padding: clamp(10px, 3vw, 15px); width: 100%; margin-top: 10px;"> | |
| <div id="track-info" style="text-align: center; color: white; text-shadow: 0 1px 3px rgba(0,0,0,0.5); width: 100%; padding: 0 clamp(5px, 3vw, 10px);"> | |
| <div id="track-title" style="font-size: clamp(14px, 4vw, 18px); font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;">No song playing</div> | |
| <div id="track-artist" style="font-size: clamp(12px, 3vw, 14px); opacity: 0.8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;">Upload a song to begin</div> | |
| </div> | |
| <div style="display: flex; align-items: center; gap: 8px; width: 100%; padding: 0 5px;"> | |
| <span id="current-time" style="font-size: 11px;">0:00</span> | |
| <input type="range" id="progress-bar" style="flex-grow: 1; height: 4px;" min="0" max="100" value="0"> | |
| <span id="duration" style="font-size: 11px;">0:00</span> | |
| </div> | |
| <div style="display: flex; justify-content: center; gap: clamp(8px, 4vw, 20px); margin-top: clamp(8px, 3vw, 10px);"> | |
| <button id="prev-btn" style="background: none; border: none; color: white; font-size: clamp(14px, 4vw, 20px);">⏮</button> | |
| <button id="play-btn" style="background: none; border: none; color: white; font-size: clamp(20px, 5vw, 30px);">▶</button> | |
| <button id="next-btn" style="background: none; border: none; color: white; font-size: clamp(14px, 4vw, 20px);">⏭</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <style> | |
| @media (max-width: 500px) { | |
| #music-player { | |
| width: 90% ; | |
| bottom: 10px ; | |
| } | |
| #album-art-container { | |
| width: min(200px, 80vw) ; | |
| margin: -80px auto 10px ; | |
| } | |
| .clock-container { | |
| top: 10px; | |
| padding: 15px; | |
| } | |
| .clock-time { | |
| font-size: clamp(40px, 12vw, 48px) ; | |
| } | |
| } | |
| .clock-container { | |
| position: fixed; | |
| top: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| display: flex; | |
| flex-direction: column-reverse; | |
| align-items: center; | |
| background-color: transparent; | |
| border-radius: 12px; | |
| padding: 20px; | |
| backdrop-filter: none; | |
| margin-bottom: 100px; | |
| } | |
| .clock-time { | |
| font-size: clamp(48px, 10vw, 64px); | |
| font-weight: 700; | |
| letter-spacing: -2px; | |
| opacity: 0.55; | |
| margin-top: -8px; | |
| } | |
| .clock-date { | |
| font-size: clamp(14px, 3vw, 18px); | |
| font-weight: 600; | |
| letter-spacing: -0.3px; | |
| opacity: 0.55; | |
| } | |
| </style> | |
| <div id="settings-modal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); z-index: 100; -webkit-app-region: no-drag;"> | |
| <div style="background-color: #1e1e1e; width: 400px; margin: 100px auto; padding: 20px; border-radius: 12px;"> | |
| <h2 style="margin-top: 0;">Settings</h2> | |
| <input type="file" id="wallpaper-input" accept="image/*" style="display: none;"> | |
| <button onclick="document.getElementById('wallpaper-input').click()" style="background: #2c2c2e; color: white; border: none; padding: 10px 15px; border-radius: 8px; cursor: pointer;"> | |
| Upload Wallpaper | |
| </button> | |
| <input type="file" id="music-input" accept="audio/*" style="display: none;"> | |
| <button onclick="document.getElementById('music-input').click()" style="background: #2c2c2e; color: white; border: none; padding: 10px 15px; border-radius: 8px; cursor: pointer; margin-left: 10px;"> | |
| Upload Music | |
| </button> | |
| <button onclick="document.getElementById('settings-modal').style.display = 'none'" style="background: #2c2c2e; color: white; border: none; padding: 10px 15px; border-radius: 8px; cursor: pointer; margin-left: 10px;"> | |
| Close | |
| </button> | |
| </div> | |
| </div> | |
| <script> | |
| // Check if this is first visit and prompt for wallpaper | |
| if (!localStorage.getItem('wallpaperSet')) { | |
| setTimeout(() => { | |
| document.getElementById('settings-modal').style.display = 'block'; | |
| localStorage.setItem('wallpaperSet', 'true'); | |
| }, 500); | |
| } | |
| const audio = new Audio(); | |
| let currentTrack = null; | |
| let isPlaying = false; | |
| // Initialize player with empty state | |
| document.getElementById('track-title').textContent = 'No song playing'; | |
| document.getElementById('track-artist').textContent = 'Upload a song to begin'; | |
| document.getElementById('album-art').src = ''; | |
| document.getElementById('music-player').style.display = 'none'; | |
| // Music player controls | |
| document.getElementById('play-btn').addEventListener('click', function() { | |
| if (!currentTrack) return; | |
| if (isPlaying) { | |
| audio.pause(); | |
| document.getElementById('play-btn').textContent = '▶'; | |
| } else { | |
| audio.play() | |
| .then(() => { | |
| document.getElementById('play-btn').textContent = '⏸'; | |
| }) | |
| .catch(error => { | |
| console.error('Playback failed:', error); | |
| alert('Playback failed. Please try again.'); | |
| }); | |
| } | |
| isPlaying = !isPlaying; | |
| }); | |
| document.getElementById('progress-bar').addEventListener('input', function() { | |
| if (currentTrack) { | |
| const seekTime = (audio.duration * this.value) / 100; | |
| audio.currentTime = seekTime; | |
| } | |
| }); | |
| audio.addEventListener('timeupdate', function() { | |
| if (currentTrack) { | |
| const progress = (audio.currentTime / audio.duration) * 100; | |
| document.getElementById('progress-bar').value = progress; | |
| document.getElementById('current-time').textContent = formatTime(audio.currentTime); | |
| } | |
| }); | |
| audio.addEventListener('loadedmetadata', function() { | |
| if (currentTrack) { | |
| document.getElementById('duration').textContent = formatTime(audio.duration); | |
| } | |
| }); | |
| audio.addEventListener('ended', function() { | |
| document.getElementById('play-btn').textContent = '▶'; | |
| isPlaying = false; | |
| }); | |
| function formatTime(seconds) { | |
| const minutes = Math.floor(seconds / 60); | |
| const secs = Math.floor(seconds % 60); | |
| return `${minutes}:${secs < 10 ? '0' : ''}${secs}`; | |
| } | |
| let clickCount = 0; | |
| let clickTimer; | |
| document.getElementById('settings-button').addEventListener('click', function() { | |
| document.getElementById('settings-modal').style.display = 'block'; | |
| }); | |
| document.getElementById('music-input').addEventListener('change', function(e) { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| // Reset player state | |
| document.getElementById('track-title').textContent = file.name.replace(/\.[^/.]+$/, ""); | |
| document.getElementById('track-artist').textContent = 'Unknown Artist'; | |
| document.getElementById('album-art').src = ''; | |
| document.getElementById('music-player').style.display = 'block'; | |
| currentTrack = file; | |
| const url = URL.createObjectURL(file); | |
| audio.src = url; | |
| audio.load(); | |
| audio.play().catch(error => console.log('Autoplay prevented:', error)); | |
| document.getElementById('play-btn').textContent = '⏸'; | |
| isPlaying = true; | |
| // Read metadata | |
| const reader = new FileReader(); | |
| reader.onload = function(event) { | |
| try { | |
| jsmediatags.read(file, { | |
| onSuccess: function(tag) { | |
| const tags = tag.tags; | |
| document.getElementById('track-title').textContent = tags.title || file.name.replace(/\.[^/.]+$/, ""); | |
| document.getElementById('track-artist').textContent = tags.artist || 'Unknown Artist'; | |
| if (tags.picture) { | |
| const base64String = arrayBufferToBase64(tags.picture.data); | |
| const imageUrl = `data:${tags.picture.format};base64,${base64String}`; | |
| document.getElementById('album-art').src = imageUrl; | |
| setBackgroundFromImage(imageUrl); | |
| } else { | |
| document.getElementById('album-art').src = ''; | |
| // Reset to default background if no album art | |
| document.body.style.background = 'transparent'; | |
| document.body.style.backdropFilter = 'none'; | |
| } | |
| document.getElementById('music-player').style.display = 'block'; | |
| audio.play().catch(e => console.log('Autoplay prevented:', e)); | |
| document.getElementById('play-btn').textContent = '⏸'; | |
| isPlaying = true; | |
| }, | |
| onError: function(error) { | |
| console.log('Error reading metadata:', error); | |
| document.getElementById('track-title').textContent = file.name.replace(/\.[^/.]+$/, ""); | |
| document.getElementById('track-artist').textContent = 'Unknown Artist'; | |
| document.getElementById('album-art').src = ''; | |
| document.getElementById('music-player').style.display = 'block'; | |
| audio.play().catch(e => console.log('Autoplay prevented:', e)); | |
| document.getElementById('play-btn').textContent = '⏸'; | |
| isPlaying = true; | |
| } | |
| }); | |
| } catch (error) { | |
| console.log('Error processing file:', error); | |
| document.getElementById('track-title').textContent = file.name.replace(/\.[^/.]+$/, ""); | |
| document.getElementById('track-artist').textContent = 'Unknown Artist'; | |
| document.getElementById('album-art').src = ''; | |
| document.getElementById('music-player').style.display = 'block'; | |
| audio.play().catch(e => console.log('Autoplay prevented:', e)); | |
| document.getElementById('play-btn').textContent = '⏸'; | |
| isPlaying = true; | |
| } | |
| }; | |
| reader.onerror = function() { | |
| console.log('FileReader error'); | |
| document.getElementById('track-title').textContent = file.name.replace(/\.[^/.]+$/, ""); | |
| document.getElementById('track-artist').textContent = 'Unknown Artist'; | |
| document.getElementById('album-art').src = ''; | |
| document.getElementById('music-player').style.display = 'block'; | |
| audio.play().catch(e => console.log('Autoplay prevented:', e)); | |
| document.getElementById('play-btn').textContent = '⏸'; | |
| isPlaying = true; | |
| }; | |
| reader.readAsArrayBuffer(file); | |
| } | |
| }); | |
| function arrayBufferToBase64(buffer) { | |
| let binary = ''; | |
| const bytes = new Uint8Array(buffer); | |
| for (let i = 0; i < bytes.byteLength; i++) { | |
| binary += String.fromCharCode(bytes[i]); | |
| } | |
| return window.btoa(binary); | |
| } | |
| function setBackgroundFromImage(imageUrl) { | |
| const img = new Image(); | |
| img.src = imageUrl; | |
| img.onload = function() { | |
| // Apply background with blur and overlay | |
| document.body.style.background = ` | |
| linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), | |
| url(${imageUrl}) | |
| `; | |
| document.body.style.backgroundSize = 'cover'; | |
| document.body.style.backgroundPosition = 'center'; | |
| document.body.style.backgroundRepeat = 'no-repeat'; | |
| document.body.style.backdropFilter = 'blur(20px)'; | |
| }; | |
| } | |
| document.getElementById('wallpaper-input').addEventListener('change', function(e) { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| const reader = new FileReader(); | |
| reader.onload = function(event) { | |
| document.body.style.backgroundImage = `url(${event.target.result})`; | |
| document.body.style.backgroundSize = 'cover'; | |
| document.body.style.backgroundPosition = 'center'; | |
| document.body.style.backgroundRepeat = 'no-repeat'; | |
| localStorage.setItem('wallpaperSet', 'true'); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| }); | |
| function updateTime() { | |
| const now = new Date(); | |
| const timeElement = document.getElementById('time'); | |
| const dateElement = document.getElementById('date'); | |
| // Format time (12:34) - iOS 18 style | |
| let hours = now.getHours(); | |
| const minutes = now.getMinutes().toString().padStart(2, '0'); | |
| timeElement.textContent = `${hours}:${minutes}`; | |
| // Format date (Monday, September 25) - iOS 18 style | |
| const options = { | |
| weekday: 'long', | |
| month: 'long', | |
| day: 'numeric', | |
| hour12: false | |
| }; | |
| dateElement.textContent = now.toLocaleDateString('en-US', options); | |
| } | |
| updateTime(); | |
| setInterval(updateTime, 1000); | |
| </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=Gcuore/macos" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |