@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Rajdhani:wght@300;500;700&display=swap'); :root { --bg-dark: #0a0a12; --panel-bg: rgba(20, 20, 30, 0.8); --primary-cyan: #00f3ff; --secondary-magenta: #bc13fe; --text-main: #e0e0e0; --text-dim: #888; --glass-border: 1px solid rgba(255, 255, 255, 0.1); --glow-opacity: 0.3; --glow-spread: 30px; --glow-border: 5px; } body { margin: 0; background-color: var(--bg-dark); color: var(--text-main); font-family: 'Rajdhani', sans-serif; height: 100vh; display: flex; flex-direction: column; overflow: hidden; background-image: radial-gradient(circle at 10% 20%, rgba(0, 243, 255, 0.15) 0%, transparent 25%), radial-gradient(circle at 90% 80%, rgba(188, 19, 254, 0.15) 0%, transparent 25%), radial-gradient(circle at 50% 50%, rgba(0, 243, 255, 0.05) 0%, transparent 50%); } body::before { content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 99999; border: 1px solid rgba(80, 80, 80, 0.1); box-sizing: border-box; } body.playing-A::before { border: none; box-shadow: 0 0 var(--glow-spread) rgba(0, 243, 255, var(--glow-opacity)), inset 0 0 var(--glow-spread) rgba(0, 243, 255, calc(var(--glow-opacity) * 0.8)); animation: pulse-cyan 3s ease-in-out infinite; } body.playing-B::before { border: none; box-shadow: 0 0 var(--glow-spread) rgba(188, 19, 254, var(--glow-opacity)), inset 0 0 var(--glow-spread) rgba(188, 19, 254, calc(var(--glow-opacity) * 0.8)); animation: pulse-magenta 3s ease-in-out infinite; } body.playing-A.playing-B::before { border: none; box-shadow: 0 0 var(--glow-spread) rgba(0, 243, 255, var(--glow-opacity)), 0 0 calc(var(--glow-spread) * 1.5) rgba(188, 19, 254, var(--glow-opacity)), inset 0 0 var(--glow-spread) rgba(0, 243, 255, calc(var(--glow-opacity) * 0.6)), inset 0 0 calc(var(--glow-spread) * 1.5) rgba(188, 19, 254, calc(var(--glow-opacity) * 0.6)); animation: pulse-both 3s ease-in-out infinite; } body.listener-glow::before { border: none; box-shadow: 0 0 var(--glow-spread) rgba(0, 80, 255, calc(var(--glow-opacity) * 1.5)), 0 0 calc(var(--glow-spread) * 1.5) rgba(188, 19, 254, calc(var(--glow-opacity) * 1.5)), 0 0 calc(var(--glow-spread) * 2.5) rgba(0, 243, 255, calc(var(--glow-opacity) * 0.5)), inset 0 0 var(--glow-spread) rgba(0, 80, 255, calc(var(--glow-opacity) * 1)), inset 0 0 calc(var(--glow-spread) * 1.5) rgba(188, 19, 254, calc(var(--glow-opacity) * 1)); animation: pulse-listener 4s ease-in-out infinite; } @keyframes pulse-listener { 0%, 100% { filter: hue-rotate(0deg) brightness(1.2); box-shadow: 0 0 var(--glow-spread) rgba(0, 80, 255, calc(var(--glow-opacity) * 1.5)), 0 0 calc(var(--glow-spread) * 1.5) rgba(188, 19, 254, calc(var(--glow-opacity) * 1.5)), inset 0 0 var(--glow-spread) rgba(0, 80, 255, calc(var(--glow-opacity) * 1)), inset 0 0 calc(var(--glow-spread) * 1.5) rgba(188, 19, 254, calc(var(--glow-opacity) * 1)); } 50% { filter: hue-rotate(15deg) brightness(1.8); box-shadow: 0 0 calc(var(--glow-spread) * 1.5) rgba(0, 120, 255, calc(var(--glow-opacity) * 2.2)), 0 0 calc(var(--glow-spread) * 2) rgba(220, 50, 255, calc(var(--glow-opacity) * 2.2)), 0 0 calc(var(--glow-spread) * 4) rgba(0, 243, 255, calc(var(--glow-opacity) * 1)), inset 0 0 calc(var(--glow-spread) * 1.5) rgba(0, 120, 255, calc(var(--glow-opacity) * 1.5)), inset 0 0 calc(var(--glow-spread) * 2) rgba(220, 50, 255, calc(var(--glow-opacity) * 1.5)); } } #start-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.95); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 1000; backdrop-filter: blur(10px); } .overlay-title { font-family: 'Orbitron', sans-serif; font-size: 3rem; color: var(--primary-cyan); text-shadow: 0 0 20px var(--primary-cyan); margin-bottom: 2rem; letter-spacing: 5px; } #start-btn { padding: 15px 40px; font-family: 'Orbitron', sans-serif; font-size: 1.2rem; background: transparent; color: var(--primary-cyan); border: 2px solid var(--primary-cyan); cursor: pointer; transition: all 0.3s; box-shadow: 0 0 15px rgba(0, 243, 255, 0.2); } #start-btn:hover { background: var(--primary-cyan); color: #000; box-shadow: 0 0 30px var(--primary-cyan); } header { display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; height: 60px; box-sizing: border-box; background: rgba(0, 0, 0, 0.5); border-bottom: 1px solid rgba(255, 255, 255, 0.05); } header h1 { font-family: 'Orbitron', sans-serif; color: #fff; margin: 0; font-size: 1.5rem; letter-spacing: 2px; } .status-bar { font-family: 'Orbitron', sans-serif; font-size: 0.8rem; color: #00ff00; text-shadow: 0 0 5px #00ff00; } /* LAYOUT GRID */ .app-container { display: grid; grid-template-columns: 320px 1fr 1fr; grid-template-rows: 1fr 80px; gap: 10px; padding: 10px; height: calc(100vh - 60px); /* Adjust based on header height */ min-height: 0; overflow: hidden; } /* LIBRARY SECTION */ .library-section { grid-row: 1 / -1; background: var(--panel-bg); border: 2px solid var(--primary-cyan); box-shadow: 0 0 20px rgba(0, 243, 255, 0.1); border-radius: 10px; display: flex; flex-direction: column; overflow: hidden; } .lib-header { padding: 15px; background: rgba(255, 255, 255, 0.02); border-bottom: var(--glass-border); display: flex; gap: 10px; align-items: center; } .lib-header input { flex: 1; padding: 10px; background: rgba(0, 0, 0, 0.3); border: 1px solid #333; color: #fff; border-radius: 4px; font-family: 'Rajdhani', sans-serif; } .refresh-btn { background: rgba(0, 243, 255, 0.1); border: 1px solid var(--primary-cyan); color: var(--primary-cyan); border-radius: 4px; padding: 8px 12px; cursor: pointer; font-size: 1.2rem; transition: all 0.3s; } .refresh-btn:hover { background: rgba(0, 243, 255, 0.2); box-shadow: 0 0 10px rgba(0, 243, 255, 0.3); } .refresh-btn.spinning { animation: spin 0.5s linear; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* YouTube Search */ .youtube-search-container { padding: 10px 15px; background: rgba(0, 0, 0, 0.3); border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .youtube-search-container input { width: 100%; padding: 10px; background: rgba(0, 0, 0, 0.5); border: 1px solid var(--primary-cyan); color: #fff; border-radius: 4px; font-family: 'Rajdhani', sans-serif; font-size: 0.9rem; box-shadow: 0 0 10px rgba(0, 243, 255, 0.2); transition: all 0.3s; } .youtube-search-container input:focus { outline: none; border-color: var(--primary-cyan); box-shadow: 0 0 15px rgba(0, 243, 255, 0.4); } .youtube-results { max-height: 300px; overflow-y: auto; margin-top: 10px; } .youtube-result-card { display: flex; align-items: center; gap: 10px; padding: 8px; background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.05); border-radius: 4px; margin-bottom: 6px; transition: all 0.2s; cursor: pointer; } .youtube-result-card:hover { background: rgba(255, 255, 255, 0.08); border-color: var(--primary-cyan); transform: translateX(2px); } .result-thumbnail { width: 80px; height: 60px; object-fit: cover; border-radius: 4px; border: 1px solid rgba(255, 255, 255, 0.1); } .result-info { flex: 1; min-width: 0; } .result-title { font-size: 0.85rem; font-weight: bold; color: #fff; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .result-channel { font-size: 0.75rem; color: #888; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .result-download-btn { padding: 8px 12px; background: rgba(0, 243, 255, 0.2); border: 1px solid var(--primary-cyan); color: var(--primary-cyan); border-radius: 4px; cursor: pointer; font-size: 1.2rem; transition: all 0.2s; flex-shrink: 0; } .result-download-btn:hover { background: rgba(0, 243, 255, 0.3); box-shadow: 0 0 10px rgba(0, 243, 255, 0.4); transform: scale(1.1); } .result-download-btn:active { transform: scale(0.95); } .search-loading, .search-error, .search-success, .search-empty { padding: 15px; text-align: center; border-radius: 4px; font-family: 'Orbitron', sans-serif; font-size: 0.9rem; } .search-loading { background: rgba(255, 187, 0, 0.1); color: #ffbb00; border: 1px solid rgba(255, 187, 0, 0.3); } .search-error { background: rgba(255, 68, 68, 0.1); color: #ff4444; border: 1px solid rgba(255, 68, 68, 0.3); } .search-success { background: rgba(0, 255, 0, 0.1); color: #00ff00; border: 1px solid rgba(0, 255, 0, 0.3); } .search-empty { background: rgba(255, 255, 255, 0.03); color: #666; border: 1px solid rgba(255, 255, 255, 0.05); } .library-list { flex: 1; overflow-y: auto; padding: 10px; } .track-row { background: rgba(255, 255, 255, 0.03); margin-bottom: 8px; padding: 10px; border-radius: 4px; transition: 0.2s; border-left: 3px solid transparent; } .track-row:hover { background: rgba(255, 255, 255, 0.08); border-left: 3px solid var(--primary-cyan); } .track-name { display: block; font-weight: bold; margin-bottom: 5px; color: #fff; } .load-actions { display: flex; gap: 5px; } .load-btn { flex: 1; border: none; padding: 4px; font-size: 0.7rem; cursor: pointer; font-family: 'Orbitron', sans-serif; opacity: 0.7; transition: 0.2s; } .btn-a { background: rgba(0, 243, 255, 0.2); color: var(--primary-cyan); border: 1px solid var(--primary-cyan); } .btn-b { background: rgba(188, 19, 254, 0.2); color: var(--secondary-magenta); border: 1px solid var(--secondary-magenta); } .load-btn:hover { opacity: 1; box-shadow: 0 0 10px currentColor; } /* DECKS */ .deck { background: var(--panel-bg); border: var(--glass-border); border-radius: 8px; padding: 8px; display: flex; flex-direction: column; position: relative; transition: box-shadow 0.3s; min-height: 0; overflow-y: auto; } #deck-A { border: 2px solid var(--primary-cyan); box-shadow: 0 0 25px rgba(0, 243, 255, 0.3); } #deck-B { border: 2px solid var(--secondary-magenta); box-shadow: 0 0 25px rgba(188, 19, 254, 0.3); } .deck.playing { box-shadow: 0 0 45px rgba(0, 243, 255, 0.5); } #deck-B.playing { box-shadow: 0 0 45px rgba(188, 19, 254, 0.5); } .deck-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; background: #000; padding: 4px 6px; border-radius: 4px; border: 1px solid #333; } .deck-title { font-family: 'Orbitron', sans-serif; font-size: 1rem; font-weight: bold; } .title-a { color: var(--primary-cyan); } .title-b { color: var(--secondary-magenta); } .track-display { font-family: 'Rajdhani', monospace; color: #fff; font-size: 0.9rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; max-width: 200px; } .blink { animation: blinker 1s linear infinite; } @keyframes blinker { 50% { opacity: 0; } } /* DISK */ .disk-container { display: flex; justify-content: center; margin-bottom: 6px; } .dj-disk { width: 90px; height: 90px; background: radial-gradient(circle, #222 10%, #111 11%, #000 100%); border-radius: 50%; border: 2px solid #333; display: flex; justify-content: center; align-items: center; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); cursor: pointer; position: relative; transition: transform 0.2s; } .dj-disk::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 50%; background: repeating-radial-gradient(#111 0, #111 2px, #181818 3px, #181818 4px); opacity: 0.3; pointer-events: none; } .dj-disk:active { transform: scale(0.95); } .disk-label { width: 38px; height: 38px; background: #fff; border-radius: 50%; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 0.9rem; color: #000; font-family: 'Orbitron', sans-serif; z-index: 2; border: 2px solid #ccc; } #deck-A .disk-label { background: var(--primary-cyan); box-shadow: 0 0 10px var(--primary-cyan); } #deck-B .disk-label { background: var(--secondary-magenta); box-shadow: 0 0 10px var(--secondary-magenta); } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .deck.playing .dj-disk { animation: rotate 2s linear infinite; box-shadow: 0 0 20px rgba(0, 243, 255, 0.3); } #deck-B.playing .dj-disk { box-shadow: 0 0 20px rgba(188, 19, 254, 0.3); } canvas { width: 100%; height: 60px; background: #000; border-radius: 4px; margin-bottom: 6px; border: 1px solid #333; } /* SEARCH & DOWNLOAD */ .start-group { position: relative; margin-bottom: 4px; display: flex; flex-direction: column; gap: 4px; } .search-input { width: 100%; padding: 6px 8px; background: #111; border: 1px solid #444; color: #fff; font-family: 'Rajdhani', sans-serif; font-size: 0.85rem; border-radius: 4px; box-sizing: border-box; } .download-btn { width: 100%; padding: 6px; background: var(--primary-cyan); border: 1px solid var(--primary-cyan); font-weight: bold; cursor: pointer; font-size: 0.8rem; font-family: 'Orbitron', sans-serif; color: #000; border-radius: 4px; transition: all 0.3s; box-shadow: 0 0 10px rgba(0, 243, 255, 0.2); } .download-btn:hover { box-shadow: 0 0 20px rgba(0, 243, 255, 0.5); transform: translateY(-1px); } .download-btn:active { transform: translateY(0); } #deck-B .download-btn { background: var(--secondary-magenta); border-color: var(--secondary-magenta); color: #fff; box-shadow: 0 0 10px rgba(188, 19, 254, 0.2); } #deck-B .download-btn:hover { box-shadow: 0 0 20px rgba(188, 19, 254, 0.5); } .quality-selector { background: rgba(10, 10, 12, 0.8); color: var(--text-color); border: 1px solid rgba(255, 255, 255, 0.2); padding: 4px 6px; border-radius: 4px; font-family: 'Rajdhani', sans-serif; font-size: 0.8rem; outline: none; cursor: pointer; -webkit-appearance: none; -moz-appearance: none; appearance: none; } .download-status .loading { color: #ffa500; animation: pulse 1.5s ease-in-out infinite; } .download-status .success { color: #00ff00; font-weight: bold; } .download-status .error { color: #ff4444; font-weight: bold; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* CONTROLS */ .controls-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-top: auto; } .fader-group { display: flex; flex-direction: column; align-items: center; } .fader-group label { font-size: 0.65rem; color: #888; margin-bottom: 3px; } input[type=range] { width: 100%; cursor: pointer; } /* EQ */ .eq-container { display: flex; justify-content: space-between; margin: 4px 0; } .eq-band { display: flex; flex-direction: column; align-items: center; width: 30%; } .eq-band input { writing-mode: bt-lr; /* IE */ -webkit-appearance: slider-vertical; appearance: slider-vertical; width: 8px; height: 60px; } /* TRANSPORT */ .transport { display: flex; gap: 4px; margin-top: 3px; } .big-btn { flex: 1; padding: 6px; border: none; font-family: 'Orbitron', sans-serif; font-weight: bold; cursor: pointer; font-size: 0.85rem; transition: 0.1s; background: #222; color: #666; border-bottom: 2px solid #000; } .big-btn:active { transform: translateY(2px); border-bottom: 1px solid #000; } .play-btn:hover { background: #333; color: #fff; } .deck.playing .play-btn { background: var(--primary-cyan); color: #000; box-shadow: 0 0 15px var(--primary-cyan); } #deck-B.playing .play-btn { background: var(--secondary-magenta); color: #fff; box-shadow: 0 0 15px var(--secondary-magenta); } /* CROSSFADER */ .mixer-section { grid-column: 2 / 4; grid-row: 2; background: linear-gradient(to bottom, #1a1a1a, #0a0a0a); border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 15px 40px; border: 2px solid #444; position: relative; box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.8), inset 0 2px 10px rgba(255, 255, 255, 0.05); } .mixer-section::before { content: 'A'; position: absolute; left: 20px; font-family: 'Orbitron', sans-serif; font-size: 1.5rem; font-weight: bold; color: var(--primary-cyan); text-shadow: 0 0 10px var(--primary-cyan); } .mixer-section::after { content: 'B'; position: absolute; right: 20px; font-family: 'Orbitron', sans-serif; font-size: 1.5rem; font-weight: bold; color: var(--secondary-magenta); text-shadow: 0 0 10px var(--secondary-magenta); } .xfader { width: 100%; appearance: none; height: 12px; background: linear-gradient(to right, var(--primary-cyan) 0%, #333 50%, var(--secondary-magenta) 100%); border-radius: 6px; outline: none; border: 2px solid #555; box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5), 0 0 15px rgba(255, 255, 255, 0.1); } .xfader::-webkit-slider-thumb { -webkit-appearance: none; width: 60px; height: 40px; background: linear-gradient(145deg, #aaa, #666); border: 3px solid #ccc; border-radius: 8px; cursor: grab; box-shadow: 0 0 25px rgba(255, 255, 255, 0.4), inset 0 -3px 8px rgba(0, 0, 0, 0.6); transition: all 0.1s; } .xfader::-webkit-slider-thumb:hover { background: linear-gradient(145deg, #ccc, #888); box-shadow: 0 0 35px rgba(255, 255, 255, 0.6); } .xfader::-webkit-slider-thumb:active { cursor: grabbing; box-shadow: 0 0 40px rgba(255, 255, 255, 0.8); transform: scale(1.05); } .xfader::-moz-range-thumb { width: 60px; height: 40px; background: linear-gradient(145deg, #aaa, #666); border: 3px solid #ccc; border-radius: 8px; cursor: grab; box-shadow: 0 0 25px rgba(255, 255, 255, 0.4); } /* ====== NEW PROFESSIONAL DJ FEATURES ====== */ /* Waveform Display */ .waveform-container { position: relative; background: #000; border: 1px solid #333; border-radius: 4px; margin-bottom: 4px; padding: 3px; } .waveform-canvas { width: 100%; height: 40px; display: block; } .playhead { position: absolute; top: 10px; bottom: 10px; width: 2px; background: #ff0; box-shadow: 0 0 10px #ff0; pointer-events: none; left: 0%; transform: translateX(-1px); transition: left 0.1s linear; } .time-display { margin-top: 3px; display: flex; justify-content: space-between; font-family: 'Orbitron', monospace; font-size: 0.75rem; color: #0ff; } .bpm-display { color: #f0f; font-weight: bold; } /* Hot Cues */ .hot-cues { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; margin-bottom: 4px; } .cue-btn { padding: 6px; background: rgba(255, 255, 255, 0.05); border: 1px solid #444; color: #888; font-family: 'Orbitron', sans-serif; font-size: 0.7rem; cursor: pointer; transition: all 0.2s; border-radius: 4px; } .cue-btn:hover { background: rgba(255, 255, 255, 0.1); border-color: #666; } .cue-btn.cue-set { background: rgba(0, 243, 255, 0.2); border-color: var(--primary-cyan); color: var(--primary-cyan); box-shadow: 0 0 10px rgba(0, 243, 255, 0.3); } #deck-B .cue-btn.cue-set { background: rgba(188, 19, 254, 0.2); border-color: var(--secondary-magenta); color: var(--secondary-magenta); box-shadow: 0 0 10px rgba(188, 19, 254, 0.3); } .cue-btn.cue-triggered { transform: scale(0.95); box-shadow: 0 0 20px rgba(0, 243, 255, 0.8) !important; } #deck-B .cue-btn.cue-triggered { box-shadow: 0 0 20px rgba(188, 19, 254, 0.8) !important; } @keyframes flash { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; transform: scale(1.05); } } /* Loop Controls */ .loop-controls { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; margin-bottom: 4px; } .loop-btn { padding: 5px; background: rgba(255, 100, 0, 0.1); border: 1px solid #883300; color: #ff6600; font-family: 'Orbitron', sans-serif; font-size: 0.7rem; cursor: pointer; transition: all 0.2s; border-radius: 4px; } .loop-btn:hover { background: rgba(255, 100, 0, 0.2); border-color: #ff6600; box-shadow: 0 0 10px rgba(255, 100, 0, 0.3); } .loop-btn:active { transform: scale(0.95); } /* Auto-Loop Beat Controls */ .auto-loop-controls { margin-bottom: 4px; padding: 6px; background: rgba(0, 0, 0, 0.3); border-radius: 6px; border: 1px solid rgba(255, 255, 255, 0.05); } .auto-loop-label { display: block; font-size: 0.6rem; color: #666; font-family: 'Orbitron', sans-serif; margin-bottom: 4px; text-align: center; letter-spacing: 1px; } .auto-loop-buttons { display: flex; justify-content: space-between; gap: 3px; } .auto-loop-btn { flex: 1; aspect-ratio: 1; min-width: 0; padding: 0; background: rgba(255, 255, 255, 0.03); border: 1.5px solid #333; border-radius: 50%; color: #666; font-family: 'Orbitron', sans-serif; font-size: 0.65rem; font-weight: bold; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; } .auto-loop-btn:hover { background: rgba(255, 255, 255, 0.08); border-color: #555; color: #aaa; transform: scale(1.1); } /* Active state for Deck A */ #deck-A .auto-loop-btn.active { background: rgba(0, 243, 255, 0.2); border-color: var(--primary-cyan); color: var(--primary-cyan); box-shadow: 0 0 15px rgba(0, 243, 255, 0.5), inset 0 0 10px rgba(0, 243, 255, 0.2); transform: scale(1.05); } #deck-A .auto-loop-btn:hover { border-color: var(--primary-cyan); color: var(--primary-cyan); } /* Active state for Deck B */ #deck-B .auto-loop-btn.active { background: rgba(188, 19, 254, 0.2); border-color: var(--secondary-magenta); color: var(--secondary-magenta); box-shadow: 0 0 15px rgba(188, 19, 254, 0.5), inset 0 0 10px rgba(188, 19, 254, 0.2); transform: scale(1.05); } #deck-B .auto-loop-btn:hover { border-color: var(--secondary-magenta); color: var(--secondary-magenta); } .auto-loop-btn:active { transform: scale(0.95); } /* Pitch Bend Buttons */ .pitch-bend-buttons { display: flex; gap: 4px; margin-top: 3px; justify-content: center; } .pitch-bend { padding: 4px 12px; background: #222; border: 1px solid #444; color: #fff; font-family: 'Orbitron', sans-serif; font-size: 0.85rem; font-weight: bold; cursor: pointer; border-radius: 4px; transition: all 0.1s; } .pitch-bend:hover { background: #333; border-color: #666; } .pitch-bend:active { background: var(--primary-cyan); color: #000; box-shadow: 0 0 15px rgba(0, 243, 255, 0.5); } #deck-B .pitch-bend:active { background: var(--secondary-magenta); color: #fff; box-shadow: 0 0 15px rgba(188, 19, 254, 0.5); } /* Sync Button */ .sync-btn { background: rgba(0, 255, 0, 0.1) !important; border: 1px solid #0a0 !important; color: #0f0 !important; } .sync-btn:hover { background: rgba(0, 255, 0, 0.2) !important; box-shadow: 0 0 15px rgba(0, 255, 0, 0.3) !important; } .reset-btn { background: rgba(255, 140, 0, 0.1) !important; border: 1px solid #ff8c00 !important; color: #ffa500 !important; } .reset-btn:hover { background: rgba(255, 140, 0, 0.2) !important; box-shadow: 0 0 15px rgba(255, 140, 0, 0.4) !important; transform: rotate(15deg); } .reset-btn:active { transform: rotate(360deg) scale(0.95); } /* Transport Buttons - Make room for 4 buttons */ .transport { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 8px; margin-top: 10px; } /* Spinning Animation for Refresh */ @keyframes rotate360 { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .spinning { animation: rotate360 0.5s linear; } /* Quality Selector and Download Controls */ .download-controls { display: flex; gap: 8px; } .quality-selector { background: #222; border: 1px solid #444; color: #0ff; padding: 8px; border-radius: 4px; font-family: 'Orbitron', sans-serif; font-size: 0.85rem; cursor: pointer; } .quality-selector option { background: #111; color: #0ff; } #deck-B .quality-selector { color: #f0f; } /* Enhanced Crossfader Visibility */ .mixer-section { background: linear-gradient(to bottom, #1a1a1a, #0a0a0a) !important; border: 2px solid #333 !important; padding: 20px 40px !important; box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.5) !important; } .xfader { height: 8px !important; background: linear-gradient(to right, var(--primary-cyan) 0%, #555 50%, var(--secondary-magenta) 100%) !important; border-radius: 4px !important; } .xfader::-webkit-slider-thumb { width: 60px !important; height: 40px !important; background: linear-gradient(145deg, #888, #555) !important; border: 3px solid #aaa !important; border-radius: 6px !important; box-shadow: 0 0 20px rgba(255, 255, 255, 0.3), inset 0 -2px 5px rgba(0, 0, 0, 0.5) !important; cursor: grab !important; } .xfader::-webkit-slider-thumb:active { cursor: grabbing !important; box-shadow: 0 0 30px rgba(255, 255, 255, 0.5) !important; } .xfader::-moz-range-thumb { width: 60px !important; height: 40px !important; background: linear-gradient(145deg, #888, #555) !important; border: 3px solid #aaa !important; border-radius: 6px !important; box-shadow: 0 0 20px rgba(255, 255, 255, 0.3) !important; cursor: grab !important; } /* Waveform drag cursor */ .waveform-canvas:active { cursor: grabbing !important; } /* COMPACT MODE - Make everything fit at 100% zoom */ .deck { padding: 15px !important; gap: 10px !important; } .waveform-container { margin-bottom: 10px !important; padding: 5px !important; } .waveform-canvas { height: 60px !important; } .hot-cues { gap: 5px !important; margin-bottom: 10px !important; } .cue-btn { padding: 6px !important; font-size: 0.7rem !important; } .loop-controls { gap: 5px !important; margin-bottom: 10px !important; } .loop-btn { padding: 6px !important; font-size: 0.7rem !important; } .start-group { margin-bottom: 10px !important; } .search-input { padding: 8px !important; font-size: 0.85rem !important; } .download-btn { padding: 8px 15px !important; font-size: 0.85rem !important; } .controls-grid { gap: 10px !important; margin-bottom: 10px !important; } .eq-container { gap: 8px !important; } .eq-band input { height: 80px !important; } .fader-group label { font-size: 0.75rem !important; margin-bottom: 5px !important; } .transport { gap: 8px !important; margin-top: 8px !important; } .big-btn { padding: 10px !important; font-size: 0.9rem !important; } .disk-container { margin: 10px 0 !important; } .dj-disk { width: 120px !important; height: 120px !important; } .mixer-section { padding: 15px 40px !important; } .library-section { padding: 15px !important; } .track-row { padding: 8px !important; margin-bottom: 6px !important; } .track-name { font-size: 0.85rem !important; } .load-btn { padding: 6px 12px !important; font-size: 0.75rem !important; } #viz-A, #viz-B { height: 80px !important; } .pitch-bend-buttons { margin-top: 3px !important; } .pitch-bend { padding: 4px 12px !important; font-size: 0.8rem !important; } .quality-selector { padding: 6px !important; font-size: 0.75rem !important; } .download-controls { gap: 5px !important; } /* === VOLUME FADERS === */ .volume-fader { writing-mode: bt-lr; -webkit-appearance: slider-vertical; appearance: slider-vertical; width: 30px !important; height: 100px !important; background: linear-gradient(to top, #ff0000, #ffff00, #00ff00); border-radius: 5px; } /* === FILTER KNOBS === */ .filter-knobs { display: flex; flex-direction: column; gap: 10px; } .filter-knob { display: flex; flex-direction: column; align-items: center; } .filter-knob label { font-size: 0.7rem; margin-bottom: 5px; color: #ff8800; font-family: 'Orbitron', sans-serif; } .filter-slider { width: 100px; height: 6px; background: linear-gradient(to right, #ff8800, #ffcc00); border-radius: 3px; outline: none; } .filter-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; background: #ff8800; border: 2px solid #ffaa00; border-radius: 50%; cursor: pointer; box-shadow: 0 0 10px rgba(255, 136, 0, 0.5); } .filter-slider::-moz-range-thumb { width: 20px; height: 20px; background: #ff8800; border: 2px solid #ffaa00; border-radius: 50%; cursor: pointer; } /* === SAMPLE PADS === */ .sample-pads { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 10px 0; } .sample-pad { padding: 10px 5px; background: linear-gradient(145deg, #333, #1a1a1a); border: 2px solid #444; color: #fff; font-family: 'Orbitron', sans-serif; font-size: 0.75rem; cursor: pointer; border-radius: 6px; transition: all 0.1s; box-shadow: inset 0 -2px 5px rgba(0, 0, 0, 0.3); } .sample-pad:hover { background: linear-gradient(145deg, #444, #2a2a2a); border-color: #666; box-shadow: 0 0 15px rgba(255, 255, 255, 0.2); } .sample-pad:active { transform: scale(0.9); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 20px rgba(0, 255, 255, 0.4); } #deck-A .sample-pad:active { box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 20px var(--primary-cyan); } #deck-B .sample-pad:active { box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 20px var(--secondary-magenta); } /* Adjust controls grid for new elements */ .controls-grid { display: grid; grid-template-columns: auto repeat(3, 1fr) auto; gap: 15px; align-items: center; } @keyframes glow-pulse { 0%, 100% { box-shadow: inset 0 0 30px rgba(0, 243, 255, 0.3), inset 0 0 60px rgba(188, 19, 254, 0.2), 0 0 30px rgba(0, 243, 255, 0.4), 0 0 60px rgba(188, 19, 254, 0.3); } 50% { box-shadow: inset 0 0 40px rgba(0, 243, 255, 0.5), inset 0 0 80px rgba(188, 19, 254, 0.4), 0 0 40px rgba(0, 243, 255, 0.6), 0 0 80px rgba(188, 19, 254, 0.5); } } /* === DOWNLOAD PROGRESS BAR === */ .download-status { min-height: 30px; margin-top: 8px; position: relative; text-align: center; font-family: 'Orbitron', sans-serif; color: #0ff; } .progress-container { width: 100%; height: 20px; background: rgba(0, 0, 0, 0.5); border-radius: 10px; overflow: hidden; border: 1px solid #333; position: relative; } .progress-bar { height: 100%; background: linear-gradient(90deg, var(--primary-cyan) 0%, var(--secondary-magenta) 100%); border-radius: 10px; transition: width 0.3s ease; box-shadow: 0 0 10px var(--primary-cyan); position: relative; overflow: hidden; } .progress-bar::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.3) 50%, transparent 100%); animation: shimmer 1.5s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } .progress-text { font-size: 0.8rem; font-family: 'Orbitron', sans-serif; color: #fff; padding: 5px; } #deck-B .progress-bar { background: linear-gradient(90deg, var(--secondary-magenta) 0%, var(--primary-cyan) 100%); box-shadow: 0 0 10px var(--secondary-magenta); } /* Remove static border, replace with dynamic one */ /* === ULTRA COMPACT MODE - Ensure crossfader visible at 100% zoom === */ .deck-header { padding: 8px !important; margin-bottom: 8px !important; } .deck-title { font-size: 1rem !important; } .track-display { font-size: 0.75rem !important; } .waveform-container { margin-bottom: 6px !important; padding: 3px !important; } .waveform-canvas { height: 50px !important; } .time-display { font-size: 0.75rem !important; margin-top: 3px !important; } .disk-container { margin: 6px 0 !important; } .dj-disk { width: 100px !important; height: 100px !important; } .disk-label { font-size: 1.5rem !important; } #viz-A, #viz-B { height: 60px !important; margin-bottom: 6px !important; } .hot-cues { gap: 4px !important; margin-bottom: 6px !important; } .cue-btn { padding: 4px !important; font-size: 0.65rem !important; } .loop-controls { gap: 4px !important; margin-bottom: 6px !important; } .loop-btn { padding: 4px !important; font-size: 0.65rem !important; } .start-group { margin-bottom: 6px !important; } .search-input { padding: 6px !important; font-size: 0.8rem !important; margin-bottom: 4px !important; } .download-btn { padding: 6px 12px !important; font-size: 0.8rem !important; } .quality-selector { padding: 5px !important; font-size: 0.7rem !important; } .controls-grid { gap: 8px !important; margin-bottom: 6px !important; } .eq-band input { height: 70px !important; } .eq-band label { font-size: 0.65rem !important; } .volume-fader { height: 70px !important; } .fader-group label { font-size: 0.65rem !important; margin-bottom: 3px !important; } .filter-knob label { font-size: 0.6rem !important; margin-bottom: 3px !important; } .filter-slider { width: 80px !important; } .sample-pads { gap: 4px !important; margin: 6px 0 !important; } .sample-pad { padding: 6px 3px !important; font-size: 0.65rem !important; } .transport { gap: 6px !important; margin-top: 6px !important; } .big-btn { padding: 8px !important; font-size: 0.85rem !important; } .pitch-bend { padding: 3px 10px !important; font-size: 0.75rem !important; } .mixer-section { padding: 12px 40px !important; min-height: auto !important; } .mixer-section::before, .mixer-section::after { font-size: 1.2rem !important; } .library-section { padding: 10px !important; } .library-header { padding: 8px !important; margin-bottom: 8px !important; } .track-row { padding: 6px !important; margin-bottom: 4px !important; } .track-name { font-size: 0.8rem !important; } .load-btn { padding: 5px 10px !important; font-size: 0.7rem !important; } /* Make main container fit better */ #app-container { padding: 10px !important; gap: 10px !important; } /* === SETTINGS PANEL === */ /* === MOBILE RESPONSIVE & TABS === */ .mobile-tabs { display: none; position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); width: 90%; max-width: 400px; background: rgba(15, 15, 25, 0.85); border: 1px solid rgba(0, 243, 255, 0.3); border-radius: 50px; z-index: 10003; justify-content: space-around; padding: 8px; backdrop-filter: blur(15px); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5), 0 0 20px rgba(0, 243, 255, 0.1); } .tab-btn { background: none; border: none; color: var(--text-dim); font-family: 'Orbitron', sans-serif; font-size: 0.65rem; padding: 10px; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; border-radius: 40px; } .tab-icon { font-size: 1.2rem; margin-bottom: 2px; } .tab-btn.active { color: var(--primary-cyan); background: rgba(0, 243, 255, 0.1); text-shadow: 0 0 10px var(--primary-cyan); box-shadow: inset 0 0 10px rgba(0, 243, 255, 0.2); } @media (max-width: 1024px) { body { height: 100vh; overflow: hidden; /* Prevent body scroll, use container scroll */ } body::before { border-width: 2px; } .app-container { grid-template-columns: 1fr; grid-template-rows: 1fr; gap: 0; padding: 5px; padding-bottom: 90px; height: 100vh; overflow-y: auto; } .mobile-tabs { display: flex; } .library-section, #deck-A, #deck-B, .mixer-section { display: none; width: 100%; height: 100%; } .app-container.show-library .library-section { display: flex; } .app-container.show-deck-A #deck-A { display: flex; } .app-container.show-deck-B #deck-B { display: flex; } /* Mixer integration: Show mixer combined with active deck in a scrollable view */ .app-container.show-deck-A .mixer-section, .app-container.show-deck-B .mixer-section { display: flex; padding: 20px !important; margin-top: 20px; border-radius: 15px; background: rgba(0, 0, 0, 0.3); } .library-section { height: calc(100vh - 120px); } .deck { padding: 15px; min-height: min-content; } .dj-disk { width: 180px; height: 180px; margin: 20px auto; } .waveform-container { height: 100px; } .controls-grid { grid-template-columns: 1fr 1fr; gap: 15px; } .big-btn { padding: 15px !important; font-size: 1rem !important; } .settings-btn { bottom: 100px; right: 20px; width: 50px; height: 50px; } .volume-fader { height: 220px !important; } /* Library specific mobile fixes */ .track-row { flex-direction: row; justify-content: space-between; padding: 12px !important; background: rgba(255, 255, 255, 0.03); margin-bottom: 8px; border-radius: 8px; } .load-actions { gap: 5px; } .load-btn { font-size: 0.6rem !important; padding: 5px 8px !important; } .track-name { font-size: 0.9rem !important; max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .mixer-controls { gap: 20px !important; } .settings-btn { bottom: 120px !important; } .lib-header { padding: 10px !important; flex-direction: column; gap: 8px !important; } .lib-header input { width: 100%; background: rgba(0, 0, 0, 0.5) !important; border: 1px solid var(--primary-cyan) !important; box-shadow: 0 0 10px rgba(0, 243, 255, 0.1) inset; } } /* ========== LIVE STREAMING CONTROLS ========== */ /* Streaming Button */ .streaming-btn { position: fixed; bottom: 25px; right: 100px; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(145deg, #222, #111); border: 2px solid var(--secondary-magenta); color: var(--secondary-magenta); font-size: 1.8rem; cursor: pointer; z-index: 10000; box-shadow: 0 0 20px rgba(188, 19, 254, 0.4); transition: all 0.3s; display: flex; align-items: center; justify-content: center; } .streaming-btn:hover { transform: scale(1.1); box-shadow: 0 0 30px rgba(188, 19, 254, 0.6); } .streaming-btn:active { transform: scale(0.95); } /* Streaming Panel */ .streaming-panel { position: fixed; top: 0; right: -400px; height: 100vh; width: 380px; background: rgba(10, 10, 20, 0.98); border-left: 2px solid var(--secondary-magenta); padding: 30px; z-index: 10001; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); backdrop-filter: blur(15px); overflow-y: auto; } .streaming-panel.active { right: 0 !important; } .streaming-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; border-bottom: 1px solid rgba(188, 19, 254, 0.3); padding-bottom: 15px; font-family: 'Orbitron', sans-serif; font-size: 1.2rem; color: var(--secondary-magenta); } .close-streaming { background: none; border: none; color: var(--text-dim); font-size: 1.5rem; cursor: pointer; transition: all 0.3s; } .close-streaming:hover { color: var(--secondary-magenta); transform: rotate(90deg); } .streaming-content { display: flex; flex-direction: column; gap: 25px; } /* Broadcast Controls */ .broadcast-controls { display: flex; flex-direction: column; gap: 15px; } .broadcast-btn { padding: 20px; background: linear-gradient(145deg, #1a1a1a, #0a0a0a); border: 2px solid var(--secondary-magenta); color: var(--secondary-magenta); font-family: 'Orbitron', sans-serif; font-size: 1.1rem; font-weight: bold; cursor: pointer; border-radius: 10px; transition: all 0.3s; display: flex; align-items: center; justify-content: center; gap: 10px; box-shadow: 0 0 20px rgba(188, 19, 254, 0.2); } .broadcast-btn:hover { background: linear-gradient(145deg, #2a2a2a, #1a1a1a); box-shadow: 0 0 30px rgba(188, 19, 254, 0.4); transform: translateY(-2px); } .broadcast-btn.active { background: var(--secondary-magenta); color: #000; box-shadow: 0 0 40px rgba(188, 19, 254, 0.6); animation: pulse-broadcast 2s ease-in-out infinite; } @keyframes pulse-broadcast { 0%, 100% { box-shadow: 0 0 40px rgba(188, 19, 254, 0.6); } 50% { box-shadow: 0 0 60px rgba(188, 19, 254, 0.9); } } .broadcast-icon { font-size: 1.3rem; } .broadcast-btn.active .broadcast-icon { animation: blink-red 1.5s ease-in-out infinite; } @keyframes blink-red { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } } .broadcast-status { text-align: center; font-family: 'Rajdhani', sans-serif; font-size: 0.9rem; color: var(--text-dim); padding: 8px; background: rgba(0, 0, 0, 0.3); border-radius: 5px; } .broadcast-status.live { color: var(--secondary-magenta); font-weight: bold; text-shadow: 0 0 10px var(--secondary-magenta); } /* Listener Info */ .listener-info { background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(188, 19, 254, 0.3); border-radius: 10px; padding: 20px; } .listener-count { display: flex; align-items: center; justify-content: center; gap: 10px; font-family: 'Orbitron', sans-serif; font-size: 2rem; color: var(--secondary-magenta); } .count-icon { font-size: 2.5rem; } .count-label { font-size: 0.9rem; color: var(--text-dim); font-family: 'Rajdhani', sans-serif; } /* Stream URL Section */ .stream-url-section { display: flex; flex-direction: column; gap: 10px; } .stream-url-section label { font-size: 0.9rem; color: var(--text-dim); } .url-copy-group { display: flex; gap: 5px; } .url-copy-group input { flex: 1; padding: 10px; background: rgba(0, 0, 0, 0.5); border: 1px solid rgba(188, 19, 254, 0.3); color: var(--text-main); border-radius: 5px; font-family: 'Rajdhani', monospace; font-size: 0.85rem; } .copy-btn { padding: 10px 15px; background: rgba(188, 19, 254, 0.2); border: 1px solid var(--secondary-magenta); color: var(--secondary-magenta); border-radius: 5px; cursor: pointer; font-size: 1.2rem; transition: all 0.3s; } .copy-btn:hover { background: rgba(188, 19, 254, 0.3); box-shadow: 0 0 15px rgba(188, 19, 254, 0.4); } .copy-btn:active { transform: scale(0.95); } /* Stream Settings */ .stream-settings { padding: 15px; background: rgba(0, 0, 0, 0.3); border-radius: 8px; } .stream-settings label { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 1rem; } .stream-settings input[type="checkbox"] { width: 20px; height: 20px; cursor: pointer; } /* Quality Selector */ .quality-selector-group { display: flex; flex-direction: column; gap: 8px; margin-top: 15px; padding-top: 15px; border-top: 1px solid rgba(188, 19, 254, 0.2); } .quality-selector-group label { font-size: 0.9rem; color: var(--text-dim); margin-bottom: 5px; } .stream-quality-select { padding: 10px; background: rgba(0, 0, 0, 0.5); border: 1px solid var(--secondary-magenta); color: var(--text-main); border-radius: 5px; font-family: 'Rajdhani', sans-serif; font-size: 1rem; cursor: pointer; transition: all 0.3s; } .stream-quality-select:hover { background: rgba(0, 0, 0, 0.7); border-color: #ff00ff; box-shadow: 0 0 10px rgba(188, 19, 254, 0.3); } .stream-quality-select:focus { outline: none; box-shadow: 0 0 15px rgba(188, 19, 254, 0.5); } .quality-hint { font-size: 0.75rem; color: var(--text-dim); font-style: italic; opacity: 0.7; } /* ========== LISTENER MODE ========== */ .listener-mode { position: fixed; inset: 0; background: linear-gradient(135deg, #0a0a12 0%, #1a0a1a 100%); z-index: 10010; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px; } .listener-header { text-align: center; margin-bottom: 40px; } .listener-header h1 { font-family: 'Orbitron', sans-serif; font-size: 3rem; color: var(--secondary-magenta); text-shadow: 0 0 30px var(--secondary-magenta); margin: 0 0 20px 0; } .glow-text { color: #fff; text-shadow: 0 0 10px var(--secondary-magenta), 0 0 20px var(--secondary-magenta); animation: text-glow-pulse 2s infinite ease-in-out; } @keyframes text-glow-pulse { 0%, 100% { opacity: 0.8; text-shadow: 0 0 10px var(--secondary-magenta); } 50% { opacity: 1; text-shadow: 0 0 15px var(--secondary-magenta), 0 0 30px var(--secondary-magenta); } } .live-indicator { display: inline-flex; align-items: center; gap: 10px; padding: 10px 20px; background: rgba(188, 19, 254, 0.2); border: 2px solid var(--secondary-magenta); border-radius: 25px; font-family: 'Orbitron', sans-serif; font-size: 1.2rem; color: var(--secondary-magenta); box-shadow: 0 0 20px rgba(188, 19, 254, 0.4); } .pulse-dot { width: 12px; height: 12px; background: var(--secondary-magenta); border-radius: 50%; animation: pulse-dot 1.5s ease-in-out infinite; } @keyframes pulse-dot { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.7; } } .listener-content { max-width: 600px; width: 100%; background: rgba(10, 10, 20, 0.8); border: 2px solid var(--secondary-magenta); border-radius: 20px; padding: 40px; box-shadow: 0 0 40px rgba(188, 19, 254, 0.3); backdrop-filter: blur(10px); } .now-playing { text-align: center; font-family: 'Orbitron', sans-serif; font-size: 1.5rem; color: var(--text-main); margin-bottom: 30px; padding: 20px; background: rgba(0, 0, 0, 0.3); border-radius: 10px; min-height: 60px; display: flex; align-items: center; justify-content: center; } .volume-control { margin-bottom: 20px; } .volume-control label { display: block; margin-bottom: 10px; font-size: 1.1rem; color: var(--text-dim); } .volume-control input[type="range"] { width: 100%; height: 8px; } .connection-status { text-align: center; font-family: 'Rajdhani', sans-serif; font-size: 0.9rem; color: var(--text-dim); padding: 10px; background: rgba(0, 0, 0, 0.3); border-radius: 5px; } .connection-status.connected { color: #00ff00; text-shadow: 0 0 10px #00ff00; } .connection-status.disconnected { color: #ff4444; } /* Enable Audio Button */ .enable-audio-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 30px 40px; margin: 30px 0; background: linear-gradient(145deg, #1a1a1a, #0a0a0a); border: 3px solid var(--secondary-magenta); border-radius: 15px; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 0 30px rgba(188, 19, 254, 0.3); font-family: 'Orbitron', sans-serif; } .enable-audio-btn:hover { background: linear-gradient(145deg, #2a2a2a, #1a1a1a); box-shadow: 0 0 50px rgba(188, 19, 254, 0.6); transform: translateY(-3px); border-color: #ff00ff; } .enable-audio-btn:active { transform: translateY(-1px); box-shadow: 0 0 40px rgba(188, 19, 254, 0.5); } .enable-audio-btn .audio-icon { font-size: 3rem; animation: pulse-icon 2s ease-in-out infinite; } @keyframes pulse-icon { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.1); opacity: 0.8; } } .enable-audio-btn .audio-text { font-size: 1.5rem; font-weight: bold; color: var(--secondary-magenta); text-shadow: 0 0 10px var(--secondary-magenta); } .enable-audio-btn .audio-subtitle { font-size: 0.9rem; color: var(--text-dim); font-family: 'Rajdhani', sans-serif; } /* Mobile Responsiveness for Listener Mode */ @media (max-width: 768px) { .listener-mode { padding: 20px; justify-content: flex-start; padding-top: 60px; } .listener-header h1 { font-size: 2.2rem; margin-bottom: 10px; } .live-indicator { font-size: 0.9rem; padding: 6px 15px; } .listener-content { padding: 25px; margin-top: 10px; border-radius: 15px; } .now-playing { font-size: 1.1rem; min-height: 80px; line-height: 1.4; margin-bottom: 20px; } .volume-control label { font-size: 0.9rem; } } /* Hide landscape prompt globally when listening-active class is present */ body.listening-active .landscape-prompt { display: none !important; } /* Base Settings Button Fix */ .keyboard-btn { position: fixed; bottom: 25px; right: 100px; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(145deg, #222, #111); border: 2px solid #ffbb00; color: #ffbb00; font-size: 1.8rem; cursor: pointer; z-index: 10000; box-shadow: 0 0 20px rgba(255, 187, 0, 0.4); transition: all 0.3s; display: flex; align-items: center; justify-content: center; } .keyboard-btn:hover { transform: scale(1.1) rotate(5deg); box-shadow: 0 0 30px rgba(255, 187, 0, 0.6); } .settings-btn { position: fixed; bottom: 25px; right: 25px; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(145deg, #222, #111); border: 2px solid var(--primary-cyan); color: var(--primary-cyan); font-size: 1.8rem; cursor: pointer; z-index: 10000; box-shadow: 0 0 20px rgba(0, 243, 255, 0.4); transition: all 0.3s; display: flex; align-items: center; justify-content: center; } .settings-panel { position: fixed; top: 0; right: -350px; height: 100vh; width: 320px; background: rgba(10, 10, 20, 0.98); border-left: 1px solid var(--primary-cyan); padding: 30px; z-index: 10001; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); backdrop-filter: blur(15px); } .settings-panel.active { right: 0 !important; } .settings-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; border-bottom: 1px solid rgba(0, 243, 255, 0.3); padding-bottom: 15px; } .settings-content { display: flex; flex-direction: column; gap: 20px; } .setting-item label { display: flex; align-items: center; gap: 15px; font-size: 1.1rem; cursor: pointer; } /* Pulsing animations for edge border */ @keyframes pulse-cyan { 0%, 100% { box-shadow: inset 0 0 0 10px var(--primary-cyan), inset 0 0 80px rgba(0, 243, 255, 1), inset 0 0 150px rgba(0, 243, 255, 0.7); } 50% { box-shadow: inset 0 0 0 12px var(--primary-cyan), inset 0 0 120px rgba(0, 243, 255, 1), inset 0 0 200px rgba(0, 243, 255, 0.9); } } @keyframes pulse-magenta { 0%, 100% { box-shadow: inset 0 0 0 10px var(--secondary-magenta), inset 0 0 80px rgba(188, 19, 254, 1), inset 0 0 150px rgba(188, 19, 254, 0.7); } 50% { box-shadow: inset 0 0 0 12px var(--secondary-magenta), inset 0 0 120px rgba(188, 19, 254, 1), inset 0 0 200px rgba(188, 19, 254, 0.9); } } @keyframes pulse-both { 0%, 100% { box-shadow: inset 0 0 0 10px var(--primary-cyan), inset 0 0 80px rgba(0, 243, 255, 0.9), inset 0 0 120px rgba(188, 19, 254, 0.9); } 50% { box-shadow: inset 0 0 0 12px var(--primary-cyan), inset 0 0 120px rgba(0, 243, 255, 1), inset 0 0 180px rgba(188, 19, 254, 1); } } /* Enhanced Mobile Improvements */ @media (max-width: 1024px) { /* Larger tap targets */ button, .cue-btn, .loop-btn { min-height: 44px; min-width: 44px; font-size: 0.9rem; } /* Better spacing */ .hot-cues, .loop-controls { gap: 8px; } /* Larger sliders */ input[type="range"] { height: 40px; } /* Bigger disk for easier touch */ .dj-disk { width: 180px; height: 180px; } .disk-label { width: 60px; height: 60px; font-size: 1.5rem; } /* Better waveform touch area */ .waveform-canvas { min-height: 100px; } /* Larger text */ .track-display { font-size: 1rem; } .time-display { font-size: 1rem; } /* Better tab buttons */ .mobile-tabs { padding: 12px 0; } .tab-btn { padding: 12px 20px; font-size: 1rem; } /* Settings panel improvements */ .setting-item { padding: 12px; font-size: 1rem; } /* Better library items */ .track-row { padding: 12px; min-height: 60px; } .track-name { font-size: 1rem; } .load-btn { padding: 10px 16px; font-size: 0.9rem; } } @media (max-width: 768px) { /* Even larger for phones */ .dj-disk { width: 200px; height: 200px; } .disk-label { width: 70px; height: 70px; font-size: 1.8rem; } /* Stack controls vertically */ .controls { flex-direction: column; gap: 15px; } /* Larger crossfader */ .crossfader-section { padding: 20px; } #crossfader { height: 50px; } /* Better EQ controls */ .eq-controls, .filter-controls { gap: 15px; } .eq-knob, .filter-knob { min-width: 80px; } /* Larger speed control */ .speed-control { padding: 15px; } .speed-slider { height: 50px; } /* Better pitch bend buttons */ .pitch-bend-controls button { min-width: 60px; min-height: 50px; font-size: 1.2rem; } } @media (max-width: 480px) { /* Extra small phones */ body { font-size: 14px; } .deck-title { font-size: 1rem; } /* Compact hot cues */ .hot-cues { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .cue-btn { padding: 12px; } /* Compact loop controls */ .loop-controls { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; } /* Smaller VU meters */ canvas#viz-A, canvas#viz-B { height: 60px; } /* Compact library */ .lib-header input { font-size: 0.9rem; } .track-row { flex-direction: column; align-items: flex-start; gap: 8px; } .load-actions { width: 100%; justify-content: space-between; } } /* ========== LANDSCAPE MODE OPTIMIZATIONS (Phone Sideways) ========== */ @media (max-width: 1024px) and (orientation: landscape) { /* Override the portrait tab system - show both decks */ .mobile-tabs { display: none !important; } .app-container { display: grid !important; grid-template-columns: 1fr 1fr !important; grid-template-rows: 1fr auto !important; gap: 8px !important; padding: 8px !important; padding-bottom: 8px !important; height: 100vh; overflow: hidden; } /* Hide library in landscape - focus on DJing */ .library-section { display: none !important; } /* Show both decks side by side */ #deck-A, #deck-B { display: flex !important; flex-direction: column; padding: 8px !important; overflow-y: auto; height: 100%; border-radius: 8px; } /* Show crossfader at bottom spanning both decks */ .mixer-section { display: flex !important; grid-column: 1 / 3 !important; grid-row: 2 !important; padding: 8px 30px !important; min-height: 60px !important; height: 60px !important; } /* Compact deck headers */ .deck-header { padding: 6px 8px !important; margin-bottom: 6px !important; flex-shrink: 0; } .deck-title { font-size: 0.9rem !important; } .track-display { font-size: 0.7rem !important; max-width: 150px !important; } /* Compact waveform */ .waveform-container { margin-bottom: 6px !important; padding: 6px !important; min-height: auto !important; } .waveform-canvas { height: 50px !important; min-height: 50px !important; } .time-display { font-size: 0.7rem !important; margin-top: 3px !important; } /* Smaller disk */ .disk-container { margin-bottom: 6px !important; } .dj-disk { width: 80px !important; height: 80px !important; } .disk-label { width: 30px !important; height: 30px !important; font-size: 0.9rem !important; } /* Hide VU meters to save space */ canvas#viz-A, canvas#viz-B { display: none !important; } /* Compact hot cues */ .hot-cues { grid-template-columns: repeat(4, 1fr) !important; gap: 4px !important; margin-bottom: 6px !important; } .cue-btn { padding: 6px 4px !important; font-size: 0.65rem !important; min-height: 32px !important; } /* Compact loop controls */ .loop-controls { gap: 4px !important; margin-bottom: 6px !important; } .loop-btn { padding: 6px 4px !important; font-size: 0.65rem !important; min-height: 32px !important; } /* Hide download section to save space */ .start-group { display: none !important; } /* Compact controls grid */ .controls-grid { grid-template-columns: auto auto auto auto !important; gap: 6px !important; margin-top: 6px !important; } /* Compact faders */ .fader-group { min-width: 50px; } .fader-group label { font-size: 0.6rem !important; margin-bottom: 2px !important; } .volume-fader { height: 80px !important; width: 8px !important; } /* Compact EQ */ .eq-container { margin: 0 !important; gap: 4px; } .eq-band { width: auto !important; } .eq-band input { height: 80px !important; width: 8px !important; } .eq-band label { font-size: 0.6rem !important; } /* Compact filters */ .filter-knobs { display: flex; flex-direction: column; gap: 4px; } .filter-knob { min-width: auto !important; } .filter-knob label { font-size: 0.55rem !important; margin-bottom: 2px !important; } .filter-slider { width: 60px !important; height: 6px !important; } /* Compact pitch control */ .speed-slider { height: 6px !important; } .pitch-bend-buttons { gap: 4px; margin-top: 4px; } .pitch-bend { padding: 4px 8px !important; font-size: 0.7rem !important; min-height: 28px !important; } /* Compact transport buttons */ .transport { gap: 4px !important; margin-top: 6px !important; } .big-btn { padding: 8px 6px !important; font-size: 0.75rem !important; min-height: 36px !important; } /* Prominent crossfader */ .xfader { height: 16px !important; } .xfader::-webkit-slider-thumb { width: 50px !important; height: 40px !important; } .xfader::-moz-range-thumb { width: 50px !important; height: 40px !important; } .mixer-section::before, .mixer-section::after { font-size: 1.3rem !important; top: 50%; transform: translateY(-50%); } .mixer-section::before { left: 10px !important; } .mixer-section::after { right: 10px !important; } /* Settings button adjustment */ .settings-btn { bottom: 70px !important; right: 10px !important; width: 40px !important; height: 40px !important; font-size: 1.2rem !important; } /* Reduce edge border effect intensity */ body::before { border: 2px solid rgba(80, 80, 80, 0.3) !important; } body.playing-A::before { border: 10px solid var(--primary-cyan) !important; box-shadow: 0 0 60px rgba(0, 243, 255, 1), inset 0 0 60px rgba(0, 243, 255, 0.7) !important; } body.playing-B::before { border: 10px solid var(--secondary-magenta) !important; box-shadow: 0 0 60px rgba(188, 19, 254, 1), inset 0 0 60px rgba(188, 19, 254, 0.7) !important; } body.playing-A.playing-B::before { border: 10px solid var(--primary-cyan) !important; box-shadow: 0 0 60px rgba(0, 243, 255, 1), 0 0 80px rgba(188, 19, 254, 1), inset 0 0 60px rgba(0, 243, 255, 0.6), inset 0 0 80px rgba(188, 19, 254, 0.6) !important; } } /* Extra compact for very small landscape screens (phones) */ @media (max-width: 768px) and (orientation: landscape) { .deck-header { flex-direction: column; align-items: flex-start; gap: 2px; } .track-display { max-width: 100% !important; } /* Even more compact controls */ .hot-cues { grid-template-columns: repeat(2, 1fr) !important; } .controls-grid { grid-template-columns: auto auto !important; } .filter-knobs { display: none !important; } } /* Tiny landscape screens */ @media (max-width: 640px) and (orientation: landscape) { .app-container { gap: 4px !important; padding: 4px !important; } #deck-A, #deck-B { padding: 4px !important; } .waveform-canvas { height: 40px !important; } .dj-disk { width: 60px !important; height: 60px !important; } .disk-label { width: 24px !important; height: 24px !important; font-size: 0.7rem !important; } .hot-cues, .loop-controls { gap: 2px !important; } .cue-btn, .loop-btn { font-size: 0.55rem !important; padding: 4px 2px !important; min-height: 28px !important; } } /* Touch-friendly hover states */ @media (hover: none) { button:hover, .cue-btn:hover, .loop-btn:hover { transform: none; } button:active, .cue-btn:active, .loop-btn:active { transform: scale(0.95); opacity: 0.8; } } /* Landscape orientation prompt */ .landscape-prompt { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0, 0, 0, 0.95); border: 2px solid var(--primary-cyan); border-radius: 15px; padding: 30px; z-index: 10005; text-align: center; max-width: 80%; box-shadow: 0 0 40px rgba(0, 243, 255, 0.5); backdrop-filter: blur(20px); } .landscape-prompt h2 { font-family: 'Orbitron', sans-serif; color: var(--primary-cyan); margin: 0 0 15px 0; font-size: 1.3rem; text-shadow: 0 0 10px var(--primary-cyan); } .landscape-prompt p { color: var(--text-main); margin: 0 0 20px 0; font-size: 1rem; line-height: 1.5; } .landscape-prompt .rotate-icon { font-size: 3rem; margin-bottom: 15px; animation: rotate-hint 2s ease-in-out infinite; } @keyframes rotate-hint { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(90deg); } } .landscape-prompt button { background: var(--primary-cyan); color: #000; border: none; padding: 12px 30px; font-family: 'Orbitron', sans-serif; font-size: 1rem; border-radius: 5px; cursor: pointer; box-shadow: 0 0 20px rgba(0, 243, 255, 0.4); transition: all 0.3s; } .landscape-prompt button:hover { box-shadow: 0 0 30px rgba(0, 243, 255, 0.6); transform: translateY(-2px); } /* Show prompt on mobile portrait */ @media (max-width: 1024px) and (orientation: portrait) { .landscape-prompt { display: block; } .landscape-prompt.dismissed { display: none; } } /* ========================================== QUEUE SYSTEM STYLING ========================================== */ .queue-panel { background: rgba(10, 10, 20, 0.9); border: 2px solid rgba(255, 255, 255, 0.1); border-radius: 8px; margin-top: 15px; padding: 10px; max-height: 200px; display: flex; flex-direction: column; } .queue-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .queue-title { font-family: 'Orbitron', sans-serif; font-size: 0.9rem; font-weight: bold; color: #0ff; } #queue-panel-B .queue-title { color: #f0f; } .queue-clear-btn { background: rgba(255, 0, 0, 0.1); border: 1px solid #f00; color: #f00; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 0.9rem; transition: all 0.2s; } .queue-clear-btn:hover { background: rgba(255, 0, 0, 0.2); box-shadow: 0 0 10px rgba(255, 0, 0, 0.3); } .queue-list { flex: 1; overflow-y: auto; min-height: 50px; } .queue-empty { text-align: center; padding: 20px; color: #666; font-size: 0.85rem; font-style: italic; } .queue-item { display: flex; align-items: center; gap: 8px; padding: 8px; margin-bottom: 5px; background: rgba(255, 255, 255, 0.03); border-radius: 4px; border-left: 3px solid #0ff; cursor: move; transition: all 0.2s; } #queue-panel-B .queue-item { border-left-color: #f0f; } .queue-item:hover { background: rgba(255, 255, 255, 0.08); transform: translateX(3px); } .queue-item.dragging { opacity: 0.5; } .queue-number { font-family: 'Orbitron', sans-serif; font-size: 0.8rem; color: #0ff; min-width: 20px; } #queue-panel-B .queue-number { color: #f0f; } .queue-track-title { flex: 1; font-size: 0.85rem; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .queue-actions { display: flex; gap: 4px; } .queue-load-btn, .queue-remove-btn { background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff; padding: 4px 8px; border-radius: 3px; cursor: pointer; font-size: 0.8rem; transition: all 0.2s; } .queue-load-btn:hover { background: rgba(0, 255, 0, 0.2); border-color: #0f0; color: #0f0; } .queue-remove-btn:hover { background: rgba(255, 0, 0, 0.2); border-color: #f00; color: #f00; } /* Queue buttons in library */ .queue-btn-a, .queue-btn-b { font-size: 0.65rem !important; padding: 4px 6px !important; } .queue-btn-a { background: rgba(0, 243, 255, 0.15) !important; border-color: rgba(0, 243, 255, 0.4) !important; } .queue-btn-b { background: rgba(188, 19, 254, 0.15) !important; border-color: rgba(188, 19, 254, 0.4) !important; } .queue-btn-a:hover, .queue-btn-b:hover { opacity: 1 !important; transform: scale(1.05); } /* Update load-actions to fit 4 buttons */ .load-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; } /* ========================================== KEYBOARD SETTINGS PANEL ========================================== */ .keyboard-mapping-item { display: flex; align-items: center; gap: 15px; padding: 12px; margin-bottom: 8px; background: rgba(255, 255, 255, 0.03); border-radius: 6px; border-left: 3px solid transparent; transition: all 0.2s; } .keyboard-mapping-item:hover { background: rgba(255, 255, 255, 0.06); border-left-color: #0ff; } .keyboard-mapping-item.listening { background: rgba(255, 255, 0, 0.1); border-left-color: #ff0; animation: pulse 1s infinite; } .key-display { font-family: 'Orbitron', monospace; font-size: 0.9rem; font-weight: bold; color: #0ff; background: rgba(0, 243, 255, 0.1); padding: 6px 12px; border-radius: 4px; border: 1px solid rgba(0, 243, 255, 0.3); min-width: 60px; text-align: center; } .key-arrow { color: #666; font-size: 1.2rem; } .action-label { flex: 1; color: #ccc; font-size: 0.9rem; } .key-reassign-btn { background: rgba(0, 243, 255, 0.1); border: 1px solid #0ff; color: #0ff; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 0.8rem; font-family: 'Orbitron', sans-serif; transition: all 0.2s; } .key-reassign-btn:hover { background: rgba(0, 243, 255, 0.2); box-shadow: 0 0 10px rgba(0, 243, 255, 0.3); } .btn-secondary { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-family: 'Orbitron', sans-serif; font-size: 0.85rem; transition: all 0.2s; } .btn-secondary:hover { background: rgba(255, 255, 255, 0.1); border-color: #0ff; color: #0ff; } #keyboard-settings-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); width: 90%; max-width: 600px; max-height: 80vh; background: rgba(10, 10, 20, 0.98); border: 2px solid #0ff; border-radius: 10px; box-shadow: 0 0 50px rgba(0, 243, 255, 0.3); z-index: 10000; opacity: 0; pointer-events: none; transition: all 0.3s ease; display: flex; flex-direction: column; } #keyboard-settings-panel.active { opacity: 1; pointer-events: all; transform: translate(-50%, -50%) scale(1); } .panel-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .panel-header h2 { margin: 0; font-family: 'Orbitron', sans-serif; color: #0ff; font-size: 1.3rem; } .panel-header button { background: rgba(255, 0, 0, 0.1); border: 1px solid #f00; color: #f00; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; font-size: 1.2rem; transition: all 0.2s; } .panel-header button:hover { background: rgba(255, 0, 0, 0.2); transform: rotate(90deg); } .panel-content { padding: 20px; overflow-y: auto; flex: 1; } #keyboard-mappings-list { max-height: 400px; overflow-y: auto; } /* Scrollbar styling */ #keyboard-mappings-list::-webkit-scrollbar { width: 8px; } #keyboard-mappings-list::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.3); border-radius: 4px; } #keyboard-mappings-list::-webkit-scrollbar-thumb { background: rgba(0, 243, 255, 0.3); border-radius: 4px; } #keyboard-mappings-list::-webkit-scrollbar-thumb:hover { background: rgba(0, 243, 255, 0.5); } /* ========================================== LIBRARY TRACK HIGHLIGHTING ========================================== */ /* Track loaded on Deck A (Cyan) */ .track-row.loaded-deck-a { border-left: 4px solid var(--primary-cyan); background: linear-gradient(90deg, rgba(0, 243, 255, 0.15) 0%, rgba(0, 243, 255, 0.03) 100%); } .track-row.loaded-deck-a .track-name { color: var(--primary-cyan); font-weight: bold; } .track-row.loaded-deck-a::before { content: '▶ A'; position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 0.7rem; font-weight: bold; color: var(--primary-cyan); font-family: 'Orbitron', sans-serif; } /* Track loaded on Deck B (Magenta) */ .track-row.loaded-deck-b { border-left: 4px solid var(--secondary-magenta); background: linear-gradient(90deg, rgba(188, 19, 254, 0.15) 0%, rgba(188, 19, 254, 0.03) 100%); } .track-row.loaded-deck-b .track-name { color: var(--secondary-magenta); font-weight: bold; } .track-row.loaded-deck-b::before { content: '▶ B'; position: absolute; right: 8px; top: 50%; transform: translateY(-50%); font-size: 0.7rem; font-weight: bold; color: var(--secondary-magenta); font-family: 'Orbitron', sans-serif; } /* Track loaded on BOTH decks */ .track-row.loaded-both { border-left: 4px solid var(--primary-cyan); border-right: 4px solid var(--secondary-magenta); background: linear-gradient(90deg, rgba(0, 243, 255, 0.15) 0%, rgba(188, 19, 254, 0.15) 100%); } .track-row.loaded-both .track-name { background: linear-gradient(90deg, var(--primary-cyan), var(--secondary-magenta)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-weight: bold; } .track-row.loaded-both::before { content: '▶ A'; position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 0.7rem; font-weight: bold; color: var(--primary-cyan); font-family: 'Orbitron', sans-serif; } .track-row.loaded-both::after { content: '▶ B'; position: absolute; right: 8px; top: 50%; transform: translateY(-50%); font-size: 0.7rem; font-weight: bold; color: var(--secondary-magenta); font-family: 'Orbitron', sans-serif; } /* Ensure track-row is positioned for absolute children */ .track-row { position: relative; padding-left: 40px; padding-right: 40px; }