Der Typ `changelog` schreibt gewöhnliche Markdown-Seiten, deren Körper zwei
MDC-Komponenten sind, gerendert in einem eigenen Layout. Alle drei sind
dokumentiert, weil sie Teil der öffentlichen Oberfläche sind — ein Konsument kann
jede davon ersetzen — und nicht, weil eine Seite von Hand geschrieben werden
müsste.

## Das Layout `changelog`

Gebunden nur an die [Granularität `split`](/reference/changelog/granularity); ein
flaches Changelog ist eine gewöhnliche Doku-Seite und rendert im Doku-Gerüst.

Es unterscheidet sich von `docs` in zwei Punkten, und beide folgen daraus, was die
Seiten sind. Die **Seitenleiste ist die Release-Liste** statt eines Prosa-Baums —
dieselbe Navigation, dieselbe Collection, weil eine generierte Sektion eine
gewöhnliche Collection ist und ihre Seiten die Releases sind. Und die
**Lesespalte ist auf ein Maß begrenzt**: Eine Release-Notiz ist Prosa, und über
das ganze Fenster gesetzte Prosa ist unlesbar. Die Inhaltsspalte bleibt und listet
die Gruppen.

Ersetze es durch eine eigene Datei am selben Pfad:

```
app/layouts/changelog.vue
```

## ChangelogReleases

Die Zeitleiste der Übersicht: jedes Release, neueste zuerst, filterbar nach dem,
was sich geändert hat. Auf die Indexseite der Sektion geschrieben.

| Prop       | Typ   | Anmerkungen                                              |
| :--------- | :---- | :-------------------------------------------------------- |
| `releases` | Array | Je mit `version`, `date`, `to`, `groups` und `contributors` |

Die Historie beginnt mit **vier Kennzahlen**: Releases, Änderungen,
Contributors und Datum des letzten Releases. Ein **Raster mit vier Spalten über
die ganze Breite** macht sie zum Kopf der Liste. Das Datum ist als
einziges keine Anzahl; enthält die Datei keine Datumsangaben, entfällt es statt
eines Strichs. Die Kennzahlen zeigen den Umfang, den einzelne Zeilen nicht
vermitteln. Sie zählen **das Angezeigte**: Nach dem Filtern beziehen sie sich auf
die gefilterte Seite, die Gesamtzahl bleibt neben der ersten Kennzahl stehen —
bei Breaking Changes zeigt die Contributor-Zahl also, wer je eines ausgeliefert
hat.

### Woher die Contributors kommen

Nicht aus der Changelog-Datei, sondern aus dem Git-Bereich zwischen dem vorigen
Release-Tag und diesem Release. `1.2.0` und `v1.2.0` werden beide versucht.
Merge-Commits setzen Grenzen, werden aber nicht als eigene Änderung
gutgeschrieben; als Apps markierte Bot-Accounts bleiben draußen.

Die **Beschriftung trägt den Akzent**, nicht die Zahl: `--primary` ist die Farbe,
mit der eine konsumierende Site das Theme anpasst. Zwei kurze Beschriftungszeilen
sind ein günstiger Ort dafür.

Darunter steht jedes Release in **einer Zeile mit Spalten**: Version, Abzeichen,
Inhalt, Datum. Versionen stehen untereinander, Zusammenfassungen beginnen an
derselben Stelle. Unterhalb von `sm` rutscht die Zusammenfassung in eine zweite
Zeile; nichts scrollt seitwärts. Ein Abzeichen neben der Version kennzeichnet das
aktuelle Release. Es sitzt in einer **festen, auch leer vorhandenen Spur**, damit
die Zusammenfassungen von Releases ohne Abzeichen genauso ausgerichtet bleiben.
Das Datum steht ganz außen neben dem Pfeil: Leser überfliegen dieses Feld
senkrecht, statt es quer mitzulesen.

Das Filtern **animiert beide Seiten**: die Chips oberhalb der Liste und die sich
bewegenden Zeilen darunter, mit gleichem Timing als eine zusammengehörige Geste.
Zeilen blenden über 200 ms ein oder aus und gleiten an ihren Platz. Eine
verschwindende Zeile verlässt den Dokumentfluss, damit die darunterliegenden die
Lücke bereits währenddessen schließen; das browserseitige FLIP bewegt die
verbleibenden Zeilen. Dafür dient eine `TransitionGroup`, keine zusätzliche
Animationsbibliothek: Einblenden und leichtes Verschieben rechtfertigen keine
Laufzeitabhängigkeit für jede konsumierende Site. Unter `prefers-reduced-motion`
ist alles deaktiviert. Eine Zeile nennt die **drei größten Gruppen und zählt den
Rest**: „Features 2 · Bug Fixes 2 · Documentation 1 · und 9 weitere“. Drei, **nach
Anzahl**, nicht nach der festen und bedeutungslosen Abschnittsreihenfolge von
release-please. Nichts verschwindet still; eine gefilterte Zeile nennt zuerst das,
wonach gefiltert wurde.

Die Farbtöne stehen dort, wo sie unterscheiden statt dekorieren: im Filtermenü
und in der Beschriftung jeder Gruppe auf einer Release-Seite, nicht in der Historie.

Ein **Zeichen vor dem Namen wird nur in der Darstellung entfernt**, überall dort,
wo der Name erscheint: etwa `⚠` vor dem Breaking-Block von release-please oder
ein Emoji vor einer handgepflegten Abschnittsüberschrift. Nur am Anfang, damit
`C++ Support` erhalten bleibt. Der gespeicherte Name bleibt vollständig: Der
Filter vergleicht ihn, der Anker wird daraus gebildet und die Props tragen ihn.
Deshalb geschieht die Kürzung bei der Darstellung statt im Parser. Siehe
`changelogLabel`.

Die `groups` eines Releases tragen nur einen `name` und einen `count` — die
Einträge sind nicht hier, weil jedes Release eine eigene Seite hat und seine
Punkte zu wiederholen die ganze Historie doppelt in den Suchindex, in
`llms-full.txt` und in den Feed legen würde.

Die Filter-Chips werden aus den Namen gebaut, die die Datei selbst benutzt hat.
Ist nichts ausgewählt, zeigt die Seite **alles**, und das ist auch, was der Server
rendert: Ein Filter ist die Wahl eines Lesers, die Seite muss also vollständig
sein, bevor jemand sie trifft — sonst bekommen der Crawler und der Leser, dessen
Hydration noch nicht angekommen ist, je ein gefiltertes Changelog, um das niemand
gebeten hat.

## ChangelogGroup

Eine Gruppe eines Releases — „Features“, „Bug Fixes“, was die Datei eben sagte.

| Prop    | Typ      | Anmerkungen                                    |
| :------ | :------- | :----------------------------------------------- |
| `name`  | `string` | Die eigene Überschrift der Datei, wörtlich       |
| `count` | `number` | Wie viele Einträge die Gruppe listet             |

Die Einträge kommen im **Slot an, als das Markdown, als das sie geschrieben
wurden** — so indexiert die Suche sie, `llms-full.txt` trägt sie, und die
Kopieren-Schaltfläche reicht einem Modell Prosa statt eines Komponentenaufrufs.
Nur der Name und die Zahl, die das Abzeichen und die Filter als Daten brauchen,
reisen als Props.

Der Name ist eine **Beschriftung, keine Schlagzeile**: klein, in Großbuchstaben
und im eigenen Farbton über einer dicht anschließenden Liste. Als Überschrift
mit 20 Pixeln beanspruchte ein Wort für vier Listenpunkte das Gewicht eines
Kapitels; sechs davon wirkten wie sechs Abschnitte statt eines Releases. Es bleibt
ein `<h2>`: Gliederung, Inhaltsspalte und Anker bleiben erhalten, nur der Satz
verändert die Gewichtung.

Die Farbe ist ein **Hinweis und nie eine Bedeutung**: Ein unbekannter Name bekommt
einen eigenen stabilen Farbton. Dadurch bleibt dieselbe Änderungsart auf einer
Seite mit vierzig Releases in jeder Sprache überfliegbar. Die Beschriftung nutzt
das `text`-Paar des Farbtons statt der `dot`-Füllung: Wörter und ein sechs Pixel
großer Punkt erfüllen die Kontrastanforderungen nicht bei derselben Helligkeit.

Die **Listenmarker der Einträge bleiben grau**. Die Farbe steht bereits in der
Beschriftung darüber; auf jeder Zeile wiederholt verliert sie ihren Signalwert.
Die Marker werden in `duxt.css` gesetzt, nicht in dieser Komponente, weil sie als
Markdown durch den Slot kommen.

## Eine davon ersetzen

Wie bei jeder anderen Komponente der Ebene: Eine Datei am selben Pfad in der
konsumierenden Site gewinnt.

```
app/components/content/ChangelogGroup.vue
```

Die Props oben sind der Vertrag, und der Name des Layouts ebenso. Eine Umbenennung
hier ist ein Breaking Change der Ebene.

## Was eine Release-Seite neben ihren Gruppen zeigt

Nichts im Körper. Das Veröffentlichungsdatum und der **Diff, aus dem das Release
entstand**, reisen als `date` und `compare` im Frontmatter der Seite. Sie erscheinen
im Herkunftsblock unter der Inhaltsspalte, über „Diese Seite bearbeiten“ — dort,
wo die Site bereits die Herkunft einer Seite erklärt.

Das Release-Datum **ersetzt** die Zeile des letzten Commits: Alle Releases eines
Changelogs leben in einer Datei, deren letzter Commit sie sonst alle auf denselben
Tag datieren würde — bestenfalls den des neuesten Releases.

Eine Release-Seite liest sich dadurch wie jede andere Markdown-Seite der Site:
Eine Release-Notiz ist Prosa, kein Dashboard.

## Keine eigene Überschrift

Keine der beiden Komponenten beginnt mit einem `<h1>`. Das Doku-Gerüst zeichnet
den Kopf — Brotkrumenpfad, Titel, die Kopieren-Schaltfläche daneben — für jede
generierte Seite, deren Körper mit keiner Überschrift beginnt, und eine
Release-Seite will genau das: einen Titel und eine Spur wie jede geschriebene
Seite.