The two columns of the table on the start page touched each other, so the entry
read "Donnerstag, 27.08., 19:00 UhrClub Discordia".
The table is created with the classes "table table-condensed", which no
stylesheet of the site defines, and the table styling that the theme applies
inside prose addresses "tbody td". The table is delivered empty and its rows
are added through the DOM, where a tr appended to a table stays a direct child
instead of being put into a tbody the way the HTML parser would. The rows are
therefore outside of any tbody and the padding of the theme never applied.
Give the column holding the date its own padding, and keep the date on one
line, it is one piece of information and reads badly broken after the weekday.
The padding alone does not fit, though. The table stands in a prose column that
the theme limits to 65 characters so that running text stays readable, and a
date and the name of an event next to each other are wider than that, so the
names would be wrapped over several lines. Lift the limit off the column and
put it back on everything in it except the table, which leaves the table room
to grow while the heading and the paragraph around it keep their width.
That much space then has to be filled sensibly. The theme lays a table out as a
block, "table { display: block; overflow: auto }", so that a wide one can be
scrolled sideways, and a block fills its parent instead of shrinking to its
content the way a table does. Spanning the page the entries would all sit at
its left edge. Ask for the width of the content with fit-content, which the
automatic margins then centre.
Addressing the table by its id keeps all of this to the start page and takes
precedence over the theme, whose prose rules are written with :where() and
carry no specificity.
Measured in a browser at 1280, 768 and 500 pixels: date and name share one line
at the first two, the table is 602 pixels wide with the same distance left and
right, and at 500 the column is narrower than the table, so the table fills it
and only the longest name wraps. The page never scrolls sideways.
Fixes: c28f04c6e8 ("switch to ics files; make calendars work; fix some minor issues")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The calendar page brought its own ICS parser and its own RRULE expansion. Both
only covered the cases that happened to be needed when they were written, and
the calendar has moved on since. Against the published calendar, for September
2026:
Spieleabend FREQ=WEEKLY;INTERVAL=2;BYDAY=SA shown 05. 12. 19. 26., correct 05. 19.
CCCB Plenum FREQ=MONTHLY;BYDAY=TU;BYSETPOS=2 shown 01., correct 08.
CCCB Plenum FREQ=MONTHLY;BYDAY=TU;BYSETPOS=4 shown 01., correct 22.
INTERVAL was only read for monthly rules, so the Spieleabend was shown twice as
often as it takes place. BYSETPOS was not implemented at all, and since
parseInt("TU") is NaN the fallback turned both Plenum rules into "first
Tuesday", putting two Plenums on a day without one and none on the two days
with one. UNTIL, COUNT, EXDATE, RECURRENCE-ID, BYMONTHDAY and a BYDAY listing
more than one weekday were not handled either.
The text was no better. Content lines longer than 75 characters are continued
on the next line, of which there are 477 in the calendar, and the parser did
not join them, so it cut values off in the middle of a word. It also split
every line at the first colon, which lands inside the parameter of
DESCRIPTION;ALTREP="data:text/html,...". And it never resolved the escaping, so
"\n" was shown as those two characters. 30 of 31 descriptions were wrong:
before: "Der Club Discordia ist ein öffentliches Treffen in den Clubr"
after: "Der Club Discordia ist ein öffentliches Treffen in den Clubräumen des CCC Berlin"
Hand the parsing and the expansion to ical.js, which is vendored for the start
page anyway. The month view now asks the library for the occurrences that touch
the month, which removes the reimplementation along with all of the above.
While the events are being reduced to what the view needs:
- An event is entered on every day it covers, so the Amateurfunk trip from
30.10. to 01.11. is no longer marked on 30.10. alone. The end of an event is
not part of it, so one ending at midnight stays on the day before.
- Days and times are derived in Europe/Berlin instead of from the digits of the
ICS string. Every event currently carries TZID=Europe/Berlin, so the wall
clock time shown does not change, but a UTC timestamp would have been shown
in UTC.
- The URL of the event is used for the link in the detail panel. Events without
one are shown without a link, as on the start page. This replaces
createEventLink(), which guessed URLs from the title and was never called,
and the panel no longer builds an <h> element, which is not an element.
Descriptions may contain line breaks, so keep them in the panel.
Fixes: 4068fab565 ("improved calendar and fixed url temporarily")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>