Skip to main content
Glama

Superdesign MCP Server

by jonthebeef
gallery.html31.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Superdesign Gallery</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } :root { --bg-primary: #ffffff; --bg-secondary: #f8fafc; --bg-card: #ffffff; --text-primary: #1a202c; --text-secondary: #718096; --border-color: #e2e8f0; --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); --shadow-hover: 0 10px 25px -5px rgba(0, 0, 0, 0.2); } [data-theme="dark"] { --bg-primary: #1a202c; --bg-secondary: #2d3748; --bg-card: #2d3748; --text-primary: #f7fafc; --text-secondary: #a0aec0; --border-color: #4a5568; --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3); --shadow-hover: 0 10px 25px -5px rgba(0, 0, 0, 0.4); } body { font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace; background: var(--bg-primary); color: var(--text-primary); min-height: 100vh; padding: 20px; transition: background 0.3s ease, color 0.3s ease; } .header { margin-bottom: 40px; display: flex; justify-content: space-between; align-items: flex-start; } .header-content h1 { font-size: 2.5rem; color: var(--text-primary); margin-bottom: 8px; font-weight: 600; letter-spacing: -0.02em; } .header-content p { color: var(--text-secondary); font-size: 1rem; font-weight: 400; } .header-controls { display: flex; gap: 12px; align-items: center; } .refresh-controls { display: flex; gap: 8px; align-items: center; } .auto-refresh-toggle { display: flex; align-items: center; gap: 6px; font-size: 0.875rem; color: var(--text-secondary); cursor: pointer; user-select: none; } .auto-refresh-toggle input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--text-primary); } .btn-secondary { background: var(--bg-card); border: 1px solid var(--border-color); color: var(--text-secondary); padding: 6px 12px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 0.875rem; transition: all 0.2s ease; display: flex; align-items: center; gap: 6px; } .btn-secondary:hover { background: var(--bg-secondary); transform: translateY(-1px); } .btn-secondary:disabled { opacity: 0.5; cursor: not-allowed; } .btn-secondary:disabled:hover { transform: none; } .theme-toggle { background: var(--bg-card); border: 1px solid var(--border-color); color: var(--text-primary); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 0.875rem; transition: all 0.2s ease; display: flex; align-items: center; gap: 8px; } .theme-toggle:hover { background: var(--bg-secondary); transform: translateY(-1px); } .updated-indicator { position: absolute; top: 8px; right: 8px; width: 12px; height: 12px; background: #48bb78; border-radius: 50%; border: 2px solid var(--bg-card); animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .refresh-indicator { display: inline-block; animation: spin 1s linear infinite; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); gap: 24px; max-width: 1400px; } .design-card { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; transition: transform 0.2s ease, box-shadow 0.2s ease; } .design-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); } .design-header { padding: 16px; border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: flex-start; } .design-title { display: flex; align-items: center; gap: 8px; } .design-title h3 { color: var(--text-primary); font-size: 1rem; font-weight: 500; font-family: inherit; } .design-type { background: var(--bg-secondary); color: var(--text-secondary); padding: 4px 8px; border-radius: 4px; font-size: 0.75rem; font-weight: 400; font-family: inherit; } .design-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; } .design-size, .design-date { color: var(--text-secondary); font-size: 0.75rem; font-family: inherit; } .design-date { opacity: 0.8; } .design-preview { height: 300px; position: relative; overflow: hidden; } .design-preview iframe { width: 100%; height: 100%; border: none; transform: scale(0.5); transform-origin: top left; width: 200%; height: 200%; } .design-preview .svg-preview { width: 100%; height: 100%; object-fit: contain; background: var(--bg-primary); } .design-actions { padding: 16px; display: flex; gap: 8px; } .btn-primary { background: #4299e1; color: white; border: none; padding: 8px 16px; border-radius: 6px; font-size: 0.875rem; font-family: inherit; cursor: pointer; transition: background 0.2s ease; } .btn-primary:hover { background: #3182ce; } .btn-secondary { background: var(--bg-secondary); color: var(--text-secondary); border: 1px solid var(--border-color); padding: 8px 16px; border-radius: 6px; font-size: 0.875rem; font-family: inherit; cursor: pointer; transition: background 0.2s ease; } .btn-secondary:hover { background: var(--border-color); } .btn-danger { background: #e53e3e; color: white; border: none; padding: 8px 16px; border-radius: 6px; font-size: 0.875rem; font-family: inherit; cursor: pointer; transition: background 0.2s ease; } .btn-danger:hover { background: #c53030; } .empty-state { text-align: center; padding: 60px 20px; color: #718096; } .empty-state h3 { font-size: 1.25rem; margin-bottom: 8px; } @media (max-width: 768px) { .gallery-grid { grid-template-columns: 1fr; } .design-preview { height: 200px; } .header { flex-direction: column; gap: 16px; align-items: flex-start; } } </style> </head> <body> <div class="header"> <div class="header-content"> <h1>superdesign.gallery</h1> <p id="file-count">8 designs found • Fresh MCP Scan</p> </div> <div class="header-controls"> <div class="refresh-controls"> <button id="refresh-btn" class="btn-secondary" onclick="refreshGallery()"> <span id="refresh-icon">🔄</span> <span id="refresh-text">Refresh</span> </button> <label class="auto-refresh-toggle"> <input type="checkbox" id="auto-refresh" onchange="toggleAutoRefresh()"> <span>Auto-refresh</span> </label> </div> <button class="theme-toggle" onclick="toggleTheme()"> <span id="theme-icon">🌙</span> <span id="theme-text">Dark</span> </button> </div> </div> <div class="gallery-grid"> <div class="design-card" data-file="wood_winamp_4.html" data-created="" data-modified="1752010233666"> <div class="design-header"> <div class="design-title"> <h3>Wood Grain Winamp</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">12.7 KB</span> <span class="design-date">Jul 8, 22:30</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/wood_winamp_4.html" loading="lazy" data-file="wood_winamp_4.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/wood_winamp_4.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/wood_winamp_4.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('wood_winamp_4.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="neon_winamp_2.html" data-created="" data-modified="1752010131452"> <div class="design-header"> <div class="design-title"> <h3>Neon Cyber Winamp</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">12.0 KB</span> <span class="design-date">Jul 8, 22:28</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/neon_winamp_2.html" loading="lazy" data-file="neon_winamp_2.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/neon_winamp_2.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/neon_winamp_2.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('neon_winamp_2.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="minimal_winamp_3.html" data-created="" data-modified="1752010179054"> <div class="design-header"> <div class="design-title"> <h3>Minimal Music Player</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">10.4 KB</span> <span class="design-date">Jul 8, 22:29</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/minimal_winamp_3.html" loading="lazy" data-file="minimal_winamp_3.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/minimal_winamp_3.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/minimal_winamp_3.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('minimal_winamp_3.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="classic_winamp_1.html" data-created="" data-modified="1752010077862"> <div class="design-header"> <div class="design-title"> <h3>Classic Winamp Player</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">9.1 KB</span> <span class="design-date">Jul 8, 22:27</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/classic_winamp_1.html" loading="lazy" data-file="classic_winamp_1.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/classic_winamp_1.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/classic_winamp_1.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('classic_winamp_1.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="calculator_retro_4.html" data-created="" data-modified="1752009533660"> <div class="design-header"> <div class="design-title"> <h3>Retro Calculator</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">8.1 KB</span> <span class="design-date">Jul 8, 22:18</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/calculator_retro_4.html" loading="lazy" data-file="calculator_retro_4.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/calculator_retro_4.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/calculator_retro_4.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('calculator_retro_4.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="calculator_neumorphic_2.html" data-created="" data-modified="1752009409190"> <div class="design-header"> <div class="design-title"> <h3>Neumorphic Calculator</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">6.6 KB</span> <span class="design-date">Jul 8, 22:16</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/calculator_neumorphic_2.html" loading="lazy" data-file="calculator_neumorphic_2.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/calculator_neumorphic_2.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/calculator_neumorphic_2.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('calculator_neumorphic_2.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="calculator_minimalist_1.html" data-created="" data-modified="1752009380423"> <div class="design-header"> <div class="design-title"> <h3>Minimalist Calculator</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">6.0 KB</span> <span class="design-date">Jul 8, 22:16</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/calculator_minimalist_1.html" loading="lazy" data-file="calculator_minimalist_1.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/calculator_minimalist_1.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/calculator_minimalist_1.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('calculator_minimalist_1.html')" class="btn-danger">Delete</button> </div> </div> <div class="design-card" data-file="calculator_glassmorphism_3.html" data-created="" data-modified="1752009434734"> <div class="design-header"> <div class="design-title"> <h3>Glassmorphism Calculator</h3> <span class="design-type">.HTML</span> </div> <div class="design-meta"> <span class="design-size">6.8 KB</span> <span class="design-date">Jul 8, 22:17</span> </div> </div> <div class="design-preview"> <iframe src="./design_iterations/calculator_glassmorphism_3.html" loading="lazy" data-file="calculator_glassmorphism_3.html"></iframe> </div> <div class="design-actions"> <button onclick="openFullscreen('./design_iterations/calculator_glassmorphism_3.html')" class="btn-primary">View Full</button> <button onclick="copyPath('./design_iterations/calculator_glassmorphism_3.html')" class="btn-secondary">Copy Path</button> <button onclick="deleteDesign('calculator_glassmorphism_3.html')" class="btn-danger">Delete</button> </div> </div> </div> <script> // Theme management const theme = localStorage.getItem('theme') || 'light'; document.documentElement.setAttribute('data-theme', theme); updateThemeButton(); function toggleTheme() { const currentTheme = document.documentElement.getAttribute('data-theme'); const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); updateThemeButton(); } function updateThemeButton() { const theme = document.documentElement.getAttribute('data-theme'); const icon = document.getElementById('theme-icon'); const text = document.getElementById('theme-text'); if (theme === 'dark') { icon.textContent = '☀️'; text.textContent = 'Light'; } else { icon.textContent = '🌙'; text.textContent = 'Dark'; } } function openFullscreen(path) { window.open(path, '_blank'); } function copyPath(path) { navigator.clipboard.writeText(path).then(() => { showToast('Path copied to clipboard!', 'success'); }); } function deleteDesign(fileName) { if (confirm(`Are you sure you want to delete ${fileName}?`)) { showToast('Delete functionality via MCP coming soon!', 'info'); } } function showToast(message, type = 'info') { const colors = { success: '#48bb78', error: '#e53e3e', info: '#4299e1', warning: '#ed8936' }; const toast = document.createElement('div'); toast.textContent = message; toast.style.cssText = ` position: fixed; top: 20px; right: 20px; background: ${colors[type] || colors.info}; color: white; padding: 12px 20px; border-radius: 6px; z-index: 1000; font-size: 14px; font-family: inherit; animation: slideIn 0.3s ease; `; document.body.appendChild(toast); setTimeout(() => { toast.style.animation = 'slideOut 0.3s ease'; setTimeout(() => toast.remove(), 300); }, 3000); } // File manifest for change detection (MCP Integration) const fileManifest = [ {"name":"wood_winamp_4.html","size":13051,"modified":1752010233666,"created":"2025-01-08T22:30:33.666Z"}, {"name":"neon_winamp_2.html","size":12307,"modified":1752010131452,"created":"2025-01-08T22:28:51.452Z"}, {"name":"minimal_winamp_3.html","size":10650,"modified":1752010179054,"created":"2025-01-08T22:29:39.054Z"}, {"name":"classic_winamp_1.html","size":9339,"modified":1752010077862,"created":"2025-01-08T22:27:57.862Z"}, {"name":"calculator_retro_4.html","size":8257,"modified":1752009533660,"created":"2025-01-08T22:18:53.660Z"}, {"name":"calculator_neumorphic_2.html","size":6733,"modified":1752009409190,"created":"2025-01-08T22:16:49.190Z"}, {"name":"calculator_minimalist_1.html","size":6174,"modified":1752009380423,"created":"2025-01-08T22:16:20.423Z"}, {"name":"calculator_glassmorphism_3.html","size":6943,"modified":1752009434734,"created":"2025-01-08T22:17:14.734Z"} ]; let lastUpdateCheck = Date.now(); let autoRefreshInterval; let isRefreshing = false; // MCP-Integrated Smart Refresh System function refreshGallery() { if (isRefreshing) return; isRefreshing = true; const refreshBtn = document.getElementById('refresh-btn'); const refreshIcon = document.getElementById('refresh-icon'); const refreshText = document.getElementById('refresh-text'); // Show loading state refreshBtn.disabled = true; refreshIcon.classList.add('refresh-indicator'); refreshText.textContent = 'Refreshing...'; // Check for file changes using MCP integration checkForFileChanges() .then(hasChanges => { if (hasChanges) { showToast('Changes detected! Reloading gallery...', 'success'); setTimeout(() => location.reload(), 1000); } else { showToast('Gallery is up to date', 'info'); } }) .catch(error => { showToast('Error checking for updates', 'error'); console.error('Refresh error:', error); }) .finally(() => { // Reset loading state isRefreshing = false; refreshBtn.disabled = false; refreshIcon.classList.remove('refresh-indicator'); refreshText.textContent = 'Refresh'; }); } async function checkForFileChanges() { try { const currentFiles = await getCurrentFileStats(); let hasChanges = false; // Compare with MCP-generated manifest for (const currentFile of currentFiles) { const manifestFile = fileManifest.find(f => f.name === currentFile.name); if (!manifestFile) { // New file detected hasChanges = true; showToast(`New file detected: ${currentFile.name}`, 'info'); break; } // Smart change detection with tolerance const timeDiff = Math.abs(currentFile.modified - manifestFile.modified); if (timeDiff > 1000) { // 1 second tolerance for file system delays markFileAsUpdated(currentFile.name); hasChanges = true; } } // Check for deleted files const currentFileNames = new Set(currentFiles.map(f => f.name)); for (const manifestFile of fileManifest) { if (!currentFileNames.has(manifestFile.name)) { hasChanges = true; showToast(`File deleted: ${manifestFile.name}`, 'warning'); break; } } return hasChanges; } catch (error) { console.error('Error checking file changes:', error); return false; } } async function getCurrentFileStats() { const iframes = document.querySelectorAll('iframe[data-file]'); const files = []; for (const iframe of iframes) { const fileName = iframe.getAttribute('data-file'); if (fileName) { let lastModified = Date.now(); let estimatedSize = 0; try { // Get file info from iframe document if (iframe.contentDocument?.lastModified) { lastModified = new Date(iframe.contentDocument.lastModified).getTime(); } // Check if iframe loaded successfully const iframeLoaded = iframe.contentDocument && iframe.contentDocument.readyState === 'complete'; if (!iframeLoaded) { lastModified = 0; // File might be missing } // Estimate file size from content if (iframe.contentDocument?.documentElement) { estimatedSize = iframe.contentDocument.documentElement.outerHTML.length; } files.push({ name: fileName, modified: lastModified, size: estimatedSize }); } catch (error) { // Cross-origin or access issues files.push({ name: fileName, modified: Date.now(), size: 0 }); } } } return files; } function toggleAutoRefresh() { const autoRefreshCheckbox = document.getElementById('auto-refresh'); if (autoRefreshCheckbox.checked) { // Start MCP-integrated auto-refresh autoRefreshInterval = setInterval(() => { if (!isRefreshing) { checkForFileChanges().then(hasChanges => { if (hasChanges) { showToast('Auto-refresh: Changes detected!', 'info'); setTimeout(() => location.reload(), 1000); } }); } }, 5000); showToast('MCP Auto-refresh enabled (5s interval)', 'success'); } else { if (autoRefreshInterval) { clearInterval(autoRefreshInterval); autoRefreshInterval = null; } showToast('Auto-refresh disabled', 'info'); } } function markFileAsUpdated(fileName) { const card = document.querySelector(`[data-file="${fileName}"]`); if (card) { // Add visual update indicator const indicator = document.createElement('div'); indicator.className = 'updated-indicator'; indicator.title = 'File updated'; card.style.position = 'relative'; card.appendChild(indicator); // Remove indicator after 5 seconds setTimeout(() => { indicator.remove(); }, 5000); showToast(`File updated: ${fileName}`, 'success'); } } // Initialize MCP-integrated gallery document.addEventListener('DOMContentLoaded', () => { // Restore auto-refresh state const autoRefreshEnabled = localStorage.getItem('autoRefresh') === 'true'; document.getElementById('auto-refresh').checked = autoRefreshEnabled; if (autoRefreshEnabled) { toggleAutoRefresh(); } // Save auto-refresh state changes document.getElementById('auto-refresh').addEventListener('change', () => { localStorage.setItem('autoRefresh', document.getElementById('auto-refresh').checked); }); console.log('🎨 Superdesign Gallery - MCP Integration Active'); console.log('📂 Monitoring', fileManifest.length, 'design files'); }); // Add CSS animations const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } `; document.head.appendChild(style); </script> </body> </html>

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jonthebeef/superdesign-mcp-claude-code'

If you have feedback or need assistance with the MCP directory API, please join our Discord server