diff --git a/layouts/_default/baseof.calendar.html b/layouts/_default/baseof.calendar.html
deleted file mode 100644
index bddf04a..0000000
--- a/layouts/_default/baseof.calendar.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ block "main" . }}{{ .Content }}{{ end }}
diff --git a/layouts/_default/list.calendar.html b/layouts/_default/list.calendar.html
deleted file mode 100644
index 3259690..0000000
--- a/layouts/_default/list.calendar.html
+++ /dev/null
@@ -1,21 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CCCB//Calendar//DE
-{{ with .Title }}
-X-WR-CALNAME:{{ . }}
-{{ end }}
-CALSCALE:GREGORIAN
-METHOD:PUBLISH
-{{ range .Pages }}
-{{ if .Date }}
-BEGIN:VEVENT
-UID:{{ .File.UniqueID }}@berlin.ccc.de
-DTSTAMP:{{ .Date.Format "20060102T150405Z" }}
-DTSTART:{{ .Date.Format "20060102T150405Z" }}
-SUMMARY:{{ .Title }}
-DESCRIPTION:{{ .Summary | plainify }}
-URL:{{ .Permalink }}
-END:VEVENT
-{{ end }}
-{{ end }}
-END:VCALENDAR
diff --git a/layouts/_default/list.xml.html b/layouts/_default/list.xml.xml
similarity index 100%
rename from layouts/_default/list.xml.html
rename to layouts/_default/list.xml.xml
diff --git a/layouts/_default/single.calendar.html b/layouts/_default/single.calendar.html
deleted file mode 100644
index 5a22ec4..0000000
--- a/layouts/_default/single.calendar.html
+++ /dev/null
@@ -1,21 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CCCB//Calendar//DE
-{{ with .Title }}
-X-WR-CALNAME:{{ . }}
-{{ end }}
-CALSCALE:GREGORIAN
-METHOD:PUBLISH
-{{ if .Date }}
-BEGIN:VEVENT
-UID:{{ .File.UniqueID }}@berlin.ccc.de
-DTSTAMP:{{ .Date.Format "20060102T150405Z" }}
-DTSTART:{{ .Date.Format "20060102T150405Z" }}
-{{ with .Params.event.end }}DTEND:{{ dateFormat "20060102T150405Z" . }}{{ end }}
-SUMMARY:{{ .Title }}
-DESCRIPTION:{{ .Summary | plainify }}
-URL:{{ .Permalink }}
-{{ with .Params.location }}LOCATION:{{ . }}{{ end }}
-END:VEVENT
-{{ end }}
-END:VCALENDAR
diff --git a/tools/gen_upcoming.py b/tools/gen_upcoming.py
index 0f69f6a..33b093d 100755
--- a/tools/gen_upcoming.py
+++ b/tools/gen_upcoming.py
@@ -3,13 +3,23 @@
import sys
import logging
import locale
-from dateutil.parser import parse
+from dateutil.parser import parse as _parse
from datetime import datetime, timedelta
from dateutil.rrule import rruleset, rrulestr
import icalendar
+def parse(value):
+ # Some templates emit DTSTART with a trailing "Z" (e.g. 20260507T190000Z)
+ # which produces tz-aware datetimes, while others emit naive local times.
+ # Normalize to naive so comparisons and sorting don't mix the two.
+ dt = _parse(value)
+ if dt.tzinfo is not None:
+ dt = dt.replace(tzinfo=None)
+ return dt
+
+
def vevent_to_event(event, rrstart=None):
if rrstart == None:
begin = parse(event["DTSTART"].to_ical())