Schedule views (weekly, today, display), inline activity detail, static per-event pages, RSS, iCal, Markdown rendering of descriptions.
Part of the requirements index. Section IDs (02-§N.M) are stable and cited from code; they do not encode the file path.
/idag.html)/live.html)version.json every 5 minutes and reloads the page automatically if a newer build is detected. /dagens-schema.html serves a redirect page that sends the visitor to /live.html via <meta http-equiv="refresh"> and a JavaScript fallback. When a participant clicks an activity, a detail view must show:
Fields with no value must not appear. The user must clearly understand whether additional information exists beyond what the schedule row shows.
The owner and meta fields are internal and must never appear in any public view.
The activity schedule must be available as an RSS feed at /schema.rss.
The feed must reflect the current state of the schedule. It is intended for participants who want to follow the schedule in an RSS reader or use it to integrate the schedule elsewhere.
The feed must be valid RSS 2.0 XML.
All feed metadata must be in Swedish:
<title> — “Schema – {camp name}”<description> — “Aktivitetsschema för {camp name}”<language> — svThe feed <link> must point to the weekly schedule page using the site’s
base URL (e.g. https://sommar.digitalasynctransparency.com/schema.html).
Each event in the active camp must produce one <item> in the feed.
Each item must include:
<title> — event title<link> — absolute URL to the event’s per-event detail page (see §36)<guid isPermaLink="true"> — same URL as <link><description> — a structured, multi-line human-readable summary formatted
as follows:
Plats: value ` · ` Ansvarig: value (with labels)<pubDate> — the event date and start time, formatted as RFC 822Items must be sorted chronologically (same order as the weekly schedule).
The RSS feed is generated at build time by render-rss.js and written to
public/schema.rss.
The renderer must not depend on any RSS library — the XML is simple enough to emit directly.
Absolute URLs in the RSS feed (and per-event detail pages) require a configurable base URL.
The build reads the base URL from the SITE_URL environment variable.
If SITE_URL is not set, the build must fail with a clear error message —
RSS links cannot be generated without a base URL.
CI workflows that run npm run build must pass SITE_URL as an
environment variable alongside API_URL.
Each event in the active camp must have its own static HTML page, generated at build time.
Each event page lives in its own sub-folder under /schema/:
/schema/{event-id}/index.html
For example: /schema/middag-2026-06-30-1630/index.html, accessible as
/schema/middag-2026-06-30-1630/.
Each event page must show:
Fields with no value must not appear.
The event detail body must use a structured layout matching the RSS description format (see §15.15):
Plats: value ` · ` Ansvarig: value (with labels)This replaces the previous definition-list (<dl>) layout.
The owner and meta fields must never appear on event pages.
Event pages must use the shared site layout: header navigation, footer, and stylesheet.
Each event page must include a back link to the weekly schedule page.
Event pages must include the <meta name="robots" content="noindex, nofollow">
tag, consistent with all other pages.
Event pages are generated by render-event.js and wired into build.js.
The build must create the /schema/{event-id}/ directory structure inside
public/.
The activity schedule must be available as iCalendar (.ics) files so
participants can sync events to their phone or desktop calendar.
Each event in the active camp must have a static .ics file generated at
build time, located alongside the event detail page:
/schema/{event-id}/event.ics
The .ics file must be valid iCalendar format (RFC 5545).
Each per-event .ics file must include exactly one VEVENT with:
DTSTART / DTEND — event start and end timeSUMMARY — event titleLOCATION — event locationDESCRIPTION — responsible person, followed by description text if setURL — absolute URL to the event detail pageUID — {event-id}@{hostname} (stable, unique)All times must use floating local format (YYYYMMDDTHHMMSS with no Z
suffix and no TZID) — consistent with the no-timezone policy
(05-§4.5).
When end is null, DTEND must be omitted.
The iCal renderer must not depend on any external iCal library — the format is simple enough to emit directly.
The event detail page (§36) must include a download link to the per-event
.ics file.
The link must appear as a third line in the event detail body, after the existing Plats/Ansvarig line, styled consistently with those lines.
A complete iCalendar file containing all events in the active camp must be
generated at build time at /schema.ics.
The full-camp .ics file must contain one VEVENT per event, using the
same field mapping as per-event files (§45.4).
The VCALENDAR must include:
PRODID — identifies the generator (e.g. -//SB Sommar//Schema//SV)X-WR-CALNAME — Schema – {camp name}METHOD — PUBLISHThe weekly schedule page must include a webcal subscription link to the full-camp iCal feed, alongside the existing RSS link.
The link must use the webcal:// protocol scheme (replacing https:// in
the site URL).
A static page must exist at /kalender.html.
The page must include step-by-step instructions for subscribing to the camp calendar on: iOS Calendar, Android / Google Calendar, Gmail (web), and Outlook.
The page must explain the difference between subscribing to the full camp calendar (auto-updates) and downloading individual event files (one-time import).
The page must be written in Swedish.
The page must use the shared site layout: header, navigation, and footer.
The iCal renderer must be a separate module (render-ical.js), following
the same pattern as render-rss.js.
The tips page renderer must be a separate module
(render-kalender.js).
Both must be wired into build.js.
iCal generation reuses the existing SITE_URL environment variable — no
new configuration is needed.
The schedule page header displays a calendar icon that links to the
calendar tips page (kalender.html).
The icon is an inline SVG, matching the RSS icon height (38 px).
No text label accompanies the icon — the title attribute and visual design provide sufficient affordance.
Every event row on the weekly schedule page includes a download link to
its .ics file.
The link appears at the end of the row, after location and responsible metadata, as a small text link labelled “iCal”.
It is styled consistently with .ev-meta (small font, terracotta colour)
and does not disrupt the existing row layout.
The link uses the download attribute so the browser saves the file
rather than navigating.
The weekly schedule page includes a visible link to kalender.html near
the header or intro text so users can find instructions for subscribing
to the calendar.
The calendar tips page uses the card-based layout style used elsewhere on the site (white background, rounded corners, card shadow, sage left border).
Each platform section (iOS, Android, Gmail, Outlook) is visually separated as its own card or clearly delineated section.
The webcal URL is displayed in a copy-friendly code block styled consistently with existing code blocks on the site.
Every VEVENT block in both per-event and full-camp .ics files
includes a DTSTAMP property (RFC 5545 §3.6.1).
The value is a UTC timestamp representing the build time, formatted as
YYYYMMDDTHHMMSSZ.
The description field in event YAML files may contain Markdown syntax
(parsed by marked, the same library used for content/*.md). All
rendering paths must treat the description as Markdown and produce
appropriate output for each context.
marked.parse(). marked.parse(). marked library to the client. <description>
element. DESCRIPTION property. <script>, <iframe>, <object>, <embed>,
any other raw tags, and any on* event-handler attributes never appear
in the rendered output. URIs in links and images that use the
javascript:, vbscript:, data:, or file: scheme — matched
case-insensitively and tolerant of leading whitespace and control
characters — are neutralized to an empty href/src. marked wraps them in <p> tags, which is
acceptable. .event-description p rule must no longer apply font-style:
italic, so that Markdown emphasis renders distinctly. 07-DESIGN.md. No new custom properties are introduced. renderDescriptionHtml()
and stripMarkdown() to avoid duplicating Markdown processing logic
across render modules. The global heading styles (h1 = 40 px, h2 = 35 px, h3 = 30 px) are designed
for page-level headings. When Markdown descriptions containing headings are
rendered inside event cards (.event-desc, .event-description) and the
Markdown preview (.md-preview), those page-level sizes are applied,
producing oversized headings and — in .md-preview where only h2 was
overridden — a broken size hierarchy where h3 appears larger than h2.
.md-preview, .event-desc, and
.event-description must be visually smaller than the global page
headings and must follow a strictly decreasing size
order (h1 > h2 > h3 > h4). em units so they scale with the
container’s font-size context (e.g. 13 px in .event-extra vs
16 px in .md-preview). em values — no hardcoded pixel sizes. https://www.markdownguide.org/basic-syntax/),
not a library API reference. /lagg-till.html and
/redigera.html.