Compare commits

...

2 Commits

Author SHA1 Message Date
N0\A
9a0fb86d80 librecounter 2025-10-30 08:51:52 +01:00
N0\A
eadbf18661 animations 2025-10-30 08:41:03 +01:00
5 changed files with 465 additions and 142 deletions

31
animations.js Normal file
View File

@@ -0,0 +1,31 @@
(function () {
const backToTopButton = document.getElementById("back-to-top");
if (backToTopButton) {
function toggleBackToTop() {
if (window.pageYOffset > 300) {
backToTopButton.classList.add("visible");
} else {
backToTopButton.classList.remove("visible");
}
}
backToTopButton.addEventListener("click", function () {
window.scrollTo({
top: 0,
behavior: "smooth",
});
});
window.addEventListener("scroll", toggleBackToTop);
toggleBackToTop();
}
const listItems = document.querySelectorAll("li");
listItems.forEach((item, index) => {
if (!item.style.animationDelay) {
item.style.animationDelay = `${0.1 + index * 0.05}s`;
}
});
})();

View File

@@ -1,58 +1,98 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Krzak.org</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="container">
<h1>
<span class="icon">
<img src="/icon.svg" alt="krzak.org" />
</span>
Krzak.org
</h1>
<p>Contact:</p>
<ul>
<li>
<a href="https://fedi.krzak.org/@krzak">
<strong>Fediverse</strong>
<span>@krzak@fedi.krzak.org</span>
</a>
</li>
<li>
<a href="mailto:admin@krzak.org">
<strong>Mail</strong>
<span>admin@krzak.org</span>
</a>
</li>
<li>
<a href="">
<strong>Discord</strong>
<span>n0va_bot</span>
</a>
</li>
</ul>
<p>Support:</p>
<ul>
<li>
<a href="">
<strong>Blik</strong>
<span>+48 536 605 450</span>
</a>
</li>
</ul>
<br />
<ul>
<li>
<a href="/">
<strong>Back</strong>
</a>
</li>
</ul>
</div>
<script src="/refresh.js"></script>
</body>
</html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Krzak.org - Contact</title>
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<div class="container fade-in">
<h1 class="slide-down">
<span class="icon">
<img src="/icon.svg" alt="krzak.org" />
</span>
Krzak.org
</h1>
<p class="slide-down">Contact:</p>
<ul>
<li class="slide-up" style="animation-delay: 0.1s">
<a href="https://fedi.krzak.org/@krzak">
<strong>Fediverse</strong>
<span>@krzak@fedi.krzak.org</span>
</a>
</li>
<li class="slide-up" style="animation-delay: 0.15s">
<a href="mailto:admin@krzak.org">
<strong>Mail</strong>
<span>admin@krzak.org</span>
</a>
</li>
<li class="slide-up" style="animation-delay: 0.2s">
<a href="">
<strong>Discord</strong>
<span>n0va_bot</span>
</a>
</li>
</ul>
<p class="fade-in" style="animation-delay: 0.25s">Support:</p>
<ul>
<li class="slide-up" style="animation-delay: 0.3s">
<a href="">
<strong>Blik</strong>
<span>+48 536 605 450</span>
</a>
</li>
</ul>
<br />
<ul>
<li class="slide-up" style="animation-delay: 0.35s">
<a href="/">
<strong>Back</strong>
</a>
</li>
</ul>
<div class="librecounter fade-in" style="animation-delay: 0.4s">
<span class="librecounter-text">
Indexed by
<a href="https://librecounter.org/referer/show" target="_blank"
>LibreCounter</a
>
</span>
<a href="https://librecounter.org/referer/show" target="_blank">
<img
src="https://librecounter.org/counter.svg"
referrerpolicy="unsafe-url"
alt="LibreCounter"
/>
</a>
</div>
</div>
<!-- Back to top button -->
<button
id="back-to-top"
class="back-to-top"
aria-label="Back to top"
title="Back to top"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="18 15 12 9 6 15"></polyline>
</svg>
</button>
<script src="/refresh.js"></script>
<script src="/animations.js"></script>
</body>
</html>

View File

@@ -4,74 +4,156 @@
<title>Krzak.org</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Favicons -->
<link rel="icon" type="image/svg+xml" href="/favicons/favicon.svg">
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="48x48" href="/favicons/favicon-48x48.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/favicon-192x192.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/favicon-180x180.png">
<link rel="shortcut icon" href="/favicons/favicon.ico">
<link rel="icon" type="image/svg+xml" href="/favicons/favicon.svg" />
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicons/favicon-16x16.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="48x48"
href="/favicons/favicon-48x48.png"
/>
<link
rel="icon"
type="image/png"
sizes="96x96"
href="/favicons/favicon-96x96.png"
/>
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/favicons/favicon-192x192.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/favicons/favicon-180x180.png"
/>
<link rel="shortcut icon" href="/favicons/favicon.ico" />
<!-- Android Chrome -->
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/favicon-192x192.png">
<link rel="icon" type="image/png" sizes="512x512" href="/favicons/favicon-512x512.png">
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/favicons/favicon-192x192.png"
/>
<link
rel="icon"
type="image/png"
sizes="512x512"
href="/favicons/favicon-512x512.png"
/>
<!-- PWA -->
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#2a1a5e">
<link rel="stylesheet" href="/styles.css">
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#2a1a5e" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<div class="container">
<h1>
<div class="container fade-in">
<h1 class="slide-down">
<span class="icon">
<img src="/icon.svg" alt="krzak.org" />
</span>
Krzak.org
</h1>
<p>Hi, welcome to krzak.org</p>
<p class="slide-down">Hi, welcome to krzak.org</p>
<ul>
<li>
<li class="slide-up" style="animation-delay: 0.1s">
<a href="https://fedi.krzak.org">
<strong>Fediverse</strong>
<span>Sharkey</span>
</a>
</li>
<li>
<li class="slide-up" style="animation-delay: 0.15s">
<a href="https://mail.krzak.org">
<strong>Mail</strong>
<span>Mailu</span>
</a>
</li>
<li>
<li class="slide-up" style="animation-delay: 0.2s">
<a href="https://music.krzak.org">
<strong>Music</strong>
<span>Navidrome</span>
</a>
</li>
<li>
<li class="slide-up" style="animation-delay: 0.25s">
<a href="https://mu.krzak.org">
<strong>Music Upload</strong>
</a>
</li>
<li>
<li class="slide-up" style="animation-delay: 0.3s">
<a href="https://git.krzak.org">
<strong>Git</strong>
<span>Gitea</span>
</a>
</li>
<li>
<li class="slide-up" style="animation-delay: 0.35s">
<a href="/contact.html">
<strong>Contact</strong>
</a>
</li>
</ul>
<p>If you want an account on any of these, want to suggest something new or get a subdomain, just message me</p>
<p class="fade-in" style="animation-delay: 0.4s">
If you want an account on any of these, want to suggest something new or
get a subdomain, just message me
</p>
<div class="librecounter fade-in" style="animation-delay: 0.5s">
<span class="librecounter-text">
Indexed by
<a href="https://librecounter.org/referer/show" target="_blank"
>LibreCounter</a
>
</span>
<a href="https://librecounter.org/referer/show" target="_blank">
<img
src="https://librecounter.org/counter.svg"
referrerpolicy="unsafe-url"
alt="LibreCounter"
/>
</a>
</div>
</div>
<!-- Back to top button -->
<button
id="back-to-top"
class="back-to-top"
aria-label="Back to top"
title="Back to top"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="18 15 12 9 6 15"></polyline>
</svg>
</button>
<script src="/refresh.js"></script>
<script src="/animations.js"></script>
</body>
</html>

View File

@@ -1,63 +1,57 @@
(function() {
// Configuration
const SSE_PORT = 8765;
const RECONNECT_DELAY = 5000; // 5 seconds
let eventSource = null;
let reconnectTimer = null;
function connect() {
// Clear any existing reconnect timer
if (reconnectTimer) {
clearTimeout(reconnectTimer);
reconnectTimer = null;
}
// Close existing connection
if (eventSource) {
eventSource.close();
}
// Connect to SSE server
const url = `${window.location.protocol}//${window.location.hostname}:${SSE_PORT}/events`;
eventSource = new EventSource(url);
eventSource.onmessage = function(event) {
try {
const data = JSON.parse(event.data);
if (data.type === 'reload') {
console.log('Repository updated, reloading page...');
// Hard reload to bypass cache
window.location.reload(true);
}
} catch (e) {
console.error('Error parsing SSE message:', e);
}
};
eventSource.onerror = function(error) {
console.log('SSE connection error, will reconnect...');
eventSource.close();
// Attempt to reconnect after delay
reconnectTimer = setTimeout(connect, RECONNECT_DELAY);
};
eventSource.onopen = function() {
console.log('Connected to auto-refresh service');
};
(function () {
const SSE_PORT = 8765;
const RECONNECT_DELAY = 5000; // miliseconds
let eventSource = null;
let reconnectTimer = null;
function connect() {
if (reconnectTimer) {
clearTimeout(reconnectTimer);
reconnectTimer = null;
}
// Start connection when page loads
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', connect);
} else {
connect();
if (eventSource) {
eventSource.close();
}
// Cleanup on page unload
window.addEventListener('beforeunload', function() {
if (eventSource) {
eventSource.close();
const url = `${window.location.protocol}//${window.location.hostname}:${SSE_PORT}/events`;
eventSource = new EventSource(url);
eventSource.onmessage = function (event) {
try {
const data = JSON.parse(event.data);
if (data.type === "reload") {
console.log("Repository updated, reloading page...");
// Hard reload to bypass cache
window.location.reload(true);
}
});
})();
} catch (e) {
console.error("Error parsing SSE message:", e);
}
};
eventSource.onerror = function (error) {
console.log("SSE connection error, will reconnect...");
eventSource.close();
// Attempt to reconnect
reconnectTimer = setTimeout(connect, RECONNECT_DELAY);
};
eventSource.onopen = function () {
console.log("Connected to auto-refresh service");
};
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", connect);
} else {
connect();
}
window.addEventListener("beforeunload", function () {
if (eventSource) {
eventSource.close();
}
});
})();

View File

@@ -16,6 +16,10 @@
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
background: linear-gradient(
var(--bg-gradient-1),
@@ -130,6 +134,24 @@ li a {
gap: 12px;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
position: relative;
overflow: hidden;
}
li a::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(244, 162, 97, 0.1),
transparent
);
transition: left 0.5s ease;
}
li a:active {
@@ -160,12 +182,148 @@ br {
content: "";
}
/* LibreCounter */
.librecounter {
margin-top: 24px;
padding-top: 16px;
border-top: 1px solid rgba(244, 162, 97, 0.3);
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
min-height: 73px;
}
.librecounter-text {
color: var(--text-color);
font-size: 0.9rem;
opacity: 0.9;
}
.librecounter-text a {
color: var(--link-color);
text-decoration: none;
transition: color 0.2s ease;
}
.librecounter-text a:hover {
color: var(--subtitle-color);
text-decoration: underline;
}
.librecounter a {
display: inline-block;
transition: transform 0.2s ease, opacity 0.2s ease;
flex-shrink: 0;
line-height: 0;
}
.librecounter a:hover {
transform: scale(1.05);
opacity: 0.9;
}
.librecounter img {
display: block;
height: 64px;
width: auto;
max-width: 100%;
}
/* Back to top button */
.back-to-top {
position: fixed;
bottom: 24px;
right: 24px;
width: 48px;
height: 48px;
border-radius: 50%;
background: var(--link-bg);
border: 1px solid var(--container-border);
color: var(--link-color);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
z-index: 1000;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.3);
}
.back-to-top.visible {
opacity: 1;
visibility: visible;
}
.back-to-top:hover {
background: var(--link-hover-bg);
border-color: var(--link-hover-border);
transform: translateY(-2px);
}
.back-to-top:active {
transform: translateY(0);
}
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in {
animation: fadeIn 0.6s ease-out forwards;
}
.slide-down {
animation: slideDown 0.6s ease-out forwards;
}
.slide-up {
animation: slideUp 0.6s ease-out forwards;
opacity: 0;
}
@media (hover: hover) {
li a:hover {
background-color: var(--link-hover-bg);
border-color: var(--link-hover-border);
transform: scale(1.02);
}
li a:hover::before {
left: 100%;
}
}
@media (min-width: 768px) {
@@ -209,11 +367,29 @@ br {
li a span {
font-size: 0.85rem;
}
.back-to-top {
bottom: 16px;
right: 16px;
width: 44px;
height: 44px;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
* {
animation: none !important;
transition: none !important;
}
.fade-in,
.slide-down,
.slide-up {
opacity: 1 !important;
transform: none !important;
}
}