Themenvertrag
Dieses Dokument regelt
site.theme, d. h. die Theme-Blöcke, denen eine Website folgt, sowie die Regeln für Theme-Token und CSS.
Die Shell-CSS-Topologie, die Ebenen „Root Background“ und „Chrome Overlay“ sowie das „Region Chrome“ werden in
SHELL.md geregelt. Wie Schriftartdateien auf die Seite gelangen, wird in
NEXT_INTEGRATION.md geregelt. Die Bereitstellung von Theme-Blöcken aus einem Modul wird in
THIRD_PARTY_MODULES.md erläutert. Die Verfügbarkeit von Sprachumgebungen ist kein Thema des Themes;
dies wird von
@phis/server geregelt (
phis-server TRANSLATIONS.md, „Locale capability“).
Woher das Thema stammt
site.theme (PhiSiteTheme, gateway/site-config.ts) ist Teil der Site-Konfiguration, die @phis/server
bei einem GET /api/v1/site-Aufruf zurückgibt. Es handelt sich um den gespeicherten Theme-Datensatz der Site, der bei jeder Anfrage ausgelesen wird.
site.themeRevision enthält publishedRevisionId und workingDraftRevisionId, die Zeiger für den Theme-Bereich.
Diese werden getrennt von den visuellen Daten gespeichert.
Ein gespeicherter Datensatz enthält lediglich die Informationen darüber, welche Blöcke die Website verwendet und welche Werte deren Autor geändert hat. Alles
Sonstige wird bei jedem Lesevorgang anhand der Blöcke ermittelt (in der Datei theme/phi-theme-composition.ts). Die vom Autor festgelegten Werte
haben stets Vorrang vor den Blöcken.
resolvePhiThemeRuntimePayload(...) (theme/phi-theme-runtime.ts) fasst die Blöcke einmalig zu einem gewöhnlichen
„Theme“-Datensatz zusammen, und zwar in PhiRootLayout. Jeder nachgelagerte Verbraucher liest diesen Datensatz; keine nachgelagerte Komponente weiß,
welche Felder ein Block bereitgestellt hat, und ein aufgelöster Wert wird niemals zurückgeschrieben.
Themenblöcke
Ein Theme besteht aus vier Teilen, von denen jeweils ein Modul bereitgestellt werden kann (theme/phi-theme-blocks.ts):
Ein Set
(PhiThemeSetBlock
) benennt jeweils einen Block jedes Teils anhand eines Schlüssels und kann ein logo
(PhiSiteThemeBrandLogos
) enthalten. Es setzt sich zusammen, es enthält nichts.
Jeder Block enthält einen key, eine positive ganzzahlige version, einen title sowie eine optionale description. „Core“ liefert genau einen
Block jeder Art sowie ein „Set“, die alle mit dem Schlüssel phis versehen sind; sie bilden die Grundlage, auf die jede Auswahl zurückgreift. Das
Logo des Kern-Sets ist ein Platzhalter – ein gestrichelter Rahmen mit der Aufschrift „Ihr Logo“ –, da dieses Set jede
Installation ausfüllt, für die nichts angegeben wurde, und das, was dort steht, darf kein bestimmtes Zeichen sein.
Module stellen Blöcke über ihren Eintrag im Server-Katalog (types/cms-module-descriptors.ts) bereit:
themes: PhiCmsThemePresetDescriptor[] für Paletten – themeKey, title, optionale description,
presetVersion und loadPreset().
themeBlocks: PhiCmsThemeBlockDescriptor[] für die anderen vier Arten – blockKind ist genau style,
ground, fonts oder set, dazu blockKey, title, optional description, presetVersion und
loadBlock().
Lader werden nur für ein aktives Modul ausgeführt. Bei der Themenauswahl werden ausschließlich die Bindungen des aktiven Moduldeskriptors gelesen; globale
Register und Nebenwirkungen der Registrierung sind ungültig.
Auswahl und Auflösung
theme.blocks wählt { set?, palette?, style?, ground?, fonts? } aus, jeweils { key, version? }.
Jeder Teil wird separat ausgewertet: Eine explizite Teilauswahl hat Vorrang, dann der Teil des Sets, dann (nur in der Palette)
theme.preset. Ein Teil, der keinen Namen angibt oder auf einen nicht verfügbaren Block verweist, wird auf dem Kernblock ausgeführt; die Auswahl
selbst wird niemals überschrieben, sodass durch erneutes Aktivieren des Moduls das Erscheinungsbild wiederhergestellt wird.
theme.preset und theme.presetVersion bezeichnen die Palette, anhand derer die Laufzeit-Payload die Farben auflöst.
Eine aufgelöste Komposition meldet, welche Teile nicht verfügbar sind, sodass der Theme-Arbeitsbereich angeben kann, dass ein Modul
fehlt, anstatt den Kernblock als Auswahlmöglichkeit anzuzeigen.
Das Theme eines Moduls wird angeboten, jedoch niemals übernommen. Die Installation eines Moduls, das Blöcke enthält, ändert nichts an dem, was ein
Besucher sieht; seine Blöcke werden in die Liste aufgenommen, die der Theme-Arbeitsbereich anzeigt, und jemand wählt sie aus. Dies ist der einzige
Fall, in dem ein Modulbeitrag die mitgelieferte Standardeinstellung
nicht ersetzt, und der Unterschied zu einer
öffentlichen Adresse ist erwähnenswert, da dort die Regel umgekehrt gilt („Eine Landingpage ist ein Angebot“, in
THIRD_PARTY_MODULES.md): Eine Adresse kann von
genau einem Modul belegt werden, sodass sich eines durchsetzen muss und die Aktivierung darüber entscheidet. Ein „Look“ ist nur ein Wert unter vielen
Kandidaten – allein
@phis/example liefert dreizehn Sets aus –, daher beantwortet „das Modul gewinnt“ keine Frage, und
die Installation eines zweiten Moduls zusammen mit einem Theme würde eine Website stillschweigend neu gestalten, ohne dass diese jemals darum gebeten hat.
Drei Gründe sprechen dafür, dass die explizite Wahl die kostengünstigere ist:
Ein Thema ist ein gespeicherter Datensatz, keine Erklärung. Es spiegelt die Werte des Autors wider, wird wie eine Seite verfasst und
veröffentlicht und überdauert sein Modul: Eine Auswahl, deren Block nicht mehr vorhanden ist, greift auf den Kern zurück und
wird wieder angezeigt, sobald das Modul zurückkehrt. Eine automatische Auswahl würde eine bereits getroffene Entscheidung überschreiben.
Die Übernahme erfolgt einseitig. Sobald ein Theme, das auf die Blöcke eines Moduls verweist, gespeichert wird, gehen diese Blöcke
in den Besitz der Website über, und die Bilder werden in deren Medienbibliothek abgelegt (siehe
Übernahme beim Speichern).
Ein Design, das nie ausgewählt wurde, würde bereits beim ersten Speichern durch einen beliebigen Benutzer dauerhaft übernommen werden.
Es ist nichts ausgewählt und somit auch nichts sichtbar. Das Logo des Kern-Sets ist der Platzhalter „Ihr Logo“, sodass eine Website, auf der
keine Auswahl getroffen wurde, dies in ihrer eigenen Kopfzeile anzeigt. Dies ist die Aufforderung; ein automatisches Design würde diese entfernen.
Übernahme beim Speichern
Das Speichern eines Themes, das auf die Palette, den Stil (einschließlich der Steuerungsform), den Hintergrund oder die Schriftarten eines Moduls verweist, kopiert
diesen Block in die eigenen Felder der Website (theme/phi-theme-adoption.ts). Bereits vom Autor festgelegte Teile bleiben erhalten;
der Block-Schlüssel verbleibt als Herkunftsangabe in blocks. Ein Bild, das ein Modul-Hintergrund inline enthält, wird durch denselben Speichervorgang in die
Medienbibliothek der Website hochgeladen, ebenso wie das Logo eines Modul-Sets. Kernblöcke werden übernommen, jedoch niemals
kopiert – einschließlich des Sets, sodass das Platzhalter-Logo niemals zu einem eigenen Asset der Website wird.
Auswahl des Themen-Arbeitsbereichs
Der Theme-Arbeitsbereich befindet sich unter /builder/phis/ui/theme
(Eigentümer: @phis/ui/modules/theme
). Seine Auswahl „Set“
bietet die Modul-Sets sowie zwei Site-Einträge: site:<siteKey>:published
und site:<siteKey>:draft
(theme/phi-theme-selection.ts
). Der erste Eintrag ist der Entwurf, sofern ein „Working Draft“-Zeiger vorhanden ist; andernfalls das
veröffentlichte Theme, sofern ein „Published“-Zeiger vorhanden ist; andernfalls das Kern-Set phis
. Die Site-Zugehörigkeit wird ausschließlich aus den
Revisionszeigern abgelesen und niemals durch den Vergleich von Theme-Nutzdaten abgeleitet.
Der Schalter „Hell/Dunkel“ im Arbeitsbereich wählt aus, welche Hälfte des Designs gerade in der Vorschau angezeigt und bearbeitet wird; er
speichert den Modus nicht dauerhaft.
site.theme field reference
Alle Felder sind optional. Fehlt ein Wert, bedeutet dies „dem Block folgen“ oder die dokumentierte Standardeinstellung. Die dauerhaft gespeicherte Konfiguration bleibt
lückenhaft: Leser normalisieren fehlende Werte.
Modus
mode?: "light" | "dark" – die Hälfte des Themes, in der ein Datensatz oder Entwurf erstellt wurde. Der Modus, der einem Betrachter
angezeigt wird, stammt nicht von hier:
resolvePhiThemeMode(...) (
theme/phi-theme-mode.ts) verwendet die Einstellung des Betrachters
(
light | dark | system, Standard:
system) und, im Falle von
system, die im
phis_color_scheme-Cookie übermittelte Einstellung
prefers-color-scheme des Browsers, wobei auf
light zurückgegriffen wird. Ein Live-Signal
themeMode oder
theme an den Core Runtime Controller überschreibt die Projektion, solange die
Seite geöffnet bleibt (
SIGNALS.md).
Wo diese Einstellung gespeichert ist und warum an zwei Stellen gleichzeitig: im Benutzerkonto als user_accounts.theme_mode
(NULL bedeutet system, und der Endpunkt lautet PATCH /api/v1/auth/profile/theme), sowie gespiegelt im
phis_theme_mode-Cookie, das von resolvePhiThemeMode tatsächlich ausgelesen wird. Diese Spiegelung dient nicht der
Bequemlichkeit – der statische Proxy wählt ein Rendering aus, und das Bootstrap-Skript trifft die Entscheidung vor dem ersten Rendering,
und keines von beiden kann eine Sitzung auflösen. Der Server schreibt das Cookie bei der Anmeldung und bei jeder Änderung; somit
ist das Konto das, was eine Person über verschiedene Browser hinweg begleitet, und das Cookie ist das, was diese Anfrage erkennen kann.
system bedeutet das Fehlen des Cookies und nicht, dass es einen dritten Wert enthält.
Die vom Konto selbst gelieferte Antwort wird ebenfalls als runtime.viewer.preferredThemeMode übermittelt; dabei handelt es sich um die Auswahl, die möglicherweise
system lautet. runtime.viewer.themeMode daneben ist die Auflösung und bezeichnet stets einen Wert von „half“. Ein Einstellungsfenster
liest den ersten Wert aus: Würde der zweite Wert angezeigt, würde dies dem Nutzer mitteilen, dass er „Hell“ ausgewählt hat, als er sich dafür entschieden hat,
gefragt zu werden. Das Paar verhält sich zueinander wie preferredLocale zu locale.current.
Der Schalter in der Kopfzeile und das Einstellungsfeld beziehen sich auf dieselbe Einstellung. Der Schalter weist zwei Zustände auf und speichert
die Einstellung auf dem Konto, sofern ein solches vorhanden ist (storePhiThemeModePreferenceOnAccount); im Einstellungsfeld befindet sich die dritte
Option, da kein Schalter den Zustand „System“ anzeigen kann.
Blöcke
preset?: string, presetVersion?: number – der Palettenschlüssel und die Version.
Farbe
palette?: PhiThemePalette (theme/phi-theme-presets.ts), in derselben Form, wie sie ein Palettenblock bereitstellt:
seed – von beiden Modi gemeinsam genutzte Startwerte (colorPrimary, colorInfo, colorSuccess, colorWarning,
colorError, colorLink).
modes.light / modes.dark, jeweils mit
seed -- the per-mode base seeds colorTextBase and colorBgBase;
overrides – explizite Farb-Tokens, die keine Startwerte sind, wie beispielsweise colorLinkHover oder colorBgLayout;
customColors – die zehn benutzerdefinierten Phi-Farben custom1 bis custom10;
gradients – die drei Gradienten-Slots gradient1 bis gradient3, jeweils bestehend aus einer Richtung und zwei oder
mehreren Farbstopps (theme/phi-theme-gradients.ts). Sie sind modusspezifisch, und zwar aus demselben Grund, aus dem es einen Modus-Seed gibt:
Der Verlauf, der auf einer hellen Seite als Markierung erkennbar ist, kann auf einer dunklen Seite eine Lücke darstellen. Ein Slot, den die Palette
auslässt, wird aus den vom Modus selbst festgelegten Farben (Primär, Warnung, Info) abgeleitet, sodass jedes Theme
alle drei bereitstellt, ohne dass jemand sie zeichnen muss. Die Slots eines Palettenblocks und die von theme.palette werden pro
Slot zusammengeführt (phi-theme-presets.ts). Sie gelangen als Tokens phiGradient1–phiGradient3
(mit einer passenden …Text-Farbe) auf die Seite, die Ant Design als --ant-phi-gradient-1 usw. schreibt; ein
Control oder ein Background liest die Eigenschaft aus und befindet sich unabhängig von seiner Position im richtigen Modus.
Stil
style?: { token?: Record<string, unknown> } – modusunabhängige strukturelle Ant-Design-Token: Radien, Steuerhöhen,
Abstände, Schriftgrößen.
shape?: { controls?: PhiControlShapeCorners } – siehe
Control shape.
buttons?: { shadow?: { default?, primary?, danger? } } – ein Schritt pro Schaltflächentyp, jeweils
none | soft | strong (theme/phi-button-shadow.ts). Ein Schritt wird zum Token der Button-Komponente
(defaultShadow, primaryShadow, dangerShadow) pro Modus, da ein Schatten, der auf hellem Hintergrund sichtbar ist,
auf dunklem Hintergrund verschwindet. Wird ein Typ nicht festgelegt, wird die getönte Linie von Ant Design beibehalten.
buttons.primaryGradient?: "gradient1" | "gradient2" | "gradient3" | null – der Theme-Farbverlauf, mit dem jeder primäre
Button gefüllt wird (theme/phi-button-shadow.ts, aufgelöst in phi-theme-gradients.ts). Fehlt dieser Wert, behalten primäre
Buttons ihre einfarbige Darstellung bei. Bei Hover und beim Drücken wird ein Filter über den Bereich gelegt, anstatt ihn durch ein
zweites Bild zu ersetzen, da Ant Design jede Button-Eigenschaft überblendet und ein ausgetauschtes Bild zu
störenden Überblendungen führt. Ein einzelner Button kann mit der Variante gradient weiterhin einen eigenen Farbverlauf auswählen.
typography?: { headings?: "body" | "serif" | "display" } – der Schriftart-Slot für die Überschriften h1 bis h3
(theme/phi-theme-typography.ts). Fehlt dieser, wird „body“ verwendet. Bei einer anderen Auswahl als „body“ wird --phi-font-heading für das
Stammelement gesetzt; ein Slot ohne Angabe einer Schriftfamilie greift auf die body-Schriftart zurück.
components?: Record<string, Record<string, unknown>> – Überschreibungen von Ant-Design-Komponenten, die pro
Komponente mit den gemeinsamen Standardwerten der Komponente zusammengeführt werden, ohne dabei jemals das gesamte Objekt zu ersetzen.
Boden
root?: PhiSiteThemeRoot (types/site-theme.ts):
root.background.light / root.background.dark – der Root-Hintergrund pro Modus, basierend auf dem kanonischen
strukturierten Hintergrund-Kontrakt (PhiCmsBackgroundWidgetConfig). Ein Modus ohne diese Angabe verwendet das aufgelöste
Ant Design-colorBgLayout.
root.chrome.light /
root.chrome.dark – das Chrome-Overlay, das die Bereiche „Header“, „Sider“ und „Footer“ gemeinsam nutzen.
Jede Oberfläche kann es als Hintergrund mit dem Basis-Hintergrund
theme anzeigen, und zwar im entsprechenden Farbmodus
(
LAYOUTING.md).
root.chrome.shadow.header | sider | footer -- the Shadow each Chrome family casts at its outer edge
(PhiShadow), independent of mode.
Was die einzelnen Ebenen enthalten können, welche Regionen sie zeichnen und wie eine Region sie überschreibt, ist in
der Datei SHELL.md festgelegt. Die Grundebene gilt für die gesamte Website; es gibt keine
Überschreibung auf Bereichsebene.
Schriftarten
fonts?: { body?, mono?, serif?, accent?, display? } – fünf Slots (PhiSiteFontSlots). Ein Slot enthält einen
Familiennamen oder eine phis:asset/<id>-Referenz auf ein zur Website gehörendes Schrift-Asset.
Es gibt keine „rem“-Einstellung. Ein rem entspricht überall 16px (PHI_REM_ROOT_PX in theme/phi-css-vars.ts):
die Schriftgröße des Dokuments, alle Längenangaben, die dieses Paket umrechnet, sowie die von Ant Design generierte Struktur. Ein
Theme, das alles größer darstellen möchte, passt die fontSize-Einstellung und die Größentoken entsprechend an.
Marke
brand?: PhiSiteThemeBrand, dargestellt durch das Marken-Widget. Die Identität der Website wird hier verwaltet und niemals in einer
Bereichsvoreinstellung.
homeLinkTarget?: PhiLinkTarget – wohin das „Brand“-Widget führt: eine Seite per Verweis oder eine externe Adresse,
das gleiche Ziel, das jeder Link speichert (
REFERENCES.md). Das Seitenziel
bezeichnet den öffentlichen Bereich, da die Marke dorthin führt, wo immer sie angezeigt wird. Es wird auf dem
Server im Rahmen des Render-Durchlaufs für Linkziele aufgelöst, und die Adresse wird an das Marken-Widget übergeben. Fehlt diese
oder ist eine Seite nicht mehr aufrufbar, gilt das Stammverzeichnis der Website in der gerade gelesenen Sprache. Der Referenzindex des Servers
liest CMS-Bäume und nicht den Theme-Eintrag, daher gehört dieses Ziel nicht zu den betroffenen Referenzen, bei denen eine
Pfadänderung berücksichtigt wird.
eyebrow?: string – die schmale Linie oberhalb des Wortzeichens.
logo?: { light?, dark? } – ein Logo pro Modus, jeweils eines von
{ sourceKind: "asset", assetId: number, url?: string } (Die url wird beim Lesen aufgelöst und vom
Picker zusammen mit der ID geschrieben),
{ sourceKind: "url", sourceUrl: string } (a Set's inline Logo until a save uploads it),
{ sourceKind: "none" } (explicitly no Logo, so a Set's Logo does not show through).
Ein Modus, der in der Datensatzdefinition nicht festgelegt ist, zeigt das Logo des zugehörigen Sets an; handelt es sich bei diesem Set um das eines Moduls, wird es beim ersten
Speichern in die Medienbibliothek aufgenommen. Das Kern-Set wird übernommen und niemals kopiert, wie jeder andere
Kernblock auch – sein Logo ist der Platzhalter „Ihr Logo“, und eine Website darf keinesfalls ein leeres Feld enthalten.
logoAlt?: string – greift andernfalls auf den eigenen Alternativtext des Assets zurück.
logoYOffset?: number – Anzahl der Pixel, um die das Logo gegenüber der Wortmarke verschoben wird, um den grafischen
Leerraum auszugleichen. Wird nur dort angewendet, wo das Logo gezeichnet wird. Fehlt der Wert, erfolgt keine Verschiebung.
slogan?: { label?, icon? }, location?: { label?, icon? } – die beiden Rahmenzeilen. Eine Zeile ohne
label zeichnet überhaupt nichts, auch kein Symbol; nur das Symbol verfügt über einen Standardwert (antd:star, antd:location,
PHI_BRAND_LINE_FALLBACK_ICONS), und ein Symbol vor einer leeren Zeile würde signalisieren, dass etwas fehlt,
anstatt dass etwas nicht angefordert wurde.
wordmark?: { fontFamily?, fontWeight?, fontStyle?: "normal" | "italic", letterSpacing?, parts? } mit
parts[] vom Typ { text, color?, fontWeight? }. Die Angaben eines einzelnen Elements haben Vorrang vor denen der Wordmark.
Eine Platzierung gibt nichts davon erneut wieder. Das Marken-Widget wird nur nach einer Sache gefragt – dem mode, d. h., welches der Elemente
lockup | logo | wordmark | slogan | location es hier anzeigt – und liest den Rest aus dem
Datensatz aus. Es gibt keine instanzspezifischen Einstellungen für Titel, Augenbraue, Logo-Umschaltung oder Versatz; eine Marke, die sich an zwei
Stellen einer Website unterscheidet, würde als zwei Marken gelten.
Die Standardvoreinstellung „Public“ platziert das Widget viermal: slogan und location im oberen Bereich der Kopfzeile,
lockup im Hauptbereich der Kopfzeile und wordmark in der Fußzeile. Für keines dieser Elemente wird Text eingefügt. Eine Voreinstellung wird
von jeder Website übernommen, die sie verwendet; daher würde ein dort eingegebener Slogan in der Kopfzeile aller Seiten erscheinen, und eine
Website, die keine der beiden Zeilen angegeben hat, zeigt keine davon an – der Streifen behält seine Form bei.
Was eine Website erhält, ohne etwas anzugeben, ist daher eine Sache und nicht vier: das Logo des ausgewählten Sets.
Ein Set verweist auf eine Farbpalette, einen Stil, einen Hintergrund und ein Schriftpaar, und der einzige Wert, den es vermittelt, ist dieses
Logo (theme/phi-theme-blocks.ts); ein Wortzeichen gehört zu dem Erscheinungsbild, für das es entworfen wurde, und ein Slogan gehört
zur Website, sodass keines von beiden Teil eines Sets ist. Wenn nichts festgelegt ist, greift das Wortzeichen auf den Namen der Website
und anschließend auf deren Schlüssel zurück, und die Linien werden auf nichts zurückgesetzt.
Auf der Builder-Arbeitsfläche wird eine nicht beschriebene Zeile als sie selbst dargestellt – als ihr Fallback-Symbol – sowie ein Satz, der angibt,
welcher Teil des Themes leer ist; denn dort muss ein Widget sichtbar sein, damit man damit arbeiten kann, und der
Slot, den es einnimmt, verfügt über kein eigenes +-Symbol.
Kontakt
contact?: { label?, href?, icon? } – die einzige Möglichkeit, den Betreiber der Website zu erreichen, wie sie im Frame angeboten wird
(helpers/brand-contact.ts). Standardwerte: label Contact, href mailto:info@<site hostname>, icon antd:mail.
widgets.locale?: { mode?: "label-list" | "compact-pill", showText?: boolean } – wird vom „Locale“-Widget ausgelesen; Standardwerte sind compact-pill und true.
widgets.account?: { variant?: "full" | "compact" | "icon-only", showLabel?: boolean, showChevron?: boolean }
– wird vom Account-Widget gelesen; die Konfiguration der jeweiligen Instanz hat Vorrang.
Hierbei handelt es sich ausschließlich um siteweite Standard-Darstellungsoptionen. Die Konfiguration der Widget-Instanzen gehört zu den CMS-Knoten und befindet sich niemals unter
theme.widgets.*.
Schale
shell?: PhiShellTheme (components/shell/shell-types.ts) – Standardeinstellungen auf Shell-Ebene, die keine Widget-
Instanzkonfiguration darstellen:
light / dark: { background?, color? } – globale Shell-Oberfläche pro Modus.
header, sider, footer: jeweils mit den auf Familienebene definierten Einstellungen light / dark sowie Metriken und Einträgen pro Region
header.top | main | bottom, sider.left | right, footer.top | main | bottom. Jeder Eintrag verfügt über die Einstellungen
light / dark { background?, color? } sowie height, width, collapsedWidth, sticky, offsetTop,
und zIndex.
Ein Oberflächenwert wird zunächst regionsspezifisch, dann auf Familienebene und schließlich global aufgelöst; die dunklen Elemente „Header main“ und „Sider“
greifen auf
#001529 zurück. Metriken speisen die Standardvoreinstellungen und die Shell-Brückenvariablen
(
--phi-shell-*,
theme/phi-css-vars.ts). Diese Oberflächen ersetzen weder
root.background noch
root.chrome. Die Aufteilung der Variablen erfolgt über
SHELL.md.
Einbindung in Ant Design
Pro Modus erstellt die Funktion resolvePhiRootTheme(...) (components/root/phi-root-theme-resolver.ts) einen Token-Satz:
- 1.
strukturelle Standardwerte (`buildPhiThemeStructuralTokens`, abgeleitet von der Phi-Skala),
- 2.
Farbmarker aus dem Palettenblock, über die theme.palette überlagert wurde,
- 3.
- 4.
fontFamily / fontFamilyCode aus den aufgelösten Slots body / mono.
Der Algorithmus von Ant Design leitet den Rest ab, mit Ausnahme der Schriftgröße: Jede Größe wird anhand von PHI_FONT_SIZES
(theme/phi-tokens.ts
) festgelegt – xs = 9
, sm = 13
, base = 16
, lg = 21
, xl = 26
, xxl = 34
,
display = 55
– jeweils mit einer Zeilenhöhe, die der jeweiligen Größe plus 8 px entspricht. Die Skala basiert auf dem Wert „phi“ ausgehend von der Grundgröße 16,
die vom Browser vorgegeben ist: sm
, lg
, xxl
und display
sind die Fibonacci-Größen um diesen Wert herum, xl
entspricht 16 × phi, und
xs
behält den Wert 9 bei, den ein Zähler oder ein hochgestellter Wert benötigt. Der Fließtext hat die Größe base
, 16. Die Überschriften h1
–h5
haben die Größen 34, 26,
21, 16, 13; h4
und h5
entsprechen den Größen „body“ und sm
und unterscheiden sich durch Schriftstärke und Farbe. sm
–xl
sowie die Überschriften sind Ant-Design-
Token und können in style.token
überschrieben werden; xs
, xxl
und display
haben kein Token und sind bis Version 1 fest vorgegeben. Größentoken sind numerische Werte wie beispielsweise padding = 21
. Komponenten sind die gemeinsamen
Komponenten-Standardwerte, die pro Komponente mit theme.components
zusammengeführt werden, die Schattenstufen der Schaltflächen sowie die
Form-Token der Steuerelemente.
Das veröffentlichte Theme verfügt über eine Serverprojektion und eine Clientprojektion:
Die Struktur von Ant Design wird nicht gerendert. Das Root-Theme legt zeroRuntime (und hashed: false) fest, und die
Struktur jeder Komponente stammt aus @phis/ui/antd-static.css. Dieser Spezifizierer benennt keine Datei aus
diesem Paket: withPhiNextConfig aus @phis/ui/next/config, das die next.config-Datei der Website umschließt,
generiert die Struktur aus dem von der Website installierten Ant Design – einmal pro Version in
node_modules/.cache/phis-ui/ – und verweist den Spezifizierer darauf. Eine Website aktualisiert Ant Design innerhalb des
Peer-Bereichs, ohne dass eine neue Version dieses Pakets veröffentlicht wird. Die Generierung schlägt fehl – und damit auch der Build der Website –, wenn
ein von Ant Design deklarierter Style-Hook nicht erreicht wird; pnpm antd-css:check und der Paket-Build führen die
gleiche Generierung anhand des eigenen Ant Design dieses Pakets durch. Die Struktur liest jeden Theme-Wert über
`var(--ant-...)` ein, sodass eine einzige Datei für jedes Theme, jeden Modus und jeden verschachtelten Geltungsbereich ausreicht. Sie wird vor den Stylesheets dieses Pakets importiert, sodass eine unserer Regeln, die
auf Spezifität basiert, Vorrang hat.
AntdRegistry in PhiRootLayout extrahiert das, was bei SSR weiterhin gerendert wird: die --ant-*-Variablen
Markup der Serverkomponenten und die Verwendung von reinem CSS, pro Theme-Bereich.
resolvePhiPublishedRootTheme(...) (server-only) gibt ausschließlich strukturelle Variablen aus, die Phi gehören und kein
Ant Design-Token aufweisen.
PhiConfigProvider ist die einzige Client-Grenze für die Konfiguration von Ländereinstellungen und Designs in Ant Design. Sein
usePhiConfig()-Wert enthält die Parameter token, customColors, fonts, layout, mode und presets. Der Server-Root
übermittelt ausschließlich serialisierbare Daten darüber; Client-Designmodule importieren niemals Server-Resolver oder
server-only-Module, und pnpm audit:graph darf keine Erreichbarkeit vom Client zum Server-Only melden.
Die Auflösung der Root erfolgt auf dem Server, und zwar für beide Modi: resolvePhiRootThemeState(...) in PhiRootLayout übergibt
PhiRootLiveThemeProvider das antd-Theme je nach Modus sowie die benutzerdefinierten Eigenschaften des Shell-Chrome-Overlays, und
der Provider ermittelt den Modus lediglich anhand der Bildschirmanzeige, sodass für den Moduswechsel kein Hin- und Rücklauf erforderlich ist. Der Provider ruft
den Resolver erst dann mit import() ab, wenn ein Theme-Entwurf live aus dem Theme-Editor des Builders eintrifft (das
theme-Signal); bis zur Auflösung behält der Frame das vorhandene Theme bei. Der Resolver, die Shell-Bereichsstile
und das Overlay sind beim ersten Laden nicht vorhanden, und scripts/validate-area-client-reach.mjs enthält den
Stammpfad dazu (ROOT_SERVER_RESOLVED_THEME_FILES).
Der Server löst ein Theme einmal pro Prozess auf: Die Funktion
resolvePhiRootThemeState(...) behält den aufgelösten Zustand anhand
des Inhalts, aus dem er abgeleitet wurde, bei und gibt ihn in einem festgelegten Zustand weiter (
gateway/CACHES.md).
Der angegebene Wortschatz
Die Token-Bezeichnungen entsprechen der Schreibweise von Ant Design und werden auch hier verwendet. colorPrimary,
paddingSM und controlHeight haben hier dieselbe Bedeutung wie dort; eine Website speichert sie unter diesen
Bezeichnungen, und der Theme-Arbeitsbereich schreibt sie unter diesen Bezeichnungen. Nichts wird umbenannt und nichts wird
übersetzt. Was hier verwaltet wird, ist die Liste.
In der Datei theme/phi-theme-tokens.ts heißt es:
PHI_THEME_TOKEN_KEYS – alle Namen, die ein Renderer lesen oder schreiben kann. PhiThemeTokens wird anhand dieser Liste aus dem GlobalToken von Ant
Design abgeleitet, und genau diese Liste wird von usePhiConfig().token an eine Client-Komponente übergeben;
PhiServerThemeTokens wird aus derselben Liste abgeleitet, sodass die beiden Projektionen nicht voneinander abweichen können.
PHI_THEME_OWN_TOKEN_KEYS – die Namen, die dieses Haus dem Satz von Ant Design hinzufügt. paddingXXL ist einer davon:
buildPhiThemeStructuralTokens übergibt ihn zusammen mit dem Rest der Skala, und der cssVar-Pass gibt für jedes übergebene Token eine
Variable aus, sodass --ant-padding-xxl auf der Seite erscheint, obwohl AliasToken kein
solches Feld besitzt. Der Typ von Ant Design kennt den Namen nicht; seine Ausgabe hingegen schon. Ein solcher Name wird als
CSS-Variable gelesen, niemals über den Hook, da er nicht aus einem Typ extrahiert werden kann, dem er fehlt.
PHI_THEME_PALETTE_SEED_KEYS und PHI_THEME_STYLE_SEED_KEYS – was eine Palette als Ausgangsbasis liefern kann und was ein
Stil-Token über das Vokabular hinaus aussagen kann (wireframe, das kein Wert auf der Seite ist, sondern der
Schalter, unter dem die Ableitung ausgeführt wird).
Ein gespeichertes Theme wird in der Liste festgehalten. assertPhiThemeVocabulary liest palette.seed,
palette.modes.*.seed, palette.modes.*.overrides und style.token an den Stellen, an denen sie aufgelöst werden,
sowie den „palette“-Block und den „Site“-Datensatz separat, solange sie noch voneinander unterschieden werden können – nach der
Zusammenführung gehört ein falscher Schlüssel niemandem mehr. Es löst einen Fehler aus und benennt jeden fehlerhaften Schlüssel mit der Stelle, an der er stand. Dies
entspricht derselben Strenge, mit der eine gespeicherte Widget-Konfiguration gelesen wird: Ein Theme, das über einen Namen abgeleitet wurde, den niemand hat,
verbirgt den Fehler, da die Seite zwar angezeigt wird, aber genau das, was ein Autor festgelegt hat, einfach nicht vorhanden ist.
Die Bridge ist der Ort, an dem die Ant Design-spezifischen Schreibweisen und Typen vorkommen – und nirgendwo sonst:
theme/phi-theme-tokens.ts (die eine Zeile, die die Werttypen ableitet und gleichzeitig die Drift-Prüfung darstellt –
ein Name, den Ant Design nicht mehr verwendet, wird in der Liste und nicht in den Dateien, die ihn lesen, nicht mehr kompiliert),
theme/phi-antd-token-resolver.ts (die Ableitung der Aliase aus antd/es/theme/themes/*) und
components/root/phi-config-provider.tsx (der Root-Adapter). Oberhalb der Brücke liest alles die
angegebenen Namen; unterhalb davon wandelt eine Implementierung ein gespeichertes Theme in deren Werte um.
Was ein Wechsel von Ant Design also bedeuten würde, ist klar definiert und überprüfbar: Die Namen bilden den Vertrag, der
dahinterstehende Algorithmus hingegen nicht. Eine andere Implementierung muss dieselbe Liste liefern – einschließlich der
Namen, die Ant Design ableitet, anstatt sie vorzugeben; dies ist der Teil, der heute tatsächlich von Ant Design geprägt ist
– und oberhalb der Brücke ändert sich nichts.
Zwei Dinge bleiben bewusst außerhalb der Grenze:
theme.components ist der Komponentenbaum von Ant Design (Layout.*, Menu.*, einige Hundert Bezeichnungen) und
bleibt ein offenes Datensatz. Würde man ihn in einer Liste speichern, müsste der gesamte Baum als Vertrag aufgenommen werden – und das nur wegen
der wenigen Überschreibungen, die eine Website vornimmt.
Der Theme-Arbeitsbereich (plugins/runtime-modules/theme/widgets/brand-controls/client.tsx) bearbeitet diese
Token, anstatt sie zu lesen – er durchläuft sie nach Namen und schreibt sie zurück –, sodass er unterhalb der
Brücke mit den Ant-Design-eigenen Typen angesiedelt ist. Dies ist eine bewusste Entscheidung und kein Leck.
scripts/validate-control-boundaries.mjs holds both halves. It decides which files may import Ant
Design at all, and it checks which names cross: every --ant-* variable written anywhere in the tree is
read back as a token name and must be one the list states. That is the way in that needs no import --
BUILDER.md permits those variables on purpose -- and a typo in one resolves silently to nothing.
Component tokens are the exception and each is named with its reason. A stated name nothing reads or
writes fails the check, and so does a permission nobody uses.
theme.shape.controls ist { topLeft, topRight, bottomRight, bottomLeft }, jeweils
square | subtle | rounded | pill (theme/phi-control-shape.ts). Fehlt dieser Wert, wird die Form des Stilblocks verwendet (Standard:
rounded). Alles andere als die vier bekannten Bezeichnungen löst einen Fehler aus. Ein Datensatz mit abweichenden Ecken ist zwar gültig, lässt sich jedoch
noch nicht darstellen: Bei der Auflösung wird ein Fehler ausgelöst.
square hebt die Rundung auf; pill ist bei rechteckigen Steuerelementen eine volle Kapsel und bei quadratischen
„icon-only“-Steuerelementen ein Kreis. Beides gilt für alle Steuerelementgrößen.
Bei rounded bleibt die numerische Radiusskala unverändert; bei subtle wird diese Skala um eine Stufe nach unten verschoben.
pill wird zentral aus der gerenderten Steuerungshöhe abgeleitet und niemals als border-radius: 50% gespeichert.
Ein Steuerelement, das mit seinem Inhalt mitwächst – ein Textbereich, ein Mehrfachauswahlfeld, bei dem die Tags umgebrochen werden, ein Feld für Erwähnungen –
behält bei jeder Höhe die Kapselhöhe von EINEM Steuerelement bei. Die Hälfte eines vier Zeilen hohen Feldes bildet einen Bogen über dessen
Seite, keine Kapsel; daher entspricht die pill dort der halben Steuerelementhöhe, aufgerundet, und nicht dem vollen Radius.
Die anderen drei Formen geben eine Zahl an und sind davon nicht betroffen.
Die Form erhält die Standardgröße „Control“ über Ant-Design-Komponententoken und die kleinen sowie großen Größen
über die Datei styles/control-shape.css, die die aus den Live-Tokens generierten Variablen --phi-control-radius-* ausliest.
Vergrößerte Steuerelemente übernehmen alle drei Größen aus diesem Stylesheet, einschließlich der Standardgröße: Das ist die Größe, bei der
das Komponententoken für sie falsch ist, und kein Button – dessen Formen -circle und -round, die von den anderen Regeln
ausgenommen sind – kann wachsen.
Dies regelt Kontrollelement-Körper und -Auslöser sowie den Menüpunkt: Ein „Sider“-Eintrag ist in einer
Spalte von Kontrollelementen eine Kontrollelementzeile hoch, sodass sich seine ausgewählte Fläche über itemBorderRadius und
subMenuItemBorderRadius mit diesen abrundet – niemals jedoch über den menüeigenen borderRadius, der den Pfeil eines Untermenütitels
und nichts anderes zeichnet. borderRadiusSM, borderRadius und borderRadiusLG regeln weiterhin
Oberflächen: Layouts, Karten, Bäume, Modale, Schubladen und Popups, einschließlich des Popups eines
Select, Picker oder Cascader.
Die Auswahl erstreckt sich auch auf die Oberflächen, allerdings auf der Oberflächen-Skala und nicht auf der Kontroll-Skala
(resolvePhiSurfaceShapeRadius
): square
nimmt keinen Radius an, subtle
den Wert borderRadiusSM
, rounded
den Wert
borderRadius
und pill
den Wert „borderRadiusLG
LG“. Eine Kapsel um ein Raster oder um eine Inhaltsspalte herum ist kein
Element, daher stellt pill
dort die breiteste Stufe der Skala dar und nicht den vollen Radius. Der Wert wird an der Wurzel
als --phi-surface-radius
übergeben und, sofern eine Komponente ein entsprechendes Token besitzt, als dieses Token:
Table – headerBorderRadius, von dem sich der interne tableRadius-Wert von Ant Design und damit die
oberen Ecken des Containers sowie die Unterkante einer Fußzeile ableiten. Die unteren Ecken werden von Ant Design überhaupt nicht gezeichnet;
styles/controls.css schneidet sie aus der Variablen heraus, wenn eine Fußzeile oder eine Zusammenfassungszeile die Tabelle abschließt.
Collapse – seine Panels, über collapsePanelBorderRadius, das Ant Design von
borderRadiusLG ableitet und anhand dessen es den Container eines Panels, zunächst die Kopfzeile und schließlich den Hauptteil, zeichnet. Dies ist das Element, mit dem das
„Collapsible Layout“ gerendert wird.
Tree – der Knoten wird durch eine Überschreibung des globalen borderRadius-Werts auf Komponentenebene geerdet; genau diesen Wert
liest „Tree“ von Ant Design aus und für den es kein eigenes Token definiert; der Rahmen eines Tree-Elements mit Rahmen, der aus der
Variablen stammt.
Die acht Felder, die aus der globalen Eigenschaft borderRadiusLG abgeleitet wurden, jeweils durch eine Überschreibung auf Komponentenebene
dieser globalen Eigenschaft: der Container, die Kopfzeile, die Abdeckung und die Aktionsleiste einer „Card“; der Inhalt eines Modal, der wie folgt gerendert wird:
Overlay darstellt; sowie die Panels, die ein Dropdown, ein Select, ein DatePicker, ein Cascader, ein
Popover und ein eingeklapptes Untermenü des Sider-Menüs über der Seite öffnen. Ein Overlay und ein Dropdown sind
Flächen wie jede andere auch – was auf ihnen nicht angezeigt wird, ist die Form des Steuerelements, nicht der Maßstab. Ein Drawer (bündig mit dem Rand des Ansichtsbereichs
) ist keine Fläche, auf die sich dies bezieht, und die Symbolkachel, die eine „Card“ neben ihrem Titel anzeigt, ist ein Element
innerhalb einer solchen Fläche, sodass sie den numerischen Maßstab beibehält.
Tooltip – derselbe Schritt wie bei seinem eigenen borderRadius, außer bei pill, wo die Hälfte der
Steuerelementhöhe verwendet wird (resolvePhiTooltipShapeRadius). Die Abkürzung für den vollen Radius kann hier nicht verwendet werden: Ant
Design berechnet die Mindestbreite des Tooltips anhand dieses Wertes, sodass der Wert 9999 einen Tooltip mit einer Breite von zwanzig
Tausend Pixeln erfordern würde. Die Hälfte der Steuerelementhöhe entspricht derselben Kapsel, da die Mindesthöhe eines Tooltips
der Höhe des Steuerelements entspricht und ein Tooltip, der umbricht, diese Ecke beibehält, anstatt einen Bogen zu bilden.
Layout – der Rahmen eines Layouts mit einer Oberfläche, sofern der Autor keine Ecken konfiguriert hat. Eine Ecke in einem
benutzerdefinierten (custom) Rahmen hat stets Vorrang: Die Einstellung „step“ gilt als Standardwert, sie stellt keine Obergrenze dar. Außerhalb des Providers ist die
Variable nicht vorhanden, und ein Layout greift auf keinen Radius zurück. Ein Layout ohne Fläche weist keine Ecken auf,
da es dort keinen Rahmen gibt, der abgerundet werden könnte. Die Stufe wird als Langform angewendet, sodass sie niemals neben den
Ecken steht, die ein konfigurierter Rahmen definiert. Bei Phi-Steuerelementen hat die Form Vorrang vor widersprüchlichen Radius-Überschreibungen
durch Komponenten. Die geteilte Karte ist eine in zwei Teile geteilte Karte, daher entspricht ihre Ecke einfach der ihrer Fläche.
Ein Phi-Control, das seine eigene Oberfläche zeichnet – den Rahmen eines umrandeten Baums sowie eine Medienkachel zusammen mit
dem Skelett, das als Platzhalter dafür dient. Es gibt kein Komponenten-Token, das den Schritt zu einem Feld überträgt, das sich das Phi selbst zeichnet, daher
liest es die Variable direkt aus. Der Config-Provider deklariert dies auf seinem Element im Server-Render und spiegelt
es für Portale in das Dokument wider, und nichts von Phi wird außerhalb davon gerendert (dort löst usePhiConfig einen Fehler aus), sodass
ein --ant-*-Fallback daneben lediglich einen fehlenden Provider verbergen würde.
Die intrinsische Geometrie bleibt maßgeblich: „Switch“ bleibt eine Kapsel, „Checkbox“ und „Radio“ behalten ihre Formen bei, verbundene
Gruppen runden nur ihre äußere Begrenzung ab.
--ant-border-radius hat auf einer Oberfläche eine bestimmte Bedeutung und auf einem Steuerelement eine andere; daher darf ein Widget, das einen eigenen
Rahmen um ein Steuerelement zeichnet, diesen Wert nicht auslesen. Ant Design liefert ein Komponententoken im CSS-Variablenmodus als lokale
Neudefinition derselben Variablen für das Control-Element (.ant-input-css-var, .ant-select-css-var), wodurch
die Form überhaupt erst ihre Standardgröße erreicht: Auf einer Oberfläche enthält die Variable den Oberflächenradius, bei einem
Control enthält sie die Control-Form – bei pill den vollen Radius. Ein Feld, das borderless gerendert wird und dessen
Wrapper den Rahmen und die Ecken bereitstellt, nimmt daher --phi-control-radius-grown-* an, ohne dass es
daneben einen Fallback gibt. Dasselbe gilt für jedes --phi-control-radius-* in styles/control-shape.css.
Bitte geben Sie ausschließlich den semantischen Wert an. Pixelradien, Prozentangaben, Ant-Design-Token-Namen und komponentenbezogene Überschreibungen
sind nicht Bestandteil dieses Feldes.
Schriftarten und Typografie
Die fünf Kategorien sind body, mono, serif, accent und display. Die Kernschriftarten für die ersten drei Kategorien lauten
Fira Sans, Fira Mono und Lora.
Ein Schriftfamilienname wird über den Schriftkatalog (theme/phi-font-catalogue.ts) seiner CSS-Variablen zugeordnet:
--phi-font-source-body, --phi-font-source-mono, --phi-font-source-serif für die Kernfamilien sowie
den von Modulen deklarierten Variablen. Ein Name, der nicht im Katalog enthalten ist, wird unverändert an den Browser übermittelt. Ein
phis:asset/<id>-Slot wird in @font-face-Regeln für das siteeigene Asset
(theme/phi-theme-fonts.server.ts) aufgelöst.
accent und display haben keine Kernfamilie. Widget-Schriftartenschlüssel ordnen ihnen body zu, wenn sie nicht festgelegt sind.
Typografie-Schlüssel für Widgets (Datei types/site-theme.ts, Verzeichnis components/widgets/helpers/):
fontFamily = inherit | system | body | mono | serif | accent | display, ermittelt anhand von
usePhiConfig().fonts und dem Ant Design-Token; system entspricht dem Token fontFamily.
fontSize = inherit | xs | sm | base | lg | xl | xxl, aufgelöst in PHI_FONT_SIZES.xs, fontSizeSM,
fontSize, fontSizeLG, fontSizeXL, PHI_FONT_SIZES.xxl. display wird dort nicht angeboten.
Für die Größen werden Ant-Design-Token und --ant-font-size*-Variablen verwendet; es gibt keinen --phi-font-size-*- oder
--phi-font-family-*-Vertrag.
Deklaration, Vorladen, Beiträge zu Modul-Schriftarten und unternehmenseigene Schriftartdateien:
NEXT_INTEGRATION.md.
Token und CSS-Regeln
theme.palette und theme.style.token, die über die nachfolgenden Blöcke aufgelöst werden, sind die einzige Quelle für Ant Design-
Design-Token. Die cssVar-Ausgabe und die SSR-Variablen --ant-* leiten sich aus dieser Quelle ab. Der px2rem-Durchlauf über
die generierte Struktur stellt eine Rem-Brücke dar, nicht eine Token-Quelle.
Client-Komponenten lesen die Ant-Design-Semantik aus `usePhiConfig().token` (oder `theme.useToken()` innerhalb eines
verschachtelten Ant-Design-Providers) aus. Reines CSS und Server-Komponenten verwenden `var(--ant-...)`. Server-Komponenten sind niemals
von `ConfigProvider` oder Client-Theme-Hooks abhängig.
--phi-* ist für strukturelle oder technische Werte reserviert, die Phi gehören und von Ant Design nicht abgebildet werden – Shell-Geometrie,
Builder-Scaffold-Geometrie, Effekte, Schriftquellen, Radien von Steuerelementen. Bitte
übertragen Sie keine Farben, Abstände, Radien, Typografie, Schatten, Steuerelementgrößen oder Bewegungen aus Ant Design in --phi-*.
Benutzerdefinierte Farben sind Daten in usePhiConfig().customColors und niemals globale CSS-Variablen; Nutzer dürfen diese nicht
aus CSS rekonstruieren oder durch semantische Tokens ersetzen. Der Theme-Arbeitsbereich ist der einzige Ort, an dem
eine unveröffentlichte Entwurfspalette explizit bereitgestellt wird.
Eine benutzerdefinierte Eigenschaft mit Komponenten-Gültigkeitsbereich kann ein Live-Token in einen Selektor oder ein Pseudo-Element einbinden; dies ist ein
Implementierungsdetail und keine zweite Theme-API.
Verwenden Sie Inline-Stile für Geometrie- und instanzspezifische Layoutwerte. Führen Sie aus Tokens abgeleitete visuelle Endwerte
(color, background, border*, boxShadow) nicht über Inline-Stile in Client-Komponenten ein, wenn diese
durch eine Klasse oder eine CSS-Variable ausgedrückt werden; Browser normalisieren diese Werte und verursachen dadurch Abweichungen bei der Einbindung.
Die PHI_*-Konstanten (theme/phi-tokens.ts) sind Startwerte und Standardwerte, jedoch keine aktive Quelle für Laufzeitthemen.
Die Abmessungen der „Stable Shell“ stammen aus theme.shell, wobei PHI_* lediglich als Standardwerte dienen.
Serverkomponenten dürfen runtime.site.theme nur für site-eigene Verträge auslesen, die Ant Design nicht modelliert,
wie beispielsweise „Shell“, „Brand“ und „Contact“.
Bevorzugen Sie Ant-Design-Themes sowie Komponententoken und Komponentenvarianten gegenüber CSS-Überschreibungen. Fest codierte Farben,
Radii, Typografie-Werte oder individuelle Anpassungen werden nur auf ausdrücklichen Wunsch des Betreibers hinzugefügt.
Der ConfigProvider enthält ausschließlich Ant-Design-Konfigurationen, niemals Phi-Site- oder Laufzeitkonfigurationen. Komponentenstile auf Provider-Ebene
werden niemals fest im Root-Layout codiert; visuelle Standardwerte werden über die gemeinsamen Token-Helfer
weitergeleitet und können weiterhin durch site.theme überschrieben werden.
Der Feature-Code speichert semantische Phi-Werte (z. B. theme.shape.controls); die Namen der Adapter-Token und die CSS-Werte
werden zentral aufgelöst und tauchen niemals in der Modul- oder Widget-Konfiguration auf.
Phi-Skala
Die Basisabstandsskala gilt global für alle Phi-Seiten (PHI_PADDING, theme/phi-tokens.ts):
xxs = 3, xs = 8, sm = 13, base = 21, md = 34, lg = 55, xl = 89, xxl = 144.
Es handelt sich um eine einheitliche Skala für alle Abstände, die eine Phi-Oberfläche angibt, sowohl innerhalb eines Rahmens (padding) als auch zwischen zwei Elementen
(gap): Server-Stile und Voreinstellungen verwenden PHI_SPACE (var(--ant-padding-*)), und die Abstandsoptionen
im Inspektor basieren auf dieser einheitlichen Skala. Die margin*-Familie von Ant Design basiert auf derselben
Sequenz, da ihre eigenen Komponenten diese auslesen; Phi-Code schreibt sie nicht.
Website-Themes überschreiben diese Basis; sie ersetzen sie nicht durch ein unabhängiges Abstandssystem. Die Theme-Auflösung
umfasst drei Ebenen: die CSS-Basislinie, das aus der Phi-Skala abgeleitete Standard-Ant-Design-Theme und die
site.theme-Werte der Website.
CSS-Dateien
PhiRootLayout importiert antd/dist/reset.css direkt und hostet die Provider; es verfügt nicht über eine eigene Shell-Topologie.
topology.
Die Datei styles/root.css enthält die Basisregeln für html und body, Regeln mit Auswirkungen auf die oberste Ebene sowie kleine Hilfsfunktionen.
Die Datei styles/control-shape.css wendet die Steuerelementform auf kleine und große Steuerelementgrößen an.
styles/shell.css und „Region chrome:
SHELL.md“.
styles/layout.css,
layout-authoring-scaffold.css,
layout-affordances.css und
builder-scaffold.css:
LAYOUTING.md. Die Stile des Builder-Scaffolds werden ausschließlich von der Builder-Erstellung importiert,
niemals vom Root oder einem öffentlichen Laufzeiteintrag.
Regeln
site.theme holds Site-wide presentation defaults. It is not the page-metadata owner; page title and
description come from the Page record.
Die Konfiguration der Widget-Instanzen befindet sich auf den CMS-Knoten; Bereichsvoreinstellungen verfügen über eine eigene Region, ein eigenes Layout und eine eigene Widget-Struktur.
Ein Widget oder Layout ist eine Hülle um Ant Design: Innerhalb einer solchen Hülle ist Ant Design frei verfügbar, und ein Widget kann seine
eigenen Steuerelemente mit Flex, Space, Row oder Col anordnen. Das Zusammenstellen mehrerer Widgets erfolgt ausschließlich über Layouts und deren
Slots, niemals über eine Ant-Design-Layout-Primitive oder handgeschriebenes CSS. Ein Widget enthält niemals ein anderes
Widget.