diff --git a/.gitmodules b/.gitmodules
index 5a97d93..426d936 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
-[submodule "beautifulhugo"]
- path = themes/beautifulhugo
- url = https://github.com/cccb/beautifulhugo.git
[submodule "themes/blowfish"]
path = themes/blowfish
url = https://github.com/nunocoracao/blowfish.git
diff --git a/.hugo-params b/.hugo-params
index e3abdb3..2ef16a1 100644
--- a/.hugo-params
+++ b/.hugo-params
@@ -1 +1,5 @@
---baseURL=https://berlin.ccc.de/
\ No newline at end of file
+<<<<<<< HEAD
+--baseURL=https://berlin.ccc.de/
+=======
+--baseURL=https://berlin.ccc.de/
+>>>>>>> staging
diff --git a/assets/css/calendar.css b/assets/css/calendar.css
new file mode 100644
index 0000000..2806966
--- /dev/null
+++ b/assets/css/calendar.css
@@ -0,0 +1,113 @@
+ .calendar-container {
+ display: flex;
+ flex-wrap: wrap;
+ width: 100%;
+ gap: 20px;
+ }
+ #calendar {
+ flex: 1;
+ min-width: 300px;
+ }
+ #event-panel {
+ flex: 1;
+ min-width: 30%;
+ background-color: var(--color-bg-secondary);
+ padding: 15px;
+ border-radius: 5px;
+ min-height: 300px;
+ display: none;
+ }
+ #calendar-controls {
+ text-align: center;
+ margin-bottom: 10px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+ #calendar-controls button {
+ background: none;
+ border: none;
+ font-size: 2em;
+ cursor: pointer;
+ padding: 5px 15px;
+ }
+ #calendar-table {
+ width: 100%;
+ border-collapse: collapse;
+ }
+ #calendar-table th, #calendar-table td {
+ border: 1px;
+ padding: 5px;
+ text-align: center;
+ vertical-align: top;
+ height: 50px;
+ width: 15%;
+ }
+ #calendar-table th
+ #calendar-table td {
+ position: relative;
+ cursor: pointer;
+ }
+ #calendar-table td:hover {
+ background-color: rgba(255, 255, 255, 0.2);
+ box-shadow: 0 0 20px rgba(255, 255, 255, 0.2);
+ }
+ .event-dot-greenyellow {
+ height: 8px;
+ width: 8px;
+ background-color: #9acd32;
+ border-radius: 50%;
+ display: block;
+ margin: 5px auto 0;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
+ }
+ .event-dot-orange {
+ height: 8px;
+ width: 8px;
+ background-color: #ffa500;
+ border-radius: 50%;
+ display: block;
+ margin: 5px auto 0;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
+ }
+ .event-dot-red {
+ height: 8px;
+ width: 8px;
+ background-color: #ff4500;
+ border-radius: 50%;
+ display: block;
+ margin: 5px auto 0;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
+ }
+ .selected-day {
+ 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;
+ z-index: 1;
+ }
+ #event-date {
+ font-size: 1.2em;
+ margin-bottom: 15px;
+ }
+ .event-item {
+ margin-bottom: 15px;
+ padding-bottom: 15px;
+ border-bottom: 1px solid var(--color-border);
+ }
+ .event-title {
+ font-weight: bold;
+ margin-bottom: 5px;
+ }
+ .event-time, .event-description {
+ font-size: 0.9em;
+ margin-bottom: 5px;
+ }
+ .no-events {
+ font-style: italic;
+ color: var(--color-text-secondary);
+ }
diff --git a/assets/js/calendar.js b/assets/js/calendar.js
new file mode 100644
index 0000000..5aa9d6b
--- /dev/null
+++ b/assets/js/calendar.js
@@ -0,0 +1,445 @@
+document.addEventListener('DOMContentLoaded', function() {
+ (function(){
+ let events = [];
+ let eventsByDate = {};
+
+ // Funktion zum Parsen der ICS-Datei
+ function parseICS(icsText) {
+ let events = [];
+ let lines = icsText.split(/\r?\n/);
+ let event = null;
+ lines.forEach(line => {
+ if (line.startsWith("BEGIN:VEVENT")) {
+ event = {};
+ } else if (line.startsWith("END:VEVENT")) {
+ if (event) events.push(event);
+ event = null;
+ } else if (event) {
+ let colonIndex = line.indexOf(":");
+ if (colonIndex > -1) {
+ let key = line.substring(0, colonIndex);
+ let value = line.substring(colonIndex + 1);
+
+ // Handle properties with parameters (like TZID)
+ const baseKey = key.split(";")[0];
+
+ if (baseKey === "DTSTART") {
+ event.start = value;
+ event.startParams = key.includes(";") ? key.substring(key.indexOf(";") + 1) : null;
+ } else if (baseKey === "DTEND") {
+ event.end = value;
+ event.endParams = key.includes(";") ? key.substring(key.indexOf(";") + 1) : null;
+ } else if (baseKey === "SUMMARY") {
+ event.summary = value;
+ } else if (baseKey === "DESCRIPTION") {
+ event.description = value;
+ } else if (baseKey === "RRULE") {
+ event.rrule = value;
+ }
+ }
+ }
+ });
+ return events;
+ }
+
+ // Hilfsfunktion: Parst einen ICS-Datum-String ins Format "YYYY-MM-DD"
+ function parseDateString(icsDateStr) {
+ // Handle different date formats
+ if (!icsDateStr) return null;
+
+ // For basic date format: YYYYMMDD
+ if (icsDateStr.length === 8) {
+ let year = icsDateStr.substring(0, 4);
+ let month = icsDateStr.substring(4, 6);
+ let day = icsDateStr.substring(6, 8);
+ return `${year}-${month}-${day}`;
+ }
+ // For datetime formats: YYYYMMDDTHHmmssZ or YYYYMMDDTHHmmss
+ else if (icsDateStr.includes("T")) {
+ let year = icsDateStr.substring(0, 4);
+ let month = icsDateStr.substring(4, 6);
+ let day = icsDateStr.substring(6, 8);
+ return `${year}-${month}-${day}`;
+ }
+ return null;
+ }
+
+ // Extract date components from different date formats
+ function getDateComponents(icsDateStr) {
+ if (!icsDateStr) return null;
+
+ // Basic handling - extract YYYY, MM, DD regardless of format
+ const year = parseInt(icsDateStr.substring(0, 4));
+ const month = parseInt(icsDateStr.substring(4, 6)) - 1; // 0-based months
+ const day = parseInt(icsDateStr.substring(6, 8));
+
+ return { year, month, day };
+ }
+
+ function expandRecurringEvents(event, year, month) {
+ if (!event.rrule) return [event];
+
+ const rruleStr = event.rrule;
+
+ // Get start date components
+ const startComponents = getDateComponents(event.start);
+ if (!startComponents) return [event];
+
+ const startDate = new Date(
+ startComponents.year,
+ startComponents.month,
+ startComponents.day
+ );
+
+ const rangeStart = new Date(year, month, 1);
+ const rangeEnd = new Date(year, month + 1, 0);
+ const expandedEvents = [];
+
+ if (rruleStr.includes("FREQ=WEEKLY") && rruleStr.includes("BYDAY")) {
+ const bydayMatch = rruleStr.match(/BYDAY=([^;]+)/);
+ if (bydayMatch) {
+ const dayCode = bydayMatch[1];
+ const dayMap = {
+ 'MO': 1, 'TU': 2, 'WE': 3, 'TH': 4, 'FR': 5, 'SA': 6, 'SU': 0
+ };
+ const targetDay = dayMap[dayCode];
+
+ if (targetDay !== undefined) {
+ // Create events for each matching day in the month
+ let day = 1;
+ while (day <= rangeEnd.getDate()) {
+ const testDate = new Date(year, month, day);
+ if (testDate.getDay() === targetDay && testDate >= startDate) {
+ const newEvent = {...event};
+ const eventDate = formatDateForICS(testDate);
+
+ // Preserve time portion from original event
+ const timePart = event.start.includes('T') ?
+ event.start.substring(event.start.indexOf('T')) : '';
+ const endTimePart = event.end.includes('T') ?
+ event.end.substring(event.end.indexOf('T')) : '';
+
+ newEvent.start = eventDate + timePart;
+ newEvent.end = eventDate + endTimePart;
+ expandedEvents.push(newEvent);
+ }
+ day++;
+ }
+ }
+ }
+ }
+ else if (rruleStr.includes("FREQ=MONTHLY") && rruleStr.includes("BYDAY")) {
+ const bydayMatch = rruleStr.match(/BYDAY=([^;]+)/);
+ if (bydayMatch) {
+ const bydays = bydayMatch[1].split(',');
+ const dayMap = {
+ 'MO': 1, 'TU': 2, 'WE': 3, 'TH': 4, 'FR': 5, 'SA': 6, 'SU': 0
+ };
+
+ bydays.forEach(byday => {
+ const occurrence = parseInt(byday) || 1;
+ const dayCode = byday.slice(-2);
+ const dayIndex = dayMap[dayCode];
+
+ let day = 1;
+ let count = 0;
+
+ while (day <= rangeEnd.getDate()) {
+ const testDate = new Date(year, month, day);
+ if (testDate.getDay() === dayIndex) {
+ count++;
+ if (count === occurrence || (occurrence < 0 && day > rangeEnd.getDate() + occurrence * 7)) {
+ const newEvent = {...event};
+ const eventDate = new Date(year, month, day);
+
+ // Preserve time portion from original event
+ const timePart = event.start.includes('T') ?
+ event.start.substring(event.start.indexOf('T')) : '';
+ const endTimePart = event.end.includes('T') ?
+ event.end.substring(event.end.indexOf('T')) : '';
+
+ newEvent.start = formatDateForICS(eventDate) + timePart;
+ newEvent.end = formatDateForICS(eventDate) + endTimePart;
+ expandedEvents.push(newEvent);
+ }
+ }
+ day++;
+ }
+ });
+ }
+ }
+
+ return expandedEvents.length > 0 ? expandedEvents : [event];
+ }
+
+ // Kalender initialisieren
+ let currentYear, currentMonth;
+ const currentMonthElem = document.getElementById("current-month");
+ const calendarBody = document.getElementById("calendar-body");
+ const eventPanel = document.getElementById("event-panel");
+ const eventDateElem = document.getElementById("event-date");
+ const eventDetailsElem = document.getElementById("event-details");
+
+ document.getElementById("prev-month").addEventListener("click", function(){
+ currentMonth--;
+ if (currentMonth < 0) {
+ currentMonth = 11;
+ currentYear--;
+ }
+ updateEventsForMonth(currentYear, currentMonth);
+ });
+ document.getElementById("next-month").addEventListener("click", function(){
+ currentMonth++;
+ if (currentMonth > 11) {
+ currentMonth = 0;
+ currentYear++;
+ }
+ updateEventsForMonth(currentYear, currentMonth);
+ });
+
+ function updateEventsForMonth(year, month) {
+ // Clear existing events for this month view
+ eventsByDate = {};
+
+ // Process each event, expanding recurring ones
+ events.forEach(ev => {
+ if (ev.rrule) {
+ // For recurring events, expand them for current month
+ const expandedEvents = expandRecurringEvents(ev, year, month);
+ expandedEvents.forEach(expandedEv => {
+ let dateKey = parseDateString(expandedEv.start);
+ if (dateKey) {
+ if (!eventsByDate[dateKey]) {
+ eventsByDate[dateKey] = [];
+ }
+ eventsByDate[dateKey].push(expandedEv);
+ }
+ });
+ } else {
+ // For regular events, check if they fall in current month
+ let dateKey = parseDateString(ev.start);
+ if (dateKey) {
+ // Check if this event belongs to current month view
+ const eventYear = parseInt(dateKey.split('-')[0]);
+ const eventMonth = parseInt(dateKey.split('-')[1]) - 1;
+
+ if (eventYear === year && eventMonth === month) {
+ if (!eventsByDate[dateKey]) {
+ eventsByDate[dateKey] = [];
+ }
+ eventsByDate[dateKey].push(ev);
+ }
+ }
+ }
+ });
+
+ renderCalendar(year, month);
+ }
+
+ function renderCalendar(year, month) {
+ // Setze die Monatsbeschriftung (in Deutsch)
+ const monthNames = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
+ currentMonthElem.textContent = monthNames[month] + " " + year;
+ calendarBody.innerHTML = "";
+
+ let firstDay = new Date(year, month, 1);
+ let firstDayIndex = (firstDay.getDay() + 6) % 7; // Montag = 0, Dienstag = 1, etc.
+ let daysInMonth = new Date(year, month + 1, 0).getDate();
+
+ let row = document.createElement("tr");
+ // Leere Zellen vor dem 1. Tag
+ for (let i = 0; i < firstDayIndex; i++){
+ let cell = document.createElement("td");
+ row.appendChild(cell);
+ }
+
+ // Tage hinzufügen
+ for (let day = 1; day <= daysInMonth; day++){
+ if (row.children.length === 7) {
+ calendarBody.appendChild(row);
+ row = document.createElement("tr");
+ }
+ let cell = document.createElement("td");
+ cell.innerHTML = "" + day + "";
+
+ let dayStr = day < 10 ? "0" + day : day;
+ let monthStr = (month + 1) < 10 ? "0" + (month + 1) : (month + 1);
+ let dateKey = year + "-" + monthStr + "-" + dayStr;
+
+ if (eventsByDate[dateKey]) {
+ let dotsContainer = document.createElement("div");
+ dotsContainer.className = "event-dots-container";
+ cell.classList.add("has-event");
+
+ // Gruppe Events nach Typ
+ 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");
+ });
+
+ // Füge Dots entsprechend der Event-Typen hinzu
+ if (hasMembersOnly) {
+ let dot = document.createElement("div");
+ dot.className = "event-dot event-dot-red";
+ dotsContainer.appendChild(dot);
+ }
+ if (hasSubbotnik || hasBastelabend || hasSpieleabend) {
+ let dot = document.createElement("div");
+ dot.className = "event-dot event-dot-orange";
+ dotsContainer.appendChild(dot);
+ }
+ if (hasRegular) {
+ let dot = document.createElement("div");
+ dot.className = "event-dot event-dot-greenyellow";
+ dotsContainer.appendChild(dot);
+ }
+
+ cell.appendChild(dotsContainer);
+ cell.dataset.dateKey = dateKey;
+ cell.addEventListener("click", function() {
+ // Clear previous selections
+ document.querySelectorAll('.selected-day').forEach(el => {
+ el.classList.remove('selected-day');
+ });
+ cell.classList.add('selected-day');
+ showEventDetails(dateKey);
+ });
+ }
+ row.appendChild(cell);
+ }
+ // Falls die letzte Zeile nicht komplett ist
+ while (row.children.length < 7) {
+ let cell = document.createElement("td");
+ row.appendChild(cell);
+ }
+ 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);
+ eventDetailsElem.innerHTML = "";
+
+ if (events && events.length > 0) {
+ events.forEach(ev => {
+ let eventItem = document.createElement("div");
+ eventItem.className = "event-item";
+
+ let eventTitle = document.createElement("div");
+ 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);
+
+ eventItem.appendChild(eventTitle);
+
+ let eventTime = document.createElement("div");
+ eventTime.className = "event-time";
+ eventTime.textContent = `Start: ${formatTime(ev.start)}, End: ${formatTime(ev.end)}`;
+ eventItem.appendChild(eventTime);
+
+ if (ev.description) {
+ let eventDescription = document.createElement("div");
+ eventDescription.className = "event-description";
+
+ // Check if the description is a URL and make it a clickable link
+ if (ev.description.trim().startsWith('http')) {
+ let linkElement = document.createElement("a");
+ linkElement.href = ev.description.trim();
+ linkElement.textContent = ev.description.trim();
+ linkElement.target = "_blank";
+ eventDescription.innerHTML = '';
+ eventDescription.appendChild(linkElement);
+ } else {
+ eventDescription.textContent = ev.description;
+ }
+
+ eventItem.appendChild(eventDescription);
+ }
+
+ eventDetailsElem.appendChild(eventItem);
+ });
+ } else {
+ let noEvents = document.createElement("div");
+ noEvents.className = "no-events";
+ noEvents.textContent = "Keine Veranstaltungen an diesem Tag.";
+ eventDetailsElem.appendChild(noEvents);
+ }
+
+ eventPanel.style.display = "block";
+ }
+
+ function formatDate(dateStr) {
+ // Convert YYYY-MM-DD to DD.MM.YYYY
+ const parts = dateStr.split("-");
+ return `${parts[2]}.${parts[1]}.${parts[0]}`;
+ }
+
+ function formatTime(icsTimeStr) {
+ // Format time for display
+ if (!icsTimeStr) return "";
+
+ if (icsTimeStr.length === 8) {
+ // All-day event
+ return "Ganztägig";
+ } else if (icsTimeStr.includes("T")) {
+ // Time-specific event (with or without timezone)
+ const timeStart = icsTimeStr.indexOf("T") + 1;
+ const hour = icsTimeStr.substring(timeStart, timeStart + 2);
+ const minute = icsTimeStr.substring(timeStart + 2, timeStart + 4);
+ return `${hour}:${minute}`;
+ }
+ return icsTimeStr;
+ }
+
+ function formatDateForICS(date) {
+ const year = date.getFullYear();
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
+ const day = date.getDate().toString().padStart(2, '0');
+ return `${year}${month}${day}`;
+ }
+
+ // ICS-Datei abrufen und Events verarbeiten
+ fetch('/all.ics')
+ .then(response => response.text())
+ .then(data => {
+ events = parseICS(data);
+
+ // Initialize with current date
+ let today = new Date();
+ currentYear = today.getFullYear();
+ currentMonth = today.getMonth();
+
+ // Process events for current month
+
+ updateEventsForMonth(currentYear, currentMonth);
+
+ })
+ .catch(err => console.error('Fehler beim Laden der ICS-Datei:', err));
+ })();
+});
diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml
index c48a71e..9090cd4 100644
--- a/config/_default/hugo.toml
+++ b/config/_default/hugo.toml
@@ -8,7 +8,7 @@ defaultContentLanguage = "de"
RelativeURLs = true
CanonifyURLs = true
-pluralizeListTitles = "true" # hugo function useful for non-english languages, find out more in https://gohugo.io/getting-started/configuration/#pluralizelisttitles
+pluralizeListTitles = "false" # hugo function useful for non-english languages, find out more in https://gohugo.io/getting-started/configuration/#pluralizelisttitles
enableRobotsTXT = true
summaryLength = 0
diff --git a/config/_default/markup.toml b/config/_default/markup.toml
index c5449fc..4219cc6 100644
--- a/config/_default/markup.toml
+++ b/config/_default/markup.toml
@@ -9,5 +9,5 @@
noClasses = false
[tableOfContents]
- startLevel = 2
- endLevel = 4
+ startLevel = 1
+ endLevel = 5
diff --git a/config/_default/params.toml b/config/_default/params.toml
index 68f7772..d19b358 100644
--- a/config/_default/params.toml
+++ b/config/_default/params.toml
@@ -61,8 +61,8 @@ forgejoDefaultServer = "https://git.berlin.ccc.de"
showDateUpdated = true
showAuthor = false
showAuthorBottom = true
- showHero = false
- # heroStyle = "basic" # valid options: basic, big, background, thumbAndBackground
+ showHero = true
+ heroStyle = "big" # valid options: basic, big, background, thumbAndBackground
layoutBackgroundBlur = true # only used when heroStyle equals background or thumbAndBackground
layoutBackgroundHeaderSpace = true # only used when heroStyle equals background
showBreadcrumbs = true
diff --git a/content/_index.md b/content/_index.md
index 11b925a..872be10 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -6,4 +6,4 @@ description: "Startseite CCCB mit Kurzkalender"
CALENDAR
-Weitere Termine findest du [hier](/verein/calendar/).
\ No newline at end of file
+Weitere Termine findest du im [Veranstaltungskalender](/verein/calendar/).
diff --git a/content/datengarten/106/index.md b/content/datengarten/106/index.md
index 9c42a36..30fca27 100644
--- a/content/datengarten/106/index.md
+++ b/content/datengarten/106/index.md
@@ -1,6 +1,6 @@
---
categories: ["Datengarten"]
-tags: ["IOCCC", "Obfuscated C", "Wettbewerb", "Datengarten", "Veranstaltung"]
+tags: ["IOCCC", "Obfuscation", "Wettbewerb", "Datengarten", "Veranstaltung", "Programming"]
series: "Datengarten"
title: "Datengarten 106"
no: 106
diff --git a/content/datengarten/112/feature-dg-standard-logo.svg b/content/datengarten/112/feature-dg-standard-logo.svg
new file mode 100644
index 0000000..733a929
--- /dev/null
+++ b/content/datengarten/112/feature-dg-standard-logo.svg
@@ -0,0 +1,87 @@
+
+
diff --git a/content/datengarten/112/index.md b/content/datengarten/112/index.md
new file mode 100644
index 0000000..c4023db
--- /dev/null
+++ b/content/datengarten/112/index.md
@@ -0,0 +1,19 @@
+---
+categories: ["Datengarten"]
+tags: ["Alltag", "Kompression", "Mediendateien", "Datengarten", "Veranstaltung"]
+series: "Datengarten"
+title: "Datengarten 112"
+no: 112
+subtitle: "Ich hab den kleinsten ... Anhang! - Erste Hilfe für sinnvolle Mediendateigrößen"
+speaker: "Volker Diels-Grabsch"
+date: 2025-03-12T19:00:00+01:00
+event:
+ start: 2025-03-20T20:00:00+01:00
+ end: 2025-03-20T21:30:00+01:00
+location: CCCB
+language: de
+streaming: true
+recording: https://streaming.media.ccc.de/datengarten/cccb
+draft: false
+---
+to be done
\ No newline at end of file
diff --git a/content/datengarten/96/index.md b/content/datengarten/96/index.md
index 547bbd5..1be168e 100644
--- a/content/datengarten/96/index.md
+++ b/content/datengarten/96/index.md
@@ -1,6 +1,6 @@
---
categories: ["Datengarten"]
-tags: ["Compiler", "Interpreter", "Programming Language", "Trust", "Datengarten", "Veranstaltung"]
+tags: ["Compiler", "Interpreter", "Programming Language", "Trust", "Programming", "Datengarten", "Veranstaltung"]
series: "Datengarten"
title: "Datengarten 96"
no: 96
diff --git a/content/post/tag_des_offenen_hackerspace/index.md b/content/post/tag_des_offenen_hackerspace/index.md
index 52ec901..6bb06bd 100644
--- a/content/post/tag_des_offenen_hackerspace/index.md
+++ b/content/post/tag_des_offenen_hackerspace/index.md
@@ -4,6 +4,7 @@ subtitle: "Der CCCB lädt ein zum Kennenlernen und Entdecken."
date: 2025-02-10T12:00:00+02:00
dtstart: 20250329T130000
dtend: 20250329T200000
+showHero: false
---
{{< figure
diff --git a/content/veranstaltungen/bastelabend.md b/content/veranstaltungen/bastelabend.md
index b6d0157..5f3d995 100644
--- a/content/veranstaltungen/bastelabend.md
+++ b/content/veranstaltungen/bastelabend.md
@@ -9,6 +9,7 @@ menu:
main:
parent: "Veranstaltungen"
tag: ["Veranstaltung"]
+draft: true
---
diff --git a/content/veranstaltungen/plenum.md b/content/veranstaltungen/plenum.md
index f96b468..202ed96 100644
--- a/content/veranstaltungen/plenum.md
+++ b/content/veranstaltungen/plenum.md
@@ -6,6 +6,7 @@ dtstart: 20180704T200000
dtend: 20180704T220000
rrule: "FREQ=MONTHLY;BYDAY=2TU,4TU;INTERVAL=1;WKST=MO"
tags: ["Mitgliedschaft", "Veranstaltung"]
+draft: true
---
Das Plenum findet in der Regel am 2. und 4. Dienstag im Monat ab 20:00 Uhr in den Clubräumen
diff --git a/content/veranstaltungen/subbotnik.md b/content/veranstaltungen/subbotnik.md
index 589d7a9..5e86aa2 100644
--- a/content/veranstaltungen/subbotnik.md
+++ b/content/veranstaltungen/subbotnik.md
@@ -9,6 +9,7 @@ menu:
main:
parent: "Veranstaltungen"
tag: ["Veranstaltung"]
+draft: true
---

diff --git a/content/verein/calendar.md b/content/verein/calendar.md
deleted file mode 100644
index 2bd6210..0000000
--- a/content/verein/calendar.md
+++ /dev/null
@@ -1,604 +0,0 @@
----
-title: "Kalender"
-subtitle: "Der Kalender des CCCB"
-date: 2025-02-26T10:00:00+02:00
-menu:
- main:
- parent: "Verein"
-tag: ["Verein"]
----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mo |
- Di |
- Mi |
- Do |
- Fr |
- Sa |
- So |
-
-
-
-
-
-
-
-
-
-
-Keinen Termin mehr verpeilen? Einfach den [Veranstaltungskalender abonnieren](all.ics)!
diff --git a/content/verein/calendar/feature-calendar-nachts-geschlossen.jpg b/content/verein/calendar/feature-calendar-nachts-geschlossen.jpg
new file mode 100644
index 0000000..b0c8727
Binary files /dev/null and b/content/verein/calendar/feature-calendar-nachts-geschlossen.jpg differ
diff --git a/content/verein/calendar/index.md b/content/verein/calendar/index.md
new file mode 100644
index 0000000..44de0a0
--- /dev/null
+++ b/content/verein/calendar/index.md
@@ -0,0 +1,15 @@
+---
+title: "Kalender"
+subtitle: "Der Kalender des CCCB"
+date: 2025-02-26T10:00:00+02:00
+menu:
+ main:
+ parent: "Verein"
+tag: ["Verein"]
+herostyle: big
+
+---
+
+{{< calendar >}}
+
+Keinen Termin mehr verpeilen? Einfach den [Veranstaltungskalender abonnieren](all.ics)!
diff --git a/layouts/shortcodes/calendar.html b/layouts/shortcodes/calendar.html
new file mode 100644
index 0000000..b7e2271
--- /dev/null
+++ b/layouts/shortcodes/calendar.html
@@ -0,0 +1,33 @@
+{{ $style := resources.Get "css/calendar.css" | resources.ToCSS | resources.Fingerprint }}
+
+
+{{ $js := resources.Get "js/calendar.js" | resources.Fingerprint }}
+
+
+
+
+
+
+
+
+
+
+
+
+ Mo |
+ Di |
+ Mi |
+ Do |
+ Fr |
+ Sa |
+ So |
+
+
+
+
+
+
+
diff --git a/themes/beautifulhugo b/themes/beautifulhugo
deleted file mode 160000
index 0699f27..0000000
--- a/themes/beautifulhugo
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 0699f2797d2b8c2da8a6a28da9ef4a8013f5f858