mirror of
https://github.com/guyg1474/hcrb.git
synced 2026-10-16 07:13:28 +02:00
Spiel-Events, Kalenderdateien, Patches-Seite und neues Design
- Kalender: Termine als Spiel-Event markieren (nur diese zählen in der Statistik), optionale Uhrzeiten, Termine bearbeiten - .ics-Download für einzelne und alle kommenden Termine - Neue Seite Patches: Upload (PNG, JPEG, WebP, geprüftes SVG), Status "Gibt es schon" / "In Planung", Bilder in data/patches/ - Volle Seitenbreite mit Spaltenlayouts, neues Design mit selbst gehosteten Schriften, Startseite mit Zoom und drehendem Zahnrad - Bestehende Daten werden beim Laden ergänzt, keine Migration nötig Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
43356a120c
commit
486e6f6784
23 files changed
+1757
-387
No files matched your search
+102
-88
@@ -4,118 +4,132 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>HCRB – Highcap Rasselbande</title>
|
||||
<meta name="description" content="Highcap Rasselbande (HCRB), Airsoft-Gruppe aus Berlin.">
|
||||
<meta name="theme-color" content="#121730">
|
||||
<link rel="preload" href="/fonts/saira-stencil-one-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="hero">
|
||||
<div>
|
||||
<h1>HCRB</h1>
|
||||
<div class="subtitle">Highcap Rasselbande</div>
|
||||
<body class="home">
|
||||
<section class="hero" aria-label="HCRB">
|
||||
<div class="hero-stage" id="hero-stage">
|
||||
<!-- Flagge in zwei Ebenen: Hintergrund mit Bär steht, das Zahnrad darüber dreht sich beim Scrollen -->
|
||||
<img class="hero-flag" src="/img/flagge-grund.jpg" alt="Flagge der HCRB: Berliner Bär in einem Zahnrad" width="1600" height="1067" fetchpriority="high">
|
||||
<img class="hero-flag hero-gear" src="/img/zahnrad.webp" alt="" width="1600" height="1067" fetchpriority="high">
|
||||
<div class="hero-shade"></div>
|
||||
<div class="hud" aria-hidden="true">
|
||||
<span class="tl">52.520° N · 13.405° E</span>
|
||||
<span class="tr">Airsoft · Berlin</span>
|
||||
<span class="corner c1"></span><span class="corner c2"></span>
|
||||
<span class="corner c3"></span><span class="corner c4"></span>
|
||||
</div>
|
||||
<div class="hero-title">
|
||||
<h1>HCRB</h1>
|
||||
<div class="subtitle">Highcap Rasselbande</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main>
|
||||
<p class="intro">
|
||||
Wir sind die Highcap Rasselbande – eine Airsoft-Gruppe aus Berlin.
|
||||
Am häufigsten findet ihr uns auf der Darkzone.
|
||||
</p>
|
||||
<section class="next-op reveal" id="next-op">
|
||||
<div>
|
||||
<span class="eyebrow">Nächster Einsatz</span>
|
||||
<h2 id="next-title">Lädt …</h2>
|
||||
<div class="when" id="next-when"></div>
|
||||
</div>
|
||||
<div class="countdown" id="next-countdown" hidden></div>
|
||||
</section>
|
||||
|
||||
<p class="notice wip">
|
||||
<strong>Diese Seite ist noch in Arbeit.</strong> Es kommen noch Änderungen und neue Funktionen dazu.
|
||||
</p>
|
||||
|
||||
<div class="tiles">
|
||||
<a class="tile" href="/kalender">
|
||||
<nav class="areas reveal" aria-label="Bereiche">
|
||||
<a class="tile big" href="/kalender">
|
||||
<svg class="bg-gear" viewBox="0 0 100 100" aria-hidden="true"><path fill="currentColor" fill-rule="evenodd" d="M87.8 40.4 L97.5 43.1 L97.5 56.9 L87.8 59.6 L87.5 60.6 L94.6 67.8 L87.7 79.7 L77.9 77.2 L77.2 77.9 L79.7 87.7 L67.8 94.6 L60.6 87.5 L59.6 87.8 L56.9 97.5 L43.1 97.5 L40.4 87.8 L39.4 87.5 L32.2 94.6 L20.3 87.7 L22.8 77.9 L22.1 77.2 L12.3 79.7 L5.4 67.8 L12.5 60.6 L12.2 59.6 L2.5 56.9 L2.5 43.1 L12.2 40.4 L12.5 39.4 L5.4 32.2 L12.3 20.3 L22.1 22.8 L22.8 22.1 L20.3 12.3 L32.2 5.4 L39.4 12.5 L40.4 12.2 L43.1 2.5 L56.9 2.5 L59.6 12.2 L60.6 12.5 L67.8 5.4 L79.7 12.3 L77.2 22.1 L77.9 22.8 L87.7 20.3 L94.6 32.2 L87.5 39.4Z M50 28a22 22 0 1 0 0 44a22 22 0 1 0 0-44Z"/></svg>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
|
||||
<rect x="3" y="5" width="18" height="16"/><path d="M3 10h18M8 3v4M16 3v4M7 14h3M14 14h3M7 17h3"/>
|
||||
</svg>
|
||||
<div>
|
||||
<h2>Kalender</h2>
|
||||
<p>Spieltage eintragen und zusagen.</p>
|
||||
</div>
|
||||
<h2>Kalender</h2>
|
||||
<p>Spieltage und Termine eintragen, zusagen und als Kalenderdatei aufs Handy holen.</p>
|
||||
<span class="go">Zum Kalender</span>
|
||||
</a>
|
||||
<a class="tile" href="/fahrt">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
|
||||
<path d="M3 16v-4l2-5h14l2 5v4H3z"/><path d="M3 12h18"/><circle cx="7.5" cy="17.5" r="1.8"/><circle cx="16.5" cy="17.5" r="1.8"/>
|
||||
</svg>
|
||||
<div>
|
||||
<h2>Fahrtplaner</h2>
|
||||
<p>Fahrgemeinschaften einteilen.</p>
|
||||
</div>
|
||||
<h2>Fahrtplaner</h2>
|
||||
<p>Fahrgemeinschaften einteilen.</p>
|
||||
</a>
|
||||
</div>
|
||||
<a class="tile" href="/patches">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
|
||||
<path d="M12 2.5l8 3.5v6c0 5-3.5 8.2-8 9.5-4.5-1.3-8-4.5-8-9.5V6z"/><path d="M8.5 12l2.5 2.5 4.5-5"/>
|
||||
</svg>
|
||||
<h2>Patches</h2>
|
||||
<p>Alle Patches der Bande.</p>
|
||||
</a>
|
||||
<a class="tile" href="/statistik">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
|
||||
<path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/>
|
||||
</svg>
|
||||
<h2>Statistik</h2>
|
||||
<p>Wer war wie oft spielen?</p>
|
||||
</a>
|
||||
<a class="tile" href="/gruppe">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="square" aria-hidden="true">
|
||||
<circle cx="9" cy="8" r="3.5"/><path d="M2.5 20c.6-3.6 3.2-5.5 6.5-5.5s5.9 1.9 6.5 5.5"/><path d="M16 4.6a3.5 3.5 0 0 1 0 6.8M18 14.8c2 .7 3.2 2.4 3.5 5.2"/>
|
||||
</svg>
|
||||
<h2>Gruppe</h2>
|
||||
<p>Mitglieder und Treffpunkte.</p>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h2>Nächste Spieltage</h2>
|
||||
<a href="/kalender" class="button small">Zum Kalender</a>
|
||||
<section id="patch-section" class="reveal" hidden>
|
||||
<div class="section-title">
|
||||
<h2>Unsere Patches</h2>
|
||||
<a href="/patches" class="button small">Alle Patches</a>
|
||||
</div>
|
||||
<div id="upcoming"><p class="muted">Lädt …</p></div>
|
||||
</div>
|
||||
<div class="patch-rail" id="patch-rail"></div>
|
||||
</section>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h2>Pile of Shame</h2>
|
||||
<a href="/statistik" class="button small">Zur Statistik</a>
|
||||
<div class="home-grid reveal">
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h2>Nächste Termine</h2>
|
||||
<a href="/kalender" class="button small">Zum Kalender</a>
|
||||
</div>
|
||||
<div id="upcoming"><p class="muted">Lädt …</p></div>
|
||||
</div>
|
||||
<div id="shame"><p class="muted">Lädt …</p></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Über uns</h2>
|
||||
<p>
|
||||
Wir sind die <strong>Highcap Rasselbande (HCRB)</strong>, eine Airsoft-Gruppe aus Berlin.
|
||||
Gespielt wird bei uns vor allem auf der <strong>Darkzone</strong> – dort sind wir regelmäßig unterwegs.
|
||||
</p>
|
||||
<p>
|
||||
Hier planen wir unsere Spieltage und Fahrgemeinschaften. Videos und Bilder von unseren Spielen
|
||||
gibt es auf YouTube und Instagram:
|
||||
</p>
|
||||
<div class="social">
|
||||
<a class="button" href="https://www.youtube.com/@highcaprasselbande" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M23 7.2a3 3 0 0 0-2.1-2.1C19 4.6 12 4.6 12 4.6s-7 0-8.9.5A3 3 0 0 0 1 7.2 31 31 0 0 0 .5 12a31 31 0 0 0 .5 4.8 3 3 0 0 0 2.1 2.1c1.9.5 8.9.5 8.9.5s7 0 8.9-.5a3 3 0 0 0 2.1-2.1 31 31 0 0 0 .5-4.8 31 31 0 0 0-.5-4.8zM9.75 15.02V8.98L15.5 12l-5.75 3.02z"/></svg>YouTube
|
||||
</a>
|
||||
<a class="button" href="https://www.instagram.com/hcrb.airsoft" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2.5" y="2.5" width="19" height="19" rx="5"/><circle cx="12" cy="12" r="4.2"/><circle cx="17.6" cy="6.4" r="1" fill="currentColor" stroke="none"/></svg>Instagram
|
||||
</a>
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h2>Pile of Shame</h2>
|
||||
<a href="/statistik" class="button small">Zur Statistik</a>
|
||||
</div>
|
||||
<div id="shame"><p class="muted">Lädt …</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="about reveal">
|
||||
<img src="/img/logo.png" alt="" width="128" height="128">
|
||||
<div>
|
||||
<span class="eyebrow">Über uns</span>
|
||||
<h2>Highcap Rasselbande</h2>
|
||||
<p>
|
||||
Wir sind die <strong>Highcap Rasselbande (HCRB)</strong>, eine Airsoft-Gruppe aus Berlin.
|
||||
Gespielt wird bei uns vor allem auf der <strong>Darkzone</strong>, dort sind wir regelmäßig unterwegs.
|
||||
</p>
|
||||
<p>
|
||||
Hier planen wir unsere Spieltage und Fahrgemeinschaften. Videos und Bilder von unseren Spielen
|
||||
gibt es auf YouTube und Instagram.
|
||||
</p>
|
||||
<div class="social">
|
||||
<a class="button" href="https://www.youtube.com/@highcaprasselbande" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M23 7.2a3 3 0 0 0-2.1-2.1C19 4.6 12 4.6 12 4.6s-7 0-8.9.5A3 3 0 0 0 1 7.2 31 31 0 0 0 .5 12a31 31 0 0 0 .5 4.8 3 3 0 0 0 2.1 2.1c1.9.5 8.9.5 8.9.5s7 0 8.9-.5a3 3 0 0 0 2.1-2.1 31 31 0 0 0 .5-4.8 31 31 0 0 0-.5-4.8zM9.75 15.02V8.98L15.5 12l-5.75 3.02z"/></svg>YouTube
|
||||
</a>
|
||||
<a class="button" href="https://www.instagram.com/hcrb.airsoft" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2.5" y="2.5" width="19" height="19" rx="5"/><circle cx="12" cy="12" r="4.2"/><circle cx="17.6" cy="6.4" r="1" fill="currentColor" stroke="none"/></svg>Instagram
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
|
||||
<script type="module">
|
||||
import { renderHeader, renderFooter, api, esc, formatDate } from '/js/common.js';
|
||||
|
||||
renderHeader('home');
|
||||
renderFooter();
|
||||
|
||||
const box = document.getElementById('upcoming');
|
||||
try {
|
||||
const events = await api('GET', '/upcoming');
|
||||
box.innerHTML = events.length
|
||||
? `<ul class="list">${events.map((e) => `
|
||||
<li>
|
||||
<span class="name"><strong>${esc(e.title)}</strong></span>
|
||||
<span class="meta">${formatDate(e.date, true)}</span>
|
||||
<span class="badge">${e.attendeeCount} zugesagt</span>
|
||||
</li>`).join('')}</ul>`
|
||||
: '<p class="muted">Noch keine Spieltage eingetragen.</p>';
|
||||
} catch {
|
||||
box.innerHTML = '<p class="muted">Termine konnten nicht geladen werden.</p>';
|
||||
}
|
||||
|
||||
// Pile of Shame: wer dieses Jahr noch nicht spielen war
|
||||
const shame = document.getElementById('shame');
|
||||
try {
|
||||
const { year, entries } = await api('GET', '/stats');
|
||||
const names = entries.filter((s) => s.total === 0).map((s) => s.name).sort((a, b) => a.localeCompare(b, 'de'));
|
||||
shame.innerHTML = names.length
|
||||
? `<p class="muted">Waren ${year} noch kein einziges Mal spielen:</p>
|
||||
<div class="chips">${names.map((n) => `<span class="chip">${esc(n)}</span>`).join('')}</div>`
|
||||
: `<p class="muted">Leer – alle waren ${year} schon spielen.</p>`;
|
||||
} catch {
|
||||
shame.innerHTML = '<p class="muted">Konnte nicht geladen werden.</p>';
|
||||
}
|
||||
</script>
|
||||
<script type="module" src="/js/home.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user