+ This announcement does not exist, or the link has changed.
+
+
+ {%- include icon.html name="arrow-left" class="h-4 w-4" -%}
+ Back to Home
+
+
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..af608aa
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,7 @@
+source "https://rubygems.org"
+
+gem "jekyll", "~> 4.4"
+gem "jekyll-sitemap", "~> 1.4"
+
+# Required on Ruby 3.x for `jekyll serve`.
+gem "webrick", "~> 1.8"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5554fb7
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 VIB Data Core
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4efb7fa
--- /dev/null
+++ b/README.md
@@ -0,0 +1,150 @@
+# VIB Data Core — announcements
+
+Public notice board for the services run by VIB Data Core:
+**https://vib-data-core.github.io/status**
+
+Everything on that page comes from Markdown files in this repository. Posting
+an announcement means adding one file — no HTML, no CSS, no build step on your
+side.
+
+## Quick start: post an announcement
+
+Copy [`_announcements/TEMPLATE.md`](_announcements/TEMPLATE.md) to a new file
+next to it and edit it. On GitHub: open the template, **Copy raw file**, then
+in [`_announcements/`](_announcements/) click **Add file → Create new file**,
+name it `YYYY-MM-DD-short-slug.md` — for example
+`2026-09-19-project-storage-slow.md` — and paste.
+
+
+```yaml
+---
+title: Slower than usual access to Project Storage
+start: 2026-09-19 09:30:00
+type: unplanned
+services_affected:
+ - project-storage
+summary: >-
+ One or two sentences shown on the card and in the history.
+---
+
+Markdown body
+```
+
+Leave `end:` out entirely while it is still going on. When it is over, edit the
+same file and add the end time:
+
+```yaml
+end: 2026-09-19 18:00:00
+```
+
+For planned work, set `type: planned` and give both `start` and `end` up front:
+
+```yml
+---
+title: Planned maintenance of the Electronic Lab Notebook
+start: 2026-10-06 19:00:00
+end: 2026-10-06 23:00:00
+type: planned
+services_affected:
+ - eln
+summary: >-
+ The Electronic Lab Notebook is unavailable for about four hours.
+---
+```
+
+The page rebuilds automatically after the change lands on `main`.
+
+## Updates during a long announcement
+
+A long-running announcement can carry a list of updates. Newest first or
+oldest first, both work; the page sorts them. The most recent update is also
+shown on the card on the landing page.
+
+```yaml
+updates:
+ - time: 2026-09-20 11:00:00
+ body: >-
+ Performance has improved for most users.
+ - time: 2026-09-19 10:15:00
+ body: >-
+ We are aware of the slower access and are looking into it.
+```
+
+## Front matter reference
+
+| Field | Required | Type | Notes |
+| --- | --- | --- | --- |
+| `title` | yes | text | Keep it under ~90 characters. Describe the impact, not the cause. |
+| `start` | yes | date-time | Unquoted, **no timezone offset**: `2026-09-19 09:30:00`. Always Belgian local time — summer and winter time are handled for you. |
+| `end` | no | date-time | Omit while it is still going on. Once it is in the past, the entry moves to the history page. |
+| `type` | yes | keyword | `unplanned` or `planned`. |
+| `services_affected` | yes | list | Ids from [`_data/services.yml`](_data/services.yml). Unknown ids fail the build check. |
+| `summary` | recommended | text | One or two sentences, shown on cards and in the history. |
+| `updates` | no | list | Chronological updates during a long announcement, each one a `time` and a `body`. See the commented-out block in the template. |
+
+Times carry no offset because every time on this page is Belgian local time.
+[`_plugins/local_times.rb`](_plugins/local_times.rb) reads them that way; YAML
+would otherwise take a bare time for UTC and the page would move the entry an
+hour or two late.
+
+### Services
+
+Defined in [`_data/services.yml`](_data/services.yml), and they mirror the Data
+Core catalogue (the services listed in Connect). One announcement can cover
+several of them. Use the `id` in front matter; the `name` is what readers see:
+
+```yaml
+- id: project-storage
+ name: Project Storage
+ description: Laboris nisi ut aliquip ex ea commodo consequat.
+```
+
+The `description` only surfaces as the tooltip on a service chip, and the ones
+checked in are placeholder text — replace them with the catalogue wording.
+
+If the catalogue gains a service, add it here in the same change. Ids are
+lowercase with dashes and should not change afterwards — they appear in
+shareable filter links such as `/history/?services=project-storage,usegalaxy`.
+
+## Working on it locally
+
+You need Ruby (3.1+) and Node (18+).
+
+```bash
+bundle install # Jekyll and friends
+npm install # Tailwind CLI
+
+npm run serve # builds the CSS, watches it, and serves on http://localhost:3002/status/
+```
+
+Other commands:
+
+```bash
+npm run css # one-off, minified stylesheet
+npm run build # CSS + full Jekyll build into _site/
+npm run validate # check all entries against the vocabularies
+```
+
+`assets/css/main.css` is generated and git-ignored — never edit it by hand,
+edit [`assets/css/tailwind.css`](assets/css/tailwind.css) instead.
+
+
+### Checks on every change
+
+[`script/validate.rb`](script/validate.rb) runs in CI and fails on:
+
+- missing `title`, `start` or `type`
+- an unknown `type`, or a retired `severity:`/`kind:` key
+- quoted or malformed date-times, and an `end` before the `start`
+- a `Z` or `+00:00` offset on a time, which is indistinguishable from a bare
+ Belgian local time and would silently shift the entry by an hour or two
+- missing or unknown service ids
+- malformed `updates` entries
+
+It also prints warnings (empty body, missing summary, odd file name) that do
+not block the change.
+
+
+## Licence
+
+Code in this repository is MIT licensed (see [LICENSE](LICENSE)).
diff --git a/_announcements/2026-06-02-nulla-vitae-elit-libero.md b/_announcements/2026-06-02-nulla-vitae-elit-libero.md
new file mode 100644
index 0000000..0f0e81c
--- /dev/null
+++ b/_announcements/2026-06-02-nulla-vitae-elit-libero.md
@@ -0,0 +1,14 @@
+---
+title: Nulla vitae elit libero a pharetra augue
+start: 2026-06-02 16:00:00
+end: 2026-06-02 16:45:00
+type: planned
+services_affected:
+ - software-hosting
+summary: >-
+ Sed posuere consectetur est at lobortis, aenean eu leo quam pellentesque
+ ornare.
+---
+
+Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac
+cursus commodo, tortor mauris condimentum nibh.
diff --git a/_announcements/2026-06-19-cras-mattis-consectetur.md b/_announcements/2026-06-19-cras-mattis-consectetur.md
new file mode 100644
index 0000000..38fc3bf
--- /dev/null
+++ b/_announcements/2026-06-19-cras-mattis-consectetur.md
@@ -0,0 +1,13 @@
+---
+title: Cras mattis consectetur purus sit amet
+start: 2026-06-19 08:50:00
+end: 2026-06-19 09:25:00
+type: unplanned
+services_affected:
+ - eln
+summary: >-
+ Fermentum nibh, ut fermentum massa justo sit amet risus.
+---
+
+Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
+Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
diff --git a/_announcements/2026-07-08-vivamus-sagittis-lacus.md b/_announcements/2026-07-08-vivamus-sagittis-lacus.md
new file mode 100644
index 0000000..ea8cd97
--- /dev/null
+++ b/_announcements/2026-07-08-vivamus-sagittis-lacus.md
@@ -0,0 +1,14 @@
+---
+title: Vivamus sagittis lacus vel augue laoreet
+start: 2026-07-08 12:00:00
+end: 2026-07-08 14:00:00
+type: planned
+services_affected:
+ - software-licenses
+summary: >-
+ Rutrum faucibus dolor auctor, cras mattis consectetur purus sit amet
+ fermentum.
+---
+
+Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna
+mollis euismod, donec sed odio dui.
diff --git a/_announcements/2026-07-30-donec-ullamcorper-nulla.md b/_announcements/2026-07-30-donec-ullamcorper-nulla.md
new file mode 100644
index 0000000..46f0a0e
--- /dev/null
+++ b/_announcements/2026-07-30-donec-ullamcorper-nulla.md
@@ -0,0 +1,13 @@
+---
+title: Donec ullamcorper nulla non metus auctor
+start: 2026-07-30 10:40:00
+end: 2026-07-30 13:15:00
+type: unplanned
+services_affected:
+ - data-deposition
+summary: >-
+ Fringilla, duis mollis est non commodo luctus nisi erat porttitor ligula.
+---
+
+Curabitur blandit tempus porttitor. Vivamus sagittis lacus vel augue laoreet
+rutrum faucibus dolor auctor, sed posuere consectetur est at lobortis.
diff --git a/_announcements/2026-08-14-maecenas-sed-diam.md b/_announcements/2026-08-14-maecenas-sed-diam.md
new file mode 100644
index 0000000..c7ad080
--- /dev/null
+++ b/_announcements/2026-08-14-maecenas-sed-diam.md
@@ -0,0 +1,16 @@
+---
+title: Maecenas sed diam eget risus varius
+start: 2026-08-14 18:00:00
+end: 2026-08-15 02:00:00
+type: planned
+services_affected:
+ - project-storage
+ - compute
+summary: >-
+ Blandit sit amet non magna, curabitur blandit tempus porttitor.
+---
+
+Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Aenean eu
+leo quam, pellentesque ornare sem lacinia quam venenatis vestibulum.
+
+Nullam quis risus eget urna mollis ornare vel eu leo.
diff --git a/_announcements/2026-08-27-etiam-porta-sem.md b/_announcements/2026-08-27-etiam-porta-sem.md
new file mode 100644
index 0000000..77cc473
--- /dev/null
+++ b/_announcements/2026-08-27-etiam-porta-sem.md
@@ -0,0 +1,18 @@
+---
+title: Etiam porta sem malesuada magna mollis
+start: 2026-08-27 14:05:00
+end: 2026-08-27 17:20:00
+type: unplanned
+services_affected:
+ - compute
+ - secure-compute
+summary: >-
+ Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Nullam id dolor
+ id nibh ultricies.
+---
+
+Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id
+ligula porta felis euismod semper. Sed posuere consectetur est at lobortis.
+
+Nulla vitae elit libero, a pharetra augue. Donec ullamcorper nulla non metus
+auctor fringilla, duis mollis est non commodo luctus.
diff --git a/_announcements/2026-09-05-integer-posuere-erat.md b/_announcements/2026-09-05-integer-posuere-erat.md
new file mode 100644
index 0000000..d0fb62a
--- /dev/null
+++ b/_announcements/2026-09-05-integer-posuere-erat.md
@@ -0,0 +1,16 @@
+---
+title: Integer posuere erat a ante venenatis
+start: 2026-09-05 13:12:00
+end: 2026-09-05 13:54:00
+type: unplanned
+services_affected:
+ - usegalaxy
+summary: >-
+ Dapibus posuere velit aliquet, sed posuere consectetur est at lobortis.
+---
+
+Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur
+purus sit amet fermentum, etiam porta sem malesuada magna mollis euismod.
+
+Aenean lacinia bibendum nulla sed consectetur, vivamus sagittis lacus vel augue
+laoreet rutrum faucibus dolor auctor.
diff --git a/_announcements/2026-09-12-fusce-dapibus-tellus.md b/_announcements/2026-09-12-fusce-dapibus-tellus.md
new file mode 100644
index 0000000..72fa6b5
--- /dev/null
+++ b/_announcements/2026-09-12-fusce-dapibus-tellus.md
@@ -0,0 +1,14 @@
+---
+title: Fusce dapibus tellus in cursus commodo
+start: 2026-09-12 07:00:00
+end: 2026-09-12 09:30:00
+type: planned
+services_affected:
+ - data-transfer
+summary: >-
+ Maecenas faucibus mollis interdum, morbi leo risus porta ac consectetur ac
+ vestibulum at eros.
+---
+
+Cum sociis natoque penatibus et magnis dis parturient montes, nascetur
+ridiculus mus. Donec sed odio dui, nulla vitae elit libero a pharetra augue.
diff --git a/_announcements/2026-09-19-lorem-ipsum-dolor-sit.md b/_announcements/2026-09-19-lorem-ipsum-dolor-sit.md
new file mode 100644
index 0000000..427651d
--- /dev/null
+++ b/_announcements/2026-09-19-lorem-ipsum-dolor-sit.md
@@ -0,0 +1,32 @@
+---
+title: Lorem ipsum dolor sit amet consectetur
+start: 2026-09-19 09:30:00
+type: unplanned
+services_affected:
+ - project-storage
+ - compute
+summary: >-
+ Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
+ ad minim veniam.
+updates:
+ - time: 2026-09-20 11:00:00
+ body: >-
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
+ dolore eu fugiat nulla pariatur.
+ - time: 2026-09-19 10:15:00
+ body: >-
+ Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ consequat.
+---
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
+incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
+nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+
+**Nam libero tempore**
+
+- Duis aute irure dolor in reprehenderit in voluptate velit esse cillum.
+- Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia.
+
+Deserunt mollit anim id est laborum. Curabitur pretium tincidunt lacus, nulla
+gravida orci a odio.
diff --git a/_announcements/2026-10-06-nullam-varius-turpis.md b/_announcements/2026-10-06-nullam-varius-turpis.md
new file mode 100644
index 0000000..c69c000
--- /dev/null
+++ b/_announcements/2026-10-06-nullam-varius-turpis.md
@@ -0,0 +1,24 @@
+---
+title: Nullam varius turpis et commodo pharetra
+start: 2026-10-06 19:00:00
+end: 2026-10-06 23:00:00
+type: planned
+services_affected:
+ - eln
+summary: >-
+ Aenean ultricies mi vitae est mauris placerat eleifend leo quisque sit amet
+ est et sapien.
+---
+
+Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
+cubilia curae. Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit
+amet ligula.
+
+**Praesent sapien massa**
+
+- Convallis a pellentesque nec, egestas non nisi.
+- Cras ultricies ligula sed magna dictum porta.
+- Vivamus suscipit tortor eget felis porttitor volutpat.
+
+Nulla porttitor accumsan tincidunt. Quisque velit nisi, pretium ut lacinia in,
+elementum id enim.
diff --git a/_announcements/TEMPLATE.md b/_announcements/TEMPLATE.md
new file mode 100644
index 0000000..428ca37
--- /dev/null
+++ b/_announcements/TEMPLATE.md
@@ -0,0 +1,25 @@
+---
+# Copy this file to YYYY-MM-DD-short-slug.md and edit it. This file itself is
+# never rendered: _config.yml excludes it from the build.
+title: Short sentence describing what people notice
+start: 2026-09-19 09:30:00
+# Belgian local time. No timezone offset - do not write +02:00.
+# end: 2026-09-19 18:00:00
+# Leave `end` out entirely while it is still going on. Add it once it is
+# over and the entry moves to /history/ by itself.
+type: unplanned
+# unplanned | planned - see _data/levels.yml
+services_affected:
+ - project-storage
+# One or more ids from _data/services.yml
+summary: >-
+ One or two sentences shown on the card and in the history.
+# updates:
+# - time: 2026-09-19 14:00:00
+# body: >-
+# What changed since this went up. Every update is labelled "Update";
+# there is nothing else to set.
+---
+
+What people notice, and what they can do in the meantime. Normal Markdown:
+**bold**, lists, `code`.
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..605db06
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,61 @@
+# --- Site -------------------------------------------------------------------
+title: VIB Data Core Announcements
+tagline: Announcements on maintenance and disruptions of Data Core services
+description: >-
+ Announcements on maintenance and disruptions of Data Core services.
+
+url: "https://vib-data-core.github.io"
+baseurl: "/status"
+
+org:
+ name: "VIB Data Core"
+
+lang: en
+timezone: Europe/Brussels
+
+# --- Content ----------------------------------------------------------------
+# One collection: everything on this site is an announcement. There is
+# deliberately no "incident" type and no severity scale - see the README.
+collections:
+ announcements:
+ output: true
+ permalink: /:name/
+
+defaults:
+ - scope:
+ path: ""
+ type: announcements
+ values:
+ layout: entry
+
+# --- Build ------------------------------------------------------------------
+# Planned work is dated in the future by definition; without this Jekyll
+# refuses to write those pages (default: future: false).
+future: true
+
+markdown: kramdown
+kramdown:
+ input: GFM
+ syntax_highlighter: rouge
+
+# No jekyll-sitemap: the site asks not to be indexed (see robots.txt and the
+# robots meta tag in _includes/head.html), so a sitemap would contradict it.
+plugins: []
+
+sass:
+ style: compressed
+
+exclude:
+ - .github/
+ # The announcement template is meant to be copied, not published.
+ - _announcements/TEMPLATE.md
+ - Gemfile
+ - Gemfile.lock
+ - LICENSE
+ - README.md
+ - node_modules/
+ - package-lock.json
+ - package.json
+ - script/
+ - vendor/
+ - assets/css/tailwind.css # Tailwind input; the compiled file is assets/css/main.css
\ No newline at end of file
diff --git a/_data/levels.yml b/_data/levels.yml
new file mode 100644
index 0000000..9d08ade
--- /dev/null
+++ b/_data/levels.yml
@@ -0,0 +1,29 @@
+# The one controlled vocabulary of this site: the `type:` of an announcement.
+#
+# _announcements/*.md -> type: unplanned | planned
+#
+# There are only two, and there is deliberately no severity scale. Everything
+# published here is an announcement written by hand by a Data Core member; a
+# graded severity would suggest the page is fed by a monitoring system.
+#
+# `color` is the only colour setting for the whole site. Each entry carries it
+# as the CSS variable --accent, and assets/css/tailwind.css derives the rest
+# from that: the colour as given for the bar down the side of a card and the
+# dot on the timeline, the same hue at lightness 0.95 with a quarter of the
+# chroma for the badge fill, and lightness 0.43 with slightly more chroma for
+# the badge label. Keep the colours light and lightly saturated - a strong,
+# fully saturated hue reads as harsh next to the slate greys of the rest of the
+# page, and a very light or very dark one pushes the derived label below the
+# contrast it needs to stay readable.
+
+unplanned:
+ label: Unplanned
+ color: "#cf8f9c"
+ icon: circle-alert
+ description: Something is not working as it should, outside of planned work.
+
+planned:
+ label: Planned
+ color: "#8fb0cb"
+ icon: calendar-days
+ description: Work we have scheduled in advance.
diff --git a/_data/services.yml b/_data/services.yml
new file mode 100644
index 0000000..71c1af8
--- /dev/null
+++ b/_data/services.yml
@@ -0,0 +1,50 @@
+# Controlled vocabulary for the `services_affected:` front matter field.
+#
+# These are the VIB Data Core services as listed in the Data Core catalogue
+# (the ones shown in Connect). Use the `id` in front matter, e.g.
+# services_affected: [project-storage, usegalaxy]
+#
+# One announcement can cover several services. Adding a service = adding an
+# entry here; script/validate.rb (and the check on every pull request) rejects
+# ids that are not listed below. Ids are lowercase with dashes and should not
+# change afterwards - they appear in shareable filter links such as
+# ?services=usegalaxy,compute
+#
+# The descriptions below are placeholders and only surface as the tooltip on a
+# service chip; replace them with the catalogue wording.
+
+- id: compute
+ name: Compute
+ description: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+- id: secure-compute
+ name: Secure Compute
+ description: Sed do eiusmod tempor incididunt ut labore et dolore magna.
+
+- id: usegalaxy
+ name: useGalaxy.be
+ description: Ut enim ad minim veniam, quis nostrud exercitation ullamco.
+
+- id: project-storage
+ name: Project Storage
+ description: Laboris nisi ut aliquip ex ea commodo consequat.
+
+- id: eln
+ name: Electronic Lab Notebook
+ description: Duis aute irure dolor in reprehenderit in voluptate velit.
+
+- id: software-licenses
+ name: Scientific Software licenses
+ description: Esse cillum dolore eu fugiat nulla pariatur.
+
+- id: data-transfer
+ name: Data Transfer Solutions
+ description: Excepteur sint occaecat cupidatat non proident.
+
+- id: data-deposition
+ name: Data Deposition Toolbox
+ description: Sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+- id: software-hosting
+ name: Software Hosting
+ description: Curabitur pretium tincidunt lacus, nulla gravida orci.
diff --git a/_includes/entry-card.html b/_includes/entry-card.html
new file mode 100644
index 0000000..cd5bfab
--- /dev/null
+++ b/_includes/entry-card.html
@@ -0,0 +1,121 @@
+{%- comment -%}
+ One announcement, used in all three places: the "Current" and "Planned"
+ lists on the landing page and the timeline on /history/. The markup is
+ identical everywhere so assets/js/status.js can move an entry between the
+ lists when its start or end time passes, without the page being rebuilt.
+
+ Params:
+ entry the announcement document
+ placement "current" | "planned" | "history" (initial placement only)
+ hide true to render it with the hidden attribute (history page, for
+ entries that have not closed yet)
+{%- endcomment -%}
+
+{%- assign entry = include.entry -%}
+{%- assign placement = include.placement | default: "history" -%}
+{%- assign level_key = entry.type | default: "unplanned" -%}
+{%- assign level = site.data.levels[level_key] -%}
+{%- unless level -%}{%- assign level = site.data.levels.unplanned -%}{%- endunless -%}
+
+{%- if entry.end -%}{%- assign end_ts = entry.end | date: "%s" | plus: 0 -%}{%- else -%}{%- assign end_ts = 0 -%}{%- endif -%}
+
+{%- capture service_ids -%}{% for sid in entry.services_affected %}{{ sid }} {% endfor %}{%- endcapture -%}
+{%- capture service_names -%}{% for sid in entry.services_affected %}{% assign svc = site.data.services | where: "id", sid | first %}{{ svc.name | default: sid }} {% endfor %}{%- endcapture -%}
+{%- capture search_blob -%}{{ entry.title }} {{ entry.summary }} {{ level.label }} {{ service_ids }}{{ service_names }} {{ entry.content | strip_html }}{%- endcapture -%}
+
+{%- if placement == "current" -%}{%- assign state = "ongoing" -%}
+{%- elsif placement == "planned" -%}{%- assign state = "scheduled" -%}
+{%- else -%}{%- assign state = "closed" -%}{%- endif -%}
+
+
+
+ {%- comment -%}
+ Just a dot in the colour of the type - the badge on the card already
+ carries the icon. It is opaque and ringed in the page colour, which is
+ what breaks the rail around it. Its centre sits 16px across and 30px
+ down, which is what the .entry-rail rules in tailwind.css measure from.
+ {%- endcomment -%}
+
+
+
+
+
+
+
+ {%- comment -%}
+ No state pill on a card: the "Current" and "Planned" headings on the
+ landing page already say the state, and everything on the history
+ page is closed by definition. Only the type badge earns its space.
+ {%- endcomment -%}
+
+ {%- include level-badge.html level=level_key -%}
+
+{%- comment -%}
+ No state pill: the coloured rule at the top of the header, the badge
+ and the Start / End panel below already say where this
+ announcement stands.
+ {%- endcomment -%}
+ {%- include level-badge.html level=level_key -%}
+
+
+ {%- include icon.html name="hourglass" class="h-3.5 w-3.5" -%}
+ End
+
+
+ {%- if end_ts > 0 -%}
+
+ expected
+ {%- else -%}
+ Still open
+ {%- endif -%}
+
+
+
+
+ {%- if page.services_affected and page.services_affected.size > 0 %}
+
+
Services affected
+
+ {%- include service-tags.html entry=page surface="page" -%}
+
+
+ {%- endif %}
+
+ {%- if page.updates and page.updates.size > 0 %}
+
+
Updates
+ {%- comment -%}
+ Same thread-and-dot as the history timeline: each update draws its own
+ piece of the rail, and the rules in tailwind.css trim the first and the
+ last so the line runs dot to dot instead of past both ends.
+ {%- endcomment -%}
+
+
+ {%- assign sorted_updates = page.updates | sort: "time" | reverse -%}
+ {%- for u in sorted_updates %}
+
+
diff --git a/_plugins/local_times.rb b/_plugins/local_times.rb
new file mode 100644
index 0000000..5d82190
--- /dev/null
+++ b/_plugins/local_times.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+# Every time on this site is Belgian local time. Announcements are written by
+# hand, and "2026-09-19 09:30:00 +02:00" is a lot of ceremony - and a DST trap
+# twice a year - for someone who just wants to say half past nine.
+#
+# YAML reads a timestamp without an offset as UTC. Left alone, Jekyll then
+# renders a bare "09:30" as 09:30 in the visible text but as 11:30+02:00 in the
+#