Upload 3 files
Browse files- index.html +8 -2
- script.js +90 -1
- 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/
|
| 109 |
-
<a href="
|
| 110 |
</div>
|
| 111 |
<small>© 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>© 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=
|
| 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 |
-
/*
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
}
|
| 236 |
|
| 237 |
-
/*
|
| 238 |
-
.
|
| 239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
}
|
|
|
|
| 241 |
|
| 242 |
-
/*
|
| 243 |
-
|
| 244 |
-
|
| 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 |
-
|
| 250 |
-
|
|
|
|
|
|
|
| 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; } }
|