Initial commit
This commit is contained in:
commit
1a1d318d74
380
assets/index.css
Normal file
380
assets/index.css
Normal file
@ -0,0 +1,380 @@
|
||||
html {
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #0a0a0a;
|
||||
color: #c5e5e5;
|
||||
font-family: "Courier New", monospace;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
margin-left: 80px;
|
||||
padding: 20px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 80px;
|
||||
background: #0a0a0a;
|
||||
border-right: 1px solid #2a5a5a;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 20px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
cursor: pointer;
|
||||
margin: 20px 0;
|
||||
font-size: 24px;
|
||||
transition: color 0.3s ease;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-icon:hover {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
.nav-icon.active {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
/* Section Styles */
|
||||
.section {
|
||||
height: 100vh;
|
||||
padding: 20px 0;
|
||||
scroll-snap-align: start;
|
||||
scroll-snap-stop: always;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#contact {
|
||||
height: auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Header Styles */
|
||||
.header {
|
||||
border-bottom: 1px solid #2a5a5a;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
font-size: 0.9em;
|
||||
color: #88aaaa;
|
||||
}
|
||||
|
||||
.location {
|
||||
margin-top: 4px;
|
||||
color: #88aaaa;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
color: #88aaaa;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.2em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: "◈";
|
||||
margin-right: 10px;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.project-item {
|
||||
border: 1px solid #2a5a5a;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
background: rgba(42, 90, 90, 0.05);
|
||||
}
|
||||
|
||||
.project-item:hover {
|
||||
border-color: #c5e5e5;
|
||||
background: rgba(42, 90, 90, 0.1);
|
||||
}
|
||||
|
||||
.project-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.project-header .entry::before {
|
||||
content: "⎔";
|
||||
color: #88aaaa;
|
||||
}
|
||||
|
||||
.expand-icon {
|
||||
color: #88aaaa;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.project-item.expanded .expand-icon {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.project-content {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
opacity 0.3s ease,
|
||||
transform 0.3s ease;
|
||||
margin-top: 10px;
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
.project-content.expanded {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.status-item {
|
||||
margin: 10px 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.status-item:hover .status-indicator {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.status-online {
|
||||
background-color: #4caf50;
|
||||
box-shadow: 0 0 10px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
background-color: #f44336;
|
||||
box-shadow: 0 0 10px rgba(244, 67, 54, 0.3);
|
||||
}
|
||||
|
||||
.status-warning {
|
||||
background-color: #ff9800;
|
||||
box-shadow: 0 0 10px rgba(255, 152, 0, 0.3);
|
||||
}
|
||||
|
||||
.status-details {
|
||||
margin-left: 18px;
|
||||
color: #88aaaa;
|
||||
font-size: 0.9em;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
transition:
|
||||
max-height 0.3s ease-out,
|
||||
opacity 0.3s ease,
|
||||
transform 0.3s ease;
|
||||
}
|
||||
|
||||
.status-details.expanded {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.status-metric {
|
||||
margin: 4px 0;
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-metric::before {
|
||||
content: "›";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: #88aaaa;
|
||||
}
|
||||
|
||||
.loading-indicator {
|
||||
color: #88aaaa;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #f44336;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.refresh-button {
|
||||
color: #88aaaa;
|
||||
border: 1px solid #2a5a5a;
|
||||
background: none;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 20px;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.refresh-button::before {
|
||||
content: "⟳";
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.refresh-button:hover {
|
||||
border-color: #c5e5e5;
|
||||
color: #c5e5e5;
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
/* Entry and Link Styles */
|
||||
.entry-list {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.nested-entries {
|
||||
margin-left: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.entry {
|
||||
margin: 10px 0;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.entry::before {
|
||||
content: "▹";
|
||||
color: #88aaaa;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.entry-link {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.entry-link:hover {
|
||||
color: #c5e5e5;
|
||||
}
|
||||
|
||||
/* Contact Styles */
|
||||
.contact-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.contact-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #c5e5e5;
|
||||
text-decoration: none;
|
||||
padding: 15px;
|
||||
border: 1px solid #2a5a5a;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(42, 90, 90, 0.05);
|
||||
}
|
||||
|
||||
.contact-link:hover {
|
||||
border-color: #c5e5e5;
|
||||
background: rgba(42, 90, 90, 0.1);
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.contact-icon {
|
||||
margin-right: 15px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.nested-entries {
|
||||
margin-left: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.nested-entries .entry {
|
||||
color: #88aaaa;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.entry {
|
||||
margin: 10px 0;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.entry::before {
|
||||
content: "▹";
|
||||
color: #88aaaa;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.entry-link {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.entry-link:hover {
|
||||
color: #c5e5e5;
|
||||
}
|
||||
|
||||
.nested-entries .entry {
|
||||
color: #88aaaa;
|
||||
}
|
||||
|
||||
.nested-entries .entry:hover {
|
||||
color: #c5e5e5;
|
||||
}
|
||||
|
||||
.entry {
|
||||
margin: 10px 0;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.entry::before {
|
||||
content: "▹";
|
||||
color: #88aaaa;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.nested-entries .entry:hover::before {
|
||||
color: #c5e5e5;
|
||||
}
|
171
assets/index.js
Normal file
171
assets/index.js
Normal file
@ -0,0 +1,171 @@
|
||||
function updateTime() {
|
||||
const now = new Date();
|
||||
const timeString = now
|
||||
.toLocaleString("en-US", {
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
fractionalSecondDigits: 3,
|
||||
hour12: true,
|
||||
})
|
||||
.toUpperCase();
|
||||
document.getElementById("current-time").textContent = timeString;
|
||||
}
|
||||
|
||||
updateTime();
|
||||
setInterval(updateTime, 1);
|
||||
|
||||
// projects
|
||||
const projectItems = document.querySelectorAll(".project-item");
|
||||
projectItems.forEach((item) => {
|
||||
item.addEventListener("click", function () {
|
||||
const content = this.querySelector(".project-content");
|
||||
const icon = this.querySelector(".expand-icon");
|
||||
|
||||
// close other expanded items
|
||||
projectItems.forEach((otherItem) => {
|
||||
if (otherItem !== item) {
|
||||
otherItem
|
||||
.querySelector(".project-content")
|
||||
.classList.remove("expanded");
|
||||
otherItem.querySelector(".expand-icon").textContent = "+";
|
||||
}
|
||||
});
|
||||
content.classList.toggle("expanded");
|
||||
icon.textContent = content.classList.contains("expanded") ? "−" : "+";
|
||||
});
|
||||
});
|
||||
|
||||
// status updater
|
||||
function formatLatency(latency) {
|
||||
return (Math.round((latency / 1000) * 10) / 10).toFixed(1);
|
||||
}
|
||||
|
||||
function formatUptime(uptime) {
|
||||
return uptime.toFixed(2);
|
||||
}
|
||||
|
||||
function getStatusClass(service) {
|
||||
if (!service.online) return "status-offline";
|
||||
if (service.latency > 500000) return "status-warning";
|
||||
return "status-online";
|
||||
}
|
||||
|
||||
function getGroupName(groupId) {
|
||||
const groupNames = {
|
||||
4: "INFRASTRUCTURE",
|
||||
5: "SERVICES",
|
||||
6: "API",
|
||||
};
|
||||
return groupNames[groupId] || `GROUP ${groupId}`;
|
||||
}
|
||||
|
||||
function createStatusHTML(services) {
|
||||
// Group services by group_id
|
||||
const groups = services.reduce((acc, service) => {
|
||||
const groupId = service.group_id;
|
||||
if (!acc[groupId]) acc[groupId] = [];
|
||||
acc[groupId].push(service);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return Object.entries(groups)
|
||||
.map(
|
||||
([groupId, groupServices]) => `
|
||||
<div class="status-group">
|
||||
<div class="subsection-title">${getGroupName(parseInt(groupId))}</div>
|
||||
${groupServices
|
||||
.map(
|
||||
(service) => `
|
||||
<div class="status-item">
|
||||
<div class="entry" data-service="${service.permalink}">
|
||||
<span class="status-indicator ${getStatusClass(service)}"></span>
|
||||
<span class="service-name">${service.name.toUpperCase()}</span>
|
||||
<span class="service-status">${service.online ? "OPERATIONAL" : "OFFLINE"}</span>
|
||||
</div>
|
||||
<div class="status-details">
|
||||
<div class="status-metric">Latency: ${formatLatency(service.latency)}ms</div>
|
||||
<div class="status-metric">Uptime 24h: ${formatUptime(service.online_24_hours)}%</div>
|
||||
<div class="status-metric">7-day Uptime: ${formatUptime(service.online_7_days)}%</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
function updateStatus() {
|
||||
const statusContainer = document.getElementById("status-container");
|
||||
|
||||
fetch("https://status.elia.network/api/services")
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
statusContainer.innerHTML = createStatusHTML(data);
|
||||
document.querySelectorAll(".status-item .entry").forEach((item) => {
|
||||
item.addEventListener("click", function () {
|
||||
const details = this.nextElementSibling;
|
||||
details.classList.toggle("expanded");
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
statusContainer.innerHTML = `
|
||||
<div class="error-message">
|
||||
UNABLE TO FETCH STATUS DATA
|
||||
<div style="font-size: 0.8em; margin-top: 5px;">
|
||||
${error.message}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
// initial update
|
||||
updateStatus();
|
||||
|
||||
// update every minute
|
||||
setInterval(updateStatus, 60000);
|
||||
// status details toggle
|
||||
document.querySelectorAll(".status-item .entry").forEach((item) => {
|
||||
const details = item.nextElementSibling;
|
||||
if (details && details.classList.contains("status-details")) {
|
||||
item.addEventListener("click", function () {
|
||||
details.classList.toggle("expanded");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// navigation
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
document.querySelector(this.getAttribute("href")).scrollIntoView({
|
||||
behavior: "smooth",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// update active nav icon
|
||||
window.addEventListener("scroll", () => {
|
||||
let current = "";
|
||||
document.querySelectorAll("section").forEach((section) => {
|
||||
const sectionTop = section.offsetTop;
|
||||
if (scrollY >= sectionTop - 60) {
|
||||
current = section.getAttribute("id");
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll(".nav-icon").forEach((icon) => {
|
||||
icon.classList.remove("active");
|
||||
if (icon.getAttribute("href") === `#${current}`) {
|
||||
icon.classList.add("active");
|
||||
}
|
||||
});
|
||||
});
|
174
index.html
Normal file
174
index.html
Normal file
@ -0,0 +1,174 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="assets/index.css" />
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="sidebar">
|
||||
<a href="#about" class="nav-icon">⎮</a>
|
||||
<a href="#projects" class="nav-icon">⎔</a>
|
||||
<a href="#status" class="nav-icon">◈</a>
|
||||
<a href="#contact" class="nav-icon">⊡</a>
|
||||
</nav>
|
||||
|
||||
<div class="terminal">
|
||||
<section id="about" class="section">
|
||||
<div class="header">
|
||||
<div class="timestamp" id="current-time"></div>
|
||||
<div class="location">ZÜRICH, SWITZERLAND</div>
|
||||
</div>
|
||||
<div class="section-title">ELIA.NETWORK</div>
|
||||
<div class="entry-list">
|
||||
<div class="entry">
|
||||
WHAT WE DO
|
||||
<div class="nested-entries">
|
||||
<div class="entry">
|
||||
<a
|
||||
href="https://status.elia.network"
|
||||
class="entry-link"
|
||||
>NETWORK INFRASTRUCTURE</a
|
||||
>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<a
|
||||
href="https://huggingface.co/informatiker"
|
||||
class="entry-link"
|
||||
>RESEARCH</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
SERVICES
|
||||
<div class="nested-entries">
|
||||
<div class="entry">
|
||||
<a
|
||||
href="https://media.elia.services"
|
||||
class="entry-link"
|
||||
>MEDIA</a
|
||||
>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<a
|
||||
href="https://docs.elia.network"
|
||||
class="entry-link"
|
||||
>DOCS</a
|
||||
>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<a
|
||||
href="https://chat.elia.services"
|
||||
class="entry-link"
|
||||
>CHAT</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="projects" class="section">
|
||||
<div class="section-title">PROJECTS</div>
|
||||
|
||||
<div class="project-item" onclick="toggleProject(this)">
|
||||
<div class="project-header">
|
||||
<div class="entry">CAS</div>
|
||||
<span class="expand-icon">+</span>
|
||||
</div>
|
||||
<div class="project-content">
|
||||
<p>
|
||||
Open-Source Language Model interface for use in web
|
||||
browsers. If ykyk.
|
||||
</p>
|
||||
<div class="project-links">
|
||||
<a
|
||||
href="https://git.elia.network/elia/cas/"
|
||||
class="project-link"
|
||||
>⎔ GIT →</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="project-item" onclick="toggleProject(this)">
|
||||
<div class="project-header">
|
||||
<div class="entry">NETWORK</div>
|
||||
<span class="expand-icon">+</span>
|
||||
</div>
|
||||
<div class="project-content">
|
||||
<p>Infrastructure and networking solutions.</p>
|
||||
<div class="project-links">
|
||||
<a href="#" class="project-link">⎮ DOCS →</a>
|
||||
<a href="#" class="project-link">⎔ STATUS →</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="status" class="section">
|
||||
<div class="section-title">SYSTEM STATUS</div>
|
||||
<div id="status-container" class="status-grid">
|
||||
<div class="status-group">
|
||||
<div class="status-item" onclick="toggleStatus(this)">
|
||||
<span class="status-indicator status-online"></span>
|
||||
<span class="service-name">MEDIA SERVER</span>
|
||||
<div class="status-details">
|
||||
<div class="status-metric">Uptime: 99.99%</div>
|
||||
<div class="status-metric">
|
||||
Response Time: 120ms
|
||||
</div>
|
||||
<div class="status-metric">Load: Normal</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-item" onclick="toggleStatus(this)">
|
||||
<span
|
||||
class="status-indicator status-warning"
|
||||
></span>
|
||||
<span class="service-name">CHAT SERVICE</span>
|
||||
<div class="status-details">
|
||||
<div class="status-metric">Uptime: 98.5%</div>
|
||||
<div class="status-metric">
|
||||
Response Time: 350ms
|
||||
</div>
|
||||
<div class="status-metric">Load: High</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-item" onclick="toggleStatus(this)">
|
||||
<span class="status-indicator status-online"></span>
|
||||
<span class="service-name">DOCUMENTATION</span>
|
||||
<div class="status-details">
|
||||
<div class="status-metric">Uptime: 100%</div>
|
||||
<div class="status-metric">
|
||||
Response Time: 89ms
|
||||
</div>
|
||||
<div class="status-metric">Load: Low</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section">
|
||||
<div class="section-title">CONTACT</div>
|
||||
<div class="contact-links">
|
||||
<a href="mailto:contact@elia.network" class="contact-link">
|
||||
<span class="contact-icon">✉</span>
|
||||
admin@elia.network
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/informaticker"
|
||||
class="contact-link"
|
||||
>
|
||||
<span class="contact-icon">⎆</span>
|
||||
github.com/informaticker
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script src="assets/index.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user