api-ix commited on
Commit
100f2ed
·
verified ·
1 Parent(s): 37f65ea

Upload 3 files

Browse files
Files changed (3) hide show
  1. index.html +8 -2
  2. script.js +90 -1
  3. styles.css +69 -19
index.html CHANGED
@@ -14,9 +14,15 @@
14
  <script src="https://kit.fontawesome.com/64d58efce2.js" crossorigin="anonymous"></script>
15
  <!-- custom font + styles -->
16
  <link rel="stylesheet" href="styles.css"/>
 
 
17
  </head>
18
 
19
  <body>
 
 
 
 
20
  <!-- Liquid BG -->
21
  <div class="liquid-bg">
22
  <div class="orb orb-1"></div>
@@ -105,8 +111,8 @@
105
  <!-- Footer -->
106
  <footer>
107
  <div class="social">
108
- <a href="https://wa.me/2347039367" title="Support"><i class="fab fa-whatsapp"></i></a>
109
- <a href="https://github.com/your-github-profile" target="_blank"><i class="fab fa-github"></i></a>
110
  </div>
111
  <small>&copy; 2024 BLUE DEMON API</small>
112
  </footer>
 
14
  <script src="https://kit.fontawesome.com/64d58efce2.js" crossorigin="anonymous"></script>
15
  <!-- custom font + styles -->
16
  <link rel="stylesheet" href="styles.css"/>
17
+ <link rel="preload" href="./media/music.mp3" as="audio" />
18
+ <audio id="bgm" src="./media/music.mp3" loop muted playsinline></audio>
19
  </head>
20
 
21
  <body>
22
+ <div id="music-widget">
23
+ <button id="music-toggle" aria-label="Play / Pause music"><i class="fas fa-play"></i></button>
24
+ <span id="music-text">sound off</span>
25
+ </div>
26
  <!-- Liquid BG -->
27
  <div class="liquid-bg">
28
  <div class="orb orb-1"></div>
 
111
  <!-- Footer -->
112
  <footer>
113
  <div class="social">
114
+ <a href="https://wa.me/2347041039367" title="Support"><i class="fab fa-whatsapp"></i></a>
115
+ <a href="#"><i class="fab fa-github"></i></a>
116
  </div>
117
  <small>&copy; 2024 BLUE DEMON API</small>
118
  </footer>
script.js CHANGED
@@ -137,7 +137,7 @@ const endpoints = [
137
  },
138
  {
139
  name: "Npm stalker",
140
- path: "/api/npmcheck?package=baileys",
141
  method: "GET",
142
  params: ["package"],
143
  desc: "Info on an npm package",
@@ -450,3 +450,92 @@ window.scrollToSection = (id) =>
450
  document.getElementById(id).scrollIntoView({ behavior: "smooth" });
451
 
452
  init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  },
138
  {
139
  name: "Npm stalker",
140
+ path: "/api/npmcheck?package=Baileys",
141
  method: "GET",
142
  params: ["package"],
143
  desc: "Info on an npm package",
 
450
  document.getElementById(id).scrollIntoView({ behavior: "smooth" });
451
 
452
  init();
453
+ /* ====== DYNAMIC MAGIC ====== */
454
+
455
+ /* ---- auto-play music with widget ---- */
456
+ const bgm = document.getElementById('bgm');
457
+ const musicToggle = document.getElementById('music-toggle');
458
+ const musicText = document.getElementById('music-text');
459
+ let musicOn = false;
460
+
461
+ function toggleMusic() {
462
+ musicOn = !musicOn;
463
+ if (musicOn) {
464
+ bgm.muted = false;
465
+ bgm.play().catch(() => {});
466
+ musicToggle.innerHTML = '<i class="fas fa-pause"></i>';
467
+ musicText.textContent = 'sound on';
468
+ } else {
469
+ bgm.muted = true;
470
+ musicToggle.innerHTML = '<i class="fas fa-play"></i>';
471
+ musicText.textContent = 'sound off';
472
+ }
473
+ }
474
+ musicToggle.addEventListener('click', toggleMusic);
475
+
476
+ /* first user interaction un-mutes */
477
+ window.addEventListener('pointerdown', () => {
478
+ if (!musicOn) toggleMusic();
479
+ }, { once: true });
480
+
481
+ /* ---- cursor chasing orbs ---- */
482
+ document.addEventListener('pointermove', e => {
483
+ const { clientX, clientY } = e;
484
+ const { innerWidth, innerHeight } = window;
485
+ const x = (clientX / innerWidth - .5) * 30;
486
+ const y = (clientY / innerHeight - .5) * 30;
487
+ document.querySelectorAll('.orb').forEach((o, i) => {
488
+ const speed = 1 + i * .2;
489
+ o.style.transform = `translate(${x * speed}px, ${y * speed}px)`;
490
+ });
491
+ });
492
+
493
+ /* ---- header shrink on scroll ---- */
494
+ const header = document.querySelector('.header');
495
+ let last = 0;
496
+ addEventListener('scroll', () => {
497
+ const curr = scrollY;
498
+ header.classList.toggle('compact', curr > 80);
499
+ last = curr;
500
+ });
501
+
502
+ /* ---- ripple on buttons ---- */
503
+ function createRipple(e) {
504
+ const btn = e.currentTarget;
505
+ const circle = document.createElement('span');
506
+ const d = Math.max(btn.clientWidth, btn.clientHeight);
507
+ const rect = btn.getBoundingClientRect();
508
+ circle.style.width = circle.style.height = d + 'px';
509
+ circle.style.left = e.clientX - rect.left - d / 2 + 'px';
510
+ circle.style.top = e.clientY - rect.top - d / 2 + 'px';
511
+ circle.classList.add('ripple');
512
+ btn.appendChild(circle);
513
+ setTimeout(() => circle.remove(), 600);
514
+ }
515
+ document.querySelectorAll('.cta, .pill, .load-more, .btn-copy')
516
+ .forEach(b => b.addEventListener('pointerdown', createRipple));
517
+
518
+ /* ---- animate numbers on stat cards ---- */
519
+ function countUp(el, target) {
520
+ let cur = 0;
521
+ const inc = target / 60;
522
+ const t = setInterval(() => {
523
+ cur += inc;
524
+ if (cur >= target) { cur = target; clearInterval(t); }
525
+ el.textContent = Math.floor(cur).toLocaleString();
526
+ }, 16);
527
+ }
528
+ /* run when visible */
529
+ const io = new IntersectionObserver(entries => {
530
+ entries.forEach(e => {
531
+ if (e.isIntersecting) {
532
+ const card = e.target;
533
+ const num = card.querySelector('span');
534
+ if (num.dataset.done) return;
535
+ num.dataset.done = true;
536
+ const final = parseInt(num.textContent.replace(/,/g, ''), 10) || 0;
537
+ if (final) countUp(num, final);
538
+ }
539
+ });
540
+ }, { threshold: .6 });
541
+ document.querySelectorAll('.stat-card').forEach(c => io.observe(c));
styles.css CHANGED
@@ -14,9 +14,6 @@
14
  --text: #ffffff;
15
  --text2: #d2b48c;
16
  --radius: 16px;
17
- --glass-opacity: 0.8;
18
- --glass-blur: 10px;
19
- --tap-scale: 0.95;
20
  }
21
 
22
  /* 2. Apply Gagalin globally */
@@ -225,27 +222,80 @@ footer {
225
  .header { padding: 1rem; }
226
  nav { display: none; }
227
  }
 
228
 
229
- /* 13. Glassy Effect */
230
- .glassy {
231
- background: rgba(255, 255, 255, var(--glass-opacity));
232
- backdrop-filter: blur(var(--glass-blur));
233
- border: 1px solid rgba(255, 255, 255, 0.2);
234
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
 
237
- /* Apply glassy effect to specific elements */
238
- .header, .stat-card, .card, .modal-card, .docs, .load-more {
239
- @extend .glassy;
 
 
 
 
 
 
 
 
240
  }
 
241
 
242
- /* 14. Tap Animation */
243
- @keyframes tap-animation {
244
- 0% { transform: scale(1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
245
- 50% { transform: scale(var(--tap-scale)); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); }
246
- 100% { transform: scale(1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
247
  }
 
248
 
249
- .card:active {
250
- animation: tap-animation 0.2s forwards;
 
 
251
  }
 
 
 
 
14
  --text: #ffffff;
15
  --text2: #d2b48c;
16
  --radius: 16px;
 
 
 
17
  }
18
 
19
  /* 2. Apply Gagalin globally */
 
222
  .header { padding: 1rem; }
223
  nav { display: none; }
224
  }
225
+ /* ====== DYNAMIC EYE-CANDY ====== */
226
 
227
+ /* ---- music widget ---- */
228
+ #music-widget {
229
+ position: fixed;
230
+ bottom: 2rem;
231
+ right: 2rem;
232
+ z-index: 200;
233
+ display: flex;
234
+ align-items: center;
235
+ gap: .6rem;
236
+ background: var(--surface);
237
+ border: 1px solid var(--border);
238
+ border-radius: 50px;
239
+ padding: .5rem 1rem;
240
+ backdrop-filter: blur(12px);
241
+ animation: slideIn .6s ease-out;
242
+ }
243
+ #music-toggle {
244
+ width: 36px;
245
+ height: 36px;
246
+ border-radius: 50%;
247
+ border: none;
248
+ background: var(--accent);
249
+ color: #000;
250
+ font-size: 1rem;
251
+ cursor: pointer;
252
+ transition: transform .2s;
253
+ }
254
+ #music-toggle:hover { transform: scale(1.15); }
255
+ #music-text { font-size: .75rem; color: var(--text2); }
256
+
257
+ /* ---- cursor chasing orbs ---- */
258
+ .orb {
259
+ will-change: transform;
260
+ transition: transform .6s ease-out;
261
+ }
262
+ body:hover .orb { animation: none; } /* pause default drift on hover */
263
+
264
+ /* ---- 3-D tilt cards ---- */
265
+ .card {
266
+ transform-style: preserve-3d;
267
+ transition: transform .3s ease, box-shadow .3s ease;
268
+ }
269
+ .card:hover {
270
+ transform: perspective(1000px) rotateX(6deg) rotateY(-6deg) scale(1.05);
271
+ box-shadow: 0 20px 40px rgba(255, 179, 71, .45);
272
  }
273
 
274
+ /* ---- button ripple ---- */
275
+ .cta, .pill, .load-more, .btn-copy {
276
+ position: relative;
277
+ overflow: hidden;
278
+ }
279
+ .ripple {
280
+ position: absolute;
281
+ border-radius: 50%;
282
+ background: rgba(255, 255, 255, .6);
283
+ transform: scale(0);
284
+ animation: ripple .6s ease-out;
285
  }
286
+ @keyframes ripple { to { transform: scale(4); opacity: 0; } }
287
 
288
+ /* ---- header auto-shrink ---- */
289
+ .header {
290
+ transition: padding .3s, background .3s;
 
 
291
  }
292
+ .header.compact { padding: .6rem 2rem; background: rgba(0, 0, 0, .45); }
293
 
294
+ /* ---- number count-up ---- */
295
+ .stat-card span {
296
+ display: inline-block;
297
+ min-width: 3rem; /* avoid jump */
298
  }
299
+
300
+ /* ---- micro-animations ---- */
301
+ @keyframes slideIn { from { transform: translateY(30px); opacity: 0; } }