Inital Commit
32
website/api/backdrops.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[
|
||||
{
|
||||
"name": "horse_fog",
|
||||
"destructive": false
|
||||
},
|
||||
{
|
||||
"name": "horse_rainbow",
|
||||
"destructive": false
|
||||
},
|
||||
{
|
||||
"name": "campsite",
|
||||
"destructive": false
|
||||
},
|
||||
{
|
||||
"name": "village_sunset",
|
||||
"destructive": false
|
||||
},
|
||||
{
|
||||
"name": "outpost",
|
||||
"destructive": true,
|
||||
"time": 8
|
||||
},
|
||||
{
|
||||
"name": "tower_small",
|
||||
"destructive": true,
|
||||
"time": 8
|
||||
},
|
||||
{
|
||||
"name": "tower_large",
|
||||
"destructive": false
|
||||
}
|
||||
]
|
||||
11
website/api/posts.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
{
|
||||
"date": "2026-04-01",
|
||||
|
||||
"head_img": "village_sunset.png",
|
||||
"file": "CoolPost123.md",
|
||||
|
||||
"title": "This is a cool post",
|
||||
"description": "Look at this text"
|
||||
}
|
||||
]
|
||||
50
website/api/team.json
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
{
|
||||
"icon": "morice.png",
|
||||
"name": "MoriceMC",
|
||||
"priority": 0,
|
||||
"role": "Owner & Lead Developer"
|
||||
},
|
||||
{
|
||||
"icon": "ninivx.png",
|
||||
"name": "NiniVX",
|
||||
"priority": 1,
|
||||
"role": "Administrator"
|
||||
},
|
||||
{
|
||||
"name": "Burrata",
|
||||
"priority": 1,
|
||||
"role": "Administrator"
|
||||
},
|
||||
{
|
||||
"name": "Pitrex",
|
||||
"priority": 2,
|
||||
"role": "Moderator & Developer"
|
||||
},
|
||||
{
|
||||
"name": "Litus",
|
||||
"priority": 2,
|
||||
"role": "Moderator"
|
||||
},
|
||||
{
|
||||
"name": "Ahnyokatzin",
|
||||
"priority": 2,
|
||||
"role": "Moderator"
|
||||
},
|
||||
{
|
||||
"name": "T1X",
|
||||
"priority": 2,
|
||||
"role": "Moderator"
|
||||
},
|
||||
{
|
||||
"name": "Harrpy",
|
||||
"priority": 2,
|
||||
"role": "Moderator"
|
||||
},
|
||||
{
|
||||
"icon": "alexemmet.png",
|
||||
"name": "AlexEmmet",
|
||||
"priority": 3,
|
||||
"role": "Web-Developer & Critic (Professional Hater)"
|
||||
}
|
||||
]
|
||||
249
website/app.js
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
// Smooth scroll for nav links
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute("href"));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Parallax ───
|
||||
function initParallax() {
|
||||
const sections = document.querySelectorAll(".bg-image-section:not(#hero)");
|
||||
const heroLayer = document.getElementById("hero-slideshow");
|
||||
|
||||
function update() {
|
||||
sections.forEach((section) => {
|
||||
const rect = section.getBoundingClientRect();
|
||||
const yPos = -(rect.top * 0.4);
|
||||
section.style.backgroundPositionY = `${yPos}px`;
|
||||
});
|
||||
|
||||
if (heroLayer) {
|
||||
const hero = document.getElementById("hero");
|
||||
if (hero) {
|
||||
const rect = hero.getBoundingClientRect();
|
||||
const yPos = -(rect.top * 0.4);
|
||||
heroLayer.style.transform = `translateY(${yPos}px) scale(1.1)`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", update, { passive: true });
|
||||
update();
|
||||
}
|
||||
|
||||
// ─── Hero Slideshow with Destructive Theme ───
|
||||
let currentBackdrop = null;
|
||||
const NEAR_TOP_THRESHOLD = 600;
|
||||
|
||||
function checkDestructiveTheme() {
|
||||
if (!currentBackdrop) return;
|
||||
const nearTop = window.scrollY < NEAR_TOP_THRESHOLD;
|
||||
if (currentBackdrop.destructive && nearTop) {
|
||||
document.body.classList.add("destructive-mode");
|
||||
} else {
|
||||
document.body.classList.remove("destructive-mode");
|
||||
}
|
||||
}
|
||||
|
||||
function initHeroSlideshow(allBackdrops, usedNames) {
|
||||
const hero = document.getElementById("hero");
|
||||
const layer = document.getElementById("hero-slideshow");
|
||||
if (!hero || !layer) return;
|
||||
|
||||
const slides = allBackdrops.filter((b) => !usedNames.includes(b.name));
|
||||
|
||||
if (slides.length === 0) {
|
||||
console.warn("No unused backdrops for hero slideshow");
|
||||
return;
|
||||
}
|
||||
|
||||
let idx = 0;
|
||||
|
||||
function showSlide(index) {
|
||||
const backdrop = slides[index];
|
||||
currentBackdrop = backdrop;
|
||||
|
||||
layer.style.opacity = "0";
|
||||
|
||||
setTimeout(() => {
|
||||
layer.style.backgroundImage = `url('/assets/${backdrop.name}.png')`;
|
||||
layer.style.opacity = "1";
|
||||
checkDestructiveTheme();
|
||||
}, 600);
|
||||
|
||||
const delayMs = (backdrop.time || 6) * 1000;
|
||||
idx = (index + 1) % slides.length;
|
||||
setTimeout(() => showSlide(idx), delayMs);
|
||||
}
|
||||
|
||||
currentBackdrop = slides[0];
|
||||
layer.style.backgroundImage = `url('/assets/${slides[0].name}.png')`;
|
||||
layer.style.opacity = "1";
|
||||
checkDestructiveTheme();
|
||||
|
||||
idx = 1;
|
||||
const initialDelay = (slides[0].time || 6) * 1000;
|
||||
setTimeout(() => showSlide(idx), initialDelay);
|
||||
}
|
||||
|
||||
// ─── Load Backdrops ───
|
||||
async function loadBackdrops() {
|
||||
try {
|
||||
const response = await fetch("/api/backdrops.json");
|
||||
const backdrops = await response.json();
|
||||
|
||||
const safeBackdrops = backdrops.filter((b) => !b.destructive);
|
||||
const sections = document.querySelectorAll(".bg-image-section:not(#hero)");
|
||||
const used = [];
|
||||
|
||||
sections.forEach((section) => {
|
||||
let pick;
|
||||
let safety = 0;
|
||||
do {
|
||||
pick = safeBackdrops[Math.floor(Math.random() * safeBackdrops.length)];
|
||||
safety++;
|
||||
} while (
|
||||
used.includes(pick.name) &&
|
||||
used.length < safeBackdrops.length &&
|
||||
safety < 50
|
||||
);
|
||||
used.push(pick.name);
|
||||
section.style.backgroundImage = `url('/assets/${pick.name}.png')`;
|
||||
});
|
||||
|
||||
initParallax();
|
||||
initHeroSlideshow(backdrops, used);
|
||||
|
||||
window.addEventListener("scroll", checkDestructiveTheme, { passive: true });
|
||||
} catch (err) {
|
||||
console.error("Failed to load backdrops:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Load Team ───
|
||||
async function loadTeam() {
|
||||
try {
|
||||
const response = await fetch("/api/team.json");
|
||||
const team = await response.json();
|
||||
team.sort((a, b) => a.priority - b.priority);
|
||||
|
||||
const container = document.getElementById("team-grid");
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = team
|
||||
.map(
|
||||
(member) => `
|
||||
<div class="team-card">
|
||||
${
|
||||
member.icon
|
||||
? `<img src="/assets/${member.icon}" alt="${member.name}" onerror="this.style.display='none'">`
|
||||
: '<div style="width:100px;height:100px;border-radius:50%;background:#2a2e33;margin:0 auto 1.2rem;border:3px solid #2a2e33;"></div>'
|
||||
}
|
||||
<div class="name">${member.name}</div>
|
||||
<div class="role">${member.role}</div>
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
} catch (err) {
|
||||
console.error("Failed to load team:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Load Posts ───
|
||||
async function loadPosts() {
|
||||
try {
|
||||
const response = await fetch("/api/posts.json");
|
||||
const posts = await response.json();
|
||||
|
||||
const container = document.getElementById("posts-grid");
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = posts
|
||||
.map(
|
||||
(post) => `
|
||||
<a href="/post/${post.file}" class="post-card">
|
||||
<div class="post-date">${post.date}</div>
|
||||
<div class="post-title">${post.title}</div>
|
||||
<div class="post-desc">${post.description}</div>
|
||||
</a>
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
} catch (err) {
|
||||
console.error("Failed to load posts:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Video Play/Pause ───
|
||||
function initVideo() {
|
||||
const playBtn = document.getElementById("play-btn");
|
||||
const video = document.getElementById("trailer-video");
|
||||
const container = document.querySelector(".video-container");
|
||||
|
||||
if (!playBtn || !video || !container) return;
|
||||
|
||||
playBtn.addEventListener("click", () => {
|
||||
if (video.paused) {
|
||||
video.play();
|
||||
container.classList.add("playing");
|
||||
} else {
|
||||
video.pause();
|
||||
container.classList.remove("playing");
|
||||
}
|
||||
});
|
||||
|
||||
video.addEventListener("ended", () => {
|
||||
container.classList.remove("playing");
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Scroll Effects ───
|
||||
function initScrollEffects() {
|
||||
const header = document.querySelector("header");
|
||||
const footer = document.querySelector("footer");
|
||||
const scrollThreshold = 200;
|
||||
|
||||
function update() {
|
||||
const scrollY = window.scrollY;
|
||||
const docHeight = document.documentElement.scrollHeight;
|
||||
const winHeight = window.innerHeight;
|
||||
const nearBottom = scrollY + winHeight >= docHeight - 80;
|
||||
const shortPage = docHeight <= winHeight + 100;
|
||||
|
||||
if (scrollY > 10) {
|
||||
header.classList.add("scrolled");
|
||||
} else {
|
||||
header.classList.remove("scrolled");
|
||||
}
|
||||
|
||||
if (scrollY < scrollThreshold && !shortPage) {
|
||||
footer.classList.remove("visible");
|
||||
} else {
|
||||
footer.classList.add("visible");
|
||||
if (nearBottom || shortPage) {
|
||||
footer.classList.remove("glass");
|
||||
footer.classList.add("solid");
|
||||
} else {
|
||||
footer.classList.add("glass");
|
||||
footer.classList.remove("solid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", update, { passive: true });
|
||||
update();
|
||||
}
|
||||
|
||||
// ─── Initialize ───
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
loadBackdrops();
|
||||
loadTeam();
|
||||
loadPosts();
|
||||
initVideo();
|
||||
initScrollEffects();
|
||||
});
|
||||
BIN
website/assets/alexemmet.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
website/assets/anarchyphase.png
Normal file
|
After Width: | Height: | Size: 256 KiB |
BIN
website/assets/banner.png
Normal file
|
After Width: | Height: | Size: 365 KiB |
BIN
website/assets/campsite.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
website/assets/horse_fog.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
website/assets/horse_rainbow.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
website/assets/icon.png
Normal file
|
After Width: | Height: | Size: 365 KiB |
BIN
website/assets/morice.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
website/assets/ninivx.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
website/assets/outpost.png
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
website/assets/tower_large.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
website/assets/tower_small.png
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
website/assets/trailer.mp4
Normal file
BIN
website/assets/village_sunset.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
156
website/index.html
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Anarchy Phase</title>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/" class="logo">Anarchy Phase</a>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#concept">Concept</a></li>
|
||||
<li><a href="#socials">Social</a></li>
|
||||
<li><a href="#team">Team</a></li>
|
||||
<li><a href="#posts">Posts</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section id="hero" class="bg-image-section">
|
||||
<div class="slideshow-layer" id="hero-slideshow"></div>
|
||||
<div class="destructive-tint" id="hero-tint"></div>
|
||||
<div class="hero-content">
|
||||
<h2>Join us on:</h2>
|
||||
<p>Anarchyphase.net</p>
|
||||
<p>Bedrock & Java</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="concept">
|
||||
<div class="content-wrapper">
|
||||
<h2>Concept</h2>
|
||||
<div class="video-container">
|
||||
<video
|
||||
id="trailer-video"
|
||||
src="/assets/trailer.mp4"
|
||||
preload="metadata"
|
||||
></video>
|
||||
<div class="play-btn" id="play-btn"></div>
|
||||
</div>
|
||||
<div class="concept-text">
|
||||
<h3>THE CORE IDEA</h3>
|
||||
<ol>
|
||||
<li>
|
||||
With just a few text commands, players can
|
||||
easily claim chunks and invite others. These
|
||||
claims will offer complete protection, except
|
||||
for
|
||||
</li>
|
||||
<li>
|
||||
The Anarchy Phase. Monday to Thursday from
|
||||
20-21:00CET and Friday to Sunday from
|
||||
19-21:00CET claims can be raided. Even during
|
||||
this time, bases can't be easily deleted, as
|
||||
TNT, fire, and mining are nerfed inside claims.
|
||||
Destroying bases requires effort, just like
|
||||
building them.
|
||||
</li>
|
||||
<li>
|
||||
Even when a base is pillaged, there is no
|
||||
incentive to wipe it off the map. TNT and fire
|
||||
are nerfed all over the overworld, so ruins may
|
||||
be repaired or become historic.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h3>IMMERSION</h3>
|
||||
<ol>
|
||||
<li>
|
||||
There are no GUIs, official currency, or complex
|
||||
systems. Only a few text commands for claim
|
||||
</li>
|
||||
<li>
|
||||
Instead of global chat, there is now local text
|
||||
chat and SimpleVoiceChat support. Death messages
|
||||
are also only local.
|
||||
</li>
|
||||
<li>
|
||||
The world is limited, and elytras are disabled
|
||||
to encourage spontaneous meetings between
|
||||
players and building of infrastructure.
|
||||
</li>
|
||||
<li>
|
||||
PvP is kept simple, fun, and impactful by
|
||||
turning off totems, maces, and crystals.
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="socials" class="bg-image-section">
|
||||
<div class="content-wrapper">
|
||||
<h2>Socials</h2>
|
||||
<a
|
||||
href="https://www.youtube.com/@MoriceMC"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="social-btn"
|
||||
>
|
||||
<svg
|
||||
class="social-icon"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
|
||||
/>
|
||||
</svg>
|
||||
Youtube
|
||||
</a>
|
||||
<a
|
||||
href="https://discord.com/invite/Bq4GhxDwU5"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="social-btn"
|
||||
>
|
||||
<svg
|
||||
class="social-icon"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"
|
||||
/>
|
||||
</svg>
|
||||
Discord
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="team">
|
||||
<div class="content-wrapper">
|
||||
<h2>Team</h2>
|
||||
<div id="team-grid" class="team-grid"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="posts" class="bg-image-section">
|
||||
<div class="content-wrapper">
|
||||
<h2>Posts</h2>
|
||||
<div id="posts-grid" class="posts-grid"></div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>Imprint ....</p>
|
||||
</footer>
|
||||
|
||||
<script src="/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
115
website/md-render.js
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// Basic Markdown renderer
|
||||
function renderMarkdown(md) {
|
||||
let html = md
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/^### (.*$)/gim, "<h3>$1</h3>")
|
||||
.replace(/^## (.*$)/gim, "<h2>$1</h2>")
|
||||
.replace(/^# (.*$)/gim, "<h1>$1</h1>")
|
||||
.replace(/\*\*\*(.*?)\*\*\*/g, "<strong><em>$1</em></strong>")
|
||||
.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
|
||||
.replace(/\*(.*?)\*/g, "<em>$1</em>")
|
||||
.replace(/___(.*?)___/g, "<strong><em>$1</em></strong>")
|
||||
.replace(/__(.*?)__/g, "<strong>$1</strong>")
|
||||
.replace(/_(.*?)_/g, "<em>$1</em>")
|
||||
.replace(/```([\s\S]*?)```/g, "<pre><code>$1</code></pre>")
|
||||
.replace(/`([^`]+)`/g, "<code>$1</code>")
|
||||
.replace(/^> (.*$)/gim, "<blockquote>$1</blockquote>")
|
||||
.replace(/^\s*-\s+(.*$)/gim, "<li>$1</li>")
|
||||
.replace(/^\s*\d+\.\s+(.*$)/gim, "<li>$1</li>")
|
||||
.replace(
|
||||
/\[([^\]]+)\]\(([^)]+)\)/g,
|
||||
'<a href="$2" target="_blank" rel="noopener">$1</a>',
|
||||
)
|
||||
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1">')
|
||||
.replace(/^---$/gim, "<hr>")
|
||||
.replace(/\n/g, "<br>");
|
||||
|
||||
html = html.replace(/(<li>.*?<\/li>(?:<br><li>.*?<\/li>)*)/gs, (match) => {
|
||||
const clean = match.replace(/<br>/g, "");
|
||||
return `<ul>${clean}</ul>`;
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
// Parallax for post hero
|
||||
function initPostParallax() {
|
||||
const hero = document.getElementById("post-hero");
|
||||
if (!hero) return;
|
||||
|
||||
function update() {
|
||||
const rect = hero.getBoundingClientRect();
|
||||
const yPos = -(rect.top * 0.4);
|
||||
hero.style.backgroundPositionY = `${yPos}px`;
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", update, { passive: true });
|
||||
update();
|
||||
}
|
||||
|
||||
// Load post hero image from posts.json head_img, fallback to random backdrop
|
||||
async function loadPostHero(filename) {
|
||||
try {
|
||||
// Try to find the post metadata
|
||||
const response = await fetch("/api/posts.json");
|
||||
const posts = await response.json();
|
||||
const post = posts.find((p) => p.file === filename);
|
||||
|
||||
const hero = document.getElementById("post-hero");
|
||||
if (!hero) return;
|
||||
|
||||
if (post && post.head_img) {
|
||||
hero.style.backgroundImage = `url('/assets/${post.head_img}')`;
|
||||
} else {
|
||||
// Fallback to random backdrop
|
||||
const bdResponse = await fetch("/api/backdrops.json");
|
||||
const backdrops = await response.json();
|
||||
const random = backdrops[Math.floor(Math.random() * backdrops.length)];
|
||||
hero.style.backgroundImage = `url('/assets/${random.name}.png')`;
|
||||
}
|
||||
|
||||
initPostParallax();
|
||||
} catch (err) {
|
||||
console.error("Failed to load post hero:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Load post content
|
||||
async function loadPostContent() {
|
||||
const pathParts = window.location.pathname.split("/");
|
||||
const filename = pathParts[pathParts.length - 1];
|
||||
if (!filename) return;
|
||||
|
||||
loadPostHero(filename);
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/post/${filename}`);
|
||||
const md = await response.text();
|
||||
|
||||
let contentMd = md;
|
||||
const titleMatch = md.match(/^#\s+(.+)$/m);
|
||||
if (titleMatch) {
|
||||
document.title = `${titleMatch[1]} - Anarchy Phase`;
|
||||
const titleEl = document.getElementById("post-title");
|
||||
if (titleEl) titleEl.textContent = titleMatch[1];
|
||||
contentMd = md.replace(/^#\s+.+$/m, "").trim();
|
||||
}
|
||||
|
||||
const container = document.getElementById("post-body");
|
||||
if (container) {
|
||||
container.innerHTML = renderMarkdown(contentMd);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to load post:", err);
|
||||
const container = document.getElementById("post-body");
|
||||
if (container)
|
||||
container.innerHTML =
|
||||
'<p style="color:#d48a8a;">Failed to load post content.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
loadPostContent();
|
||||
});
|
||||
41
website/post.html
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Post - Anarchy Phase</title>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/" class="logo">Anarchy Phase</a>
|
||||
<ul class="nav-links">
|
||||
<li><a href="/#concept">Concept</a></li>
|
||||
<li><a href="/#socials">Social</a></li>
|
||||
<li><a href="/#team">Team</a></li>
|
||||
<li><a href="/#posts">Posts</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section id="post-hero" class="bg-image-section">
|
||||
<h1 id="post-title">Loading...</h1>
|
||||
</section>
|
||||
|
||||
<section id="post-content">
|
||||
<div id="post-body" class="post-content">
|
||||
<p>Loading post content...</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>Imprint ....</p>
|
||||
</footer>
|
||||
|
||||
<script src="/app.js"></script>
|
||||
<script src="/md-render.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
7
website/posts/CoolPost123.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# This is a cool post!
|
||||
|
||||
Look at this text..
|
||||
|
||||
# somt
|
||||
|
||||
a
|
||||
777
website/style.css
Normal file
|
|
@ -0,0 +1,777 @@
|
|||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* ─── Theme Variables ─── */
|
||||
:root {
|
||||
--bg-body: #0a0c0e;
|
||||
--bg-header: #14171a;
|
||||
--bg-footer: #14171a;
|
||||
--bg-solid: linear-gradient(180deg, #181a1d 0%, #14171a 100%);
|
||||
--bg-card: linear-gradient(145deg, #1c1e21, #181a1d);
|
||||
--bg-content: linear-gradient(145deg, #1a1d20, #14171a);
|
||||
--bg-postcard: rgba(20, 23, 26, 0.92);
|
||||
--border-base: #252a2e;
|
||||
--border-hover: #3a424a;
|
||||
--text-muted: #8a9eaa;
|
||||
--text-dim: #6e7a80;
|
||||
--accent: #5a7d8c;
|
||||
--accent-light: #7ab8d4;
|
||||
--accent-border: #4a5560;
|
||||
--tint-color: rgba(90, 125, 140, 0.15);
|
||||
--transition-theme:
|
||||
background-color 0.8s ease, border-color 0.8s ease, color 0.8s ease;
|
||||
}
|
||||
|
||||
body.destructive-mode {
|
||||
--bg-body: #0e0a0a;
|
||||
--bg-header: #1a1414;
|
||||
--bg-footer: #1a1414;
|
||||
--bg-solid: linear-gradient(180deg, #1d1818 0%, #1a1414 100%);
|
||||
--bg-card: linear-gradient(145deg, #211c1c, #1d1818);
|
||||
--bg-content: linear-gradient(145deg, #201a1a, #1a1414);
|
||||
--bg-postcard: rgba(26, 20, 20, 0.92);
|
||||
--border-base: #2e2525;
|
||||
--border-hover: #4a3a3a;
|
||||
--text-muted: #9a8a8a;
|
||||
--text-dim: #806e6e;
|
||||
--accent: #8c5a5a;
|
||||
--accent-light: #d47a7a;
|
||||
--accent-border: #604a4a;
|
||||
--tint-color: rgba(160, 60, 60, 0.25);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: var(--bg-body);
|
||||
color: #d0d0d0;
|
||||
line-height: 1.6;
|
||||
overflow-x: hidden;
|
||||
transition: background-color 0.8s ease;
|
||||
}
|
||||
|
||||
/* ─── Header ─── */
|
||||
header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: var(--bg-header);
|
||||
border-bottom: 1px solid #1f2428;
|
||||
z-index: 1000;
|
||||
padding: 0 2rem;
|
||||
transition:
|
||||
background 0.4s ease,
|
||||
backdrop-filter 0.4s ease,
|
||||
border-color 0.4s ease,
|
||||
box-shadow 0.4s ease,
|
||||
background-color 0.8s ease;
|
||||
}
|
||||
|
||||
header.scrolled {
|
||||
background: rgba(20, 23, 26, 0.65);
|
||||
backdrop-filter: blur(20px) saturate(1.4);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(1.4);
|
||||
border-bottom-color: rgba(255, 255, 255, 0.06);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
body.destructive-mode header.scrolled {
|
||||
background: rgba(26, 20, 20, 0.65);
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: #aaa;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ─── Layout ─── */
|
||||
main {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 50px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 4rem 2rem;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* ─── Backdrop Image Sections ─── */
|
||||
.bg-image-section {
|
||||
padding: 10rem 2rem;
|
||||
min-height: 600px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bg-image-section::before,
|
||||
.bg-image-section::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.bg-image-section::before {
|
||||
top: 0;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--bg-header) 0%,
|
||||
transparent 100%
|
||||
);
|
||||
}
|
||||
|
||||
.bg-image-section::after {
|
||||
bottom: 0;
|
||||
background: linear-gradient(to top, var(--bg-header) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
#hero::before {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.slideshow-layer {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
transition: opacity 1.2s ease-in-out;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.destructive-tint {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(
|
||||
ellipse at center,
|
||||
var(--tint-color),
|
||||
transparent 70%
|
||||
);
|
||||
opacity: 0;
|
||||
transition: opacity 1.2s ease;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
body.destructive-mode .destructive-tint {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ─── Solid Sections ─── */
|
||||
section:not(.bg-image-section) {
|
||||
background: var(--bg-solid);
|
||||
position: relative;
|
||||
padding: 6rem 2rem;
|
||||
transition: background 0.8s ease;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* ─── Hero ─── */
|
||||
#hero {
|
||||
min-height: 700px;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#hero h2 {
|
||||
font-size: 3.2rem;
|
||||
margin-bottom: 1.2rem;
|
||||
text-shadow: 0 3px 15px rgba(0, 0, 0, 0.9);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#hero p {
|
||||
font-size: 1.4rem;
|
||||
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9);
|
||||
color: #e0e0e0;
|
||||
margin: 0.3rem 0;
|
||||
}
|
||||
|
||||
/* ─── Concept ─── */
|
||||
#concept h2 {
|
||||
text-align: center;
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 3rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.video-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto 3rem;
|
||||
background: #0a0c0e;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
aspect-ratio: 16/9;
|
||||
border: 1px solid var(--border-base);
|
||||
transition: border-color 0.8s ease;
|
||||
}
|
||||
|
||||
.video-container video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 3px solid rgba(255, 255, 255, 0.9);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s;
|
||||
backdrop-filter: blur(6px);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.play-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
transform: translate(-50%, -50%) scale(1.08);
|
||||
}
|
||||
|
||||
.play-btn::after {
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 30px solid #fff;
|
||||
border-top: 18px solid transparent;
|
||||
border-bottom: 18px solid transparent;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.video-container.playing .play-btn {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.video-container.playing:hover .play-btn {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.video-container.playing .play-btn::after {
|
||||
border: none;
|
||||
width: 30px;
|
||||
height: 36px;
|
||||
margin-left: 0;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#fff 35%,
|
||||
transparent 35%,
|
||||
transparent 65%,
|
||||
#fff 65%
|
||||
);
|
||||
}
|
||||
|
||||
.concept-text {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.9;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.concept-text h3 {
|
||||
color: var(--accent-light);
|
||||
font-size: 1.4rem;
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
border-left: 4px solid var(--accent);
|
||||
padding-left: 1rem;
|
||||
transition: var(--transition-theme);
|
||||
}
|
||||
|
||||
.concept-text ol {
|
||||
margin-left: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.concept-text li {
|
||||
margin-bottom: 0.9rem;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
/* ─── Socials ─── */
|
||||
#socials h2 {
|
||||
text-align: center;
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 3rem;
|
||||
text-shadow: 0 3px 15px rgba(0, 0, 0, 0.9);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.social-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.8rem;
|
||||
width: 260px;
|
||||
margin: 1.5rem auto;
|
||||
padding: 1.2rem 2rem;
|
||||
background: rgba(10, 12, 14, 0.75);
|
||||
border: 1px solid #2f333a;
|
||||
border-radius: 12px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
font-size: 1.15rem;
|
||||
transition: all 0.3s;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.social-btn:hover {
|
||||
background: rgba(20, 23, 26, 0.9);
|
||||
transform: translateY(-4px);
|
||||
border-color: var(--accent-border);
|
||||
}
|
||||
|
||||
.social-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ─── Team ─── */
|
||||
#team h2 {
|
||||
text-align: center;
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 3rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.team-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.team-card {
|
||||
background: var(--bg-card);
|
||||
border-radius: 16px;
|
||||
padding: 2.5rem 1.5rem;
|
||||
text-align: center;
|
||||
border: 1px solid var(--border-base);
|
||||
transition:
|
||||
transform 0.3s,
|
||||
border-color 0.8s ease,
|
||||
background 0.8s ease;
|
||||
}
|
||||
|
||||
.team-card:hover {
|
||||
transform: translateY(-6px);
|
||||
border-color: var(--border-hover);
|
||||
}
|
||||
|
||||
.team-card img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
margin-bottom: 1.2rem;
|
||||
background: #2a2e33;
|
||||
border: 3px solid #2a2e33;
|
||||
transition: border-color 0.8s ease;
|
||||
}
|
||||
|
||||
.team-card:hover img {
|
||||
border-color: var(--accent-border);
|
||||
}
|
||||
|
||||
.team-card .name {
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.team-card .role {
|
||||
color: var(--text-muted);
|
||||
transition: color 0.8s ease;
|
||||
}
|
||||
|
||||
/* ─── Posts ─── */
|
||||
#posts h2 {
|
||||
text-align: center;
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 3rem;
|
||||
text-shadow: 0 3px 15px rgba(0, 0, 0, 0.9);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.posts-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.post-card {
|
||||
background: var(--bg-postcard);
|
||||
border-radius: 16px;
|
||||
padding: 2.2rem;
|
||||
border: 1px solid var(--border-base);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: block;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.post-card:hover {
|
||||
transform: translateY(-6px);
|
||||
border-color: var(--border-hover);
|
||||
background: rgba(24, 27, 30, 0.95);
|
||||
}
|
||||
|
||||
body.destructive-mode .post-card:hover {
|
||||
background: rgba(30, 24, 24, 0.95);
|
||||
}
|
||||
|
||||
.post-card .post-date {
|
||||
color: var(--text-dim);
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
|
||||
.post-card .post-title {
|
||||
font-size: 1.4rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.8rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.post-card .post-desc {
|
||||
color: #aaa;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ─── Post Page ─── */
|
||||
#post-hero {
|
||||
min-height: 450px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8rem 2rem;
|
||||
}
|
||||
|
||||
#post-hero h1 {
|
||||
font-size: 3rem;
|
||||
text-shadow: 0 3px 20px rgba(0, 0, 0, 0.95);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#post-content {
|
||||
padding: 5rem 2rem;
|
||||
min-height: calc(100vh - 450px - 60px - 50px);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ─── Markdown Viewer Theme ─── */
|
||||
.post-content {
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
background: var(--bg-content);
|
||||
border: 1px solid var(--border-base);
|
||||
border-radius: 20px;
|
||||
padding: 3.5rem;
|
||||
line-height: 1.9;
|
||||
font-size: 1.1rem;
|
||||
color: #ccc;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
transition:
|
||||
background 0.8s ease,
|
||||
border-color 0.8s ease;
|
||||
}
|
||||
|
||||
.post-content h1 {
|
||||
color: #fff;
|
||||
font-size: 2.4rem;
|
||||
border-bottom: 3px solid var(--accent);
|
||||
padding-bottom: 0.8rem;
|
||||
margin-bottom: 2.5rem;
|
||||
margin-top: 0;
|
||||
transition: var(--transition-theme);
|
||||
}
|
||||
|
||||
.post-content h2 {
|
||||
color: var(--accent);
|
||||
font-size: 1.8rem;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1.2rem;
|
||||
border-left: 5px solid var(--accent);
|
||||
padding-left: 1.2rem;
|
||||
transition: var(--transition-theme);
|
||||
}
|
||||
|
||||
.post-content h3 {
|
||||
color: var(--accent-light);
|
||||
font-size: 1.5rem;
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
transition: var(--transition-theme);
|
||||
}
|
||||
|
||||
.post-content p {
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
|
||||
.post-content a {
|
||||
color: #66aaff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #66aaff;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.post-content a:hover {
|
||||
color: #99ccff;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.post-content code {
|
||||
background: #0f1214;
|
||||
color: #d48a8a;
|
||||
padding: 0.25rem 0.6rem;
|
||||
border-radius: 6px;
|
||||
font-family: "Fira Code", "Courier New", monospace;
|
||||
font-size: 0.9em;
|
||||
border: 1px solid #1f2428;
|
||||
}
|
||||
|
||||
.post-content pre {
|
||||
background: #0f1214;
|
||||
border: 1px solid #1f2428;
|
||||
border-radius: 12px;
|
||||
padding: 1.8rem;
|
||||
overflow-x: auto;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.post-content pre code {
|
||||
background: transparent;
|
||||
color: #ddd;
|
||||
padding: 0;
|
||||
border: none;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.post-content blockquote {
|
||||
border-left: 4px solid var(--accent);
|
||||
background: #1a1d20;
|
||||
padding: 1.5rem 1.8rem;
|
||||
margin: 2rem 0;
|
||||
border-radius: 0 12px 12px 0;
|
||||
font-style: italic;
|
||||
color: #bbb;
|
||||
transition: var(--transition-theme);
|
||||
}
|
||||
|
||||
body.destructive-mode .post-content blockquote {
|
||||
background: #201a1a;
|
||||
}
|
||||
|
||||
.post-content ul,
|
||||
.post-content ol {
|
||||
margin: 1.5rem 0;
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
|
||||
.post-content li {
|
||||
margin-bottom: 0.7rem;
|
||||
}
|
||||
|
||||
.post-content img {
|
||||
max-width: 100%;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border-base);
|
||||
margin: 2rem 0;
|
||||
display: block;
|
||||
transition: border-color 0.8s ease;
|
||||
}
|
||||
|
||||
.post-content hr {
|
||||
border: none;
|
||||
border-top: 2px solid var(--border-base);
|
||||
margin: 3rem 0;
|
||||
transition: border-color 0.8s ease;
|
||||
}
|
||||
|
||||
.post-content table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.post-content th,
|
||||
.post-content td {
|
||||
border: 1px solid var(--border-base);
|
||||
padding: 0.8rem;
|
||||
text-align: left;
|
||||
transition: border-color 0.8s ease;
|
||||
}
|
||||
|
||||
.post-content th {
|
||||
background: #1c1e21;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
body.destructive-mode .post-content th {
|
||||
background: #211c1c;
|
||||
}
|
||||
|
||||
.post-content tr:nth-child(even) {
|
||||
background: #181a1d;
|
||||
}
|
||||
|
||||
body.destructive-mode .post-content tr:nth-child(even) {
|
||||
background: #1d1818;
|
||||
}
|
||||
|
||||
/* ─── Footer ─── */
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: var(--bg-footer);
|
||||
border-top: 1px solid #1f2428;
|
||||
padding: 1rem 2rem;
|
||||
text-align: center;
|
||||
color: #5a6b72;
|
||||
z-index: 1000;
|
||||
font-size: 0.9rem;
|
||||
transform: translateY(100%);
|
||||
transition:
|
||||
transform 0.4s ease,
|
||||
background 0.4s ease,
|
||||
backdrop-filter 0.4s ease,
|
||||
border-color 0.4s ease,
|
||||
box-shadow 0.4s ease,
|
||||
background-color 0.8s ease;
|
||||
}
|
||||
|
||||
footer.visible {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
footer.glass {
|
||||
background: rgba(20, 23, 26, 0.65);
|
||||
backdrop-filter: blur(20px) saturate(1.4);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(1.4);
|
||||
border-top-color: rgba(255, 255, 255, 0.06);
|
||||
box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
body.destructive-mode footer.glass {
|
||||
background: rgba(26, 20, 20, 0.65);
|
||||
}
|
||||
|
||||
footer.solid {
|
||||
background: var(--bg-footer);
|
||||
backdrop-filter: none;
|
||||
border-top-color: #1f2428;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: #7a8e9a;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ─── Scrollbar ─── */
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: #0a0c0e;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #2a2e33;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #3a424a;
|
||||
}
|
||||