Stilpakete: Architektur des neuen Design-Systems

Stand 15.10.2026, gemessen an 31a46db56 (beta). Vorgang E-261015-designsystem-neu, Entscheidung docs/kontext/entscheidungen/2026-10-15-designsystem-neuaufbau.md.

Christian am 15.10.2026: „Am besten von Anfang an modular arbeiten (sodass der Übergang nichts bricht und jederzeit aufs Legacy-Theme geschaltet werden kann um Nutzung zu ermöglichen (auch admin-Setting die zwischen neu und legacy toggled für alle), damit wir später noch ändern können. Da sollte unser Component/Widget-System praktisch sein als Vorarbeit.“

Dieses Papier beschreibt den Bau, nicht die Richtung. Welches neue Paket kommt, wählt Christian an den Musterbögen (docs/gestaltung/musterboegen/stilpakete/). Zahlen ohne Vermerk sind gezählt oder gemessen; Schätzungen heißen so. Gezählt wurde mit grep über packages/frontend/src und packages/plugins/src ohne Testdateien; das Hauptbündel wurde mit Vites Produktionsbau in einen eigenen Ordner gebaut (dieselbe Prüfsumme index-44m9sH9P.js wie build.blick/).


1. Bestand

1.1 Das Theme

1.2 Die Bausteinschicht und wer sie nutzt

Gezählt sind Dateien, die den Baustein einführen. Die Bereiche führen über relative Pfade ein (../../../../frontend/src/components/…).

BausteinOrtDateien
ActionButton, TextField, ControlRow, Panelcomponents/controls/Controls.tsx196 führen Controls ein; ActionButton steht in rund 180, TextField in 86
Buttoncomponents/ui/Button.tsx18, dazu 13 über ui/index.ts
Segmentwahlcomponents/ui/Segmentwahl.tsx16
MenuScreen (Kopf, Abschnittsreiter, Ansichtssegmente, Suche, Anlegen)components/menus/shell/MenuScreen.tsx, MenuShell.tsx27
EmptyStatecomponents/dataview/EmptyState.tsx24
Listecomponents/formen/Liste.tsx19
Modalcomponents/ui/Modal.tsx10
Badgecomponents/ui/Badge.tsx8
Werkstoffe papier, karton, glas, stein, korntheme/werkstoffe.ts74
Tabs, Input, Checkbox, Tooltip, Dividercomponents/ui/je 0 bis 1 außerhalb von /stil
Selectcomponents/ui/Select.tsx0
Karte, Zeile, Blattcomponents/formen/1, 1, 3
Einstellungsgruppeplugins/src/settings/client/Einstellungsgruppe.tsx1; liegt in einem Bereich und ist nach Grundsatz 43 für keinen anderen erreichbar
Table, Tab, TextButton, VerticalDividercomponents/widgets/general/0, tot

Was es gibt, reicht als Vorarbeit: Werkstoffe, MenuScreen, Segmentwahl und EmptyState sind schon Bausteine mit Regel und Test. Was fehlt, ist die Trennung zwischen dem, was ein Baustein ist (Aufbau, Verhalten, Zugänglichkeit), und dem, wie er aussieht (Werte und Gestalt). Heute steht beides in derselben Vorlage, mit den Werten des heutigen Aussehens darin.

1.3 Doppelt vorhanden

1.4 Was die Schirme selbst bauen

3 726 styled-Definitionen, davon 2 844 in den Bereichen und 206 in den Bausteinordnern (ui, controls, formen, dataview, layout, menus/shell). 284 lokale Knöpfe (styled.button: 211 in 135 Bereichsdateien, 73 in 50 Dateien des Frontends), 121 lokale Überschriften (styled.h1 bis h3). Zeilen mit einer rohen px-Zahl: rund 1 680 in plugins/*/client, rund 1 250 in frontend/src/components (ohne Kommentarzeilen; Haarlinien von 1 px zählen mit).

Bereichstyledlokale Knöpfelokale Überschriften.tsxmit gemeinsamem Knopfmit EmptyState
admin478272348230
settings31714749311
begleiter29212240240
documents2653724341
study239191124122
wiki21619623151
calendar19111720150
latex18951516155
dashboard1051551020
tasks1041121160
stundenplan1018013111

Kalender und Stundenplan zeichnen in zwei Rastern: calendar/client/Stundenraster.tsx (1 073 Zeilen) und Monatsblatt.tsx (1 579) gegen stundenplan/client/Wochenraster.tsx (1 242). Die Befunde 1 bis 4 der Befragung (uneinheitliche Bausteine, keine Hierarchie, zwei Raster, doppelte Navigation) sind zum größeren Teil Folgen dieser Zahlen.

1.5 Hauptbündel und Nachladen

1.6 Einstellungen und Admin-Werte


2. Zielbild

2.1 Drei Schichten

Schirme        ordnen an: Bausteine und Anordnung, keine eigenen Werte
   │
Bausteine      Aufbau, Verhalten, Zugänglichkeit; Aussehen nur aus
   │           Tokens (CSS-Variablen) und dem Rezept des Pakets
   │
Kern           Tokenvertrag, tk, Tokenschreiber, Paketlader, Register;
   │           Szenen, Tageszeit, Wetter, Himmelsgrund, Bewegung,
   │           Geräteschicht, Gestaltung      → im Hauptbündel
   │
Stilpaket      Werte, Rezepte, Bühne (Grund, Texturen, Schriften),
               Himmelsauftritt, Eulenkostüm   → je Paket ein Stück,
                                                nur das aktive lädt

Schirme kennen kein Paket, Bausteine kennen kein Paket, und ein Paket kennt keinen Schirm. Die einzige Stelle, die Pakete einführt, ist der Lader.

2.2 Was ein Stilpaket ist

Ein Ordner packages/frontend/src/theme/pakete/<name>/ mit einem Einstieg:

export interface Stilpaket {
  readonly name: Stilpaketname;
  /** Werte und Kompatibilität aus derselben Wahl wie heute baueTheme. */
  readonly baue: (wahl: Themewahl) => { readonly theme: Theme; readonly tokens: Tokensatz };
  /** Gestalt je Baustein; fehlt eine, gilt das Grundrezept des Kerns. */
  readonly rezepte: Partial<Rezepte>;
  /** Grund, Texturen, @font-face — ein createGlobalStyle des Pakets. */
  readonly Buehne: React.ComponentType;
  readonly himmel: Himmelsauftritt;
  readonly eule: Eulenkostuem;
  /** Welche Einstellungen das Paket versteht (Abo-Theme, eigene Szene, Zeichenstil, Serif). */
  readonly kann: Paketfaehigkeiten;
}

2.3 CSS-Variablen und Theme-Objekt: beide, mit getrennten Aufgaben

2.4 Das Legacy-Paket entsteht aus dem heutigen baueTheme

2.5 Schirme gestalten nur noch über Bausteine

Neue Bausteine stehen unter packages/frontend/src/components/bausteine/. Die alten Exporte werden Weiterleitungen, bis niemand sie mehr einführt.

Stand 18.10.2026 (E-261016-bausteine-i-knopf-feld): Knopf, Feld, Reiter, Segment und Schirmkopf stehen, jeder mit data-baustein, einem Legacy-Rezept und dem Grundrezept aus dem Vertrag; ein Test zeichnet jeden mit leerem Rezept und findet keinen eigenen Farb-, Schrift-, Rand-, Rundungs- oder Schattenwert. Weiterleitungen sind ActionButton, ui/Button, TextField, MenuSearch, der Rahmen von ui/Input, Feld und Haken aus pflegebausteine.ts, MenuTabBar, ui/Tabs (mit dem Reitermuster aus ARIA), Segmentwahl, AnsichtsReiter, MenuTitle, MenuMotiv und Titelblock; MenuTab, MenuTabs, MenuHeader, MenuKopfende und MenuTitelblock sind entfernt. Offen aus der Tabelle bleiben die toten TextButton und Tab und die lokalen Nachbauten in den Schirmen.

Stand 18.10.2026 (E-261016-bausteine-ii-flaeche): Flaeche, Zeile mit Zeilenliste und Aufgabenzeile, Leerzustand, Einstellungsgruppe mit Klappe, Nebentext, Fenster und Unterblatt sowie Stapel, Reihe und Spalten stehen, jeder mit data-baustein. Das Rezept flaeche zeichnet die Flaeche je Stoff und ihren Kartenreiter, zeile die Linien der Zeilenliste und die Aufgabenzeile, leerzustand den Leerzustand, einstellungsgruppe die Gruppe mit Faltleiste, MehrHinweis und Klappe, nebentext den Nebentext und fenster das Fenster und das Unterblatt. Jedes dieser sechs Rezepte steht wie die der Bausteine I auch im Paket Legacy, weil seine Bausteine heutiges CSS ersetzen; erst Bausteine, die nach dem Einfrieren von Legacy entstehen, zeichnen unter Legacy mit dem Grundrezept (Kommentar in theme/pakete/legacy/rezepte.ts). Die Zeile selbst, deren Linie die Zeilenliste zieht, und die Anordnung haben kein Rezept. Weiterleitungen sind beide Panel auf Flaeche, formen/Karte auf Flaeche und Kartenreiter, Liste und Listenzeile aus formen/Liste auf Zeilenliste und Zeile, formen/Zeile auf Aufgabenzeile, EmptyState und Horizont auf Leerzustand, settings/client/Einstellungsgruppe.tsx auf Einstellungsgruppe, Faltleiste und MehrHinweis, ui/Klappe auf Klappe, Unterzeile und Hinweis aus pflegebausteine.ts auf Nebentext, ui/Modal auf Fenster sowie Knopfzeile und Felder aus pflegebausteine.ts auf Reihe und Spalten; Unterblatt und Stapel führt außer den Tests noch niemand ein. Die toten Table, Tab, TextButton und VerticalDivider sind gelöscht, auch die beiden, die Bausteine I offen ließ. Offen aus der Tabelle bleiben die Einbindungen der Werkstoffe, die Zellen, die 26 lokalen Leerzustände, der Nachbau in study/client/Themengliederung.tsx, Seitenblickblatt, die Schubladen und die lokalen styled.div für Abstände, dazu die Aufgabenzeile des Bereichs tasks.

BausteinersetztAnmerkung
SchirmkopfMenuHeader, MenuTitle, MenuTitelblock, 121 lokale ÜberschriftenTitel, Ort, Aktionen, Platz für den Vorschlag der einen Suche (Befund 4); heißt nicht „Seitenkopf“, weil layout/Seitenkopf.tsx den Dokumentkopf hält
ReiterMenuTabBar/MenuTab, ui/Tabs, toter Tab, sechs lokaleAbschnitte, Navigation, aria-current
SegmentSegmentwahl, AnsichtsReiterwenige Stellungen, aria-pressed, Kapsel
KnopfActionButton, ui/Button, toter TextButton, 284 lokaleprimär, sekundär, Geist, Gefahr; xs, sm; als Verweis; Zielfläche 44 px unter pointer: coarse; Wegtun bleibt die Hülle darüber
FeldTextField, ui/Input, MenuSearch, Admin-FeldText; Auswahl, Datum, Haken und Schalter als Hüllen um SelectField, DateField, Checkbox
Flaechebeide Panel, formen/Karte, Werkstoff-EinbindungenPapier, Karton, Stein und der Rahmen um ein Formular; Glas nur für Schwebendes (Liste in verifyEigenstil.ts)
Zeileformen/Zeile, formen/Liste, ZellenHaarlinie, Fälligkeit kippt (Guide §7.6)
Einstellungsgruppesettings/client/Einstellungsgruppe.tsx, ui/Klappe, Nachbau in study/client/Themengliederung.tsxzieht aus dem Bereich ins Gerüst; Klappe ist ihre Form am Telefon
NebentextUnterzeile und Hinweis aus admin/client/pflegebausteine.tsder kleine Satz unter einer Zeile oder neben einem Feld, leiser als der Lesetext
LeerzustandEmptyState, Horizont, 26 lokaleFels und sitzende Eule zeichnet der Kern in jedem Paket; Tinte, Familie und wie leise das Band ist, sagt das Rezept
ZeitrasterStundenraster, Monatsblatt, Wochenrasterein Raster mit Ebenen; der Stundenplan wird eine Ebene (Befund 3), die Daten bleiben getrennt
Fenster, Unterblattui/Modal, Seitenblickblatt, SchubladenFenster am Schreibtisch und iPad, Blatt von unten am Telefon; nicht „Blatt“, weil formen/Blatt das Dokument mit Eselsohr ist
Stapel, Reihe, Spaltenlokale styled.div für Abstände, Knopfzeile und Felder aus admin/client/pflegebausteine.tsAnordnung mit Token-Abständen, damit ein Schirm für Lücken keine eigene Vorlage braucht

Ein Schirm darf danach noch anordnen (Raster, Spaltenbreiten, Reihenfolge), aber keinen Farb-, Schrift-, Rand-, Rundungs- oder Schattenwert setzen. verify:bausteine hält das fest (5.2).


3. Umschalten

3.1 Der Wert

3.2 Beim Laden

index.tsx ──┬─ ersterSchirm(adresse, 2000)
            ├─ tabelleVorDemErstenBild(sprache, 2000)
            └─ stilpaketVorDemErstenBild(paketVomGeraet(), 2000)     neu
                  import('./theme/pakete/<name>')   eigenes Stück
                        │
            erstes Bild: Paket steht, Tokens an :root, data-stilpaket
                        │
            startabruf → Einstellungen → GestaltungProvider löst
            theme.stilpaket auf; anders als am Gerät → Lader holt das
            andere Paket, wechselt einmal, merkt es am Gerät

3.3 Ob ein Konto selbst zurückschalten kann

Gebaut ist nur „Ändern für: mein Konto“ (E-261016-admin-schalter): Die Einstellungsseite zeigt unter Darstellung die Gruppe „Aussehen“ (Stufe „erweitert“) mit „wie für alle (<Vorgabe>)“ und den gebauten wählbaren Themes. Unter „nur dieses Gerät“ steht sie nie (amGeraetEinstellbar); den Gerätewert schreiben nur /ansehen und die Vorschau im Abschnitt „Gestaltung“ der Verwaltung. Die Gruppe fehlt, solange keines von klar, ruhig und marker gebaut ist oder die Vorgabe legacy ist. „wie für alle“ nimmt den eigenen Wert zurück, statt den Namen der Vorgabe zu speichern: Wer so wählt, geht mit, wenn die Verwaltung die Vorgabe wechselt.

Seit 2026-10-15-vier-themes geöffnet: Es gibt vier Themes (flaggschiff, klar, ruhig, marker). Der Admin-Wert setzt das Haupttheme für alle, und die Nutzerschicht nimmt die drei anderen an; legacy bleibt dem Admin vorbehalten. /ansehen --pakete deckt damit alle vier ab, und der Lader holt nur das aktive Theme. Ergibt die Vorgabe aus eingebaut, Instanz und Rolle legacy, gilt legacy, gleich was das Konto gewählt hat (vorgabeUeberstimmt in preferenceKeys.ts). So bleibt „jederzeit aufs Legacy-Theme geschaltet … für alle“ (2026-10-15-designsystem-neuaufbau) wahr, und vor der Umstellung der Vorgabe sieht außerhalb der Probegruppe niemand ein neues Theme. Die Geräteschicht gewinnt weiter über alles.

3.4 Was beim Umschalten zur Laufzeit geschieht

3.5 /ansehen nimmt beide Pakete auf


4. Bündel

Regel: Kein Modul aus theme/pakete/ steht im Hauptbündel. Der Kern wächst nur um Vertrag, tk, Tokenschreiber, Lader und Register. Jeder Vorgang misst vorher und nachher mit node betrieb/buendel.mjs --build (nicht mit dem Bau von /ansehen, siehe fallstricke.md, WI27) und schreibt beide Zahlen in den Commit.

Wie nur das aktive Paket lädt: Das Register ordnet jedem Namen ein import() zu; Vite macht daraus je Paket ein Stück. Schriften und Texturen sind eigene Dateien, angemeldet in der Bühne des Pakets; der Browser holt sie erst bei Gebrauch. Eine echte CSS-Datei je Paket ist möglich (ein .css, das der Einstieg des Pakets einführt, hängt Vite mit dem Stück an), aber nicht nötig: Die Werte schreibt der Tokenschreiber, die Gestalt tragen die Rezepte, und beides bleibt bei styled-components (Projektregel „nur Styled Components“).

Teilheutemit StilpaketenGrundlage
Hauptbündel1 964,3 kB, Grenze 1 434,0 kBwächst nicht, wird kleinergemessen
Theme im Hauptbündel33 Module, 138,9 kB vor dem Verkleinern, rund 65 kB danachKern bleibt: Szenen, Tageszeit, Wetter, Himmelsgrund, Bewegung, Geräteschicht, Gestaltunggemessen; „danach“ geschätzt mit 0,466
davon nur Legacytheme.ts 18,9 · metalle 9,2 · steinschliff 4,4 · vorspannfarbe 2,9 · werkstoffe 2,4 · lesefarbe 2,1 · kontrast 1,5 · muster 1,2 = 42,6 kB vor dem Verkleinernins Legacy-Stück, bis rund 20 kB weniger im Hauptbündelgeschätzt; die Abo-Stufe aus metalle braucht Gestaltung.tsx, bis sie eine Fähigkeit des Pakets ist
neuer Kern–3 bis 6 kBgeschätzt
Kommentare in styled-Vorlagen33,2 kB im Hauptbündel, 121,6 kB in allen Stücken0gemessen
Einrückung in styled-Vorlagenrund 11,5 kB im Hauptbündelnahe 0gemessen, grob
Legacy-Stück–20 bis 35 kB, lädt neben dem ersten Schirmgeschätzt
neues Paket–15 bis 35 kB Code; Schriften und Texturen eigene DateienAnnahme
Schriften7 Dateien, 208,7 kB, alle angemeldetje Paket nur die eigenengemessen

Spielraum, den das Vorhaben braucht: Die Kommentare und die Einrückung in styled-Vorlagen kann ein Bauschritt entfernen (ein eigenes Plugin unter src/bau/ oder babel-plugin-styled-components mit minify, das wäre ein neues npm-Paket). Das gehört zu B-261015-glieder-gruen und ist mit ihm abzustimmen. Die Überschreitung selbst (Krypto über startabruf.ts, Begleiter) löst dieses Vorhaben nicht.

Hülle: Stand 18.10.2026 (E-261016-huelle-legt-nur-aktive): Die Bauliste in public/sw.js nennt je Datei ihre Pakete, eine leere Liste heißt Kern, und als fallbackPackage das Paket legacy. assignChunks in huelle/bauliste.ts ordnet die Stücke über ihre Erreichbarkeit im Bündel zu: Ein Paket beginnt mit dem Stück, dessen Einstieg theme/pakete/<name>/index.ts ist; Kern ist, was das Hauptbündel erreicht, ohne über ein import() in ein Paket zu gehen, ein Paket, was sein Stück erreicht, ohne durch den Kern zu gehen. Stile und Assets gehören wie ihr Stück; das Legacy-Stück trägt Legacy und das Prüfpaket, weil das Prüfpaket es einführt. Eine Schrift unter schrift/ gehört dem, der sie mit url(/schrift/….woff2) anfordert; eine Schrift zweier Pakete liegt einmal und trägt beide, eine, die niemand anfordert, gehört dem Paket ihres Ordners schrift/<name>/, wenn es eines gibt, sonst dem Kern. Der Worker legt beim Einrichten den Kern und das zuletzt gemeldete Paket ab, die Dateien eines später gemeldeten erst mit dessen Meldung, geprüft wie jede Datei. Den Namen merkt er sich in einem eigenen Speicher (denotato-huelle-meldung), der jede Fassung überdauert; wechselt das Paket, während eine neue Fassung wartet, nimmt diese beim Aktivieren die Dateien des gemeldeten Pakets aus den alten Ablagen mit, ohne das Netz zu fragen. Was ein früher gemeldetes Paket abgelegt hat, bleibt bis zur nächsten Fassung liegen. Der Lader meldet jedes Paket, das aktiv wird, vor dem ersten Bild und nach jedem Wechsel (onActivePackage); huelle/anmelden.ts reicht es nur im Bau per postMessage an den Worker weiter, sobald einer aktiv ist. Beim ersten Besuch richtet sich der Worker vor jeder Meldung ein und legt legacy ab; das gemeldete Paket folgt mit der Meldung. Ohne Netz startet das zuletzt gemeldete Paket, ein anderes fängt huelle/fehlendeStuecke.ts ab. Seit dem 19.10.2026 nimmt die Hülle auch Bilder auf: gehoertInDieHuelle lässt außer Stücken, Stilen und WOFF2 ein Bild unter assets/ zu, wenn ein Stück es einführt; assignChunks liest dazu die importedAssets jedes Stücks, also gehört ein Bild dem Paket, dessen Stück es einführt. Beim Flaggschiff ist das nur himmel-nacht.svg (eingeführt mit ?no-inline); die kleineren Texturen legt Vite als data:-Adresse ins Stück. Den Boden Legacy legt der Worker immer mit ab: Auf ihn fällt der Lader zurück, wenn das aktive Paket nicht lädt, und ohne Netz muss er dann liegen. Unter dem Prüfpaket kostet das keine Datei, weil sein Stück das Legacy-Stück einführt. Das Flaggschiff führt Legacy nicht ein; unter ihm legt der Worker dessen Dateien zusätzlich ab, rund 226 KB im Hintergrund (Empfehlung aus E-261016-huelle-legt-nur-aktive). Christian hat am 19.10.2026 entschieden („Erst später weg“): Der Boden bleibt vorerst und fällt weg, sobald das Flaggschiff Vorgabe für alle ist.


5. Übergang

5.1 Reihenfolge

SchrittVorgangsetzt voraussichtbar
1Token-Schicht aus dem heutigen Theme–nein
2Legacy-Paket und Paketlader1nein
3Admin-Schalter, Prüfpaket, /ansehen --pakete2nur in der Verwaltung
4Bausteine I: Knopf, Feld, Reiter, Segment, Schirmkopf1, Rezepte aus 2unter Legacy nein
5Prüfglieder verify:bausteine, verify:stilpakete4nein
6Bausteine II: Fläche, Zeile, Leerzustand, Einstellungsgruppe, Fenster und Unterblatt, Anordnung4unter Legacy nein
7Bausteine III: Zeitraster mit Ebenen6ja (Befund 3)
8Erstes neues Paket nach Christians Wahl3, 4, 6nur mit Schalter
9Schirme umziehen, je Bereich ein Vorgang5, 6unter Legacy nur gewollte Vereinheitlichung
10Gerüst: schmale Leiste, eine Suche, weniger ReiterFrage 2ja
11Vorgabe umstellen, Legacy nach Frage 5 behandeln, Theme-Objekt je Paket festhaltenFragen 4, 5ja

Das Prüfpaket aus Schritt 3 ist Legacy mit wenigen anderen Werten (etwa Handlung in Kobalt, kleinere Rundung, Grotesk im Aufmacher), nur für Entwickler in der Liste. Es beweist den Wechsel und lässt jeden Baustein in zwei Paketen testen, bevor das neue Paket existiert.

Reihenfolge der Schirme in Schritt 9 nach der Befragung: Kalender und Stundenplan, Studium und Tutor, Verwaltung, Einstellungen, Leiste und Kopf, danach der Rest nach Nutzung; jeweils das iPad im Querformat zuerst.

5.2 Prüfglieder

Beide nach dem Muster von verifyEigenstil.ts mit eigenstilBestand.ts. verify:bausteine führt einen Bestand je Datei (bausteineBestand.ts): Er wurde einmal mit --schreiben --heben erzeugt; danach senkt --schreiben ihn nur, er darf nicht steigen, und jede Meldung nennt Datei, Zeile und den Baustein als Abhilfe (P9). verify:stilpakete braucht keinen Bestand: Es gibt keinen Fund, der bleiben dürfte; die Regeln 2 und 5 stehen als Vitest-Test in theme/paket/stilpakete.test.ts, den das Glied startet.

verify:bausteine in Schirmdateien (plugins/src/*/client/**, frontend/src/components/screens/**, frontend/src/components/pages/**):

  1. lokaler Knopf (styled.button, styled(motion.button)) → Knopf
  2. lokale Überschrift (styled.h1 bis h3) → Schirmkopf
  3. eigener Reiter (role="tablist", Namen auf Reiter, Tab, Segment) → Reiter oder Segment
  4. eigener Leerzustand (Leer…, Empty…) → Leerzustand
  5. Gestaltungseigenschaft in einer styled-Vorlage (color, background, border, border-radius, box-shadow, font-*) → Baustein oder Flaeche
  6. rohe px-Zahl außerhalb von Anordnungseigenschaften → Token-Abstand
  7. Import aus theme/werkstoffe oder theme/pakete/ → Flaeche

verify:stilpakete:

  1. STILPAKETE in shared, das Register und die Ordner unter theme/pakete/ nennen dieselben Namen.
  2. Jedes Paket liefert jeden Wert des Vertrags (die Typen erzwingen es) und jedes Rezept oder ausdrücklich das Grundrezept.
  3. Nur der Lader und Tests führen theme/pakete/* ein; kein Paket führt ein anderes oder etwas aus components/ ein.
  4. Im Bündelbild des Hauptbündels (packages/frontend/.buendel/) steht kein Modul aus theme/pakete/.
  5. Kontrast je Paket: Text-, Lese- und Nebentinte auf jeder Fläche mindestens 4,5 : 1, Tag und Nacht, alle zwölf Szenen (Test nach dem Muster von theme/kontrast.test.ts).

verify:stil (Guide gegen Theme) liest künftig den Tokenvertrag; betrieb/designsystem/design-md.mjs erzeugt die Tokentabelle für DESIGN.md aus ihm.

5.3 Wie ein Schirm umzieht, ohne dass Legacy bricht

  1. /ansehen <weg> --geraete ipad,telefon,desktop --pakete legacy vorher.
  2. Lokale Nachbauten durch Bausteine ersetzen; was im Schirm bleibt, ist Anordnung.
  3. /ansehen nachher mit --pakete legacy,<neu> und Vergleich. Unter Legacy ändert sich nur gewollte Vereinheitlichung; sie steht im Commit-Rumpf.
  4. npx tsx src/database/scripts/verifyBausteine.ts --schreiben (in packages/backend) senkt den Bestand.
  5. docs/seiten/<seite>.md nachziehen.

Legacy bricht nicht, weil die Legacy-Rezepte das heutige Aussehen der Bausteine zeichnen und das Theme-Objekt für nicht umgezogene Teile gleich bleibt.


6. Risiken und offene Fragen

RisikoWirkungGegenmittel
verify:buendel ist schon rotkein Vorgang kann „nicht gewachsen“ am Glied zeigenVorher-nachher-Zahl je Commit; Grenze zurück über B-261015-glieder-gruen
Erstes Bild wartet auf ein weiteres Stückverify:schirmzeit ist schon rot (fünf Schirme über 1000 ms p90)Paket parallel zum ersten Schirm laden; p90 je Schirm vorher und nachher vergleichen
JavaScript liest FarbenMermaid, Canvas, SVG-Attribute und ${karton}cc vertragen kein var()Theme-Objekt behält konkrete Werte; nur Bausteine lesen Variablen
Eckenplugin streckt nur pxRundungen aus Variablen blieben ungestrecktPlugin wird tokengesteuert (2.4)
Variable mit var() im Wertlöst sich am falschen Element aufVerläufe ins Rezept
Legacy-Rezepte doppeln die Gestaltungsarbeitjeder Baustein zweimalFrage 5: Legacy nach dem Umzug einfrieren
Gemischtes Bild unter dem neuen Paketnicht umgezogene Schirme mit alter Gestaltneues Paket erst Vorgabe nach dem Umzug (Frage 4), Probegruppe über Rolle
Einmaliger Wechsel nach dem ersten Bildein Gerät sieht nach dem Umschalten einmal das alte Pakethinnehmen; später ein öffentlicher Weg für den Instanzwert
Hülle legt alle Pakete abSchriften und Texturen inaktiver Pakete auf jedem GerätKern und gemeldetes Paket statt aller, gebaut am 18.10.2026 (E-261016-huelle-legt-nur-aktive, Abschnitt 4); Texturen erst mit dem Flaggschiff
iPad quer misst 1194 px, breakpoints.desktop 1200 pxTeile, die an desktop hängen, zeigen auf dem Hauptgerät die TabletformBruchstellen beim Umzug in den Kern neu schneiden; welche Schirme betroffen sind, ist nicht geprüft
Namensgleiche Bausteinezwei Panel, Seitenkopf und Blatt schon vergebenneue Namen (2.5), tote Widgets entfernen
Parallele Musterbögenihre Werte passen nicht zum VertragVertrag und Musterbögen benutzen die Gruppen aus 2.2
Bausteine im BereichEinstellungsgruppe, pflegebausteine sind für andere Bereiche unerreichbarins Gerüst ziehen (Schritt 6)

Die fünf Fragen aus Abschnitt 7 sind beantwortet: docs/kontext/entscheidungen/2026-10-15-stilpakete-bau.md. Christian entschied Frage 1 (kein Kontoschalter) und Frage 2 (Legacy bekommt die neue Anordnung); die Fragen 3 bis 5 laufen mit der Empfehlung weiter. Frage 1 ist für die vier Themes überholt: 2026-10-15-vier-themes öffnet die Nutzerschicht für klar, ruhig und marker (3.3); zurück auf legacy schaltet weiter nur der Admin.


7. Fragen an Christian (beantwortet am 15.10.2026)

  1. Darf ein Konto selbst auf das bisherige Aussehen zurückschalten? Empfehlung: nein. Der Admin schaltet für alle, eine Rolle trägt Probegruppe und Ausnahmen, Admins und Entwickler sehen je Gerät vor. Für die vier Themes überholt (2026-10-15-vier-themes): Ein Konto wählt klar, ruhig oder marker; auf Legacy zurück schaltet weiter nur der Admin (3.3).
  2. Bekommt Legacy die neue Anordnung mit (schmale Leiste, eine Suche, Kalender mit Stundenplan als Ebene, weniger Reiter)? Empfehlung: ja; Legacy bewahrt Farben, Werkstoffe, Schriften und Formen, nicht die Anordnung.
  3. Wie weit darf ein Stilpaket gestalten? Empfehlung: Werte, Rezepte je Baustein und Bühne (Grund, Texturen, Schriften, Himmelsauftritt, Eulenkostüm), nicht die Anordnung.
  4. Wann wird das neue Paket die Vorgabe für alle? Empfehlung: wenn alle Schirme auf Bausteinen stehen; bis dahin schaltet der Admin, erst für eine Probegruppe.
  5. Was geschieht danach mit Legacy? Empfehlung: Es bleibt wählbar, wird aber eingefroren; neue Bausteine bekommen dort nur das Grundrezept.

8. Erste Vorgänge

  1. Token-Schicht aus dem heutigen Theme — ohne sichtbare Änderung.
  2. Legacy-Paket auslagern, Paketlader vor dem ersten Bild.
  3. Admin-Schalter für das Stilpaket, mit Prüfpaket und /ansehen --pakete.
  4. Bausteine I: Knopf, Feld, Reiter, Segment, Schirmkopf.
  5. Prüfglieder verify:bausteine und verify:stilpakete.
  6. Bausteine II: Fläche, Zeile, Leerzustand, Einstellungsgruppe, Fenster und Unterblatt, Anordnung; tote Widgets entfernen.

Je Vorgang ein kurzer Branch (bash betrieb/bahn.sh claim <KENNUNG>), angelegt mit node betrieb/vorgang.mjs new 5-bereiche/gestaltung "<Titel>"; „Fertig, wenn“ steht im jeweiligen Vorgang.