Files
tessera-ctl/apps/web/src/components/brand/brand.ts
T
schalli ecff144449 feat(brand): ganzes T der Bildmarke übernimmt die Akzentfarbe – Kacheln als abgeleiteter dunklerer Ton
- BRAND_OLIVE_MIX (54 %, #363636) und BRAND_OLIVE_FILL in brand.ts, Kalibrierung kommentiert
- vier achsenparallele Kacheln in tessera-logo.tsx: Inline-Style BRAND_OLIVE_FILL, festes Oliv-Attribut als Rückfall
- brand.test.ts (neu): rechnet Kalibrierung, Neutralität und Grenzfälle aus denselben Konstanten nach
- tessera-logo.test.tsx: Kacheltest auf Token-Fuellung (1x) und abgeleitete Fuellung (4x) umgestellt

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 14:18:58 +02:00

66 lines
3.1 KiB
TypeScript

/**
* Markenfarben der Tessera-Bildmarke.
*
* Dies ist die einzige Stelle im Web-Quellcode, an der eine Markenfarbe
* notiert wird. Jede Stelle der Oberflaeche, die eine Markenfarbe braucht
* (die Bildmarken-Komponente, das Anmelde-Panel, der Vorgabewert der
* persoenlichen Akzentfarbe), importiert sie von hier. Eine spaetere
* mandantenspezifische Gestaltung setzt an dieser Datei an. Auch die
* Ableitungsregel fuer den Olivton der vier achsenparallelen Kacheln lebt
* hier (BRAND_OLIVE_MIX, BRAND_OLIVE_FILL).
*/
/**
* Standard-Gelb der gedrehten Signalkachel und Rueckfall, wenn keine
* persoenliche Akzentfarbe (`--primary`) gesetzt ist. Die Kachel selbst wird
* in tessera-logo.tsx per `style={{ fill: var(--primary, BRAND_YELLOW) }}`
* gefuellt -- nicht mehr per festem `fill`-Praesentationsattribut.
*/
export const BRAND_YELLOW = '#ffed00';
/**
* Olivton der vier achsenparallelen Kacheln bei Standard-Gelb. In der
* Bildmarke seit quick-260917-jdf Kalibrierziel und Rueckfall
* (Praesentationsattribut fuer Browser ohne `color-mix()`) -- die
* eigentliche Fuellung leitet BRAND_OLIVE_FILL aus der Akzentfarbe ab.
* `apps/web/src/app/icon.svg` (Favicon) und die daraus erzeugten
* Tauri-Icons verwenden den Wert weiterhin fest.
*/
export const BRAND_OLIVE = '#9c9440';
/** Farbe der abgerundeten Grundplatte. */
export const BRAND_PLATE = '#1a1a1a';
/**
* Mischanteil der Akzentfarbe (in Prozent) und neutrales Mischgrau fuer den
* abgeleiteten Olivton der vier achsenparallelen Kacheln (quick-260917-jdf).
*
* Gesucht war `color-mix(in oklab, #ffed00 P%, #GRAU)` = `#9c9440`. Rechnung
* sRGB -> OKLab -> sRGB nach CSS Color 4 (Referenz:
* `260917-jdf-oklab-kalibrierung.cjs` im Quick-Ordner, Nachweis in
* brand.test.ts). Ergebnis: 54 % / #363636 -> `#9c9440` exakt (Abweichung
* 0/0/0 je Kanal). OKLCH-Verhaeltnis Gelb -> Oliv: L 0.931 -> 0.656,
* C 0.197 -> 0.106, Farbton 104 Grad gleich.
*
* Warum `oklab` statt `oklch`: mit neutralem Grau ist das Ergebnis
* identisch (Farbton bleibt, Chroma und L skalieren linear), aber ohne
* Abhaengigkeit von der Sonderregel fuer den Farbton achromatischer Farben
* in polaren Raeumen.
*
* Verhalten fuer andere Akzentfarben: CSS-Standard `oklch(0.91 0.19 102)`
* (globals.css) -> `#9a903f` (-2/-4/-1), #ffffff -> neutrales Grau
* `#9c9c9c`, #0057b8 -> `#284a7b`. Akzentfarben dunkler als das Mischgrau
* (OKLab-L < 0.333, z. B. Schwarz -> `#0c0c0c`) werden heller statt dunkler
* -- bewusst hingenommen, kein Schutzmechanismus.
*/
export const BRAND_OLIVE_MIX = { primaryShare: 54, mixWith: '#363636' } as const;
/**
* CSS-Ausdruck fuer den Inline-`fill` der vier achsenparallelen Kacheln in
* tessera-logo.tsx -- die einzige Stelle, an der dieser Ausdruck gebildet
* wird. `--primary` setzt `applyAccentColor` (auth-store.ts); der
* CSS-Standardwert steht in globals.css; der `var()`-Rueckfall
* (BRAND_YELLOW) greift nur, wenn gar kein Stylesheet geladen ist.
*/
export const BRAND_OLIVE_FILL = `color-mix(in oklab, var(--primary, ${BRAND_YELLOW}) ${BRAND_OLIVE_MIX.primaryShare}%, ${BRAND_OLIVE_MIX.mixWith})`;