AdityaAdaki commited on
Commit
ba222a5
·
1 Parent(s): e8298b2

design rework

Browse files
Files changed (3) hide show
  1. static/player.js +1 -77
  2. static/style.css +783 -111
  3. templates/index.html +34 -27
static/player.js CHANGED
@@ -971,80 +971,4 @@ function escapeHtml(unsafe) {
971
  .replace(/>/g, ">")
972
  .replace(/"/g, """)
973
  .replace(/'/g, "'");
974
- }
975
-
976
- // Mobile navigation handling
977
- function initializeMobileNav() {
978
- const menuToggle = document.getElementById('menu-toggle');
979
- const sidebar = document.querySelector('.sidebar');
980
- const overlay = document.getElementById('sidebar-overlay');
981
- const mobileNavLinks = document.querySelectorAll('.mobile-nav a');
982
-
983
- menuToggle.addEventListener('click', toggleSidebar);
984
- overlay.addEventListener('click', closeSidebar);
985
-
986
- mobileNavLinks.forEach(link => {
987
- link.addEventListener('click', (e) => {
988
- e.preventDefault();
989
- const view = e.currentTarget.dataset.view;
990
- switchView(view);
991
- closeSidebar();
992
- });
993
- });
994
-
995
- // Handle swipe gestures
996
- let touchStartX = 0;
997
- let touchEndX = 0;
998
-
999
- document.addEventListener('touchstart', e => {
1000
- touchStartX = e.changedTouches[0].screenX;
1001
- }, false);
1002
-
1003
- document.addEventListener('touchend', e => {
1004
- touchEndX = e.changedTouches[0].screenX;
1005
- handleSwipe();
1006
- }, false);
1007
-
1008
- function handleSwipe() {
1009
- const swipeThreshold = 50;
1010
- const diff = touchEndX - touchStartX;
1011
-
1012
- if (Math.abs(diff) < swipeThreshold) return;
1013
-
1014
- if (diff > 0) { // Swipe right
1015
- if (touchStartX < 30) { // Only if swipe starts near the left edge
1016
- openSidebar();
1017
- }
1018
- } else { // Swipe left
1019
- closeSidebar();
1020
- }
1021
- }
1022
- }
1023
-
1024
- function toggleSidebar() {
1025
- const sidebar = document.querySelector('.sidebar');
1026
- const overlay = document.getElementById('sidebar-overlay');
1027
- sidebar.classList.toggle('active');
1028
- overlay.classList.toggle('active');
1029
- }
1030
-
1031
- function openSidebar() {
1032
- const sidebar = document.querySelector('.sidebar');
1033
- const overlay = document.getElementById('sidebar-overlay');
1034
- sidebar.classList.add('active');
1035
- overlay.classList.add('active');
1036
- }
1037
-
1038
- function closeSidebar() {
1039
- const sidebar = document.querySelector('.sidebar');
1040
- const overlay = document.getElementById('sidebar-overlay');
1041
- sidebar.classList.remove('active');
1042
- overlay.classList.remove('active');
1043
- }
1044
-
1045
- // Update the initialization code
1046
- document.addEventListener('DOMContentLoaded', function() {
1047
- initializeAudioPlayer();
1048
- initializeMobileNav();
1049
- // ... rest of your initialization code
1050
- });
 
971
  .replace(/>/g, "&gt;")
972
  .replace(/"/g, "&quot;")
973
  .replace(/'/g, "&#039;");
974
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/style.css CHANGED
@@ -1,9 +1,9 @@
1
  :root {
2
- --sidebar-width: 250px;
3
- --player-height: 100px;
4
  --primary-color: #1a73e8;
5
- --background-color: #f0f2f5;
6
- --card-background: white;
 
 
7
  }
8
 
9
  * {
@@ -14,193 +14,865 @@
14
 
15
  body {
16
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
17
- background: var(--background-color);
18
- color: #333;
19
- overflow: hidden;
20
  }
21
 
22
  .container {
23
  display: grid;
24
  grid-template-columns: var(--sidebar-width) 1fr;
25
- grid-template-rows: 1fr var(--player-height);
26
- height: 100vh;
 
 
27
  transition: all 0.3s ease;
28
  }
29
 
30
- .mobile-nav {
31
- display: none;
32
  position: fixed;
33
  bottom: 0;
34
  left: 0;
35
  right: 0;
36
- background: var(--card-background);
37
- padding: 0.5rem;
38
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
39
- z-index: 1000;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
 
42
- .mobile-nav ul {
 
 
43
  display: flex;
44
- justify-content: space-around;
45
- list-style: none;
46
  }
47
 
48
- .mobile-nav a {
 
 
 
 
 
 
49
  color: #666;
50
- text-decoration: none;
 
 
 
51
  display: flex;
52
  flex-direction: column;
 
 
 
 
 
 
53
  align-items: center;
54
- font-size: 0.8rem;
 
55
  }
56
 
57
- .mobile-nav i {
58
- font-size: 1.2rem;
59
- margin-bottom: 0.2rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  }
61
 
62
  .sidebar {
63
- background: var(--card-background);
 
64
  padding: 1rem;
 
 
 
 
65
  overflow-y: auto;
66
- transition: transform 0.3s ease;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
 
69
  .main-content {
 
 
70
  padding: 1rem;
 
71
  overflow-y: auto;
72
- background: var(--background-color);
73
  }
74
 
75
- .music-player {
76
- grid-column: 1 / -1;
77
- background: var(--card-background);
78
- padding: 1rem;
79
  display: flex;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  align-items: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  gap: 1rem;
82
- height: var(--player-height);
83
  }
84
 
85
- .now-playing {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  display: flex;
87
  align-items: center;
88
- gap: 1rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  flex: 1;
 
 
 
 
 
90
  }
91
 
92
- #album-art {
93
- width: 60px;
94
- height: 60px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  border-radius: 8px;
96
  object-fit: cover;
97
  }
98
 
99
- @media (max-width: 768px) {
100
- :root {
101
- --sidebar-width: 0px;
102
- --player-height: 80px;
103
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  .container {
106
  grid-template-columns: 1fr;
107
  }
108
 
 
 
 
 
109
  .sidebar {
110
  position: fixed;
111
- left: 0;
112
  top: 0;
113
  bottom: 0;
114
- width: 280px;
115
- z-index: 1001;
116
- transform: translateX(-100%);
 
117
  }
118
 
119
  .sidebar.active {
120
- transform: translateX(0);
121
- }
122
-
123
- .mobile-nav {
124
- display: block;
125
- height: 60px;
126
- }
127
-
128
- .main-content {
129
- padding-bottom: 60px; /* Space for mobile nav */
130
- }
131
-
132
- .music-player {
133
- padding: 0.5rem;
134
- }
135
-
136
- .player-controls {
137
- flex-direction: column;
138
- gap: 0.5rem;
139
  }
140
 
141
- .volume-control {
142
- display: none;
143
  }
144
 
145
  .lyrics-container {
146
  display: none;
147
  }
148
 
149
- /* Add hamburger menu button */
150
- .menu-toggle {
151
- display: block;
152
- position: fixed;
153
- top: 1rem;
154
- left: 1rem;
155
- z-index: 1002;
156
- background: var(--primary-color);
157
- color: white;
158
- border: none;
159
- border-radius: 50%;
160
- width: 40px;
161
- height: 40px;
162
- cursor: pointer;
163
  }
 
164
 
165
- /* Add overlay for sidebar */
166
- .sidebar-overlay {
167
- display: none;
168
- position: fixed;
169
- top: 0;
170
- left: 0;
171
- right: 0;
172
- bottom: 0;
173
- background: rgba(0, 0, 0, 0.5);
174
- z-index: 1000;
175
  }
176
 
177
- .sidebar-overlay.active {
178
- display: block;
 
 
179
  }
180
- }
181
 
182
- .track-list .music-item {
183
- padding: 0.75rem;
184
- border-radius: 8px;
185
- }
186
-
187
- .album-grid, .artist-grid {
188
- grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
189
  }
190
 
191
- .album-art-container, .artist-art-container {
192
- width: 150px;
193
- height: 150px;
 
 
 
 
 
 
194
  }
195
 
196
- @media (max-width: 480px) {
197
- .album-grid, .artist-grid {
198
- grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
199
- }
200
-
201
- .album-art-container, .artist-art-container {
202
- width: 120px;
203
- height: 120px;
204
  }
205
  }
206
 
 
1
  :root {
 
 
2
  --primary-color: #1a73e8;
3
+ --secondary-color: #e8f0fe;
4
+ --text-color: #333;
5
+ --bg-color: #f0f2f5;
6
+ --sidebar-width: 250px;
7
  }
8
 
9
  * {
 
14
 
15
  body {
16
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
17
+ background: var(--bg-color);
18
+ color: var(--text-color);
 
19
  }
20
 
21
  .container {
22
  display: grid;
23
  grid-template-columns: var(--sidebar-width) 1fr;
24
+ grid-template-rows: 1fr auto;
25
+ min-height: 100vh;
26
+ gap: 1rem;
27
+ padding: 1rem;
28
  transition: all 0.3s ease;
29
  }
30
 
31
+ .music-player {
 
32
  position: fixed;
33
  bottom: 0;
34
  left: 0;
35
  right: 0;
36
+ background: white;
37
+ padding: 1rem;
38
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
39
+ z-index: 100;
40
+ }
41
+
42
+ .now-playing {
43
+ display: grid;
44
+ grid-template-columns: auto 1fr auto;
45
+ gap: 1rem;
46
+ align-items: center;
47
+ }
48
+
49
+ #album-art {
50
+ width: 60px;
51
+ height: 60px;
52
+ border-radius: 8px;
53
+ object-fit: cover;
54
+ }
55
+
56
+ .player-header h1 {
57
+ margin-bottom: 2rem;
58
+ color: #1a73e8;
59
  }
60
 
61
+ .track-info {
62
+ flex: 1;
63
+ cursor: pointer;
64
  display: flex;
65
+ flex-direction: column;
66
+ gap: 0.25rem;
67
  }
68
 
69
+ #track-title {
70
+ font-size: 1.5rem;
71
+ font-weight: bold;
72
+ margin-bottom: 0.5rem;
73
+ }
74
+
75
+ #track-artist, #track-album {
76
  color: #666;
77
+ margin-bottom: 0.5rem;
78
+ }
79
+
80
+ .player-controls {
81
  display: flex;
82
  flex-direction: column;
83
+ gap: 0.5rem;
84
+ padding: 0.5rem 0;
85
+ }
86
+
87
+ .control-buttons {
88
+ display: flex;
89
  align-items: center;
90
+ justify-content: center;
91
+ gap: 1.5rem;
92
  }
93
 
94
+ .play-btn {
95
+ width: 50px;
96
+ height: 50px;
97
+ border-radius: 50%;
98
+ background: var(--primary-color);
99
+ color: white;
100
+ border: none;
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: center;
104
+ cursor: pointer;
105
+ transition: transform 0.2s ease;
106
+ }
107
+
108
+ .play-btn:hover {
109
+ transform: scale(1.1);
110
+ }
111
+
112
+ .time-control {
113
+ display: flex;
114
+ align-items: center;
115
+ gap: 1rem;
116
+ margin-bottom: 1rem;
117
+ }
118
+
119
+ #seek-slider {
120
+ flex: 1;
121
+ }
122
+
123
+ button {
124
+ background: none;
125
+ border: none;
126
+ cursor: pointer;
127
+ font-size: 1.5rem;
128
+ color: #1a73e8;
129
+ padding: 0.5rem;
130
+ border-radius: 50%;
131
+ transition: background-color 0.3s;
132
+ }
133
+
134
+ button:hover {
135
+ background-color: #f0f2f5;
136
+ }
137
+
138
+ .volume-control {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 0.5rem;
142
+ margin-left: 2rem;
143
+ }
144
+
145
+ #volume-slider {
146
+ width: 100px;
147
  }
148
 
149
  .sidebar {
150
+ background: white;
151
+ border-radius: 12px;
152
  padding: 1rem;
153
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
154
+ height: calc(100vh - 2rem);
155
+ position: sticky;
156
+ top: 1rem;
157
  overflow-y: auto;
158
+ }
159
+
160
+ .nav-menu, .playlist-menu {
161
+ list-style: none;
162
+ padding: 0;
163
+ margin: 1rem 0;
164
+ }
165
+
166
+ .nav-menu li a, .playlist-menu li a {
167
+ display: block;
168
+ padding: 0.75rem 1rem;
169
+ color: #333;
170
+ text-decoration: none;
171
+ border-radius: 6px;
172
+ transition: background-color 0.3s;
173
+ }
174
+
175
+ .nav-menu li a:hover, .playlist-menu li a:hover {
176
+ background-color: #f0f2f5;
177
+ }
178
+
179
+ .nav-menu li a.active {
180
+ background-color: #e8f0fe;
181
+ color: #1a73e8;
182
+ }
183
+
184
+ .btn-new-playlist {
185
+ width: 100%;
186
+ padding: 0.75rem;
187
+ background: none;
188
+ border: 1px dashed #1a73e8;
189
+ color: #1a73e8;
190
+ border-radius: 6px;
191
+ cursor: pointer;
192
+ transition: all 0.3s;
193
+ }
194
+
195
+ .btn-new-playlist:hover {
196
+ background: #e8f0fe;
197
  }
198
 
199
  .main-content {
200
+ background: white;
201
+ border-radius: 12px;
202
  padding: 1rem;
203
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
204
  overflow-y: auto;
 
205
  }
206
 
207
+ .view-header {
 
 
 
208
  display: flex;
209
+ justify-content: space-between;
210
+ align-items: center;
211
+ margin-bottom: 2rem;
212
+ }
213
+
214
+ .search-box {
215
+ position: relative;
216
+ }
217
+
218
+ .search-box input {
219
+ padding: 0.5rem 2rem 0.5rem 1rem;
220
+ border: 1px solid #ddd;
221
+ border-radius: 20px;
222
+ width: 200px;
223
+ }
224
+
225
+ .search-box i {
226
+ position: absolute;
227
+ right: 0.75rem;
228
+ top: 50%;
229
+ transform: translateY(-50%);
230
+ color: #666;
231
+ }
232
+
233
+ .album-grid, .artist-grid {
234
+ display: grid;
235
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
236
+ gap: 1.5rem;
237
+ padding: 1rem;
238
+ }
239
+
240
+ .album-card, .artist-card {
241
+ text-align: center;
242
+ cursor: pointer;
243
+ transition: transform 0.3s;
244
+ }
245
+
246
+ .album-card:hover, .artist-card:hover {
247
+ transform: translateY(-5px);
248
+ }
249
+
250
+ .album-art, .artist-image {
251
+ width: 180px;
252
+ height: 180px;
253
+ border-radius: 8px;
254
+ margin-bottom: 0.5rem;
255
+ object-fit: cover;
256
+ }
257
+
258
+ .track-list {
259
+ display: grid;
260
+ gap: 0.5rem;
261
+ padding: 1rem;
262
+ }
263
+
264
+ .music-item {
265
+ display: grid;
266
+ grid-template-columns: auto 1fr auto;
267
+ align-items: center;
268
+ padding: 0.75rem;
269
+ border-radius: 8px;
270
+ background: white;
271
+ transition: transform 0.2s ease;
272
+ }
273
+
274
+ .music-item:hover {
275
+ transform: translateX(5px);
276
+ }
277
+
278
+ .music-item.playing {
279
+ background-color: #e8f0fe;
280
+ color: #1a73e8;
281
+ }
282
+
283
+ input[type="range"] {
284
+ -webkit-appearance: none;
285
+ appearance: none;
286
+ height: 5px;
287
+ background: #ddd;
288
+ border-radius: 5px;
289
+ cursor: pointer;
290
+ }
291
+
292
+ input[type="range"]::-webkit-slider-thumb {
293
+ -webkit-appearance: none;
294
+ width: 15px;
295
+ height: 15px;
296
+ background: #1a73e8;
297
+ border-radius: 50%;
298
+ }
299
+
300
+ .modal {
301
+ display: none;
302
+ position: fixed;
303
+ top: 0;
304
+ left: 0;
305
+ width: 100%;
306
+ height: 100%;
307
+ background: rgba(0, 0, 0, 0.5);
308
  align-items: center;
309
+ justify-content: center;
310
+ }
311
+
312
+ .modal-content {
313
+ background: white;
314
+ padding: 2rem;
315
+ border-radius: 12px;
316
+ width: 400px;
317
+ }
318
+
319
+ .modal-content input {
320
+ width: 100%;
321
+ padding: 0.75rem;
322
+ margin: 1rem 0;
323
+ border: 1px solid #ddd;
324
+ border-radius: 6px;
325
+ }
326
+
327
+ .modal-buttons {
328
+ display: flex;
329
+ justify-content: flex-end;
330
  gap: 1rem;
 
331
  }
332
 
333
+ .modal-buttons button {
334
+ padding: 0.5rem 1rem;
335
+ border-radius: 6px;
336
+ cursor: pointer;
337
+ }
338
+
339
+ #save-playlist {
340
+ background: #1a73e8;
341
+ color: white;
342
+ border: none;
343
+ }
344
+
345
+ #cancel-playlist {
346
+ background: none;
347
+ border: 1px solid #ddd;
348
+ }
349
+
350
+ .track-actions {
351
  display: flex;
352
  align-items: center;
353
+ }
354
+
355
+ .track-name {
356
+ font-weight: 500;
357
+ }
358
+
359
+ .track-artist {
360
+ color: #666;
361
+ font-size: 0.9em;
362
+ }
363
+
364
+ .playlist-menu-popup {
365
+ background: white;
366
+ border-radius: 8px;
367
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
368
+ z-index: 1000;
369
+ min-width: 200px;
370
+ }
371
+
372
+ .menu-items {
373
+ padding: 0.5rem;
374
+ }
375
+
376
+ .menu-item {
377
+ padding: 0.75rem 1rem;
378
+ cursor: pointer;
379
+ border-radius: 4px;
380
+ display: flex;
381
+ align-items: center;
382
+ gap: 0.5rem;
383
+ }
384
+
385
+ .menu-item:hover {
386
+ background-color: #f0f2f5;
387
+ }
388
+
389
+ .notification {
390
+ position: fixed;
391
+ bottom: 20px;
392
+ right: 20px;
393
+ background: #1a73e8;
394
+ color: white;
395
+ padding: 0.75rem 1.5rem;
396
+ border-radius: 4px;
397
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
398
+ animation: slide-in 0.3s ease-out;
399
+ z-index: 1000;
400
+ }
401
+
402
+ .notification.fade-out {
403
+ animation: fade-out 0.3s ease-out;
404
+ }
405
+
406
+ .playlist-grid {
407
+ display: grid;
408
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
409
+ gap: 1.5rem;
410
+ padding: 1rem;
411
+ }
412
+
413
+ .playlist-card {
414
+ background: white;
415
+ border-radius: 8px;
416
+ padding: 1rem;
417
+ text-align: center;
418
+ cursor: pointer;
419
+ position: relative;
420
+ transition: transform 0.3s;
421
+ }
422
+
423
+ .playlist-card:hover {
424
+ transform: translateY(-5px);
425
+ }
426
+
427
+ .playlist-art {
428
+ width: 150px;
429
+ height: 150px;
430
+ background: #f0f2f5;
431
+ border-radius: 8px;
432
+ margin: 0 auto 1rem;
433
+ display: flex;
434
+ align-items: center;
435
+ justify-content: center;
436
+ }
437
+
438
+ .playlist-art i {
439
+ font-size: 3rem;
440
+ color: #1a73e8;
441
+ }
442
+
443
+ .delete-playlist {
444
+ position: absolute;
445
+ top: 0.5rem;
446
+ right: 0.5rem;
447
+ background: none;
448
+ border: none;
449
+ color: #666;
450
+ padding: 0.5rem;
451
+ cursor: pointer;
452
+ opacity: 0;
453
+ transition: opacity 0.3s;
454
+ }
455
+
456
+ .playlist-card:hover .delete-playlist {
457
+ opacity: 1;
458
+ }
459
+
460
+ @keyframes slide-in {
461
+ from {
462
+ transform: translateX(100%);
463
+ opacity: 0;
464
+ }
465
+ to {
466
+ transform: translateX(0);
467
+ opacity: 1;
468
+ }
469
+ }
470
+
471
+ @keyframes fade-out {
472
+ from {
473
+ transform: translateX(0);
474
+ opacity: 1;
475
+ }
476
+ to {
477
+ transform: translateX(100%);
478
+ opacity: 0;
479
+ }
480
+ }
481
+
482
+ .menu-trigger {
483
+ padding: 0.5rem;
484
+ opacity: 0;
485
+ transition: opacity 0.3s;
486
+ color: #666;
487
+ }
488
+
489
+ .music-item:hover .menu-trigger {
490
+ opacity: 1;
491
+ }
492
+
493
+ .context-menu {
494
+ background: white;
495
+ border-radius: 8px;
496
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
497
+ z-index: 1000;
498
+ min-width: 200px;
499
+ overflow: hidden;
500
+ }
501
+
502
+ .menu-items {
503
+ padding: 0.5rem 0;
504
+ }
505
+
506
+ .menu-item {
507
+ padding: 0.75rem 1rem;
508
+ cursor: pointer;
509
+ display: flex;
510
+ align-items: center;
511
+ gap: 0.75rem;
512
+ transition: background-color 0.2s;
513
+ }
514
+
515
+ .menu-item:hover {
516
+ background-color: #f0f2f5;
517
+ }
518
+
519
+ .menu-item i {
520
+ width: 20px;
521
+ text-align: center;
522
+ color: #666;
523
+ }
524
+
525
+ .menu-separator {
526
+ height: 1px;
527
+ background-color: #eee;
528
+ margin: 0.5rem 0;
529
+ }
530
+
531
+ .lyrics-container {
532
  flex: 1;
533
+ max-width: 400px;
534
+ margin-left: 2rem;
535
+ display: flex;
536
+ flex-direction: column;
537
+ max-height: 200px;
538
  }
539
 
540
+ .lyrics-header {
541
+ display: flex;
542
+ justify-content: space-between;
543
+ align-items: center;
544
+ margin-bottom: 1rem;
545
+ }
546
+
547
+ .lyrics-toggle {
548
+ background: none;
549
+ border: 1px solid #ddd;
550
+ padding: 0.5rem 1rem;
551
+ border-radius: 4px;
552
+ font-size: 0.9rem;
553
+ }
554
+
555
+ .lyrics-content {
556
+ flex: 1;
557
+ overflow-y: auto;
558
+ padding-right: 1rem;
559
+ line-height: 1.6;
560
+ scroll-behavior: smooth;
561
+ padding: 1rem;
562
+ }
563
+
564
+ .lyrics-line {
565
+ margin-bottom: 0.5rem;
566
+ transition: all 0.3s ease;
567
+ cursor: pointer;
568
+ padding: 0.5rem 1rem;
569
+ border-radius: 4px;
570
+ opacity: 0.7;
571
+ }
572
+
573
+ .lyrics-line:hover {
574
+ background-color: #f0f2f5;
575
+ opacity: 1;
576
+ }
577
+
578
+ .lyrics-line.active {
579
+ color: #1a73e8;
580
+ font-weight: bold;
581
+ opacity: 1;
582
+ background-color: #e8f0fe;
583
+ }
584
+
585
+ .playlist-header {
586
+ display: flex;
587
+ justify-content: space-between;
588
+ align-items: center;
589
+ padding: 1rem;
590
+ background: #f8f9fa;
591
+ border-radius: 8px;
592
+ margin-bottom: 1rem;
593
+ }
594
+
595
+ .playlist-info {
596
+ display: flex;
597
+ align-items: center;
598
+ gap: 1rem;
599
+ }
600
+
601
+ .playlist-icon {
602
+ font-size: 2.5rem;
603
+ color: #1a73e8;
604
+ background: #e8f0fe;
605
+ padding: 1rem;
606
+ border-radius: 8px;
607
+ }
608
+
609
+ .play-playlist {
610
+ background: #1a73e8;
611
+ color: white;
612
+ padding: 0.75rem 1.5rem;
613
+ border-radius: 20px;
614
+ font-size: 1rem;
615
+ }
616
+
617
+ .play-playlist:hover {
618
+ background: #1557b0;
619
+ }
620
+
621
+ .playlist-count {
622
+ color: #666;
623
+ font-size: 0.9em;
624
+ margin-left: 0.5rem;
625
+ }
626
+
627
+ #playlist-list a {
628
+ display: flex;
629
+ align-items: center;
630
+ justify-content: space-between;
631
+ }
632
+
633
+ #playlist-list i {
634
+ margin-right: 0.5rem;
635
+ }
636
+
637
+ .album-art-container, .artist-art-container {
638
+ position: relative;
639
+ width: 180px;
640
+ height: 180px;
641
+ margin-bottom: 0.5rem;
642
+ }
643
+
644
+ .album-art, .artist-image {
645
+ width: 100%;
646
+ height: 100%;
647
  border-radius: 8px;
648
  object-fit: cover;
649
  }
650
 
651
+ .play-overlay {
652
+ position: absolute;
653
+ top: 50%;
654
+ left: 50%;
655
+ transform: translate(-50%, -50%);
656
+ background: rgba(26, 115, 232, 0.9);
657
+ color: white;
658
+ width: 50px;
659
+ height: 50px;
660
+ border-radius: 50%;
661
+ display: flex;
662
+ align-items: center;
663
+ justify-content: center;
664
+ opacity: 0;
665
+ transition: opacity 0.3s;
666
+ cursor: pointer;
667
+ border: none;
668
+ font-size: 1.2rem;
669
+ }
670
+
671
+ .album-art-container:hover .play-overlay,
672
+ .artist-art-container:hover .play-overlay {
673
+ opacity: 1;
674
+ }
675
+
676
+ .album-info, .artist-info {
677
+ cursor: pointer;
678
+ }
679
+
680
+ .album-card, .artist-card {
681
+ display: flex;
682
+ flex-direction: column;
683
+ align-items: center;
684
+ text-align: center;
685
+ }
686
+
687
+ .artist-image {
688
+ background-color: #e8f0fe;
689
+ }
690
+
691
+ .artist-image[src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMjAwIDIwMCI+PHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IiNlOWVjZWYiLz48dGV4dCB4PSI1MCUiIHk9IjUwJSIgc3R5bGU9ImZvbnQtZmFtaWx5OiBBcmlhbDsgZm9udC1zaXplOiAyMHB4OyBmaWxsOiAjNmM3NTdkOyBkb21pbmFudC1iYXNlbGluZTogbWlkZGxlOyB0ZXh0LWFuY2hvcjogbWlkZGxlOyI+Tm8gQWxidW0gQXJ0PC90ZXh0Pjwvc3ZnPg=="] {
692
+ background: #e8f0fe;
693
+ padding: 2rem;
694
+ }
695
+
696
+ .existing-playlists {
697
+ max-height: 200px;
698
+ overflow-y: auto;
699
+ margin-bottom: 1rem;
700
+ border-bottom: 1px solid #eee;
701
+ }
702
+
703
+ .existing-playlist-item {
704
+ padding: 0.75rem;
705
+ cursor: pointer;
706
+ display: flex;
707
+ align-items: center;
708
+ gap: 0.5rem;
709
+ border-radius: 4px;
710
+ transition: background-color 0.2s;
711
+ }
712
+
713
+ .existing-playlist-item:hover {
714
+ background-color: #f0f2f5;
715
+ }
716
+
717
+ .existing-playlist-item i {
718
+ color: #1a73e8;
719
+ }
720
+
721
+ .new-playlist-section {
722
+ padding-top: 1rem;
723
+ }
724
+
725
+ .new-playlist-section h3 {
726
+ margin-bottom: 0.75rem;
727
+ font-size: 1rem;
728
+ color: #666;
729
+ }
730
 
731
+ .album-header {
732
+ padding: 2rem;
733
+ margin-bottom: 2rem;
734
+ background: #f8f9fa;
735
+ border-radius: 12px;
736
+ }
737
+
738
+ .album-info-large {
739
+ display: flex;
740
+ gap: 2rem;
741
+ align-items: flex-start;
742
+ }
743
+
744
+ .album-art-large {
745
+ width: 200px;
746
+ height: 200px;
747
+ border-radius: 8px;
748
+ object-fit: cover;
749
+ }
750
+
751
+ .album-details {
752
+ flex: 1;
753
+ }
754
+
755
+ .album-details h2 {
756
+ margin-bottom: 0.5rem;
757
+ font-size: 2rem;
758
+ }
759
+
760
+ .album-details p {
761
+ color: #666;
762
+ margin-bottom: 0.5rem;
763
+ }
764
+
765
+ .play-album-btn {
766
+ margin-top: 1rem;
767
+ background: #1a73e8;
768
+ color: white;
769
+ padding: 0.75rem 1.5rem;
770
+ border-radius: 20px;
771
+ font-size: 1rem;
772
+ }
773
+
774
+ .play-album-btn:hover {
775
+ background: #1557b0;
776
+ }
777
+
778
+ .track-number {
779
+ color: #666;
780
+ margin-right: 1rem;
781
+ min-width: 2rem;
782
+ }
783
+
784
+ .music-item .track-info {
785
+ display: flex;
786
+ align-items: center;
787
+ }
788
+
789
+ /* Mobile menu button */
790
+ .mobile-menu-btn {
791
+ display: none;
792
+ position: fixed;
793
+ top: 1rem;
794
+ left: 1rem;
795
+ z-index: 1000;
796
+ background: white;
797
+ border: none;
798
+ padding: 0.5rem;
799
+ border-radius: 50%;
800
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
801
+ cursor: pointer;
802
+ }
803
+
804
+ /* Media queries for responsive design */
805
+ @media (max-width: 768px) {
806
  .container {
807
  grid-template-columns: 1fr;
808
  }
809
 
810
+ .mobile-menu-btn {
811
+ display: block;
812
+ }
813
+
814
  .sidebar {
815
  position: fixed;
816
+ left: -100%;
817
  top: 0;
818
  bottom: 0;
819
+ width: 80%;
820
+ max-width: 300px;
821
+ z-index: 1000;
822
+ transition: left 0.3s ease;
823
  }
824
 
825
  .sidebar.active {
826
+ left: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827
  }
828
 
829
+ .now-playing {
830
+ grid-template-columns: auto 1fr;
831
  }
832
 
833
  .lyrics-container {
834
  display: none;
835
  }
836
 
837
+ .main-content {
838
+ margin-bottom: 120px; /* Space for player */
 
 
 
 
 
 
 
 
 
 
 
 
839
  }
840
+ }
841
 
842
+ /* Dark mode support */
843
+ @media (prefers-color-scheme: dark) {
844
+ :root {
845
+ --bg-color: #121212;
846
+ --text-color: #ffffff;
847
+ --secondary-color: #282828;
 
 
 
 
848
  }
849
 
850
+ .sidebar,
851
+ .music-player,
852
+ .music-item {
853
+ background: #282828;
854
  }
 
855
 
856
+ .modal-content {
857
+ background: #282828;
858
+ color: white;
859
+ }
 
 
 
860
  }
861
 
862
+ .sidebar-overlay {
863
+ position: fixed;
864
+ top: 0;
865
+ left: 0;
866
+ right: 0;
867
+ bottom: 0;
868
+ background: rgba(0, 0, 0, 0.5);
869
+ z-index: 999;
870
+ display: none;
871
  }
872
 
873
+ @media (max-width: 768px) {
874
+ .sidebar-overlay {
875
+ display: block;
 
 
 
 
 
876
  }
877
  }
878
 
templates/index.html CHANGED
@@ -8,33 +8,6 @@
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
9
  </head>
10
  <body>
11
- <button class="menu-toggle" id="menu-toggle">
12
- <i class="fas fa-bars"></i>
13
- </button>
14
-
15
- <div class="sidebar-overlay" id="sidebar-overlay"></div>
16
-
17
- <nav class="mobile-nav">
18
- <ul>
19
- <li><a href="#" data-view="all">
20
- <i class="fas fa-music"></i>
21
- <span>Songs</span>
22
- </a></li>
23
- <li><a href="#" data-view="albums">
24
- <i class="fas fa-compact-disc"></i>
25
- <span>Albums</span>
26
- </a></li>
27
- <li><a href="#" data-view="artists">
28
- <i class="fas fa-user"></i>
29
- <span>Artists</span>
30
- </a></li>
31
- <li><a href="#" data-view="playlists">
32
- <i class="fas fa-list"></i>
33
- <span>Playlists</span>
34
- </a></li>
35
- </ul>
36
- </nav>
37
-
38
  <div class="container">
39
  <div class="sidebar">
40
  <nav>
@@ -131,5 +104,39 @@
131
 
132
  <audio id="audio-player"></audio>
133
  <script src="{{ url_for('static', filename='player.js') }}"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  </body>
135
  </html>
 
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
9
  </head>
10
  <body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  <div class="container">
12
  <div class="sidebar">
13
  <nav>
 
104
 
105
  <audio id="audio-player"></audio>
106
  <script src="{{ url_for('static', filename='player.js') }}"></script>
107
+ <button class="mobile-menu-btn">
108
+ <i class="fas fa-bars"></i>
109
+ </button>
110
+ <script>
111
+ // Mobile menu handling
112
+ const mobileMenuBtn = document.querySelector('.mobile-menu-btn');
113
+ const sidebar = document.querySelector('.sidebar');
114
+ const overlay = document.createElement('div');
115
+ overlay.className = 'sidebar-overlay';
116
+
117
+ mobileMenuBtn.addEventListener('click', () => {
118
+ sidebar.classList.toggle('active');
119
+ if (sidebar.classList.contains('active')) {
120
+ document.body.appendChild(overlay);
121
+ } else {
122
+ overlay.remove();
123
+ }
124
+ });
125
+
126
+ overlay.addEventListener('click', () => {
127
+ sidebar.classList.remove('active');
128
+ overlay.remove();
129
+ });
130
+
131
+ // Close sidebar when clicking a menu item on mobile
132
+ document.querySelectorAll('.nav-menu a, .playlist-menu a').forEach(link => {
133
+ link.addEventListener('click', () => {
134
+ if (window.innerWidth <= 768) {
135
+ sidebar.classList.remove('active');
136
+ overlay.remove();
137
+ }
138
+ });
139
+ });
140
+ </script>
141
  </body>
142
  </html>