SOLCOM-Brandfarben als Hybrid-Layer im Theme verankern
theme.brand.css), shadcn-Semantik als Schnittstelle — sodass Components bg-primary schreiben können, ohne Brand-Hex-Werte zu kennen.
Kontext
Die SOLCOM-Brand-Palette aus dem Figma Design System (figma.com/design/CHHDfbpX8Ys2LBiGs5HVK0, Node 657:12324 „Colors") muss im byte_theme (Fork von drupal/byte_theme, siehe ADR-0001) hinterlegt werden. Die Palette unterscheidet drei Gruppen: Brand Colors (Lime #BEDC00, Background Blue #011C53, Dark Blue #001F46, zwei Gradients), Gray (Dark Gray #828282 plus Opazitäten 70/40/15 %, Light Gray #EBEBEB) und Basic Colors (Black, White, Error #F59678, Disabled Blue #28468C). Das bestehende Theme nutzt das shadcn/ui-Vokabular (--primary, --accent, --destructive, …) in oklch()-Notation. Eine 1:1-Übernahme der Brand-Hex-Werte in die shadcn-Slots wäre intransparent (welcher Slot bekommt Lime?), eine reine Brand-Layer ohne Mapping würde das shadcn-konforme Component-Inventar (button.twig referenziert bg-primary, bg-accent, ring-ring, …) brechen.
Entscheidung
Hybrid: Brand-Tokens als Quelle der Wahrheit, shadcn-Semantik als Schnittstelle. Eine neue Datei src/theme.brand.css definiert alle Marken-Variablen (--brand-lime, --brand-dark-blue, --brand-bg-blue, --brand-gray, --brand-gray-15/40/70, --brand-light-gray, --brand-error, --brand-disabled-blue, --brand-black, --brand-white, --brand-gradient-1/2). Sie wird in byte_theme.libraries.yml vor src/theme.css als raw CSS geladen. src/theme.css definiert die shadcn-Tokens ausschließlich als Aliasse (--primary: var(--brand-lime), --background: var(--brand-bg-blue), …) und ersetzt damit die bisherigen oklch()-Literale. Zusätzlich wird --ring: var(--brand-lime) neu eingeführt und --color-ring plus --color-brand-*-Aliasse in src/main.css (@theme inline) ergänzt, damit Tailwind-Utilities (ring-ring, bg-brand-lime, …) auflösen.
Semantisches Mapping
Das Mapping wurde aus realen Layouts in Figma abgeleitet (Job-Listing Node 1160:20009, Buttons Node 766:15037):
--background → --brand-bg-blue(#011C53Page-BG)--card → --brand-white(Cards sind weiß auf Dark-BG)--primary → --brand-lime,--primary-foreground → --brand-dark-blue(alle CTAs Lime mit Dark-Blue-Text)--ring → --brand-lime(Focus-Outline der Buttons ist Lime)--destructive → --brand-error--borderund--input → --brand-gray-15(dezente Card-Trenner)--muted-foreground → --brand-gray(Sekundärtext)--accent → --brand-light-gray(bewusst nicht Lime:button.twigziehtbg-accent text-accent-foregroundfür diesecondary-Variante; Lime dort hätte Primär- und Sekundärbutton visuell identisch gemacht)--secondary → --brand-light-gray(Fallback; aktuell nicht von Components genutzt, aber von shadcn-Defaults erwartet)
theme.brand.css ändern — shadcn-Mapping und Component-Klassen bleiben unberührt.Rejected alternatives
Direkt-Replacement der shadcn-Tokens mit Brand-Hex-Werten (--primary: #BEDC00) rejected
Kürzer, aber Brand-Updates erfordern Suche/Ersetzung an mehreren Stellen; kein klares Vokabular für Designer:innen, die eine spezifische Brand-Farbe referenzieren wollen, ohne über die semantische Bedeutung nachzudenken.
Reine Brand-Layer ohne shadcn-Mapping rejected
Hätte alle Components zwingen, bg-[var(--brand-lime)] o. ä. zu schreiben statt bg-primary. Bricht den bestehenden Component-Stil und verliert die shadcn-Compatibility.
Alles in einer Datei (theme.css) mit Section-Headern rejected
Lesbar, aber vermischt zwei Lebenszyklen (Brand-Refresh vs. Component-Mapping-Refactor) in derselben Datei. Bei separaten Dateien sieht man im PR-Diff direkt, ob das Brand-Layer geändert wurde oder „nur" das Mapping.
--accent auf Lime mappen rejected
shadcn-typische Wahl (Accent = Brand-Highlight), bricht aber button.twig — der Sekundärbutton würde optisch mit dem Primärbutton verschmelzen, weil er bg-accent zieht.
Opazitäts-Grays als Tailwind-Modifier (bg-brand-gray/15) statt eigene Tokens rejected
Tailwind-idiomatisch und kürzer, aber die Figma-Palette nennt vier explizite Tokens. 1:1-Tokens machen Code-Suche deterministisch.
Adobe Color, Open Color o. Ä. als Brand-Layer-Generator rejected
Nicht erwogen, weil Figma die Quelle der Wahrheit ist und eigenständige Hex-Pflege ausreicht.
Consequences
- Visueller Bruch im bestehenden Theme: Die alten
oklch()-Werte waren ein zusammenhängendes Dunkelblau-Schema, das aktuelle Mapping ist ein Dunkelblau-mit-weißen-Cards-Schema. Auf Seiten, diebg-cardbenutzen, wechselt der Hintergrund von Dunkelblau zu Weiß; Komponenten, die für den vorherigen Dunkelblau-Card erwartet waren, brauchen ggf. ein Component-CSS-Update, damit Text und Border noch lesbar sind. Vor dem Live-Schalten visuell durch alle Hauptseiten gehen. - Button-Component bleibt vorerst auf shadcn-Defaults: SOLCOM-spezifische Button-States (Hover invertiert zu Weiß, Focus mit Lime-Outline plus weißem Fill, Disabled mit
--brand-disabled-blue) sind im aktuellenbutton.twignicht implementiert.disabled:opacity-50bleibt generisch. Für Brand-Konformität ist eine separate Überarbeitung nötig. - Gradient-Winkel sind eine Schätzung:
--brand-gradient-1(135°) und--brand-gradient-2(45°) wurden aus den Swatches im Color-Board-Layout abgeleitet, ohne reales Verwendungs-Layout als Referenz. Beim ersten echten Einsatz gegen den dortigen Figma-Frame validieren. --ringist neu definiert, nicht aus alten Defaults migriert: Falls künftig Custom-Komponenten einen anderen Focus-Ring brauchen, müssen siering-[…]mit eigenem Wert nutzen oder--ringlokal überschreiben.color-mix(in oklab, …)-Support: Browser-Baseline ist Safari 16.4+ / Chrome 111+ / Firefox 113+ (Mai 2023). Für SOLCOM-Site-Zielgruppen unproblematisch; bei Bedarf Fallback-Werte für ältere Browser nachrüsten.- Tailwind-Tree-Shaking: Die Brand-
--color-*-Aliasse inmain.csswerden nur dann inbuild/main.min.cssausgegeben, wenn ein Twig-Template eine entsprechende Utility referenziert. Die Brand-CSS-Variablen selbst sind aber unabhängig davon im Browser verfügbar (übertheme.brand.cssals raw-CSS-Library).