This commit is contained in:
parent
5e43f076c3
commit
d6960d0980
@ -3,13 +3,13 @@
|
|||||||
--border-color: #2a5a5a;
|
--border-color: #2a5a5a;
|
||||||
--text-muted: #88aaaa;
|
--text-muted: #88aaaa;
|
||||||
--text-bright: #cef0f0;
|
--text-bright: #cef0f0;
|
||||||
--glow-color: rgba(42, 90, 90, 0.4);
|
--glow-color: rgba(42, 90, 90, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0% {
|
0% {
|
||||||
box-shadow: 0 0 5px var(--glow-color);
|
box-shadow: 0 0 5px var(--glow-color);
|
||||||
opacity: 0.7;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
box-shadow: 0 0 10px var(--glow-color);
|
box-shadow: 0 0 10px var(--glow-color);
|
||||||
@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
box-shadow: 0 0 5px var(--glow-color);
|
box-shadow: 0 0 5px var(--glow-color);
|
||||||
opacity: 0.7;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,16 +482,21 @@ body::before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contact-link {
|
.contact-link {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--text-bright);
|
|
||||||
text-decoration: none;
|
|
||||||
padding: 15px;
|
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
padding: 15px;
|
||||||
|
margin: 15px 0;
|
||||||
|
cursor: pointer;
|
||||||
transition:
|
transition:
|
||||||
border-color 0.3s ease,
|
border-color 0.3s ease,
|
||||||
background-color 0.3s ease;
|
background-color 0.3s ease,
|
||||||
background: rgba(42, 90, 90, 0.05);
|
box-shadow 0.3s ease,
|
||||||
|
transform 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(42, 90, 90, 0.1),
|
||||||
|
rgba(42, 90, 90, 0.2)
|
||||||
|
);
|
||||||
clip-path: polygon(
|
clip-path: polygon(
|
||||||
0 0,
|
0 0,
|
||||||
98% 0,
|
98% 0,
|
||||||
@ -500,11 +505,28 @@ body::before {
|
|||||||
2% 100%,
|
2% 100%,
|
||||||
0 calc(100% - 15px)
|
0 calc(100% - 15px)
|
||||||
);
|
);
|
||||||
|
transform: translateZ(20px);
|
||||||
|
box-shadow:
|
||||||
|
0 5px 15px rgba(0, 0, 0, 0.4),
|
||||||
|
0 10px 20px rgba(42, 90, 90, 0.3),
|
||||||
|
inset 0 1px rgba(255, 255, 255, 0.2),
|
||||||
|
inset -2px -2px 4px rgba(0, 0, 0, 0.5);
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
perspective: 1000px;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
border-left: 3px solid rgba(42, 90, 90, 0.6);
|
||||||
|
border-top: 2px solid rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-link:hover {
|
.contact-link:hover {
|
||||||
border-color: var(--text-bright);
|
border-color: var(--text-bright);
|
||||||
background: rgba(42, 90, 90, 0.1);
|
background: rgba(42, 90, 90, 0.1);
|
||||||
|
box-shadow:
|
||||||
|
0 5px 15px rgba(0, 0, 0, 0.3),
|
||||||
|
0 10px 20px rgba(42, 90, 90, 0.2),
|
||||||
|
inset 0 1px rgba(255, 255, 255, 0.2);
|
||||||
|
transform: translateY(-2px) translateZ(10px);
|
||||||
|
animation: pulse 2s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-icon {
|
.contact-icon {
|
||||||
|
141
assets/index.js
141
assets/index.js
@ -2,24 +2,60 @@
|
|||||||
// atleast i'm not a reactfag.
|
// atleast i'm not a reactfag.
|
||||||
|
|
||||||
// we add some fancy text typing animation blah blah blah
|
// we add some fancy text typing animation blah blah blah
|
||||||
function writeoutnavlabel() {
|
// it is quite overcomplicated. i have no hobbies
|
||||||
const firstNavIcon = document.querySelector('.nav-icon[href="#about"]');
|
function writeoutnavlabel(label) {
|
||||||
const label = firstNavIcon.querySelector(".nav-label");
|
if (label.getAttribute("data-animating") === "true") return;
|
||||||
const text = label.textContent;
|
|
||||||
|
const text = label.getAttribute("data-text") || label.textContent;
|
||||||
|
label.setAttribute("data-text", text);
|
||||||
label.textContent = "";
|
label.textContent = "";
|
||||||
label.style.opacity = "1";
|
label.style.opacity = "1";
|
||||||
|
label.setAttribute("data-animating", "true");
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
function type() {
|
let animationInterval = setInterval(() => {
|
||||||
if (i < text.length) {
|
if (i < text.length) {
|
||||||
label.textContent += text.charAt(i);
|
label.textContent += text.charAt(i);
|
||||||
i++;
|
i++;
|
||||||
setTimeout(type, 180);
|
} else {
|
||||||
|
clearInterval(animationInterval);
|
||||||
|
label.setAttribute("data-animating", "false");
|
||||||
|
const icon = label.closest(".nav-icon");
|
||||||
|
if (icon) {
|
||||||
|
icon.isAnimating = false;
|
||||||
|
icon.hoverAnimationDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 180);
|
||||||
|
|
||||||
|
label.setAttribute("data-animation-interval", animationInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
function eraselabel(label) {
|
||||||
|
if (label.getAttribute("data-animating") === "true") {
|
||||||
|
// clear the existing interval
|
||||||
|
const existingInterval = label.getAttribute("data-animation-interval");
|
||||||
|
if (existingInterval) {
|
||||||
|
clearInterval(existingInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// why am i using a function inside a function?
|
|
||||||
// i don't know. i'm sorry.
|
label.setAttribute("data-animating", "true");
|
||||||
type();
|
|
||||||
|
let eraseInterval = setInterval(() => {
|
||||||
|
const currentText = label.textContent;
|
||||||
|
if (currentText.length > 0) {
|
||||||
|
label.textContent = currentText.slice(0, -1);
|
||||||
|
} else {
|
||||||
|
clearInterval(eraseInterval);
|
||||||
|
label.setAttribute("data-animating", "false");
|
||||||
|
label.style.opacity = "0";
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
// store the interval so we can clear it if needed
|
||||||
|
// this is a terrible way to do this like horrible
|
||||||
|
label.setAttribute("data-animation-interval", eraseInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTime() {
|
function updateTime() {
|
||||||
@ -88,7 +124,7 @@ function getStatusClass(service) {
|
|||||||
if (service.latency > 500000) return "status-warning";
|
if (service.latency > 500000) return "status-warning";
|
||||||
return "status-online";
|
return "status-online";
|
||||||
}
|
}
|
||||||
|
// not sure if this is the best way to do this
|
||||||
function getGroupName(groupId) {
|
function getGroupName(groupId) {
|
||||||
const groupNames = {
|
const groupNames = {
|
||||||
4: "INFRASTRUCTURE",
|
4: "INFRASTRUCTURE",
|
||||||
@ -98,8 +134,8 @@ function getGroupName(groupId) {
|
|||||||
return groupNames[groupId] || `GROUP ${groupId}`;
|
return groupNames[groupId] || `GROUP ${groupId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// populate status page first
|
||||||
function createStatusHTML(services) {
|
function createStatusHTML(services) {
|
||||||
// Group services by group_id
|
|
||||||
const groups = services.reduce((acc, service) => {
|
const groups = services.reduce((acc, service) => {
|
||||||
const groupId = service.group_id;
|
const groupId = service.group_id;
|
||||||
if (!acc[groupId]) acc[groupId] = [];
|
if (!acc[groupId]) acc[groupId] = [];
|
||||||
@ -136,6 +172,7 @@ function createStatusHTML(services) {
|
|||||||
.join("");
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// status page func
|
||||||
function updateStatus() {
|
function updateStatus() {
|
||||||
const statusContainer = document.getElementById("status-container");
|
const statusContainer = document.getElementById("status-container");
|
||||||
const averageUptimeElement = document.getElementById("average-uptime");
|
const averageUptimeElement = document.getElementById("average-uptime");
|
||||||
@ -201,16 +238,88 @@ window.addEventListener("scroll", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll(".nav-icon").forEach((icon) => {
|
document.querySelectorAll(".nav-icon").forEach((icon) => {
|
||||||
icon.classList.remove("active");
|
const label = icon.querySelector(".nav-label");
|
||||||
if (icon.getAttribute("href") === `#${current}`) {
|
const isCurrentSection = icon.getAttribute("href") === `#${current}`;
|
||||||
icon.classList.add("active");
|
const wasActive = icon.classList.contains("active");
|
||||||
|
|
||||||
|
if (isCurrentSection) {
|
||||||
|
if (!wasActive) {
|
||||||
|
icon.classList.add("active");
|
||||||
|
// complete instantly
|
||||||
|
if (icon.isAnimating) {
|
||||||
|
const text = label.getAttribute("data-text") || label.textContent;
|
||||||
|
label.textContent = text;
|
||||||
|
label.setAttribute("data-animating", "false");
|
||||||
|
clearInterval(
|
||||||
|
parseInt(label.getAttribute("data-animation-interval")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// only start if not currently animating
|
||||||
|
if (!icon.hoverAnimationDone) {
|
||||||
|
writeoutnavlabel(label);
|
||||||
|
}
|
||||||
|
icon.hoverAnimationDone = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (wasActive) {
|
||||||
|
eraselabel(label);
|
||||||
|
icon.classList.remove("active");
|
||||||
|
icon.hoverAnimationDone = false;
|
||||||
|
icon.isAnimating = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// dom content event listener
|
document.querySelectorAll(".nav-icon").forEach((icon) => {
|
||||||
|
icon.hoverAnimationDone = false;
|
||||||
|
icon.isAnimating = false;
|
||||||
|
|
||||||
|
icon.addEventListener("mouseenter", () => {
|
||||||
|
if (!icon.classList.contains("active") && !icon.isAnimating) {
|
||||||
|
const label = icon.querySelector(".nav-label");
|
||||||
|
writeoutnavlabel(label);
|
||||||
|
icon.isAnimating = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
icon.addEventListener("mouseleave", () => {
|
||||||
|
if (!icon.classList.contains("active")) {
|
||||||
|
const label = icon.querySelector(".nav-label");
|
||||||
|
eraselabel(label);
|
||||||
|
icon.isAnimating = false;
|
||||||
|
icon.hoverAnimationDone = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
icon.addEventListener("click", (e) => {
|
||||||
|
const label = icon.querySelector(".nav-label");
|
||||||
|
|
||||||
|
// continue if already active
|
||||||
|
// prevent mouseleave from erasing label
|
||||||
|
if (icon.isAnimating) {
|
||||||
|
icon.hoverAnimationDone = true;
|
||||||
|
}
|
||||||
|
// if no animation, start one
|
||||||
|
else if (!icon.hoverAnimationDone) {
|
||||||
|
writeoutnavlabel(label);
|
||||||
|
icon.isAnimating = true;
|
||||||
|
icon.hoverAnimationDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.style.opacity = "1";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// dom (196 reference) content event listener
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
writeoutnavlabel();
|
// write out active nav icon label instantly
|
||||||
|
const activeNavIcon = document.querySelector(".nav-icon.active");
|
||||||
|
if (activeNavIcon) {
|
||||||
|
const label = activeNavIcon.querySelector(".nav-label");
|
||||||
|
if (label) writeoutnavlabel(label);
|
||||||
|
}
|
||||||
|
// fancy console log
|
||||||
console.log(
|
console.log(
|
||||||
"%cELIA.NETWORK",
|
"%cELIA.NETWORK",
|
||||||
"color: #2a5a5a; font-size: 24px; font-weight: bold; text-shadow: 2px 2px 4px rgba(42, 90, 90, 0.4), 4px 4px 8px rgba(42, 90, 90, 0.2), 6px 6px 12px rgba(42, 90, 90, 0.1), 0 0 20px rgba(42, 90, 90, 0.3); transform: perspective(1000px) rotateX(20deg) rotateY(-10deg) translateZ(50px); animation: console3d 8s infinite cubic-bezier(0.4, 0, 0.2, 1), glow 2s infinite alternate; @keyframes console3d { 0% { transform: perspective(1000px) rotateX(20deg) rotateY(-10deg) translateZ(50px); } 25% { transform: perspective(1000px) rotateX(-15deg) rotateY(15deg) translateZ(75px); } 50% { transform: perspective(1000px) rotateX(10deg) rotateY(20deg) translateZ(100px); } 75% { transform: perspective(1000px) rotateX(-20deg) rotateY(-15deg) translateZ(75px); } 100% { transform: perspective(1000px) rotateX(20deg) rotateY(-10deg) translateZ(50px); } } @keyframes glow { from { text-shadow: 0 0 20px rgba(42, 90, 90, 0.3), 0 0 40px rgba(42, 90, 90, 0.2); } to { text-shadow: 0 0 40px rgba(42, 90, 90, 0.5), 0 0 80px rgba(42, 90, 90, 0.3); } }",
|
"color: #2a5a5a; font-size: 24px; font-weight: bold; text-shadow: 2px 2px 4px rgba(42, 90, 90, 0.4), 4px 4px 8px rgba(42, 90, 90, 0.2), 6px 6px 12px rgba(42, 90, 90, 0.1), 0 0 20px rgba(42, 90, 90, 0.3); transform: perspective(1000px) rotateX(20deg) rotateY(-10deg) translateZ(50px); animation: console3d 8s infinite cubic-bezier(0.4, 0, 0.2, 1), glow 2s infinite alternate; @keyframes console3d { 0% { transform: perspective(1000px) rotateX(20deg) rotateY(-10deg) translateZ(50px); } 25% { transform: perspective(1000px) rotateX(-15deg) rotateY(15deg) translateZ(75px); } 50% { transform: perspective(1000px) rotateX(10deg) rotateY(20deg) translateZ(100px); } 75% { transform: perspective(1000px) rotateX(-20deg) rotateY(-15deg) translateZ(75px); } 100% { transform: perspective(1000px) rotateX(20deg) rotateY(-10deg) translateZ(50px); } } @keyframes glow { from { text-shadow: 0 0 20px rgba(42, 90, 90, 0.3), 0 0 40px rgba(42, 90, 90, 0.2); } to { text-shadow: 0 0 40px rgba(42, 90, 90, 0.5), 0 0 80px rgba(42, 90, 90, 0.3); } }",
|
||||||
|
44
index.html
44
index.html
@ -203,14 +203,42 @@
|
|||||||
<section id="contact" class="section">
|
<section id="contact" class="section">
|
||||||
<div class="section-title">CONTACT</div>
|
<div class="section-title">CONTACT</div>
|
||||||
<div class="contact-links">
|
<div class="contact-links">
|
||||||
<a href="mailto:noc@elia.network" class="contact-link">
|
<div class="project-item">
|
||||||
<span class="contact-icon">✉</span>
|
<div class="project-header">
|
||||||
NOC EMAIL
|
<div class="entry">E-Mail</div>
|
||||||
</a>
|
<span class="expand-icon">+</span>
|
||||||
<a href="https://t.me/beslikmeister" class="contact-link">
|
</div>
|
||||||
<span class="contact-icon">⎆</span>
|
<div class="project-content">
|
||||||
TELEGRAM
|
<div class="project-links">
|
||||||
</a>
|
<a
|
||||||
|
href="mailto:alerts@elia.network"
|
||||||
|
class="project-link"
|
||||||
|
>⎔ ALERTS →</a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="mailto:noc@elia.network"
|
||||||
|
class="project-link"
|
||||||
|
>⎔ NOC →</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-header">
|
||||||
|
<div class="entry">TELEGRAM</div>
|
||||||
|
<span class="expand-icon">+</span>
|
||||||
|
</div>
|
||||||
|
<div class="project-content">
|
||||||
|
<div class="project-links">
|
||||||
|
<a
|
||||||
|
href="https://t.me/beslikmeister"
|
||||||
|
class="project-link"
|
||||||
|
>⎔ T.ME →</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user