Die Vulnerabilities-Seite trug auf neun Job-Buttons, sieben Filtern und einem Dutzend Row-Badges je einen eigenen Farbton (blau/amber/lila/rot/ orange/emerald/sky/cyan/gelb). Wenn alles schreit, hoert man nichts: das Rot von KEV konkurrierte mit dem Lila von "EOL Check". Statt Hexcodes zu tauschen erst eine Token-Schicht in OKLCH (Neutral / Brand / Semantisch, Werte fuer light + mid + dark), dann die Komponenten darauf umgestellt. Farbwechsel ist ab jetzt eine Token-Aenderung. Die Regel dahinter, dokumentiert in DESIGN.md: ein Farbton bedeutet Zustand, sonst nichts. - Job-Buttons neutral, genau ein Brand-Button (Refresh Threat Intel). - Filter sind neutrale Pills und faerben sich nur, wenn sie greifen — ueber :has(input:checked), ohne JS. Informativer als vorher, weil man jetzt sieht, welche Filter aktiv sind. - Badges nur noch danger/warn/ok/info. Was bloss eine Identitaet nennt (Scanner-Name, Paketname, PoC-Zaehler), bleibt neutral. MSF und SSVC "widespread" behalten die einzige Vollton-Flaeche, sie sind die hoechste Stufe. Jedes Tag traegt weiterhin seinen Text, damit der Zustand nicht allein an der Farbe haengt. - Die acht Data-Jobs sind keine Filter und standen mitten in der Filterzeile — jetzt in einem zugeklappten <details>. Die .tv-*-Klassen sind ausschliesslich aus Tokens gebaut und laufen dadurch in allen drei Themes ohne Eintrag in der Utility-Remap-Schicht. Das ist der Weg, die Schicht langfristig loszuwerden. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KRCKYPm4DQ2vwDkNugGvHK
3.1 KiB
TrueVuln — Design-Tokens
Alle Farben liegen als CSS-Variablen in frontend/app/globals.css.
Farbwechsel = Token-Werte ändern, nichts anderes. Keine neuen Hex-Werte
in Komponenten.
Format ist OKLCH (L C H): wahrnehmungsgleichmäßige Helligkeit, dunkle
und helle Stufen verlieren die Sättigung nicht. Chroma bleibt für UI unter
~0.22, Neutrale unter 0.02.
Die Regel
Drei Gruppen, und nur die Zuordnung entscheidet — nicht der Geschmack:
| Gruppe | Wofür | Tokens |
|---|---|---|
| Neutral | Der Großteil der UI: Flächen, Text, Border, alles was nur benennt | --tv-fg, --tv-fg-soft, --tv-fg-muted, --tv-line, --tv-line-strong, --tv-btn-bg, --tv-mute-* |
| Brand | Genau eine Sache: die primäre Aktion und der aktive Filter | --tv-brand, --tv-brand-solid, --tv-brand-hover, --tv-brand-soft, --tv-brand-ring |
| Semantisch | Nur Zustand | --tv-danger*, --tv-warn*, --tv-ok*, --tv-info* |
Ein Farbton bedeutet Zustand, sonst nichts. Ein Label, das nur eine Identität nennt (Scanner-Name, Paketname, PoC-Anzahl), bleibt neutral — sonst konkurriert es mit dem Rot, das wirklich zählt. Vorher trug jeder Job-Button und jeder Filter eine eigene Farbe; dadurch stach nichts mehr hervor.
Zustände nie nur über Farbe: jedes Tag trägt zusätzlich seinen Text
(KEV, PATCH AVAILABLE, TI-TOTAL), damit es auch bei Farbfehl-
sichtigkeit lesbar bleibt.
Semantik-Zuordnung (Vulnerabilities)
| Token | Bedeutung | Beispiele |
|---|---|---|
--tv-danger |
akute Bedrohung / offen | CRITICAL, KEV, RANSOM, TI-TOTAL, EXPLOITABLE, Status open, CPR/Priority-Balken hoch |
--tv-danger-solid (.tv-tag--alarm) |
eine Stufe darüber: waffenfähig | MSF, SSVC widespread |
--tv-warn |
erhöht, aber nicht akut | HIGH, EDB, AUTO, EU-CRIT, VPR ≥ 7, SSVC active |
--tv-ok |
erledigt / bestätigt gut | PATCH AVAILABLE, Status patched, cross-confirmed |
--tv-info |
Einordnung ohne Dringlichkeit | MEDIUM, EUVD, EOL, aktiver Suchbegriff |
| neutral | reine Identität | Scanner-Namen, Paketnamen, PoC-Zähler, deferred, LOW, NON-CVE |
Komponenten-Klassen
.tv-btn / .tv-btn--primary, .tv-chip (+ .tv-chip__box), .tv-tag
(+ --danger --warn --ok --info --alarm --lg), .tv-bar
(+ __hi __mid __low), .tv-pop, .tv-drawer.
Sie sind ausschließlich aus Tokens gebaut und funktionieren dadurch in
allen drei Themes (light / mid / dark) ohne Eintrag in der
Utility-Remap-Schicht darüber. Neue UI bitte damit bauen, nicht mit
bg-red-100 text-red-700-Ketten — das ist der Weg, die Remap-Schicht
langfristig loszuwerden.
Der aktive Zustand eines Filter-Chips kommt aus :has(input:checked) —
kein JS, kein State-Prop.
Themes
:root = light. html[data-theme="mid"|"dark"] überschreiben nur die
Token-Werte: Neutrale hängen sich an die vorhandene Surface-Skala,
semantische Flächen werden über color-mix(… , transparent) zu
Tints (eine Pastellfläche würde auf dunklem Grund ein Loch reißen),
und die Vordergrundfarben steigen in der Helligkeit, damit AA bleibt.
--tv-brand-solid bleibt in beiden Modi dunkel genug für weißen
Button-Text.