forked from cccb-website-team/www
adjust styling and bump dates etc
This commit is contained in:
parent
476bf0d6d9
commit
a584a5252f
40 changed files with 678 additions and 294 deletions
|
|
@ -36,15 +36,12 @@
|
|||
border-collapse: collapse;
|
||||
}
|
||||
#calendar-table th, #calendar-table td {
|
||||
border: 1px;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
height: 50px;
|
||||
width: 15%;
|
||||
}
|
||||
#calendar-table th
|
||||
#calendar-table td {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -83,8 +80,6 @@
|
|||
background-color: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 0 20px rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 5px solid grey;
|
||||
font-weight: lighter;
|
||||
position: relative;
|
||||
|
|
|
|||
411
assets/css/custom.css
Normal file
411
assets/css/custom.css
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
/* ── Self-hosted fonts ──────────────────────────────────────────────────── */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Press Start 2P';
|
||||
src: url('/fonts/PressStart2P.woff2') format('woff2');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* ── Modern micro-improvements ─────────────────────────────────────────── */
|
||||
|
||||
/* Smooth scrolling */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Thin, modern scrollbar on WebKit */
|
||||
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(var(--color-neutral-500), 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(var(--color-primary-400), 0.7);
|
||||
}
|
||||
|
||||
/* ── Typography ─────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Tighter, more confident headings */
|
||||
h1, h2, h3 {
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
/* Slightly warmer body text contrast in dark mode */
|
||||
.dark .prose {
|
||||
color: rgba(var(--color-neutral-200), 0.92);
|
||||
}
|
||||
|
||||
/* ── Cards ──────────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Lift + glow on card hover */
|
||||
article.cursor-pointer,
|
||||
.cursor-pointer[class*="backdrop"] {
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
article.cursor-pointer:hover,
|
||||
.cursor-pointer[class*="backdrop"]:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 12px 32px rgba(var(--color-primary-400), 0.12);
|
||||
}
|
||||
|
||||
/* ── Links ──────────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Animated underline: grows from left on hover */
|
||||
.prose a:not([class]) {
|
||||
text-decoration: none;
|
||||
background-image: linear-gradient(
|
||||
rgba(var(--color-primary-400), 0.9),
|
||||
rgba(var(--color-primary-400), 0.9)
|
||||
);
|
||||
background-size: 0 1.5px;
|
||||
background-position: 0 100%;
|
||||
background-repeat: no-repeat;
|
||||
transition: background-size 0.2s ease;
|
||||
}
|
||||
.prose a:not([class]):hover {
|
||||
background-size: 100% 1.5px;
|
||||
}
|
||||
|
||||
/* ── Header ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Crisper blur on the fixed-fill-blur header */
|
||||
#menu-blur {
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
background: rgba(var(--color-neutral-50), 0.85) !important;
|
||||
}
|
||||
.dark #menu-blur {
|
||||
background: rgba(var(--color-neutral-900), 0.72) !important;
|
||||
}
|
||||
|
||||
/* ── Hero / Background ──────────────────────────────────────────────────── */
|
||||
|
||||
/* Subtle gradient vignette over hero images */
|
||||
.single_hero_background::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent 40%,
|
||||
rgba(var(--color-neutral-200), 0.5) 100%
|
||||
);
|
||||
pointer-events: none;
|
||||
}
|
||||
.dark .single_hero_background::after {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent 40%,
|
||||
rgba(var(--color-neutral-900), 0.6) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Focus rings ────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Modern, rounded focus ring */
|
||||
:focus-visible {
|
||||
outline: 2px solid rgba(var(--color-primary-400), 0.9);
|
||||
outline-offset: 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* ── Buttons / Tags ─────────────────────────────────────────────────────── */
|
||||
|
||||
/* Pill-shaped tags with subtle glow on hover */
|
||||
a[href*="/tags/"],
|
||||
a[href*="/categories/"] {
|
||||
border-radius: 9999px;
|
||||
transition: box-shadow 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
a[href*="/tags/"]:hover,
|
||||
a[href*="/categories/"]:hover {
|
||||
box-shadow: 0 0 0 3px rgba(var(--color-primary-400), 0.2);
|
||||
}
|
||||
|
||||
/* ── Code blocks ────────────────────────────────────────────────────────── */
|
||||
|
||||
/* Rounded corners and a border on code blocks */
|
||||
.dark .highlight {
|
||||
border: 1px solid rgba(var(--color-neutral-700), 1);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ── Retro-terminal layer ───────────────────────────────────────────────── */
|
||||
|
||||
/* Monospace headings + neon glow in dark mode */
|
||||
.dark .prose h1,
|
||||
.dark .prose h2,
|
||||
.dark .prose h3 {
|
||||
font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace;
|
||||
text-shadow:
|
||||
0 0 8px rgba(var(--color-primary-400), 0.55),
|
||||
0 0 28px rgba(var(--color-primary-400), 0.2),
|
||||
0 0 2px rgba(192, 132, 252, 0.35);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* Scanline texture (dark mode only) */
|
||||
.dark body::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 9998;
|
||||
pointer-events: none;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
rgba(0, 0, 0, 0.04) 0px,
|
||||
rgba(0, 0, 0, 0.04) 1px,
|
||||
transparent 1px,
|
||||
transparent 4px
|
||||
);
|
||||
}
|
||||
|
||||
/* Terminal window chrome on code blocks (traffic-light dots via radial gradients) */
|
||||
.dark .highlight::before {
|
||||
content: "";
|
||||
display: block;
|
||||
height: 28px;
|
||||
background-color: rgba(var(--color-neutral-800), 1);
|
||||
background-image:
|
||||
radial-gradient(circle 5px at 16px 14px, #ff5f56 0%, #ff5f56 100%),
|
||||
radial-gradient(circle 5px at 32px 14px, #ffbd2e 0%, #ffbd2e 100%),
|
||||
radial-gradient(circle 5px at 48px 14px, #27c93f 0%, #27c93f 100%);
|
||||
background-repeat: no-repeat;
|
||||
border-bottom: 1px solid rgba(var(--color-neutral-700), 0.8);
|
||||
}
|
||||
|
||||
/* Phosphor glow on hovered prose links in dark mode */
|
||||
.dark .prose a:not([class]):hover {
|
||||
text-shadow: 0 0 8px rgba(var(--color-primary-400), 0.4);
|
||||
}
|
||||
|
||||
/* Cyan glow on card hover in dark mode */
|
||||
.dark article.cursor-pointer:hover,
|
||||
.dark .cursor-pointer[class*="backdrop"]:hover {
|
||||
box-shadow: 0 12px 40px rgba(var(--color-primary-400), 0.18),
|
||||
0 0 0 1px rgba(var(--color-primary-400), 0.1);
|
||||
}
|
||||
|
||||
/* Slide-in "> " prompt before nav items on hover (dark mode) */
|
||||
.dark .main-menu a p::before {
|
||||
content: "> ";
|
||||
display: inline-block;
|
||||
max-width: 0;
|
||||
overflow: hidden;
|
||||
color: rgba(var(--color-primary-400), 0.65);
|
||||
font-family: ui-monospace, monospace;
|
||||
font-weight: normal;
|
||||
transition: max-width 0.15s ease;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.dark .main-menu a:hover p::before {
|
||||
max-width: 1.5em;
|
||||
}
|
||||
|
||||
/* Blinking block cursor keyframe (reusable) */
|
||||
@keyframes cursor-blink {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
/* ── Pixel font — site title ────────────────────────────────────────────── */
|
||||
|
||||
/* Navbar site title — only the first nav (space-x-3) holds the site title link;
|
||||
the menu items live in the second nav (hidden md:flex) */
|
||||
.main-menu .flex-1 nav:first-of-type a {
|
||||
font-family: 'Press Start 2P', ui-monospace, monospace !important;
|
||||
font-size: 0.6rem !important;
|
||||
transform: scaleY(1.4);
|
||||
display: inline-block;
|
||||
letter-spacing: 0 !important;
|
||||
transition: color 0.2s ease, text-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
/* Homepage hero h1 (font-extrabold is set only on the background layout h1) */
|
||||
h1.font-extrabold {
|
||||
font-family: 'Press Start 2P', ui-monospace, monospace !important;
|
||||
letter-spacing: 0 !important;
|
||||
transition: color 0.2s ease, text-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
/* Scale down the homepage h1 — pixel fonts read best smaller */
|
||||
h1.font-extrabold {
|
||||
font-size: clamp(1rem, 2.5vw, 1.6rem) !important;
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
|
||||
/* Purple glow on hover — navbar */
|
||||
.main-menu .flex-1 nav:first-of-type a:hover {
|
||||
color: #c084fc !important;
|
||||
text-shadow:
|
||||
0 0 6px rgba(192, 132, 252, 0.9),
|
||||
0 0 18px rgba(168, 85, 247, 0.6),
|
||||
0 0 40px rgba(139, 92, 246, 0.3);
|
||||
}
|
||||
|
||||
/* Purple glow on hover — homepage h1 */
|
||||
h1.font-extrabold:hover {
|
||||
color: #c084fc !important;
|
||||
text-shadow:
|
||||
0 0 8px rgba(192, 132, 252, 0.9),
|
||||
0 0 24px rgba(168, 85, 247, 0.6),
|
||||
0 0 50px rgba(139, 92, 246, 0.3);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* ── Cyberpunk layer ─────────────────────────────────────────────────────── */
|
||||
|
||||
/* Text selection — neon cyan highlight */
|
||||
.dark ::selection {
|
||||
background: rgba(34, 211, 238, 0.2);
|
||||
color: rgba(var(--color-neutral-50), 1);
|
||||
}
|
||||
|
||||
/* Cyberpunk background: ambient glows + drifting grid (dark mode) */
|
||||
@keyframes grid-drift {
|
||||
from { background-position: 0 0, 0 0, 0 0, 0 0; }
|
||||
to { background-position: 0 0, 0 0, 48px 48px, 48px 48px; }
|
||||
}
|
||||
|
||||
.dark body::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
background-image:
|
||||
radial-gradient(ellipse 55vw 55vh at 88% 4%, rgba(34, 211, 238, 0.07), transparent),
|
||||
radial-gradient(ellipse 45vw 45vh at 8% 96%, rgba(192, 132, 252, 0.06), transparent),
|
||||
linear-gradient(rgba(34, 211, 238, 0.018) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(34, 211, 238, 0.018) 1px, transparent 1px);
|
||||
background-size: 100% 100%, 100% 100%, 48px 48px, 48px 48px;
|
||||
animation: grid-drift 28s linear infinite;
|
||||
}
|
||||
|
||||
/* Neon horizontal rule — cyan-to-magenta gradient */
|
||||
.dark .prose hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(34, 211, 238, 0.6) 20%,
|
||||
rgba(192, 132, 252, 0.6) 50%,
|
||||
rgba(34, 211, 238, 0.6) 80%,
|
||||
transparent
|
||||
);
|
||||
box-shadow: 0 0 10px rgba(34, 211, 238, 0.25);
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
||||
/* Glitch keyframes for site title */
|
||||
@keyframes neon-glitch {
|
||||
0%, 88%, 100% { text-shadow: inherit; }
|
||||
89% {
|
||||
text-shadow:
|
||||
-2px 0 rgba(255, 0, 128, 0.85),
|
||||
2px 0 rgba(34, 211, 238, 0.85);
|
||||
}
|
||||
91% {
|
||||
text-shadow:
|
||||
2px 0 rgba(255, 0, 128, 0.85),
|
||||
-2px 0 rgba(34, 211, 238, 0.85);
|
||||
}
|
||||
93% { text-shadow: inherit; }
|
||||
94% {
|
||||
text-shadow:
|
||||
-1px 0 rgba(255, 0, 128, 0.6),
|
||||
1px 0 rgba(34, 211, 238, 0.6);
|
||||
}
|
||||
96% { text-shadow: inherit; }
|
||||
}
|
||||
|
||||
/* Apply glitch to pixel-font site title in dark mode */
|
||||
.dark .main-menu .flex-1 nav:first-of-type a {
|
||||
animation: neon-glitch 9s infinite;
|
||||
}
|
||||
|
||||
/* Neon card border glow — enhanced dual-color on hover */
|
||||
.dark article.cursor-pointer:hover,
|
||||
.dark .cursor-pointer[class*="backdrop"]:hover {
|
||||
box-shadow:
|
||||
0 12px 40px rgba(34, 211, 238, 0.22),
|
||||
0 0 0 1px rgba(34, 211, 238, 0.18),
|
||||
0 0 20px rgba(192, 132, 252, 0.08) inset;
|
||||
}
|
||||
|
||||
/* Neon code-block border */
|
||||
.dark .highlight {
|
||||
border-color: rgba(34, 211, 238, 0.3);
|
||||
box-shadow: 0 0 14px rgba(34, 211, 238, 0.07);
|
||||
}
|
||||
|
||||
/* ── Fairydust rocket ───────────────────────────────────────────────────── */
|
||||
|
||||
.fairydust-wrapper {
|
||||
position: fixed;
|
||||
z-index: 9997;
|
||||
pointer-events: none;
|
||||
width: 40px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.fairydust-wrapper.go-right {
|
||||
left: -100px;
|
||||
animation: fairydust-fly-right var(--fly-duration, 5s) linear forwards;
|
||||
}
|
||||
.fairydust-wrapper.go-left {
|
||||
right: -100px;
|
||||
animation: fairydust-fly-left var(--fly-duration, 5s) linear forwards;
|
||||
}
|
||||
|
||||
/* Comet trail */
|
||||
.fairydust-wrapper::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 130px;
|
||||
height: 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.fairydust-wrapper.go-right::after {
|
||||
right: 100%;
|
||||
background: linear-gradient(to right, transparent, rgba(232, 121, 249, 0.5));
|
||||
}
|
||||
.fairydust-wrapper.go-left::after {
|
||||
left: 100%;
|
||||
background: linear-gradient(to left, transparent, rgba(232, 121, 249, 0.5));
|
||||
}
|
||||
|
||||
.fairydust-rocket {
|
||||
width: 40px;
|
||||
height: 80px;
|
||||
animation: fairydust-glow 0.85s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes fairydust-glow {
|
||||
from {
|
||||
filter:
|
||||
drop-shadow(0 0 5px rgba(232, 121, 249, 0.8))
|
||||
drop-shadow(0 0 14px rgba(232, 121, 249, 0.4));
|
||||
}
|
||||
to {
|
||||
filter:
|
||||
drop-shadow(0 0 10px rgba(232, 121, 249, 1))
|
||||
drop-shadow(0 0 26px rgba(168, 85, 247, 0.65));
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fairydust-fly-right {
|
||||
from { left: -100px; }
|
||||
to { left: calc(100vw + 100px); }
|
||||
}
|
||||
@keyframes fairydust-fly-left {
|
||||
from { right: -100px; }
|
||||
to { right: calc(100vw + 100px); }
|
||||
}
|
||||
37
assets/css/schemes/fira.css
Normal file
37
assets/css/schemes/fira.css
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* Fira scheme — deep navy + cyan + emerald */
|
||||
:root {
|
||||
--color-neutral: 255, 255, 255;
|
||||
/* Deep cool-slate — richer than pure black in dark mode */
|
||||
--color-neutral-50: 247, 250, 252;
|
||||
--color-neutral-100: 234, 241, 248;
|
||||
--color-neutral-200: 210, 225, 238;
|
||||
--color-neutral-300: 168, 196, 218;
|
||||
--color-neutral-400: 120, 148, 178;
|
||||
--color-neutral-500: 80, 105, 135;
|
||||
--color-neutral-600: 50, 70, 100;
|
||||
--color-neutral-700: 32, 48, 70;
|
||||
--color-neutral-800: 20, 30, 48;
|
||||
--color-neutral-900: 10, 15, 25;
|
||||
/* Cyan — electric, technical */
|
||||
--color-primary-50: 236, 254, 255;
|
||||
--color-primary-100: 207, 250, 254;
|
||||
--color-primary-200: 165, 243, 252;
|
||||
--color-primary-300: 103, 232, 249;
|
||||
--color-primary-400: 34, 211, 238;
|
||||
--color-primary-500: 6, 182, 212;
|
||||
--color-primary-600: 8, 145, 178;
|
||||
--color-primary-700: 14, 116, 144;
|
||||
--color-primary-800: 21, 94, 117;
|
||||
--color-primary-900: 22, 78, 99;
|
||||
/* Emerald — nod to CCC's green */
|
||||
--color-secondary-50: 240, 253, 244;
|
||||
--color-secondary-100: 220, 252, 231;
|
||||
--color-secondary-200: 187, 247, 208;
|
||||
--color-secondary-300: 134, 239, 172;
|
||||
--color-secondary-400: 74, 222, 128;
|
||||
--color-secondary-500: 34, 197, 94;
|
||||
--color-secondary-600: 22, 163, 74;
|
||||
--color-secondary-700: 21, 128, 61;
|
||||
--color-secondary-800: 22, 101, 52;
|
||||
--color-secondary-900: 20, 83, 45;
|
||||
}
|
||||
|
|
@ -35,6 +35,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
event.description = value;
|
||||
} else if (baseKey === "RRULE") {
|
||||
event.rrule = value;
|
||||
} else if (baseKey === "URL") {
|
||||
event.url = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -281,13 +283,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
const events = eventsByDate[dateKey];
|
||||
const hasMembersOnly = events.some(e => e.summary.toLowerCase().includes("members only"));
|
||||
const hasSubbotnik = events.some(e => e.summary.toLowerCase().includes("subbotnik"));
|
||||
const hasBastelabend = events.some(e => e.summary.toLowerCase().includes("bastelabend"));
|
||||
const hasSpieleabend = events.some(e => e.summary.toLowerCase().includes("spieleabend"));
|
||||
const hasRegular = events.some(e => {
|
||||
const title = e.summary.toLowerCase();
|
||||
return !title.includes("members only") &&
|
||||
!title.includes("subbotnik") &&
|
||||
!title.includes("bastelabend") &&
|
||||
!title.includes("spieleabend");
|
||||
});
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
dot.className = "event-dot event-dot-red";
|
||||
dotsContainer.appendChild(dot);
|
||||
}
|
||||
if (hasSubbotnik || hasBastelabend || hasSpieleabend) {
|
||||
if (hasSubbotnik || hasSpieleabend) {
|
||||
let dot = document.createElement("div");
|
||||
dot.className = "event-dot event-dot-orange";
|
||||
dotsContainer.appendChild(dot);
|
||||
|
|
@ -329,20 +329,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
calendarBody.appendChild(row);
|
||||
}
|
||||
|
||||
function createEventLink(eventTitle) {
|
||||
if (eventTitle.startsWith("Datengarten")) {
|
||||
// Extract the number after "Datengarten "
|
||||
const match = eventTitle.match(/Datengarten\s+(\d+)/i);
|
||||
if (match && match[1]) {
|
||||
return `https://berlin.ccc.de/datengarten/${match[1]}/`;
|
||||
}
|
||||
}
|
||||
|
||||
// For other titles, convert to lowercase and use as path
|
||||
const slug = eventTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
|
||||
return `https://berlin.ccc.de/page/${slug}/`;
|
||||
}
|
||||
|
||||
function showEventDetails(dateKey) {
|
||||
const events = eventsByDate[dateKey];
|
||||
eventDateElem.textContent = formatDate(dateKey);
|
||||
|
|
@ -357,10 +343,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
eventTitle.className = "event-title";
|
||||
|
||||
// Create a link for the event title
|
||||
let titleLink = document.createElement("h");
|
||||
titleLink.textContent = ev.summary;
|
||||
titleLink.target = "_blank";
|
||||
eventTitle.appendChild(titleLink);
|
||||
if (ev.url) {
|
||||
let titleLink = document.createElement("a");
|
||||
titleLink.textContent = ev.summary;
|
||||
titleLink.href = ev.url;
|
||||
titleLink.target = "_blank";
|
||||
titleLink.rel = "noopener noreferrer";
|
||||
eventTitle.appendChild(titleLink);
|
||||
} else {
|
||||
eventTitle.textContent = ev.summary;
|
||||
}
|
||||
|
||||
eventItem.appendChild(eventTitle);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,21 @@
|
|||
const spaceapiUrl = "https://spaceapi.hamburg.ccc.de"
|
||||
const interval_ms = 60000
|
||||
|
||||
console.log("clubstatus.js geladen!"); /* TODO: ENTFERNEN */
|
||||
|
||||
function timeDistanceDE(pastDate) {
|
||||
const seconds = Math.floor((Date.now() - pastDate.getTime()) / 1000)
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const hours = Math.floor(minutes / 60)
|
||||
const days = Math.floor(hours / 24)
|
||||
|
||||
if (days = 1) return `since ${days}d`
|
||||
if (days > 1) return `since ${days}d`
|
||||
if (hours = 1) return `since ${hours}h`
|
||||
if (hours > 1) return `since ${hours}h`
|
||||
if (minutes = 1) return `since ${minutes}min`
|
||||
if (minutes > 1) return `since ${minutes}min`
|
||||
if (days >= 1) return `seit ${days}d`
|
||||
if (hours >= 1) return `seit ${hours}h`
|
||||
if (minutes >= 1) return `seit ${minutes}min`
|
||||
return `gerade eben`
|
||||
}
|
||||
|
||||
function updateRoomState(openState, lastChangeTimestamp) {
|
||||
const roomstate = document.querySelector('#clubstatus-badge')
|
||||
if (!roomstate) return
|
||||
const statusItem = roomstate.querySelector(".state")
|
||||
const durationItem = roomstate.querySelector(".duration")
|
||||
|
||||
|
|
@ -30,17 +26,20 @@ function updateRoomState(openState, lastChangeTimestamp) {
|
|||
|
||||
if (openState === null || lastChangeTimestamp === null) {
|
||||
statusItem.textContent = "unbekannt"
|
||||
roomstate.classList.add("unknown")
|
||||
statusItem.classList.add("unknown")
|
||||
durationItem.textContent = "(since unbekannt)"
|
||||
durationItem.textContent = "(seit unbekannt)"
|
||||
} else {
|
||||
const changeDate = new Date(lastChangeTimestamp * 1000)
|
||||
const sinceText = timeDistanceDE(changeDate)
|
||||
|
||||
if (openState) {
|
||||
statusItem.textContent = "open"
|
||||
roomstate.classList.add("open")
|
||||
statusItem.classList.add("open")
|
||||
} else {
|
||||
statusItem.textContent = "closed"
|
||||
roomstate.classList.add("closed")
|
||||
statusItem.classList.add("closed")
|
||||
}
|
||||
|
||||
|
|
|
|||
62
assets/js/fairydust.js
Normal file
62
assets/js/fairydust.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
var SVG = [
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 80" width="40" height="80">',
|
||||
// Exhaust flame
|
||||
'<path d="M13,65 Q20,80 27,65" fill="#f97316" opacity="0.85"/>',
|
||||
'<path d="M15,63 Q20,74 25,63" fill="#fbbf24"/>',
|
||||
// Fins
|
||||
'<path d="M11,53 L3,70 L14,58" fill="#a855f7"/>',
|
||||
'<path d="M29,53 L37,70 L26,58" fill="#a855f7"/>',
|
||||
// Body
|
||||
'<ellipse cx="20" cy="42" rx="11" ry="22" fill="#e879f9"/>',
|
||||
// Nose cone
|
||||
'<path d="M20,10 L10,32 L30,32 Z" fill="#c026d3"/>',
|
||||
// Window
|
||||
'<circle cx="20" cy="44" r="7" fill="#0ea5e9" opacity="0.82"/>',
|
||||
'<circle cx="22" cy="41" r="2.5" fill="white" opacity="0.35"/>',
|
||||
// Body highlight
|
||||
'<ellipse cx="15" cy="36" rx="3" ry="8" fill="white" opacity="0.15" transform="rotate(-15,15,36)"/>',
|
||||
'</svg>'
|
||||
].join('');
|
||||
|
||||
function isDark() {
|
||||
return document.documentElement.classList.contains('dark');
|
||||
}
|
||||
|
||||
function launch() {
|
||||
if (!isDark()) { scheduleNext(); return; }
|
||||
|
||||
var goRight = Math.random() > 0.5;
|
||||
var topPct = 6 + Math.random() * 72;
|
||||
var duration = (3.5 + Math.random() * 4).toFixed(1);
|
||||
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.className = 'fairydust-wrapper ' + (goRight ? 'go-right' : 'go-left');
|
||||
wrapper.style.top = topPct + 'vh';
|
||||
wrapper.style.setProperty('--fly-duration', duration + 's');
|
||||
|
||||
var rocket = document.createElement('div');
|
||||
rocket.className = 'fairydust-rocket';
|
||||
rocket.style.transform = 'rotate(' + (goRight ? 90 : -90) + 'deg)';
|
||||
rocket.innerHTML = SVG;
|
||||
|
||||
wrapper.appendChild(rocket);
|
||||
document.body.appendChild(wrapper);
|
||||
|
||||
wrapper.addEventListener('animationend', function (e) {
|
||||
if (e.animationName === 'fairydust-fly-right' ||
|
||||
e.animationName === 'fairydust-fly-left') {
|
||||
wrapper.remove();
|
||||
}
|
||||
});
|
||||
|
||||
scheduleNext();
|
||||
}
|
||||
|
||||
function scheduleNext() {
|
||||
setTimeout(launch, 250000 + Math.random() * 950000); // 250–1200 s
|
||||
}
|
||||
|
||||
})();
|
||||
Loading…
Reference in a new issue