tunecamp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/.env.local +2 -0
  2. package/.vercel/README.txt +11 -0
  3. package/.vercel/project.json +1 -0
  4. package/LICENSE +22 -0
  5. package/README.md +554 -0
  6. package/dist/cli.d.ts +6 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +172 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/generator/embedGenerator.d.ts +38 -0
  11. package/dist/generator/embedGenerator.d.ts.map +1 -0
  12. package/dist/generator/embedGenerator.js +92 -0
  13. package/dist/generator/embedGenerator.js.map +1 -0
  14. package/dist/generator/feedGenerator.d.ts +50 -0
  15. package/dist/generator/feedGenerator.d.ts.map +1 -0
  16. package/dist/generator/feedGenerator.js +167 -0
  17. package/dist/generator/feedGenerator.js.map +1 -0
  18. package/dist/generator/podcastFeedGenerator.d.ts +54 -0
  19. package/dist/generator/podcastFeedGenerator.d.ts.map +1 -0
  20. package/dist/generator/podcastFeedGenerator.js +173 -0
  21. package/dist/generator/podcastFeedGenerator.js.map +1 -0
  22. package/dist/generator/proceduralCoverGenerator.d.ts +51 -0
  23. package/dist/generator/proceduralCoverGenerator.d.ts.map +1 -0
  24. package/dist/generator/proceduralCoverGenerator.js +228 -0
  25. package/dist/generator/proceduralCoverGenerator.js.map +1 -0
  26. package/dist/generator/siteGenerator.d.ts +55 -0
  27. package/dist/generator/siteGenerator.d.ts.map +1 -0
  28. package/dist/generator/siteGenerator.js +539 -0
  29. package/dist/generator/siteGenerator.js.map +1 -0
  30. package/dist/generator/templateEngine.d.ts +13 -0
  31. package/dist/generator/templateEngine.d.ts.map +1 -0
  32. package/dist/generator/templateEngine.js +146 -0
  33. package/dist/generator/templateEngine.js.map +1 -0
  34. package/dist/index.d.ts +12 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +32 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/parser/catalogParser.d.ts +13 -0
  39. package/dist/parser/catalogParser.d.ts.map +1 -0
  40. package/dist/parser/catalogParser.js +120 -0
  41. package/dist/parser/catalogParser.js.map +1 -0
  42. package/dist/tools/generate-codes.d.ts +14 -0
  43. package/dist/tools/generate-codes.d.ts.map +1 -0
  44. package/dist/tools/generate-codes.js +274 -0
  45. package/dist/tools/generate-codes.js.map +1 -0
  46. package/dist/tools/generate-sea-pair.d.ts +14 -0
  47. package/dist/tools/generate-sea-pair.d.ts.map +1 -0
  48. package/dist/tools/generate-sea-pair.js +111 -0
  49. package/dist/tools/generate-sea-pair.js.map +1 -0
  50. package/dist/types/index.d.ts +117 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/index.js +5 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/dist/utils/audioUtils.d.ts +9 -0
  55. package/dist/utils/audioUtils.d.ts.map +1 -0
  56. package/dist/utils/audioUtils.js +67 -0
  57. package/dist/utils/audioUtils.js.map +1 -0
  58. package/dist/utils/configUtils.d.ts +11 -0
  59. package/dist/utils/configUtils.d.ts.map +1 -0
  60. package/dist/utils/configUtils.js +50 -0
  61. package/dist/utils/configUtils.js.map +1 -0
  62. package/dist/utils/fileUtils.d.ts +14 -0
  63. package/dist/utils/fileUtils.d.ts.map +1 -0
  64. package/dist/utils/fileUtils.js +73 -0
  65. package/dist/utils/fileUtils.js.map +1 -0
  66. package/examples/artist-free/README.md +36 -0
  67. package/examples/artist-paycurtain/README.md +49 -0
  68. package/examples/label/README.md +33 -0
  69. package/gundb-keypair.json +8 -0
  70. package/logo.svg +30 -0
  71. package/package-lock.json +1176 -0
  72. package/package.json +42 -0
  73. package/public/assets/community-registry.js +291 -0
  74. package/public/assets/download-stats.js +263 -0
  75. package/public/assets/player.js +219 -0
  76. package/public/assets/style.css +1170 -0
  77. package/public/assets/theme-widget.js +353 -0
  78. package/public/assets/unlock-codes.js +225 -0
  79. package/public/atom.xml +22 -0
  80. package/public/catalog.m3u +3 -0
  81. package/public/feed.xml +22 -0
  82. package/public/image.png +0 -0
  83. package/public/index.html +249 -0
  84. package/public/logo.svg +30 -0
  85. package/public/releases/chirichetto/Homologo - Chirichetto.wav +0 -0
  86. package/public/releases/chirichetto/cover.png +0 -0
  87. package/public/releases/chirichetto/embed-code.txt +16 -0
  88. package/public/releases/chirichetto/embed-compact.txt +8 -0
  89. package/public/releases/chirichetto/embed.html +39 -0
  90. package/public/releases/chirichetto/index.html +389 -0
  91. package/public/releases/chirichetto/playlist.m3u +3 -0
  92. package/templates/dark/assets/community-registry.js +291 -0
  93. package/templates/dark/assets/download-stats.js +263 -0
  94. package/templates/dark/assets/player.js +219 -0
  95. package/templates/dark/assets/style.css +740 -0
  96. package/templates/dark/index.hbs +73 -0
  97. package/templates/dark/layout.hbs +84 -0
  98. package/templates/dark/release.hbs +212 -0
  99. package/templates/default/assets/community-registry.js +291 -0
  100. package/templates/default/assets/download-stats.js +263 -0
  101. package/templates/default/assets/player.js +219 -0
  102. package/templates/default/assets/style.css +1170 -0
  103. package/templates/default/assets/theme-widget.js +353 -0
  104. package/templates/default/assets/unlock-codes.js +225 -0
  105. package/templates/default/index.hbs +188 -0
  106. package/templates/default/layout.hbs +117 -0
  107. package/templates/default/release.hbs +553 -0
  108. package/templates/minimal/assets/community-registry.js +291 -0
  109. package/templates/minimal/assets/download-stats.js +263 -0
  110. package/templates/minimal/assets/player.js +219 -0
  111. package/templates/minimal/assets/style.css +796 -0
  112. package/templates/minimal/index.hbs +73 -0
  113. package/templates/minimal/layout.hbs +84 -0
  114. package/templates/minimal/release.hbs +212 -0
  115. package/templates/retro/assets/community-registry.js +291 -0
  116. package/templates/retro/assets/download-stats.js +263 -0
  117. package/templates/retro/assets/player.js +219 -0
  118. package/templates/retro/assets/style.css +872 -0
  119. package/templates/retro/index.hbs +73 -0
  120. package/templates/retro/layout.hbs +84 -0
  121. package/templates/retro/release.hbs +212 -0
  122. package/templates/translucent/assets/community-registry.js +291 -0
  123. package/templates/translucent/assets/download-stats.js +263 -0
  124. package/templates/translucent/assets/player.js +219 -0
  125. package/templates/translucent/assets/style.css +1352 -0
  126. package/templates/translucent/index.hbs +73 -0
  127. package/templates/translucent/layout.hbs +84 -0
  128. package/templates/translucent/release.hbs +212 -0
  129. package/website/community.html +492 -0
  130. package/website/index.html +195 -0
  131. package/website/styles.css +396 -0
  132. package/website/tunecamp.svg +30 -0
@@ -0,0 +1,740 @@
1
+ /* Tunecamp - Dark Theme */
2
+
3
+ :root {
4
+ --primary-color: #ef4444;
5
+ --secondary-color: #dc2626;
6
+ --bg-color: #000000;
7
+ --surface-color: #0a0a0a;
8
+ --surface-elevated: #141414;
9
+ --text-color: #ffffff;
10
+ --text-muted: #a3a3a3;
11
+ --border-color: #262626;
12
+ --success-color: #22c55e;
13
+ --warning-color: #f59e0b;
14
+ }
15
+
16
+ * {
17
+ margin: 0;
18
+ padding: 0;
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ body {
23
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
24
+ background: var(--bg-color);
25
+ color: var(--text-color);
26
+ line-height: 1.6;
27
+ }
28
+
29
+ .container {
30
+ max-width: 1400px;
31
+ margin: 0 auto;
32
+ padding: 2rem;
33
+ }
34
+
35
+ /* Header */
36
+ .site-header {
37
+ background: var(--bg-color);
38
+ border-bottom: 2px solid var(--primary-color);
39
+ padding: 2.5rem 0;
40
+ margin-bottom: 3rem;
41
+ }
42
+
43
+ .site-title {
44
+ font-size: 3rem;
45
+ margin-bottom: 0.5rem;
46
+ font-weight: 900;
47
+ text-transform: uppercase;
48
+ letter-spacing: 2px;
49
+ }
50
+
51
+ .site-title a {
52
+ color: var(--text-color);
53
+ text-decoration: none;
54
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
55
+ -webkit-background-clip: text;
56
+ -webkit-text-fill-color: transparent;
57
+ background-clip: text;
58
+ }
59
+
60
+ /* Header Image (Bandcamp-style) */
61
+ .site-header-image {
62
+ margin-bottom: 1.5rem;
63
+ width: 100%;
64
+ text-align: center;
65
+ }
66
+
67
+ .site-header-image a {
68
+ display: block;
69
+ text-decoration: none;
70
+ width: 100%;
71
+ }
72
+
73
+ .header-image {
74
+ width: 100%;
75
+ max-width: 100%;
76
+ height: auto;
77
+ max-height: 400px;
78
+ min-height: 200px;
79
+ display: block;
80
+ margin: 0 auto;
81
+ object-fit: contain;
82
+ object-position: center;
83
+ }
84
+
85
+ @media (max-width: 768px) {
86
+ .header-image {
87
+ max-height: 250px;
88
+ min-height: 120px;
89
+ }
90
+ }
91
+
92
+ .site-description {
93
+ color: var(--text-muted);
94
+ font-size: 1.1rem;
95
+ text-transform: uppercase;
96
+ letter-spacing: 1px;
97
+ font-weight: 500;
98
+ }
99
+
100
+ /* Artist Section */
101
+ .artist-section {
102
+ margin-bottom: 4rem;
103
+ padding: 2rem;
104
+ background: var(--surface-color);
105
+ border: 1px solid var(--border-color);
106
+ border-left: 4px solid var(--primary-color);
107
+ }
108
+
109
+ .artist-header {
110
+ display: flex;
111
+ gap: 2rem;
112
+ align-items: center;
113
+ }
114
+
115
+ .artist-photo {
116
+ width: 150px;
117
+ height: 150px;
118
+ border-radius: 0;
119
+ object-fit: cover;
120
+ border: 3px solid var(--primary-color);
121
+ box-shadow: 8px 8px 0 var(--primary-color);
122
+ }
123
+
124
+ .artist-info h2 {
125
+ font-size: 2.25rem;
126
+ margin-bottom: 1rem;
127
+ font-weight: 900;
128
+ text-transform: uppercase;
129
+ letter-spacing: 1px;
130
+ }
131
+
132
+ .artist-bio {
133
+ color: var(--text-muted);
134
+ line-height: 1.8;
135
+ }
136
+
137
+ /* Releases Grid */
138
+ .releases-section h2 {
139
+ font-size: 2.25rem;
140
+ margin-bottom: 2.5rem;
141
+ font-weight: 900;
142
+ text-transform: uppercase;
143
+ letter-spacing: 2px;
144
+ position: relative;
145
+ padding-bottom: 1rem;
146
+ }
147
+
148
+ .releases-section h2::after {
149
+ content: '';
150
+ position: absolute;
151
+ bottom: 0;
152
+ left: 0;
153
+ width: 60px;
154
+ height: 4px;
155
+ background: var(--primary-color);
156
+ }
157
+
158
+ .releases-grid {
159
+ display: grid;
160
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
161
+ gap: 2.5rem;
162
+ }
163
+
164
+ .release-card {
165
+ background: var(--surface-color);
166
+ border: 1px solid var(--border-color);
167
+ overflow: hidden;
168
+ transition: all 0.3s;
169
+ position: relative;
170
+ }
171
+
172
+ .release-card::before {
173
+ content: '';
174
+ position: absolute;
175
+ top: 0;
176
+ left: 0;
177
+ right: 0;
178
+ height: 4px;
179
+ background: var(--primary-color);
180
+ transform: scaleX(0);
181
+ transition: transform 0.3s;
182
+ }
183
+
184
+ .release-card:hover::before {
185
+ transform: scaleX(1);
186
+ }
187
+
188
+ .release-card:hover {
189
+ transform: translateY(-8px);
190
+ box-shadow: 0 20px 40px rgba(239, 68, 68, 0.3);
191
+ border-color: var(--primary-color);
192
+ }
193
+
194
+ .release-link {
195
+ text-decoration: none;
196
+ color: inherit;
197
+ display: block;
198
+ }
199
+
200
+ .release-cover {
201
+ aspect-ratio: 1;
202
+ overflow: hidden;
203
+ background: var(--surface-elevated);
204
+ }
205
+
206
+ .release-cover img {
207
+ width: 100%;
208
+ height: 100%;
209
+ object-fit: cover;
210
+ display: block;
211
+ transition: transform 0.3s;
212
+ }
213
+
214
+ .release-card:hover .release-cover img {
215
+ transform: scale(1.05);
216
+ }
217
+
218
+ .release-cover-placeholder {
219
+ display: flex;
220
+ align-items: center;
221
+ justify-content: center;
222
+ font-size: 4rem;
223
+ color: var(--border-color);
224
+ }
225
+
226
+ .release-info {
227
+ padding: 1.5rem;
228
+ }
229
+
230
+ .release-title {
231
+ font-size: 1.25rem;
232
+ margin-bottom: 0.5rem;
233
+ font-weight: 700;
234
+ text-transform: uppercase;
235
+ letter-spacing: 0.5px;
236
+ }
237
+
238
+ .release-date {
239
+ color: var(--text-muted);
240
+ font-size: 0.85rem;
241
+ margin-bottom: 1rem;
242
+ text-transform: uppercase;
243
+ letter-spacing: 1px;
244
+ }
245
+
246
+ .release-genres {
247
+ display: flex;
248
+ gap: 0.5rem;
249
+ flex-wrap: wrap;
250
+ margin-bottom: 1rem;
251
+ }
252
+
253
+ .genre-tag {
254
+ background: var(--surface-elevated);
255
+ border: 1px solid var(--primary-color);
256
+ color: var(--primary-color);
257
+ padding: 0.25rem 0.75rem;
258
+ border-radius: 0;
259
+ font-size: 0.75rem;
260
+ font-weight: 600;
261
+ text-transform: uppercase;
262
+ letter-spacing: 0.5px;
263
+ }
264
+
265
+ .release-tracks-count {
266
+ color: var(--text-muted);
267
+ font-size: 0.85rem;
268
+ margin-bottom: 1rem;
269
+ text-transform: uppercase;
270
+ }
271
+
272
+ .release-download-badge {
273
+ background: var(--primary-color);
274
+ color: var(--bg-color);
275
+ padding: 0.5rem 1rem;
276
+ border-radius: 0;
277
+ font-size: 0.75rem;
278
+ display: inline-block;
279
+ font-weight: 700;
280
+ text-transform: uppercase;
281
+ letter-spacing: 1px;
282
+ }
283
+
284
+ /* Release Detail */
285
+ .breadcrumb {
286
+ margin-bottom: 2rem;
287
+ }
288
+
289
+ .breadcrumb a {
290
+ color: var(--primary-color);
291
+ text-decoration: none;
292
+ text-transform: uppercase;
293
+ font-size: 0.85rem;
294
+ font-weight: 600;
295
+ letter-spacing: 1px;
296
+ }
297
+
298
+ .breadcrumb a:hover {
299
+ text-decoration: underline;
300
+ }
301
+
302
+ .release-header {
303
+ display: grid;
304
+ grid-template-columns: 450px 1fr;
305
+ gap: 4rem;
306
+ margin-bottom: 4rem;
307
+ }
308
+
309
+ .release-cover-large {
310
+ position: relative;
311
+ }
312
+
313
+ .release-cover-large img {
314
+ width: 100%;
315
+ box-shadow: 16px 16px 0 var(--primary-color);
316
+ }
317
+
318
+ .release-metadata h1 {
319
+ font-size: 3rem;
320
+ margin-bottom: 0.5rem;
321
+ font-weight: 900;
322
+ text-transform: uppercase;
323
+ letter-spacing: 1px;
324
+ }
325
+
326
+ .release-artist {
327
+ font-size: 1.5rem;
328
+ color: var(--primary-color);
329
+ margin-bottom: 1rem;
330
+ font-weight: 700;
331
+ text-transform: uppercase;
332
+ }
333
+
334
+ .release-description {
335
+ line-height: 1.8;
336
+ margin: 1.5rem 0;
337
+ color: var(--text-muted);
338
+ }
339
+
340
+ .release-credits {
341
+ margin: 1.5rem 0;
342
+ padding: 1.5rem;
343
+ background: var(--surface-color);
344
+ border-left: 4px solid var(--primary-color);
345
+ }
346
+
347
+ .release-credits h3 {
348
+ margin-bottom: 0.5rem;
349
+ font-weight: 700;
350
+ text-transform: uppercase;
351
+ letter-spacing: 1px;
352
+ }
353
+
354
+ .release-credits ul {
355
+ list-style: none;
356
+ color: var(--text-muted);
357
+ }
358
+
359
+ .btn {
360
+ padding: 1rem 2rem;
361
+ border: 2px solid var(--primary-color);
362
+ border-radius: 0;
363
+ font-size: 0.9rem;
364
+ cursor: pointer;
365
+ transition: all 0.3s;
366
+ display: inline-flex;
367
+ align-items: center;
368
+ gap: 0.5rem;
369
+ font-weight: 700;
370
+ text-transform: uppercase;
371
+ letter-spacing: 1px;
372
+ position: relative;
373
+ }
374
+
375
+ .btn-primary {
376
+ background: var(--primary-color);
377
+ color: var(--bg-color);
378
+ }
379
+
380
+ .btn-primary:hover {
381
+ background: var(--bg-color);
382
+ color: var(--primary-color);
383
+ box-shadow: 0 0 20px rgba(239, 68, 68, 0.5);
384
+ }
385
+
386
+ /* Audio Player */
387
+ .audio-player {
388
+ background: var(--surface-color);
389
+ padding: 2.5rem;
390
+ margin-bottom: 3rem;
391
+ border: 1px solid var(--border-color);
392
+ border-left: 4px solid var(--primary-color);
393
+ }
394
+
395
+ .player-track-info {
396
+ display: flex;
397
+ gap: 1.5rem;
398
+ margin-bottom: 2rem;
399
+ align-items: center;
400
+ }
401
+
402
+ .player-cover {
403
+ width: 90px;
404
+ height: 90px;
405
+ overflow: hidden;
406
+ background: var(--surface-elevated);
407
+ display: flex;
408
+ align-items: center;
409
+ justify-content: center;
410
+ font-size: 2rem;
411
+ color: var(--border-color);
412
+ border: 2px solid var(--primary-color);
413
+ }
414
+
415
+ .player-cover img {
416
+ width: 100%;
417
+ height: 100%;
418
+ object-fit: cover;
419
+ }
420
+
421
+ .player-title {
422
+ font-size: 1.25rem;
423
+ font-weight: 700;
424
+ text-transform: uppercase;
425
+ letter-spacing: 0.5px;
426
+ }
427
+
428
+ .player-artist {
429
+ color: var(--text-muted);
430
+ font-size: 0.9rem;
431
+ text-transform: uppercase;
432
+ letter-spacing: 1px;
433
+ }
434
+
435
+ .player-controls {
436
+ display: flex;
437
+ justify-content: center;
438
+ gap: 1.5rem;
439
+ margin-bottom: 2rem;
440
+ }
441
+
442
+ .player-btn {
443
+ background: var(--surface-elevated);
444
+ border: 2px solid var(--border-color);
445
+ color: var(--text-color);
446
+ width: 56px;
447
+ height: 56px;
448
+ border-radius: 0;
449
+ cursor: pointer;
450
+ transition: all 0.3s;
451
+ font-size: 1.2rem;
452
+ }
453
+
454
+ .player-btn-play {
455
+ width: 70px;
456
+ height: 70px;
457
+ background: var(--primary-color);
458
+ color: var(--bg-color);
459
+ border-color: var(--primary-color);
460
+ }
461
+
462
+ .player-btn:hover {
463
+ border-color: var(--primary-color);
464
+ background: var(--primary-color);
465
+ color: var(--bg-color);
466
+ box-shadow: 0 0 20px rgba(239, 68, 68, 0.5);
467
+ }
468
+
469
+ .player-progress {
470
+ display: flex;
471
+ align-items: center;
472
+ gap: 1.5rem;
473
+ margin-bottom: 1.5rem;
474
+ }
475
+
476
+ .player-time {
477
+ color: var(--text-muted);
478
+ font-size: 0.9rem;
479
+ min-width: 45px;
480
+ font-variant-numeric: tabular-nums;
481
+ font-weight: 600;
482
+ }
483
+
484
+ .progress-bar {
485
+ flex: 1;
486
+ height: 8px;
487
+ -webkit-appearance: none;
488
+ appearance: none;
489
+ background: var(--surface-elevated);
490
+ border: 1px solid var(--border-color);
491
+ outline: none;
492
+ }
493
+
494
+ .progress-bar::-webkit-slider-thumb {
495
+ -webkit-appearance: none;
496
+ appearance: none;
497
+ width: 18px;
498
+ height: 18px;
499
+ background: var(--primary-color);
500
+ border-radius: 0;
501
+ cursor: pointer;
502
+ box-shadow: 0 0 10px rgba(239, 68, 68, 0.5);
503
+ }
504
+
505
+ .player-volume {
506
+ display: flex;
507
+ align-items: center;
508
+ gap: 1rem;
509
+ max-width: 220px;
510
+ color: var(--text-muted);
511
+ }
512
+
513
+ .volume-bar {
514
+ flex: 1;
515
+ height: 6px;
516
+ -webkit-appearance: none;
517
+ appearance: none;
518
+ background: var(--surface-elevated);
519
+ border: 1px solid var(--border-color);
520
+ }
521
+
522
+ .volume-bar::-webkit-slider-thumb {
523
+ -webkit-appearance: none;
524
+ appearance: none;
525
+ width: 14px;
526
+ height: 14px;
527
+ background: var(--primary-color);
528
+ border-radius: 0;
529
+ cursor: pointer;
530
+ }
531
+
532
+ /* Track List */
533
+ .tracklist h2 {
534
+ font-size: 1.75rem;
535
+ margin-bottom: 2rem;
536
+ font-weight: 900;
537
+ text-transform: uppercase;
538
+ letter-spacing: 1px;
539
+ }
540
+
541
+ .track-list {
542
+ list-style: none;
543
+ }
544
+
545
+ .track-item {
546
+ display: flex;
547
+ align-items: center;
548
+ gap: 1.5rem;
549
+ padding: 1.25rem;
550
+ background: var(--surface-color);
551
+ border: 1px solid var(--border-color);
552
+ margin-bottom: 0.5rem;
553
+ transition: all 0.3s;
554
+ position: relative;
555
+ }
556
+
557
+ .track-item::before {
558
+ content: '';
559
+ position: absolute;
560
+ left: 0;
561
+ top: 0;
562
+ bottom: 0;
563
+ width: 4px;
564
+ background: var(--primary-color);
565
+ transform: scaleY(0);
566
+ transition: transform 0.3s;
567
+ }
568
+
569
+ .track-item:hover::before,
570
+ .track-item.playing::before {
571
+ transform: scaleY(1);
572
+ }
573
+
574
+ .track-item:hover {
575
+ background: var(--surface-elevated);
576
+ border-color: var(--primary-color);
577
+ }
578
+
579
+ .track-item.playing {
580
+ border-color: var(--primary-color);
581
+ background: var(--surface-elevated);
582
+ }
583
+
584
+ .track-number {
585
+ width: 40px;
586
+ text-align: center;
587
+ color: var(--text-muted);
588
+ font-size: 1.1rem;
589
+ font-variant-numeric: tabular-nums;
590
+ font-weight: 700;
591
+ }
592
+
593
+ .track-info {
594
+ flex: 1;
595
+ }
596
+
597
+ .track-title {
598
+ font-weight: 600;
599
+ margin-bottom: 0.25rem;
600
+ text-transform: uppercase;
601
+ letter-spacing: 0.5px;
602
+ }
603
+
604
+ .track-meta {
605
+ font-size: 0.8rem;
606
+ color: var(--text-muted);
607
+ text-transform: uppercase;
608
+ }
609
+
610
+ .track-actions {
611
+ display: flex;
612
+ gap: 0.75rem;
613
+ }
614
+
615
+ .track-play-btn,
616
+ .track-download-btn {
617
+ background: var(--surface-elevated);
618
+ border: 2px solid var(--border-color);
619
+ color: var(--text-color);
620
+ width: 40px;
621
+ height: 40px;
622
+ border-radius: 0;
623
+ cursor: pointer;
624
+ display: flex;
625
+ align-items: center;
626
+ justify-content: center;
627
+ transition: all 0.3s;
628
+ text-decoration: none;
629
+ font-size: 0.9rem;
630
+ }
631
+
632
+ .track-play-btn:hover,
633
+ .track-download-btn:hover {
634
+ background: var(--primary-color);
635
+ color: var(--bg-color);
636
+ border-color: var(--primary-color);
637
+ box-shadow: 0 0 15px rgba(239, 68, 68, 0.5);
638
+ }
639
+
640
+ /* Footer */
641
+ .site-footer {
642
+ background: var(--bg-color);
643
+ border-top: 2px solid var(--primary-color);
644
+ padding: 3rem 0;
645
+ margin-top: 5rem;
646
+ text-align: center;
647
+ color: var(--text-muted);
648
+ }
649
+
650
+ .site-footer a {
651
+ color: var(--primary-color);
652
+ text-decoration: none;
653
+ font-weight: 600;
654
+ }
655
+
656
+ .social-links {
657
+ margin-top: 1.5rem;
658
+ display: flex;
659
+ justify-content: center;
660
+ gap: 1rem;
661
+ }
662
+
663
+ .social-link {
664
+ width: 48px;
665
+ height: 48px;
666
+ border-radius: 0;
667
+ border: 2px solid var(--border-color);
668
+ background: var(--surface-color);
669
+ display: flex;
670
+ align-items: center;
671
+ justify-content: center;
672
+ font-size: 1.2rem;
673
+ transition: all 0.3s;
674
+ color: var(--text-muted);
675
+ }
676
+
677
+ .social-link:hover {
678
+ background: var(--primary-color);
679
+ color: var(--bg-color);
680
+ border-color: var(--primary-color);
681
+ box-shadow: 0 0 20px rgba(239, 68, 68, 0.5);
682
+ }
683
+
684
+ /* Responsive */
685
+ @media (max-width: 768px) {
686
+ .site-title {
687
+ font-size: 2rem;
688
+ }
689
+
690
+ .release-header {
691
+ grid-template-columns: 1fr;
692
+ }
693
+
694
+ .release-cover-large img {
695
+ box-shadow: 8px 8px 0 var(--primary-color);
696
+ }
697
+
698
+ .artist-header {
699
+ flex-direction: column;
700
+ text-align: center;
701
+ }
702
+
703
+ .releases-grid {
704
+ grid-template-columns: 1fr;
705
+ }
706
+ }
707
+
708
+ /* Tunecamp Footer */
709
+ .tunecamp-footer {
710
+ background: #1a1a1a;
711
+ border-top: 1px solid #333;
712
+ padding: 0.75rem 0;
713
+ margin-top: 2rem;
714
+ text-align: center;
715
+ }
716
+
717
+ .footer-content {
718
+ display: flex;
719
+ align-items: center;
720
+ justify-content: center;
721
+ gap: 0.5rem;
722
+ font-size: 0.9rem;
723
+ color: #ccc;
724
+ }
725
+
726
+ .tunecamp-link {
727
+ display: flex;
728
+ align-items: center;
729
+ gap: 0.5rem;
730
+ text-decoration: none;
731
+ color: #dc2626;
732
+ }
733
+
734
+
735
+ .footer-logo {
736
+ width: 20px;
737
+ height: 20px;
738
+ }
739
+
740
+